1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <ble_os.h>
10 #include <stdbool.h>
11 #include <bt_errno.h>
12 
13 #include <net/buf.h>
14 #include <bluetooth/bluetooth.h>
15 #include <bluetooth/conn.h>
16 #include <bluetooth/uuid.h>
17 #include <api/mesh.h>
18 
19 #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_MESH_DEBUG)
20 #include "common/log.h"
21 
22 #include "test.h"
23 #include "adv.h"
24 #include "prov.h"
25 #include "net.h"
26 #include "beacon.h"
27 #include "lpn.h"
28 #include "friend.h"
29 #include "ble_transport.h"
30 #include "access.h"
31 #include "foundation.h"
32 #include "proxy.h"
33 #include "settings.h"
34 #include "mesh.h"
35 
36 #ifdef CONFIG_BT_MESH_PROVISIONER
37 #include "provisioner_prov.h"
38 #include "provisioner_main.h"
39 #include "provisioner_proxy.h"
40 
41 static volatile bool provisioner_en;
42 #endif
43 
44 #ifdef CONFIG_BT_MESH_EVENT_CALLBACK
45 #include "mesh_event_port.h"
46 #endif
47 
48 static uint8_t mesh_init = 0;
49 
bt_mesh_provision(const u8_t net_key[16],u16_t net_idx,u8_t flags,bt_u32_t iv_index,u16_t addr,const u8_t dev_key[16])50 int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx, u8_t flags, bt_u32_t iv_index, u16_t addr,
51                       const u8_t dev_key[16])
52 {
53     bool pb_gatt_enabled;
54     int err;
55 
56     BT_INFO("Primary Element: 0x%04x", addr);
57     BT_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x", net_idx, flags, iv_index);
58 
59     if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_VALID)) {
60         return -EALREADY;
61     }
62 
63     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
64         if (bt_mesh_proxy_prov_disable(false) == 0) {
65             pb_gatt_enabled = true;
66         } else {
67             pb_gatt_enabled = false;
68         }
69     } else {
70         pb_gatt_enabled = false;
71     }
72 
73     err = bt_mesh_net_create(net_idx, flags, net_key, iv_index);
74     if (err) {
75         atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
76 
77         if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && pb_gatt_enabled) {
78             bt_mesh_proxy_prov_enable();
79         }
80 
81         return err;
82     }
83 
84 #ifdef CONFIG_GENIE_MESH_ENABLE
85     // if(bt_mesh_elem_count() == 1)
86     // {
87     // bt_mesh.seq = 0U;
88     // }
89     // else
90     // {
91     atomic_set_bit(bt_mesh.flags, BT_MESH_SEQ_PENDING);
92     // }
93     // printf("bt_mesh_provision seq:0x%x\n", bt_mesh.seq);
94 #else
95     bt_mesh.seq = 0U;
96 #endif
97 
98     bt_mesh_comp_provision(addr);
99 
100     memcpy(bt_mesh.dev_key, dev_key, 16);
101 
102     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
103         BT_WARN("Storing network information persistently");
104         bt_mesh_store_net();
105         bt_mesh_store_subnet(&bt_mesh.sub[0], 0);
106         bt_mesh_store_iv(false);
107     }
108 
109     bt_mesh_net_start();
110 
111     return 0;
112 }
113 
bt_mesh_reset(void)114 void bt_mesh_reset(void)
115 {
116     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
117         return;
118     }
119 
120     bt_mesh.iv_index = 0U;
121 
122     memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
123 #ifdef CONFIG_GENIE_MESH_ENABLE
124     // if(bt_mesh_elem_count() == 1)
125     // {
126     //   bt_mesh.seq = 0U;
127     // }
128     // else
129     // {
130     atomic_set_bit(bt_mesh.flags, BT_MESH_SEQ_PENDING);
131     // }
132     // printf("bt_mesh_reset seq:0x%x\n", bt_mesh.seq);
133 #else
134     bt_mesh.seq = 0U;
135 #endif
136 
137     k_delayed_work_cancel(&bt_mesh.ivu_timer);
138 
139     bt_mesh_cfg_reset();
140 
141     bt_mesh_rx_reset();
142     bt_mesh_tx_reset();
143 
144     if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) {
145         bt_mesh_lpn_disable(true);
146     }
147 
148     if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) {
149         bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY);
150     }
151 
152     if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
153         bt_mesh_proxy_gatt_disable();
154     }
155 
156     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
157         bt_mesh_clear_net();
158     }
159 
160     memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
161 
162     bt_mesh_scan_disable();
163     bt_mesh_beacon_disable();
164 
165     bt_mesh_comp_unprovision();
166 
167     if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
168         bt_mesh_prov_reset();
169     }
170 
171 #ifdef CONFIG_BT_MESH_PROVISIONER
172     provisioner_upper_reset_all_nodes();
173 #endif
174 }
175 
bt_mesh_is_provisioned(void)176 bool bt_mesh_is_provisioned(void)
177 {
178     return atomic_test_bit(bt_mesh.flags, BT_MESH_VALID);
179 }
180 
bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)181 int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
182 {
183     if (!mesh_init) {
184         return -EINVAL;
185     }
186 
187     if (bearers >= (BT_MESH_PROV_GATT << 1) || bearers == 0) {
188         return -EINVAL;
189     }
190 
191     if (bt_mesh_is_provisioned()) {
192         return -EALREADY;
193     }
194 
195     if (IS_ENABLED(CONFIG_BT_DEBUG)) {
196         const struct bt_mesh_prov *prov = bt_mesh_prov_get();
197         struct bt_uuid_128 uuid = { .uuid.type = BT_UUID_TYPE_128 };
198 
199         memcpy(uuid.val, prov->uuid, 16);
200         BT_INFO("Device UUID: %s", bt_uuid_str(&uuid.uuid));
201     }
202 
203     if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && (bearers & BT_MESH_PROV_ADV)) {
204         /* Make sure we're scanning for provisioning inviations */
205         bt_mesh_scan_enable();
206         /* Enable unprovisioned beacon sending */
207         bt_mesh_beacon_enable();
208     }
209 
210     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) {
211         bt_mesh_proxy_prov_enable();
212         bt_mesh_adv_update();
213     }
214 
215     return 0;
216 }
217 
bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)218 int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
219 {
220     if (!mesh_init) {
221         return -EINVAL;
222     }
223 
224     if (bearers >= (BT_MESH_PROV_GATT << 1) || bearers == 0) {
225         return -EINVAL;
226     }
227 
228     if (bt_mesh_is_provisioned()) {
229         return -EALREADY;
230     }
231 
232     if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && (bearers & BT_MESH_PROV_ADV)) {
233         bt_mesh_beacon_disable();
234         bt_mesh_scan_disable();
235     }
236 
237     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) {
238         bt_mesh_proxy_prov_disable(true);
239     }
240 
241     return 0;
242 }
243 
model_suspend(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)244 static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data)
245 {
246     if (mod->pub && mod->pub->update) {
247         mod->pub->count = 0U;
248         k_delayed_work_cancel(&mod->pub->timer);
249     }
250 }
251 
bt_mesh_suspend(bool force)252 int bt_mesh_suspend(bool force)
253 {
254     int err;
255 
256     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
257         return -EINVAL;
258     }
259 
260     if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
261         return -EALREADY;
262     }
263 
264 #ifdef CONFIG_GENIE_MESH_ENABLE
265     extern bool bt_mesh_net_is_rx(void);
266     extern bool genie_transport_tx_in_progress(void);
267     if (force == false) {
268         if (!bt_mesh_is_provisioned()) {
269             BT_INFO("unprov stat no suspend");
270             return -1;
271         }
272 
273         if (bt_mesh_net_is_rx()) {
274             BT_INFO("rx stat no suspend");
275             return -2;
276         }
277 
278         if (genie_transport_tx_in_progress()) {
279             BT_INFO("tx stat no suspend");
280             return -3;
281         }
282     }
283 #endif
284 
285     err = bt_mesh_scan_disable();
286     if (err) {
287         BT_WARN("Disabling scanning failed (err %d)", err);
288         return err;
289     }
290 
291     bt_mesh_hb_pub_disable();
292 
293     if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
294         bt_mesh_beacon_disable();
295     }
296 
297     bt_mesh_model_foreach(model_suspend, NULL);
298 
299     atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
300 
301     return 0;
302 }
303 
model_resume(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)304 static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem, bool vnd, bool primary, void *user_data)
305 {
306     if (mod->pub && mod->pub->update) {
307         bt_s32_t period_ms = bt_mesh_model_pub_period_get(mod);
308 
309         if (period_ms) {
310             k_delayed_work_submit(&mod->pub->timer, period_ms);
311         }
312     }
313 }
314 
bt_mesh_resume(void)315 int bt_mesh_resume(void)
316 {
317     int err;
318 
319     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
320         return -EINVAL;
321     }
322 
323     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
324         return -EALREADY;
325     }
326 
327     err = bt_mesh_scan_enable();
328     if (err) {
329         BT_WARN("Re-enabling scanning failed (err %d)", err);
330         return err;
331     }
332 
333     if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
334         bt_mesh_beacon_enable();
335     }
336 
337     bt_mesh_model_foreach(model_resume, NULL);
338 
339     atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
340 
341     return err;
342 }
343 
344 #ifdef CONFIG_BT_MESH_PROVISIONER
345 
bt_mesh_is_provisioner_en(void)346 bool bt_mesh_is_provisioner_en(void)
347 {
348     return provisioner_en;
349 }
350 
bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)351 int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
352 {
353     int err;
354 
355     if (bearers >= (BT_MESH_PROV_GATT << 1) || bearers == 0) {
356         return -EINVAL;
357     }
358 
359     if (bt_mesh_is_provisioner_en()) {
360         BT_ERR("Provisioner already enabled");
361         return -EALREADY;
362     }
363 
364     err = provisioner_upper_init();
365     if (err) {
366         BT_ERR("%s: provisioner_upper_init fail", __func__);
367         return err;
368     }
369 
370     if ((IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && (bearers & BT_MESH_PROV_ADV)) ||
371         (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT))) {
372         bt_mesh_scan_enable();
373     }
374 
375     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) {
376         provisioner_pb_gatt_enable();
377     }
378 
379     provisioner_en = true;
380 
381     return 0;
382 }
383 
bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)384 int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)
385 {
386     if (bearers >= (BT_MESH_PROV_GATT << 1) || bearers == 0) {
387         return -EINVAL;
388     }
389 
390     if (!bt_mesh_is_provisioner_en()) {
391         BT_ERR("Provisioner already disabled");
392         return -EALREADY;
393     }
394 
395     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT)) {
396         provisioner_pb_gatt_disable();
397     }
398 
399     if ((IS_ENABLED(CONFIG_BT_MESH_PB_ADV) && (bearers & BT_MESH_PROV_ADV)) &&
400         (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && (bearers & BT_MESH_PROV_GATT))) {
401         bt_mesh_scan_disable();
402     }
403 
404     provisioner_en = false;
405 
406     return 0;
407 }
408 
409 #endif /* CONFIG_BT_MESH_PROVISIONER */
410 
bt_mesh_is_init()411 int bt_mesh_is_init()
412 {
413     return mesh_init;
414 }
415 
bt_mesh_vnd_adv_set_cb(void (* cb)(const struct adv_addr_t * addr,s8_t rssi,u8_t adv_type,void * user_data,uint16_t len))416 int bt_mesh_vnd_adv_set_cb(void (*cb)(const struct adv_addr_t *addr, s8_t rssi, u8_t adv_type, void *user_data,
417                                       uint16_t len))
418 {
419     return bt_mesh_adv_vnd_scan_register((vendor_beacon_cb)cb);
420 }
421 
bt_mesh_init(const struct bt_mesh_prov * prov,const struct bt_mesh_comp * comp,const struct bt_mesh_provisioner * provisioner)422 int bt_mesh_init(const struct bt_mesh_prov *prov, const struct bt_mesh_comp *comp,
423                  const struct bt_mesh_provisioner *provisioner)
424 {
425     int err;
426     BT_WARN(" ble_mesh log is enable \r\n");
427 
428     if (mesh_init) {
429         return -EALREADY;
430     }
431 
432     if (prov == NULL || comp == NULL) {
433         return -EINVAL;
434     }
435 
436     if (prov->uuid == NULL) {
437         return -EINVAL;
438     }
439 
440     if (prov->oob_info >= (BT_MESH_PROV_OOB_ON_DEV << 1)) {
441         return -EINVAL;
442     }
443 
444     if (prov->output_actions >= (BT_MESH_DISPLAY_STRING << 1)) {
445         return -EINVAL;
446     }
447 
448     if (prov->input_actions >= (BT_MESH_ENTER_STRING << 1)) {
449         return -EINVAL;
450     }
451 
452 //      bt_enable is aleady called before
453 //     printf("before bt_enable in %s\n", __func__);
454 //     err = bt_enable(NULL);
455 //     if (err && err != -EALREADY) {
456 //         return err;
457 //     }
458 
459     printf("before bt_mesh_test in %s\n", __func__);
460     err = bt_mesh_test();
461     if (err) {
462         return err;
463     }
464 
465     printf("before bt_mesh_comp_register in %s\n", __func__);
466     err = bt_mesh_comp_register(comp);
467     if (err) {
468         return err;
469     }
470 
471     printf("before bt_mesh_prov_init in %s\n", __func__);
472     if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
473         err = bt_mesh_prov_init(prov);
474         if (err) {
475             printf(" bt_mesh_prov_init err:%d\n", err);
476             return err;
477         }
478     }
479 
480 #ifdef CONFIG_BT_MESH_PROVISIONER
481     printf("before provisioner_prov_init in %s\n", __func__);
482     err = provisioner_prov_init(provisioner);
483     if (err) {
484         return err;
485     }
486 #endif
487 
488     bt_mesh_net_init();
489     bt_mesh_trans_init();
490     bt_mesh_beacon_init();
491     bt_mesh_adv_init();
492 
493     if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
494 #ifdef CONFIG_BT_MESH_PROVISIONER
495         provisioner_proxy_init();
496 #endif
497         bt_mesh_proxy_init();
498     }
499 
500     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
501         bt_mesh_settings_init();
502         extern int settings_load();
503         settings_load();
504     }
505 
506     mesh_init = 1;
507 
508     return 0;
509 }
510