• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*  Bluetooth Mesh */
2 
3 /*
4  * Copyright (c) 2017 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include "syscfg/syscfg.h"
10 #define MESH_LOG_MODULE BLE_MESH_LOG
11 
12 #include <stdbool.h>
13 #include <errno.h>
14 
15 #include "os/os_mbuf.h"
16 #include "host/ble_uuid.h"
17 #include "mesh/mesh.h"
18 
19 #include "adv.h"
20 #include "prov.h"
21 #include "net.h"
22 #include "beacon.h"
23 #include "lpn.h"
24 #include "friend.h"
25 #include "transport.h"
26 #include "access.h"
27 #include "foundation.h"
28 #include "proxy.h"
29 #include "shell.h"
30 #include "mesh_priv.h"
31 #include "settings.h"
32 
33 u8_t g_mesh_addr_type;
34 static struct ble_gap_event_listener mesh_event_listener;
35 
bt_mesh_provision(const u8_t net_key[16],u16_t net_idx,u8_t flags,u32_t iv_index,u16_t addr,const u8_t dev_key[16])36 int bt_mesh_provision(const u8_t net_key[16], u16_t net_idx,
37                       u8_t flags, u32_t iv_index, u16_t addr,
38                       const u8_t dev_key[16])
39 {
40     bool pb_gatt_enabled;
41     int err;
42     BT_INFO("Primary Element: 0x%04x", addr);
43     BT_DBG("net_idx 0x%04x flags 0x%02x iv_index 0x%04x",
44            net_idx, flags, (unsigned) iv_index);
45 
46     if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_VALID)) {
47         return -EALREADY;
48     }
49 
50     if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) {
51         if (bt_mesh_proxy_prov_disable(false) == 0) {
52             pb_gatt_enabled = true;
53         } else {
54             pb_gatt_enabled = false;
55         }
56     } else {
57         pb_gatt_enabled = false;
58     }
59 
60     err = bt_mesh_net_create(net_idx, flags, net_key, iv_index);
61     if (err) {
62         atomic_clear_bit(bt_mesh.flags, BT_MESH_VALID);
63 
64         if (MYNEWT_VAL(BLE_MESH_PB_GATT)  && pb_gatt_enabled) {
65             bt_mesh_proxy_prov_enable();
66         }
67 
68         return err;
69     }
70 
71     bt_mesh.seq = 0;
72     bt_mesh_comp_provision(addr);
73     memcpy(bt_mesh.dev_key, dev_key, 16); // 16:size
74 
75     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
76         BT_DBG("Storing network information persistently");
77         bt_mesh_store_net();
78         bt_mesh_store_subnet(&bt_mesh.sub[0]);
79         bt_mesh_store_iv(false);
80     }
81 
82     bt_mesh_net_start();
83     return 0;
84 }
85 
bt_mesh_provision_adv(const u8_t uuid[16],u16_t net_idx,u16_t addr,u8_t attention_duration)86 int bt_mesh_provision_adv(const u8_t uuid[16], u16_t net_idx, u16_t addr,
87                           u8_t attention_duration)
88 {
89     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
90         return -EINVAL;
91     }
92 
93     if (bt_mesh_subnet_get(net_idx) == NULL) {
94         return -EINVAL;
95     }
96 
97     if (IS_ENABLED(CONFIG_BT_MESH_PROVISIONER) &&
98             IS_ENABLED(CONFIG_BT_MESH_PB_ADV)) {
99         return bt_mesh_pb_adv_open(uuid, net_idx, addr,
100                                    attention_duration);
101     }
102 
103     return -ENOTSUP;
104 }
105 
bt_mesh_reset(void)106 void bt_mesh_reset(void)
107 {
108     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
109         return;
110     }
111 
112     bt_mesh.iv_index = 0U;
113     bt_mesh.seq = 0U;
114     memset(bt_mesh.flags, 0, sizeof(bt_mesh.flags));
115     k_delayed_work_cancel(&bt_mesh.ivu_timer);
116     bt_mesh_cfg_reset();
117     bt_mesh_rx_reset();
118     bt_mesh_tx_reset();
119 
120     if ((MYNEWT_VAL(BLE_MESH_LOW_POWER))) {
121         bt_mesh_lpn_disable(true);
122     }
123 
124     if ((MYNEWT_VAL(BLE_MESH_FRIEND))) {
125         bt_mesh_friend_clear_net_idx(BT_MESH_KEY_ANY);
126     }
127 
128     if ((MYNEWT_VAL(BLE_MESH_GATT_PROXY))) {
129         bt_mesh_proxy_gatt_disable();
130     }
131 
132     if ((MYNEWT_VAL(BLE_MESH_PB_GATT))) {
133         bt_mesh_proxy_prov_enable();
134     }
135 
136     if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
137         bt_mesh_clear_net();
138     }
139 
140     memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key));
141     bt_mesh_scan_disable();
142     bt_mesh_beacon_disable();
143     bt_mesh_comp_unprovision();
144 
145     if (IS_ENABLED(CONFIG_BT_MESH_PROV)) {
146         bt_mesh_prov_reset();
147     }
148 }
149 
bt_mesh_is_provisioned(void)150 bool bt_mesh_is_provisioned(void)
151 {
152     return atomic_test_bit(bt_mesh.flags, BT_MESH_VALID);
153 }
154 
bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)155 int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers)
156 {
157     if (bt_mesh_is_provisioned()) {
158         return -EALREADY;
159     }
160 
161     char uuid_buf[BLE_UUID_STR_LEN];
162     const struct bt_mesh_prov *prov = bt_mesh_prov_get();
163     ble_uuid_t *uuid = BLE_UUID128_DECLARE();
164     memcpy(BLE_UUID128(uuid)->value, prov->uuid, 16); // 16:len
165     BT_INFO("Device UUID: %s", ble_uuid_to_str(uuid, uuid_buf));
166 
167     if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
168             (bearers & BT_MESH_PROV_ADV)) {
169         /* Make sure we're scanning for provisioning inviations */
170         bt_mesh_scan_enable();
171         /* Enable unprovisioned beacon sending */
172         bt_mesh_beacon_enable();
173     }
174 
175     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
176             (bearers & BT_MESH_PROV_GATT)) {
177         bt_mesh_proxy_prov_enable();
178         bt_mesh_adv_update();
179     }
180 
181     return 0;
182 }
183 
bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)184 int bt_mesh_prov_disable(bt_mesh_prov_bearer_t bearers)
185 {
186     if (bt_mesh_is_provisioned()) {
187         return -EALREADY;
188     }
189 
190     if (IS_ENABLED(CONFIG_BT_MESH_PB_ADV) &&
191             (bearers & BT_MESH_PROV_ADV)) {
192         bt_mesh_beacon_disable();
193         bt_mesh_scan_disable();
194     }
195 
196     if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) &&
197             (bearers & BT_MESH_PROV_GATT)) {
198         bt_mesh_proxy_prov_disable(true);
199     }
200 
201     return 0;
202 }
203 
bt_mesh_gap_event(struct ble_gap_event * event,void * arg)204 static int bt_mesh_gap_event(struct ble_gap_event *event, void *arg)
205 {
206     ble_adv_gap_mesh_cb(event, arg);
207 #if (MYNEWT_VAL(BLE_MESH_PROXY))
208     ble_mesh_proxy_gap_event(event, arg);
209 #endif
210     return 0;
211 }
212 
model_suspend(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)213 static void model_suspend(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
214                           bool vnd, bool primary, void *user_data)
215 {
216     if (mod->pub && mod->pub->update) {
217         mod->pub->count = 0;
218         k_delayed_work_cancel(&mod->pub->timer);
219     }
220 }
221 
bt_mesh_suspend(void)222 int bt_mesh_suspend(void)
223 {
224     int err;
225 
226     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
227         return -EINVAL;
228     }
229 
230     if (atomic_test_and_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
231         return -EALREADY;
232     }
233 
234     err = bt_mesh_scan_disable();
235     if (err) {
236         atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
237         BT_WARN("Disabling scanning failed (err %d)", err);
238         return err;
239     }
240 
241     bt_mesh_hb_pub_disable();
242 
243     if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
244         bt_mesh_beacon_disable();
245     }
246 
247     bt_mesh_model_foreach(model_suspend, NULL);
248     return 0;
249 }
250 
model_resume(struct bt_mesh_model * mod,struct bt_mesh_elem * elem,bool vnd,bool primary,void * user_data)251 static void model_resume(struct bt_mesh_model *mod, struct bt_mesh_elem *elem,
252                          bool vnd, bool primary, void *user_data)
253 {
254     if (mod->pub && mod->pub->update) {
255         s32_t period_ms = bt_mesh_model_pub_period_get(mod);
256         if (period_ms) {
257             k_delayed_work_submit(&mod->pub->timer, period_ms);
258         }
259     }
260 }
261 
bt_mesh_resume(void)262 int bt_mesh_resume(void)
263 {
264     int err;
265 
266     if (!atomic_test_bit(bt_mesh.flags, BT_MESH_VALID)) {
267         return -EINVAL;
268     }
269 
270     if (!atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
271         return -EALREADY;
272     }
273 
274     err = bt_mesh_scan_enable();
275     if (err) {
276         BT_WARN("Re-enabling scanning failed (err %d)", err);
277         atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
278         return err;
279     }
280 
281     if (bt_mesh_beacon_get() == BT_MESH_BEACON_ENABLED) {
282         bt_mesh_beacon_enable();
283     }
284 
285     bt_mesh_model_foreach(model_resume, NULL);
286     return err;
287 }
288 
bt_mesh_init(uint8_t own_addr_type,const struct bt_mesh_prov * prov,const struct bt_mesh_comp * comp)289 int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov,
290                  const struct bt_mesh_comp *comp)
291 {
292     int err;
293     g_mesh_addr_type = own_addr_type;
294     /* initialize SM alg ECC subsystem (it is used directly from mesh code) */
295     ble_sm_alg_ecc_init();
296     err = bt_mesh_comp_register(comp);
297     if (err) {
298         return err;
299     }
300 
301 #if (MYNEWT_VAL(BLE_MESH_PROV))
302     err = bt_mesh_prov_init(prov);
303     if (err) {
304         return err;
305     }
306 
307 #endif
308 #if (MYNEWT_VAL(BLE_MESH_PROXY))
309     bt_mesh_proxy_init();
310 #endif
311 #if (MYNEWT_VAL(BLE_MESH_PROV))
312     /* Need this to proper link.rx.buf allocation */
313     bt_mesh_prov_reset_link();
314 #endif
315     bt_mesh_net_init();
316     bt_mesh_trans_init();
317     bt_mesh_beacon_init();
318     bt_mesh_adv_init();
319 #if (MYNEWT_VAL(BLE_MESH_PB_ADV))
320     /* Make sure we're scanning for provisioning inviations */
321     bt_mesh_scan_enable();
322     /* Enable unprovisioned beacon sending */
323     bt_mesh_beacon_enable();
324 #endif
325 #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
326     bt_mesh_proxy_prov_enable();
327 #endif
328     ble_gap_event_listener_register(&mesh_event_listener,
329                                     bt_mesh_gap_event, NULL);
330 #if (MYNEWT_VAL(BLE_MESH_SETTINGS))
331     bt_mesh_settings_init();
332 #endif
333     return 0;
334 }
335