1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include "mesh/glue.h"
21 #include "adv.h"
22 #ifndef MYNEWT
23 #include "nimble/nimble_port.h"
24 #endif
25
26 #if MYNEWT_VAL(BLE_MESH_SETTINGS)
27 #include "base64/base64.h"
28 #endif
29
30 #define BT_DBG_ENABLED (MYNEWT_VAL(BLE_MESH_DEBUG))
31
32 #if MYNEWT_VAL(BLE_EXT_ADV)
33 #define BT_MESH_ADV_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES))
34
35 #if MYNEWT_VAL(BLE_MESH_PROXY)
36 /* Note that BLE_MULTI_ADV_INSTANCES contains number of additional instances.
37 * Instance 0 is always there
38 */
39 #if MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) < 1
40 #error "Mesh needs at least BLE_MULTI_ADV_INSTANCES set to 1"
41 #endif
42 #define BT_MESH_ADV_GATT_INST (MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES) - 1)
43 #endif /* BLE_MESH_PROXY */
44 #endif /* BLE_EXT_ADV */
45
46 extern u8_t g_mesh_addr_type;
47
48 #if MYNEWT_VAL(BLE_EXT_ADV)
49 /* Store configuration for different bearers */
50 #define BT_MESH_ADV_IDX (0)
51 #define BT_MESH_GATT_IDX (1)
52 static struct ble_gap_adv_params ble_adv_cur_conf[2];
53 #endif
54
55 const char *
bt_hex(const void * buf,size_t len)56 bt_hex(const void *buf, size_t len)
57 {
58 static const char hex[] = "0123456789abcdef";
59 static char hexbufs[4][137];
60 static u8_t curbuf;
61 const u8_t *b = buf;
62 char *str;
63 int i;
64
65 str = hexbufs[curbuf++];
66 curbuf %= ARRAY_SIZE(hexbufs);
67
68 len = min(len, (sizeof(hexbufs[0]) - 1) / 2);
69
70 for (i = 0; i < len; i++) {
71 str[i * 2] = hex[b[i] >> 4];
72 str[i * 2 + 1] = hex[b[i] & 0xf];
73 }
74
75 str[i * 2] = '\0';
76
77 return str;
78 }
79
80 void
net_buf_put(struct ble_npl_eventq * fifo,struct os_mbuf * om)81 net_buf_put(struct ble_npl_eventq *fifo, struct os_mbuf *om)
82 {
83 struct ble_npl_event *ev;
84
85 assert(OS_MBUF_IS_PKTHDR(om));
86 ev = &BT_MESH_ADV(om)->ev;
87 assert(ev);
88 assert(ble_npl_event_get_arg(ev));
89
90 ble_npl_eventq_put(fifo, ev);
91 }
92
93 void *
net_buf_ref(struct os_mbuf * om)94 net_buf_ref(struct os_mbuf *om)
95 {
96 struct bt_mesh_adv *adv;
97
98 /* For bufs with header we count refs*/
99 if (OS_MBUF_USRHDR_LEN(om) == 0) {
100 return om;
101 }
102
103 adv = BT_MESH_ADV(om);
104 adv->ref_cnt++;
105
106 return om;
107 }
108
109 void
net_buf_unref(struct os_mbuf * om)110 net_buf_unref(struct os_mbuf *om)
111 {
112 struct bt_mesh_adv *adv;
113
114 /* For bufs with header we count refs*/
115 if (OS_MBUF_USRHDR_LEN(om) == 0) {
116 goto free;
117 }
118
119 adv = BT_MESH_ADV(om);
120 if (--adv->ref_cnt > 0) {
121 return;
122 }
123
124 free:
125 os_mbuf_free_chain(om);
126 }
127
128 int
bt_encrypt_be(const uint8_t * key,const uint8_t * plaintext,uint8_t * enc_data)129 bt_encrypt_be(const uint8_t *key, const uint8_t *plaintext, uint8_t *enc_data)
130 {
131 struct tc_aes_key_sched_struct s;
132
133 if (tc_aes128_set_encrypt_key(&s, key) == TC_CRYPTO_FAIL) {
134 return BLE_HS_EUNKNOWN;
135 }
136
137 if (tc_aes_encrypt(enc_data, plaintext, &s) == TC_CRYPTO_FAIL) {
138 return BLE_HS_EUNKNOWN;
139 }
140
141 return 0;
142 }
143
144 uint16_t
net_buf_simple_pull_le16(struct os_mbuf * om)145 net_buf_simple_pull_le16(struct os_mbuf *om)
146 {
147 uint16_t val;
148 struct os_mbuf *old = om;
149
150 om = os_mbuf_pullup(om, sizeof(val));
151 assert(om == old);
152 val = get_le16(om->om_data);
153 os_mbuf_adj(om, sizeof(val));
154
155 return val;
156 }
157
158 uint16_t
net_buf_simple_pull_be16(struct os_mbuf * om)159 net_buf_simple_pull_be16(struct os_mbuf *om)
160 {
161 uint16_t val;
162 struct os_mbuf *old = om;
163
164 om = os_mbuf_pullup(om, sizeof(val));
165 assert(om == old);
166 val = get_be16(om->om_data);
167 os_mbuf_adj(om, sizeof(val));
168
169 return val;
170 }
171
172 uint32_t
net_buf_simple_pull_be32(struct os_mbuf * om)173 net_buf_simple_pull_be32(struct os_mbuf *om)
174 {
175 uint32_t val;
176 struct os_mbuf *old = om;
177
178 om = os_mbuf_pullup(om, sizeof(val));
179 assert(om == old);
180 val = get_be32(om->om_data);
181 os_mbuf_adj(om, sizeof(val));
182
183 return val;
184 }
185
186 uint32_t
net_buf_simple_pull_le32(struct os_mbuf * om)187 net_buf_simple_pull_le32(struct os_mbuf *om)
188 {
189 uint32_t val;
190 struct os_mbuf *old = om;
191
192 om = os_mbuf_pullup(om, sizeof(val));
193 assert(om == old);
194 val = get_le32(om->om_data);
195 os_mbuf_adj(om, sizeof(val));
196
197 return val;
198 }
199
200 uint8_t
net_buf_simple_pull_u8(struct os_mbuf * om)201 net_buf_simple_pull_u8(struct os_mbuf *om)
202 {
203 uint8_t val;
204 struct os_mbuf *old = om;
205
206 om = os_mbuf_pullup(om, sizeof(val));
207 assert(om == old);
208 val = om->om_data[0];
209 os_mbuf_adj(om, 1);
210
211 return val;
212 }
213
214 void
net_buf_simple_add_le16(struct os_mbuf * om,uint16_t val)215 net_buf_simple_add_le16(struct os_mbuf *om, uint16_t val)
216 {
217 val = htole16(val);
218 os_mbuf_append(om, &val, sizeof(val));
219 ASSERT_NOT_CHAIN(om);
220 }
221
222 void
net_buf_simple_add_be16(struct os_mbuf * om,uint16_t val)223 net_buf_simple_add_be16(struct os_mbuf *om, uint16_t val)
224 {
225 val = htobe16(val);
226 os_mbuf_append(om, &val, sizeof(val));
227 ASSERT_NOT_CHAIN(om);
228 }
229
230 void
net_buf_simple_add_be32(struct os_mbuf * om,uint32_t val)231 net_buf_simple_add_be32(struct os_mbuf *om, uint32_t val)
232 {
233 val = htobe32(val);
234 os_mbuf_append(om, &val, sizeof(val));
235 ASSERT_NOT_CHAIN(om);
236 }
237
238 void
net_buf_simple_add_le32(struct os_mbuf * om,uint32_t val)239 net_buf_simple_add_le32(struct os_mbuf *om, uint32_t val)
240 {
241 val = htole32(val);
242 os_mbuf_append(om, &val, sizeof(val));
243 ASSERT_NOT_CHAIN(om);
244 }
245
246 void
net_buf_simple_add_u8(struct os_mbuf * om,uint8_t val)247 net_buf_simple_add_u8(struct os_mbuf *om, uint8_t val)
248 {
249 os_mbuf_append(om, &val, 1);
250 ASSERT_NOT_CHAIN(om);
251 }
252
253 void
net_buf_simple_push_le16(struct os_mbuf * om,uint16_t val)254 net_buf_simple_push_le16(struct os_mbuf *om, uint16_t val)
255 {
256 uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len];
257
258 assert(headroom >= 2);
259 om->om_data -= 2;
260 put_le16(om->om_data, val);
261 om->om_len += 2;
262
263 if (om->om_pkthdr_len) {
264 OS_MBUF_PKTHDR(om)->omp_len += 2;
265 }
266 ASSERT_NOT_CHAIN(om);
267 }
268
269 void
net_buf_simple_push_be16(struct os_mbuf * om,uint16_t val)270 net_buf_simple_push_be16(struct os_mbuf *om, uint16_t val)
271 {
272 uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len];
273
274 assert(headroom >= 2);
275 om->om_data -= 2;
276 put_be16(om->om_data, val);
277 om->om_len += 2;
278
279 if (om->om_pkthdr_len) {
280 OS_MBUF_PKTHDR(om)->omp_len += 2;
281 }
282 ASSERT_NOT_CHAIN(om);
283 }
284
285 void
net_buf_simple_push_u8(struct os_mbuf * om,uint8_t val)286 net_buf_simple_push_u8(struct os_mbuf *om, uint8_t val)
287 {
288 uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len];
289
290 assert(headroom >= 1);
291 om->om_data -= 1;
292 om->om_data[0] = val;
293 om->om_len += 1;
294
295 if (om->om_pkthdr_len) {
296 OS_MBUF_PKTHDR(om)->omp_len += 1;
297 }
298 ASSERT_NOT_CHAIN(om);
299 }
300
301 void
net_buf_add_zeros(struct os_mbuf * om,uint8_t len)302 net_buf_add_zeros(struct os_mbuf *om, uint8_t len)
303 {
304 uint8_t z[len];
305 int rc;
306
307 memset(z, 0, len);
308
309 rc = os_mbuf_append(om, z, len);
310 if(rc) {
311 assert(0);
312 }
313 ASSERT_NOT_CHAIN(om);
314 }
315
316 void *
net_buf_simple_pull(struct os_mbuf * om,uint8_t len)317 net_buf_simple_pull(struct os_mbuf *om, uint8_t len)
318 {
319 os_mbuf_adj(om, len);
320 return om->om_data;
321 }
322
323 void*
net_buf_simple_add(struct os_mbuf * om,uint8_t len)324 net_buf_simple_add(struct os_mbuf *om, uint8_t len)
325 {
326 void * tmp;
327
328 tmp = os_mbuf_extend(om, len);
329 ASSERT_NOT_CHAIN(om);
330
331 return tmp;
332 }
333
334 bool
k_fifo_is_empty(struct ble_npl_eventq * q)335 k_fifo_is_empty(struct ble_npl_eventq *q)
336 {
337 return ble_npl_eventq_is_empty(q);
338 }
339
net_buf_get(struct ble_npl_eventq * fifo,s32_t t)340 void * net_buf_get(struct ble_npl_eventq *fifo, s32_t t)
341 {
342 struct ble_npl_event *ev = ble_npl_eventq_get(fifo, 0);
343
344 if (ev) {
345 return ble_npl_event_get_arg(ev);
346 }
347
348 return NULL;
349 }
350
351 uint8_t *
net_buf_simple_push(struct os_mbuf * om,uint8_t len)352 net_buf_simple_push(struct os_mbuf *om, uint8_t len)
353 {
354 uint8_t headroom = om->om_data - &om->om_databuf[om->om_pkthdr_len];
355
356 assert(headroom >= len);
357 om->om_data -= len;
358 om->om_len += len;
359
360 return om->om_data;
361 }
362
363 void
net_buf_reserve(struct os_mbuf * om,size_t reserve)364 net_buf_reserve(struct os_mbuf *om, size_t reserve)
365 {
366 /* We need reserve to be done on fresh buf */
367 assert(om->om_len == 0);
368 om->om_data += reserve;
369 }
370
371 void
k_work_init(struct ble_npl_callout * work,ble_npl_event_fn handler)372 k_work_init(struct ble_npl_callout *work, ble_npl_event_fn handler)
373 {
374 #ifndef MYNEWT
375 ble_npl_callout_init(work, nimble_port_get_dflt_eventq(), handler, NULL);
376 #else
377 ble_npl_callout_init(work, ble_npl_eventq_dflt_get(), handler, NULL);
378 #endif
379 }
380
381 void
k_delayed_work_init(struct k_delayed_work * w,ble_npl_event_fn * f)382 k_delayed_work_init(struct k_delayed_work *w, ble_npl_event_fn *f)
383 {
384 #ifndef MYNEWT
385 ble_npl_callout_init(&w->work, nimble_port_get_dflt_eventq(), f, NULL);
386 #else
387 ble_npl_callout_init(&w->work, ble_npl_eventq_dflt_get(), f, NULL);
388 #endif
389 }
390
391 void
k_delayed_work_cancel(struct k_delayed_work * w)392 k_delayed_work_cancel(struct k_delayed_work *w)
393 {
394 ble_npl_callout_stop(&w->work);
395 }
396
397 void
k_delayed_work_submit(struct k_delayed_work * w,uint32_t ms)398 k_delayed_work_submit(struct k_delayed_work *w, uint32_t ms)
399 {
400 uint32_t ticks;
401
402 if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) {
403 assert(0);
404 }
405 ble_npl_callout_reset(&w->work, ticks);
406 }
407
408 void
k_work_submit(struct ble_npl_callout * w)409 k_work_submit(struct ble_npl_callout *w)
410 {
411 ble_npl_callout_reset(w, 0);
412 }
413
414 void
k_work_add_arg(struct ble_npl_callout * w,void * arg)415 k_work_add_arg(struct ble_npl_callout *w, void *arg)
416 {
417 ble_npl_callout_set_arg(w, arg);
418 }
419
420 void
k_delayed_work_add_arg(struct k_delayed_work * w,void * arg)421 k_delayed_work_add_arg(struct k_delayed_work *w, void *arg)
422 {
423 k_work_add_arg(&w->work, arg);
424 }
425
426 uint32_t
k_delayed_work_remaining_get(struct k_delayed_work * w)427 k_delayed_work_remaining_get (struct k_delayed_work *w)
428 {
429 int sr;
430 ble_npl_time_t t;
431
432 OS_ENTER_CRITICAL(sr);
433
434 t = ble_npl_callout_remaining_ticks(&w->work, ble_npl_time_get());
435
436 OS_EXIT_CRITICAL(sr);
437
438 return ble_npl_time_ticks_to_ms32(t);
439 }
440
k_uptime_get(void)441 int64_t k_uptime_get(void)
442 {
443 /* We should return ms */
444 return ble_npl_time_ticks_to_ms32(ble_npl_time_get());
445 }
446
k_uptime_get_32(void)447 u32_t k_uptime_get_32(void)
448 {
449 return k_uptime_get();
450 }
451
k_sleep(int32_t duration)452 void k_sleep(int32_t duration)
453 {
454 uint32_t ticks;
455
456 ticks = ble_npl_time_ms_to_ticks32(duration);
457
458 ble_npl_time_delay(ticks);
459 }
460
461 static uint8_t pub[64];
462 static uint8_t priv[32];
463 static bool has_pub = false;
464
465 int
bt_dh_key_gen(const u8_t remote_pk[64],bt_dh_key_cb_t cb)466 bt_dh_key_gen(const u8_t remote_pk[64], bt_dh_key_cb_t cb)
467 {
468 uint8_t dh[32];
469
470 if (ble_sm_alg_gen_dhkey((uint8_t *)&remote_pk[0], (uint8_t *)&remote_pk[32],
471 priv, dh)) {
472 return -1;
473 }
474
475 cb(dh);
476 return 0;
477 }
478
479 int
bt_rand(void * buf,size_t len)480 bt_rand(void *buf, size_t len)
481 {
482 int rc;
483 rc = ble_hs_hci_util_rand(buf, len);
484 if (rc != 0) {
485 return -1;
486 }
487
488 return 0;
489 }
490
491 int
bt_pub_key_gen(struct bt_pub_key_cb * new_cb)492 bt_pub_key_gen(struct bt_pub_key_cb *new_cb)
493 {
494
495 if (ble_sm_alg_gen_key_pair(pub, priv)) {
496 assert(0);
497 return -1;
498 }
499
500 new_cb->func(pub);
501 has_pub = true;
502
503 return 0;
504 }
505
506 uint8_t *
bt_pub_key_get(void)507 bt_pub_key_get(void)
508 {
509 if (!has_pub) {
510 return NULL;
511 }
512
513 return pub;
514 }
515
516 static int
set_ad(const struct bt_data * ad,size_t ad_len,u8_t * buf,u8_t * buf_len)517 set_ad(const struct bt_data *ad, size_t ad_len, u8_t *buf, u8_t *buf_len)
518 {
519 int i;
520
521 for (i = 0; i < ad_len; i++) {
522 buf[(*buf_len)++] = ad[i].data_len + 1;
523 buf[(*buf_len)++] = ad[i].type;
524
525 memcpy(&buf[*buf_len], ad[i].data,
526 ad[i].data_len);
527 *buf_len += ad[i].data_len;
528 }
529
530 return 0;
531 }
532
533 #if MYNEWT_VAL(BLE_EXT_ADV)
534 static void
ble_adv_copy_to_ext_param(struct ble_gap_ext_adv_params * ext_param,const struct ble_gap_adv_params * param)535 ble_adv_copy_to_ext_param(struct ble_gap_ext_adv_params *ext_param,
536 const struct ble_gap_adv_params *param)
537 {
538 memset(ext_param, 0, sizeof(*ext_param));
539
540 ext_param->legacy_pdu = 1;
541
542 if (param->conn_mode != BLE_GAP_CONN_MODE_NON) {
543 ext_param->connectable = 1;
544 ext_param->scannable = 1;
545 }
546
547 ext_param->itvl_max = param->itvl_max;
548 ext_param->itvl_min = param->itvl_min;
549 ext_param->channel_map = param->channel_map;
550 ext_param->high_duty_directed = param->high_duty_cycle;
551 ext_param->own_addr_type = g_mesh_addr_type;
552 }
553
554 static int
ble_adv_conf_adv_instance(const struct ble_gap_adv_params * param,int * instance)555 ble_adv_conf_adv_instance(const struct ble_gap_adv_params *param, int *instance)
556 {
557 struct ble_gap_ext_adv_params ext_params;
558 struct ble_gap_adv_params *cur_conf;
559 int err = 0;
560
561 if (param->conn_mode == BLE_GAP_CONN_MODE_NON) {
562 *instance = BT_MESH_ADV_INST;
563 cur_conf = &ble_adv_cur_conf[BT_MESH_ADV_IDX];
564 } else {
565 #if MYNEWT_VAL(BLE_MESH_PROXY)
566 *instance = BT_MESH_ADV_GATT_INST;
567 cur_conf = &ble_adv_cur_conf[BT_MESH_GATT_IDX];
568 #else
569 assert(0);
570 #endif
571 }
572
573 /* Checking interval max as it has to be in place if instance was configured
574 * before.
575 */
576 if (cur_conf->itvl_max == 0) {
577 goto configure;
578 }
579
580 if (memcmp(param, cur_conf, sizeof(*cur_conf)) == 0) {
581 /* Same parameters - skip reconfiguring */
582 goto done;
583 }
584
585 ble_gap_ext_adv_stop(*instance);
586 err = ble_gap_ext_adv_remove(*instance);
587 if (err) {
588 assert(0);
589 goto done;
590 }
591
592 configure:
593 ble_adv_copy_to_ext_param(&ext_params, param);
594
595 err = ble_gap_ext_adv_configure(*instance, &ext_params, 0,
596 ble_adv_gap_mesh_cb, NULL);
597 if (!err) {
598 memcpy(cur_conf, param, sizeof(*cur_conf));
599 }
600
601 done:
602 return err;
603 }
604
605 int
bt_le_adv_start(const struct ble_gap_adv_params * param,const struct bt_data * ad,size_t ad_len,const struct bt_data * sd,size_t sd_len)606 bt_le_adv_start(const struct ble_gap_adv_params *param,
607 const struct bt_data *ad, size_t ad_len,
608 const struct bt_data *sd, size_t sd_len)
609 {
610 struct os_mbuf *data;
611 int instance;
612 int err;
613 uint8_t buf[BLE_HS_ADV_MAX_SZ];
614 uint8_t buf_len = 0;
615
616 err = ble_adv_conf_adv_instance(param, &instance);
617 if (err) {
618 return err;
619 }
620
621 if (ad_len > 0) {
622 err = set_ad(ad, ad_len, buf, &buf_len);
623 if (err) {
624 return err;
625 }
626
627 /* For now let's use msys pool. We are not putting more then legacy */
628 data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0);
629 if (!data) {
630 return OS_ENOMEM;
631 }
632
633 err = os_mbuf_append(data, buf, buf_len);
634 if (err) {
635 goto error;
636 }
637
638 err = ble_gap_ext_adv_set_data(instance, data);
639 if (err) {
640 return err;
641 }
642
643 data = NULL;
644 }
645
646 if (sd_len > 0) {
647 buf_len = 0;
648
649 err = set_ad(sd, sd_len, buf, &buf_len);
650 if (err) {
651 return err;
652 }
653
654 /* For now let's use msys pool. We are not putting more then legace*/
655 data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_SZ, 0);
656 if (!data) {
657 return OS_ENOMEM;
658 }
659
660 err = os_mbuf_append(data, buf, buf_len);
661 if (err) {
662 goto error;
663 }
664
665 err = ble_gap_ext_adv_rsp_set_data(instance, data);
666 if (err) {
667 goto error;
668 }
669 }
670
671 /*TODO: We could use duration and max events in the future */
672 err = ble_gap_ext_adv_start(instance, 0, 0);
673 return err;
674
675 error:
676 if (data) {
677 os_mbuf_free_chain(data);
678 }
679
680 return err;
681 }
682
bt_le_adv_stop(bool proxy)683 int bt_le_adv_stop(bool proxy)
684 {
685 #if MYNEWT_VAL(BLE_MESH_PROXY)
686 int rc;
687
688 if (proxy) {
689 rc = ble_gap_ext_adv_stop(BT_MESH_ADV_GATT_INST);
690 } else {
691 rc = ble_gap_ext_adv_stop(BT_MESH_ADV_INST);
692 }
693
694 return rc;
695 #else
696 return ble_gap_ext_adv_stop(BT_MESH_ADV_INST);
697 #endif
698 }
699
700 #else
701
702 int
bt_le_adv_start(const struct ble_gap_adv_params * param,const struct bt_data * ad,size_t ad_len,const struct bt_data * sd,size_t sd_len)703 bt_le_adv_start(const struct ble_gap_adv_params *param,
704 const struct bt_data *ad, size_t ad_len,
705 const struct bt_data *sd, size_t sd_len)
706 {
707 uint8_t buf[BLE_HS_ADV_MAX_SZ];
708 uint8_t buf_len = 0;
709 int err;
710
711 err = set_ad(ad, ad_len, buf, &buf_len);
712 if (err) {
713 return err;
714 }
715
716 err = ble_gap_adv_set_data(buf, buf_len);
717 if (err != 0) {
718 return err;
719 }
720
721 if (sd) {
722 buf_len = 0;
723
724 err = set_ad(sd, sd_len, buf, &buf_len);
725 if (err) {
726 BT_ERR("Advertising failed: err %d", err);
727 return err;
728 }
729
730 err = ble_gap_adv_rsp_set_data(buf, buf_len);
731 if (err != 0) {
732 BT_ERR("Advertising failed: err %d", err);
733 return err;
734 }
735 }
736
737 err = ble_gap_adv_start(g_mesh_addr_type, NULL, BLE_HS_FOREVER, param,
738 NULL, NULL);
739 if (err) {
740 BT_ERR("Advertising failed: err %d", err);
741 return err;
742 }
743
744 return 0;
745 }
746
bt_le_adv_stop(bool proxy)747 int bt_le_adv_stop(bool proxy)
748 {
749 return ble_gap_adv_stop();
750 }
751
752 #endif
753
754 #if MYNEWT_VAL(BLE_MESH_PROXY)
755 int bt_mesh_proxy_svcs_register(void);
756 #endif
757
758 void
bt_mesh_register_gatt(void)759 bt_mesh_register_gatt(void)
760 {
761 #if MYNEWT_VAL(BLE_MESH_PROXY)
762 bt_mesh_proxy_svcs_register();
763 #endif
764 }
765
net_buf_slist_init(struct net_buf_slist_t * list)766 void net_buf_slist_init(struct net_buf_slist_t *list)
767 {
768 STAILQ_INIT(list);
769 }
770
net_buf_slist_is_empty(struct net_buf_slist_t * list)771 bool net_buf_slist_is_empty(struct net_buf_slist_t *list)
772 {
773 return STAILQ_EMPTY(list);
774 }
775
net_buf_slist_peek_head(struct net_buf_slist_t * list)776 struct os_mbuf *net_buf_slist_peek_head(struct net_buf_slist_t *list)
777 {
778 struct os_mbuf_pkthdr *pkthdr;
779
780 /* Get mbuf pointer from packet header pointer */
781 pkthdr = STAILQ_FIRST(list);
782 if (!pkthdr) {
783 return NULL;
784 }
785
786 return OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
787 }
788
net_buf_slist_peek_next(struct os_mbuf * buf)789 struct os_mbuf *net_buf_slist_peek_next(struct os_mbuf *buf)
790 {
791 struct os_mbuf_pkthdr *pkthdr;
792
793 /* Get mbuf pointer from packet header pointer */
794 pkthdr = OS_MBUF_PKTHDR(buf);
795 pkthdr = STAILQ_NEXT(pkthdr, omp_next);
796 if (!pkthdr) {
797 return NULL;
798 }
799
800 return OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
801 }
802
net_buf_slist_get(struct net_buf_slist_t * list)803 struct os_mbuf *net_buf_slist_get(struct net_buf_slist_t *list)
804 {
805 os_sr_t sr;
806 struct os_mbuf *m;
807
808 m = net_buf_slist_peek_head(list);
809 if (!m) {
810 return NULL;
811 }
812
813 /* Remove from queue */
814 OS_ENTER_CRITICAL(sr);
815 STAILQ_REMOVE_HEAD(list, omp_next);
816 OS_EXIT_CRITICAL(sr);
817 return m;
818 }
819
net_buf_slist_put(struct net_buf_slist_t * list,struct os_mbuf * buf)820 void net_buf_slist_put(struct net_buf_slist_t *list, struct os_mbuf *buf)
821 {
822 struct os_mbuf_pkthdr *pkthdr;
823
824 pkthdr = OS_MBUF_PKTHDR(buf);
825 STAILQ_INSERT_TAIL(list, pkthdr, omp_next);
826 }
827
net_buf_slist_remove(struct net_buf_slist_t * list,struct os_mbuf * prev,struct os_mbuf * cur)828 void net_buf_slist_remove(struct net_buf_slist_t *list, struct os_mbuf *prev,
829 struct os_mbuf *cur)
830 {
831 struct os_mbuf_pkthdr *pkthdr, *cur_pkthdr;
832
833 cur_pkthdr = OS_MBUF_PKTHDR(cur);
834
835 STAILQ_FOREACH(pkthdr, list, omp_next) {
836 if (cur_pkthdr == pkthdr) {
837 STAILQ_REMOVE(list, cur_pkthdr, os_mbuf_pkthdr, omp_next);
838 break;
839 }
840 }
841 }
842
net_buf_slist_merge_slist(struct net_buf_slist_t * list,struct net_buf_slist_t * list_to_append)843 void net_buf_slist_merge_slist(struct net_buf_slist_t *list,
844 struct net_buf_slist_t *list_to_append)
845 {
846 struct os_mbuf_pkthdr *pkthdr;
847
848 STAILQ_FOREACH(pkthdr, list_to_append, omp_next) {
849 STAILQ_INSERT_TAIL(list, pkthdr, omp_next);
850 }
851
852 STAILQ_INIT(list);
853 }
854
855 #if MYNEWT_VAL(BLE_MESH_SETTINGS)
856
settings_bytes_from_str(char * val_str,void * vp,int * len)857 int settings_bytes_from_str(char *val_str, void *vp, int *len)
858 {
859 *len = base64_decode(val_str, vp);
860 return 0;
861 }
862
settings_str_from_bytes(void * vp,int vp_len,char * buf,int buf_len)863 char *settings_str_from_bytes(void *vp, int vp_len, char *buf, int buf_len)
864 {
865 if (BASE64_ENCODE_SIZE(vp_len) > buf_len) {
866 return NULL;
867 }
868
869 base64_encode(vp, vp_len, buf, 1);
870
871 return buf;
872 }
873
874 #endif /* MYNEWT_VAL(BLE_MESH_SETTINGS) */
875
876