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