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