1 /** @file
2 * @brief Bluetooth shell module
3 *
4 * Provide some Bluetooth shell commands that can be useful to applications.
5 */
6
7 /*
8 * Copyright (c) 2017 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13 #include <bt_errno.h>
14 #include <ble_types/types.h>
15 #include <stddef.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <misc/byteorder.h>
19 #include <zephyr.h>
20
21 #include <settings/settings.h>
22
23 #include <bluetooth/hci.h>
24 #include <bluetooth/bluetooth.h>
25 #include <bluetooth/conn.h>
26 #include <bluetooth/l2cap.h>
27 #include <bluetooth/rfcomm.h>
28 #include <bluetooth/sdp.h>
29 #include <aos/ble.h>
30 #include <common/log.h>
31 #include <conn_internal.h>
32 #if AOS_COMP_CLI
33 #include "aos/cli.h"
34 #endif
35 // #include <yoc/hrs.h>
36
37 /** @brief Callback called when command is entered.
38 *
39 * @param argc Number of parameters passed.
40 * @param argv Array of option strings. First option is always command name.
41 *
42 * @return 0 in case of success or negative value in case of error.
43 */
44 typedef int (*shell_cmd_function_t)(int argc, char *argv[]);
45
46 struct shell_cmd {
47 const char *cmd_name;
48 shell_cmd_function_t cb;
49 const char *help;
50 const char *desc;
51 };
52
53 #include "bt.h"
54 #include "gatt.h"
55 #include "ll.h"
56 #include <app_test.h>
57
58 #define DEVICE_NAME CONFIG_BT_DEVICE_NAME
59 #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
60 #define CREDITS 10
61 #define DATA_MTU (23 * CREDITS)
62 #define DATA_BREDR_MTU 48
63
64 int fail_count = 0;
65 //int16_t g_yoc_uart_handle = -1;
66
67 static u8_t selected_id = BT_ID_DEFAULT;
68
69 #if defined(CONFIG_BT_CONN)
70 struct bt_conn *default_conn;
71 int16_t g_bt_conn_handle = -1;
72 int16_t g_security_level = 0;
73 extern int16_t g_handle;
74
75 /* Connection context for BR/EDR legacy pairing in sec mode 3 */
76 static int16_t g_pairing_handle = -1;
77 #endif /* CONFIG_BT_CONN */
78
79 static void device_find(ble_event_en event, void *event_data);
80 #if defined(CONFIG_BT_SMP)
81 static void smp_event(ble_event_en event, void *event_data);
82 #endif
83 static void conn_param_req(ble_event_en event, void *event_data);
84 static void conn_param_update(ble_event_en event, void *event_data);
85
86 #define L2CAP_DYM_CHANNEL_NUM 2
87
88 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
89 NET_BUF_POOL_DEFINE(data_tx_pool, L2CAP_DYM_CHANNEL_NUM, DATA_MTU, BT_BUF_USER_DATA_MIN, NULL);
90 NET_BUF_POOL_DEFINE(data_rx_pool, L2CAP_DYM_CHANNEL_NUM, DATA_MTU, BT_BUF_USER_DATA_MIN, NULL);
91 #endif
92
93 #if defined(CONFIG_BT_BREDR)
94 NET_BUF_POOL_DEFINE(data_bredr_pool, 1, DATA_BREDR_MTU, BT_BUF_USER_DATA_MIN,
95 NULL);
96
97 #define SDP_CLIENT_USER_BUF_LEN 512
98 NET_BUF_POOL_DEFINE(sdp_client_pool, CONFIG_BT_MAX_CONN,
99 SDP_CLIENT_USER_BUF_LEN, BT_BUF_USER_DATA_MIN, NULL);
100 #endif /* CONFIG_BT_BREDR */
101
102 #if defined(CONFIG_BT_RFCOMM)
103
104 static struct bt_sdp_attribute spp_attrs[] = {
105 BT_SDP_NEW_SERVICE,
106 BT_SDP_LIST(
107 BT_SDP_ATTR_SVCLASS_ID_LIST,
108 BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3),
109 BT_SDP_DATA_ELEM_LIST(
110 {
111 BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
112 BT_SDP_ARRAY_16(BT_SDP_SERIAL_PORT_SVCLASS)
113 },
114 )
115 ),
116 BT_SDP_LIST(
117 BT_SDP_ATTR_PROTO_DESC_LIST,
118 BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 12),
119 BT_SDP_DATA_ELEM_LIST(
120 {
121 BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 3),
122 BT_SDP_DATA_ELEM_LIST(
123 {
124 BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
125 BT_SDP_ARRAY_16(BT_SDP_PROTO_L2CAP)
126 },
127 )
128 },
129 {
130 BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 5),
131 BT_SDP_DATA_ELEM_LIST(
132 {
133 BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
134 BT_SDP_ARRAY_16(BT_SDP_PROTO_RFCOMM)
135 },
136 {
137 BT_SDP_TYPE_SIZE(BT_SDP_UINT8),
138 BT_SDP_ARRAY_8(BT_RFCOMM_CHAN_SPP)
139 },
140 )
141 },
142 )
143 ),
144 BT_SDP_LIST(
145 BT_SDP_ATTR_PROFILE_DESC_LIST,
146 BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8),
147 BT_SDP_DATA_ELEM_LIST(
148 {
149 BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6),
150 BT_SDP_DATA_ELEM_LIST(
151 {
152 BT_SDP_TYPE_SIZE(BT_SDP_UUID16),
153 BT_SDP_ARRAY_16(BT_SDP_SERIAL_PORT_SVCLASS)
154 },
155 {
156 BT_SDP_TYPE_SIZE(BT_SDP_UINT16),
157 BT_SDP_ARRAY_16(0x0102)
158 },
159 )
160 },
161 )
162 ),
163 BT_SDP_SERVICE_NAME("Serial Port"),
164 };
165
166 static struct bt_sdp_record spp_rec = BT_SDP_RECORD(spp_attrs);
167
168 #endif /* CONFIG_BT_RFCOMM */
169
170 #define NAME_LEN 30
171
addr_le_str(const bt_addr_le_t * addr)172 static char *addr_le_str(const bt_addr_le_t *addr)
173 {
174 static char bufs[2][27];
175 static u8_t cur;
176 char *str;
177
178 str = bufs[cur++];
179 cur %= ARRAY_SIZE(bufs);
180 bt_addr_le_to_str(addr, str, sizeof(bufs[cur]));
181
182 return str;
183 }
184
char2u8(char c)185 static uint8_t char2u8(char c)
186 {
187 if (c >= '0' && c <= '9') {
188 return (c - '0');
189 } else if (c >= 'a' && c <= 'f') {
190 return (c - 'a' + 10);
191 } else if (c >= 'A' && c <= 'F') {
192 return (c - 'A' + 10);
193 } else {
194 return 0;
195 }
196 }
197
str2hex(uint8_t hex[],char * s,uint8_t cnt)198 void str2hex(uint8_t hex[], char *s, uint8_t cnt)
199 {
200 uint8_t i;
201
202 if (!s) {
203 return;
204 }
205
206 for (i = 0; (*s != '\0') && (i < cnt); i++, s += 2) {
207 hex[i] = ((char2u8(*s) & 0x0f) << 4) | ((char2u8(*(s + 1))) & 0x0f);
208 }
209 }
210
bt_addr2str(const dev_addr_t * addr,char * str,uint16_t len)211 static inline int bt_addr2str(const dev_addr_t *addr, char *str,
212 uint16_t len)
213 {
214 char type[10];
215
216 switch (addr->type) {
217 case BT_ADDR_LE_PUBLIC:
218 strcpy(type, "public");
219 break;
220
221 case BT_ADDR_LE_RANDOM:
222 strcpy(type, "random");
223 break;
224
225 default:
226 snprintf(type, sizeof(type), "0x%02x", addr->type);
227 break;
228 }
229
230 return snprintf(str, len, "%02X:%02X:%02X:%02X:%02X:%02X (%s)",
231 addr->val[5], addr->val[4], addr->val[3],
232 addr->val[2], addr->val[1], addr->val[0], type);
233 }
234
chars2hex(const char * c,u8_t * x)235 static int chars2hex(const char *c, u8_t *x)
236 {
237 if (*c >= '0' && *c <= '9') {
238 *x = *c - '0';
239 } else if (*c >= 'a' && *c <= 'f') {
240 *x = *c - 'a' + 10;
241 } else if (*c >= 'A' && *c <= 'F') {
242 *x = *c - 'A' + 10;
243 } else {
244 return -EINVAL;
245 }
246
247 return 0;
248 }
249
str2bt_addr(const char * str,dev_addr_t * addr)250 static int str2bt_addr(const char *str, dev_addr_t *addr)
251 {
252 int i, j;
253 u8_t tmp;
254
255 if (strlen(str) != 17) {
256 return -EINVAL;
257 }
258
259 for (i = 5, j = 1; *str != '\0'; str++, j++) {
260 if (!(j % 3) && (*str != ':')) {
261 return -EINVAL;
262 } else if (*str == ':') {
263 i--;
264 continue;
265 }
266
267 addr->val[i] = addr->val[i] << 4;
268
269 if (chars2hex(str, &tmp) < 0) {
270 return -EINVAL;
271 }
272
273 addr->val[i] |= tmp;
274 }
275
276 return 0;
277 }
278
str2bt_addr_le(const char * str,const char * type,dev_addr_t * addr)279 static int str2bt_addr_le(const char *str, const char *type, dev_addr_t *addr)
280 {
281 int err;
282
283 err = str2bt_addr(str, addr);
284
285 if (err < 0) {
286 return err;
287 }
288
289 if (!strcmp(type, "public") || !strcmp(type, "(public)")) {
290 addr->type = DEV_ADDR_LE_PUBLIC;
291 } else if (!strcmp(type, "random") || !strcmp(type, "(random)")) {
292 addr->type = DEV_ADDR_LE_RANDOM;
293 } else {
294 return -EINVAL;
295 }
296
297 return 0;
298 }
299
conn_change(ble_event_en event,void * event_data)300 static void conn_change(ble_event_en event, void *event_data)
301 {
302 int only_one = 1;
303 evt_data_gap_conn_change_t *e = (evt_data_gap_conn_change_t *)event_data;
304
305 connect_info_t info;
306
307 if (only_one) {
308 int ret;
309 printf("******* test ble_stack_connect_info_get start ******\n");
310 ret = ble_stack_connect_info_get(e->conn_handle, &info);
311 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_connect_info_get fail");
312
313 if (ret == 0) {
314 printf("********conn get info.role=%d\n", info.role);
315 printf("********conn get info.interval=%d\n", info.interval);
316 }
317
318 printf("info.local_addr.val[]=");
319
320 for (int i = 0; i < 6; i++) {
321 printf("%x:", info.local_addr.val[i]);
322 }
323
324 printf("\n");
325
326 printf("info.peer_addr.val[]=");
327
328 for (int i = 0; i < 6; i++) {
329 printf("%x:", info.peer_addr.val[i]);
330 }
331
332 printf("\n");
333
334 ret = ble_stack_connect_info_get(e->conn_handle, NULL);
335 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_connect_info_get fail");
336
337 ret = ble_stack_connect_info_get(-1, &info);
338 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_connect_info_get fail");
339 printf("******* test ble_stack_connect_info_get end ******\n");
340
341 only_one = 0;
342 }
343
344 ble_stack_connect_info_get(e->conn_handle, &info);
345
346 if (e->connected == CONNECTED && e->err == 0) {
347 printf("Connected (%d): %s\n", e->conn_handle, addr_le_str((bt_addr_le_t *)&info.peer_addr));
348
349 if (g_bt_conn_handle == -1) {
350 g_bt_conn_handle = e->conn_handle;
351 }
352
353 /* clear connection reference for sec mode 3 pairing */
354 if (g_pairing_handle != -1) {
355 g_pairing_handle = -1;
356 }
357 } else {
358
359 printf("Disconected (%d): %s err %d\n", e->conn_handle, addr_le_str((bt_addr_le_t *)&info.peer_addr), e->err);
360
361 if (e->err == 31) {
362 while (1);
363 }
364
365 if (g_bt_conn_handle == e->conn_handle) {
366 g_bt_conn_handle = -1;
367 }
368
369 g_security_level = 0;
370 }
371 }
372
conn_security_change(ble_event_en event,void * event_data)373 static void conn_security_change(ble_event_en event, void *event_data)
374 {
375 evt_data_gap_security_change_t *e = (evt_data_gap_security_change_t *)event_data;
376 printf("conn %d security level change to level%d\n", e->conn_handle, e->level);
377 g_security_level = e->level;
378 }
379
380 //int16_t g_tx_ccc_value = 0;
381 //static void event_char_ccc_change(ble_event_en event, void *event_data)
382 //{
383 // evt_data_gatt_char_ccc_change_t *e = (evt_data_gatt_char_ccc_change_t *)event_data;
384 // g_tx_ccc_value = e->ccc_value;
385 //}
386
387 //void event_char_write(ble_event_en event, void *event_data)
388 //{
389 // evt_data_gatt_char_write_t *e = (evt_data_gatt_char_write_t *)event_data;
390 // int16_t hande_offset = 0;
391 //
392 // if (g_conn_hanlde == e->conn_handle) {
393 // if (e->char_handle > g_yoc_uart_handle) {
394 // hande_offset = e->char_handle - g_yoc_uart_handle;
395 // } else {
396 // return;
397 // }
398 //
399 // switch (hande_offset) {
400 // case YOC_UART_IDX_RX_VAL:
401 // memcpy(rx_buf, e->data, MIN(e->len, sizeof(rx_buf)));
402 // e->len = MIN(e->len, sizeof(rx_buf));
403 // rx_buf[e->len] = '\0';
404 // LOGI(TAG, "recv (%d) data:%s\n", e->len, rx_buf);
405 //
406 // memcpy(tx_buf, rx_buf, sizeof(rx_buf));
407 // return;
408 // }
409 // }
410 //
411 // e->len = 0;
412 // return;
413 //}
414
415 //void event_char_read(ble_event_en event, void *event_data)
416 //{
417 // evt_data_gatt_char_read_t *e = (evt_data_gatt_char_read_t *)event_data;
418 // int16_t hande_offset = 0;
419 //
420 // if (g_conn_hanlde == e->conn_handle) {
421 // if (e->char_handle > g_yoc_uart_handle) {
422 // hande_offset = e->char_handle - g_yoc_uart_handle;
423 // } else {
424 // return;
425 // }
426 //
427 // switch (hande_offset) {
428 // case YOC_UART_IDX_RX_VAL:
429 // memcpy(e->data, rx_buf, MIN(e->len, sizeof(rx_buf)));
430 // e->len = MIN(e->len, sizeof(rx_buf));
431 // return;
432 //
433 // case YOC_UART_IDX_TX_VAL:
434 // memcpy(e->data, tx_buf, MIN(e->len, sizeof(tx_buf)));
435 // e->len = MIN(e->len, sizeof(tx_buf));
436 // return;
437 //
438 // case YOC_UART_IDX_RX_DES:
439 // memcpy(e->data, rx_char_des, MIN(e->len, strlen(rx_char_des)));
440 // e->len = MIN(e->len, strlen(rx_char_des));
441 // return;
442 //
443 // case YOC_UART_IDX_TX_DES:
444 // memcpy(e->data, tx_char_des, MIN(e->len, strlen(tx_char_des)));
445 // e->len = MIN(e->len, strlen(tx_char_des));
446 // return;
447 // }
448 // }
449 //
450 // e->len = 0;
451 // return;
452 //}
event_callback(ble_event_en event,void * event_data)453 static int event_callback(ble_event_en event, void *event_data)
454 {
455 switch (event) {
456 case EVENT_GAP_CONN_CHANGE:
457 conn_change(event, event_data);
458 break;
459
460 case EVENT_GAP_CONN_SECURITY_CHANGE:
461 conn_security_change(event, event_data);
462 break;
463
464 //case EVENT_GATT_CHAR_CCC_CHANGE:
465 // event_char_ccc_change(event, event_data);
466 // break;
467
468 //case EVENT_GATT_CHAR_WRITE:
469 // event_char_write(event, event_data);
470 // break;
471
472 //case EVENT_GATT_CHAR_READ:
473 // event_char_read(event, event_data);
474 // break;
475
476 case EVENT_GAP_DEV_FIND:
477 device_find(event, event_data);
478 break;
479
480 case EVENT_GAP_CONN_PARAM_REQ:
481 conn_param_req(event, event_data);
482 break;
483
484 case EVENT_GAP_CONN_PARAM_UPDATE:
485 conn_param_update(event, event_data);
486 break;
487 #if defined(CONFIG_BT_SMP)
488
489 case EVENT_SMP_PASSKEY_DISPLAY:
490 case EVENT_SMP_PASSKEY_CONFIRM:
491 case EVENT_SMP_PASSKEY_ENTER:
492 case EVENT_SMP_PAIRING_CONFIRM:
493 case EVENT_SMP_PAIRING_COMPLETE:
494 case EVENT_SMP_CANCEL:
495 smp_event(event, event_data);
496 break;
497 #endif
498
499 default:
500 //printf("Unhandle event %d\n", event);
501 break;
502 }
503
504 return 0;
505 }
506
507 static ble_event_cb_t ble_cb = {
508 .callback = event_callback,
509 };
510
cmd_init(int argc,char * argv[])511 static int cmd_init(int argc, char *argv[])
512 {
513 if (!strcmp(argv[1], "test")) {
514 fail_count = 0;
515 int err;
516 #define DEV_ADDR {0xCC,0x3B,0xE3,0x82,0xBA,0xC0}
517 #define DEV_NAME "BLE_INIT"
518 init_param_t init = {NULL, NULL, 1};
519 dev_addr_t addr2 = {DEV_ADDR_LE_RANDOM, DEV_ADDR};
520 init_param_t demo = {
521 .dev_name = DEV_NAME,
522 .dev_addr = &addr2,
523 .conn_num_max = 1,
524 };
525 //param = NULL
526 err = ble_stack_init(NULL);
527 TEST_ASSERT_EQUAL(-1, err, 1, "ble_stack_init param=NULL fail");
528 //dev_name = NULL.设备的名称为NULL
529 init.dev_addr = &addr2;
530 err = ble_stack_init(&init);
531 TEST_ASSERT_EQUAL(0, err, 1, "ble_stack_init param.dev_name=NULL fail");
532 //dev_addr = NULL
533 init.dev_name = DEV_NAME;
534 init.dev_addr = NULL;
535 err = ble_stack_init(&init);
536 TEST_ASSERT_EQUAL(0, err, 1, "ble_stack_init param.dev_addr=NULL fail");
537 //最大连接数为0
538 init.dev_addr = &addr2;
539 init.conn_num_max = 0;
540 err = ble_stack_init(&init);
541 TEST_ASSERT_EQUAL(0, err, 1, "ble_stack_init conn_num_max=0 fail");
542
543 //测试设备的type
544 for (int i = 0; i < 4; i++) {
545 addr2.type = i;
546 demo.dev_addr = &addr2;
547 err = ble_stack_init(&demo);
548 TEST_ASSERT_EQUAL(0, err, 1, "ble_stack_init dev_addr->type fail");
549 }
550
551 //测试设备的最大连接数
552 addr2.type = DEV_ADDR_LE_RANDOM;
553 demo.dev_addr = &addr2;
554 demo.conn_num_max = 65535;
555 err = ble_stack_init(&demo);
556 TEST_ASSERT_EQUAL(0, err, 1, "ble_stack init conn_num_max=65535 fail");
557
558 if (fail_count == 0) {
559 printf("BLE_INIT TEST PASS\n");
560 } else {
561 fail_count = 0;
562 printf("BLE_INIT TEST FAILED\n");
563 }
564
565 return 0;
566 } else {
567 int err;
568 fail_count = 0;
569 dev_addr_t addr;
570 init_param_t init = {NULL, NULL, 1};
571
572 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
573 NET_BUF_POOL_INIT(data_tx_pool);
574 NET_BUF_POOL_INIT(data_rx_pool);
575 #endif
576
577 #if defined(CONFIG_BT_BREDR)
578 NET_BUF_POOL_INIT(data_bredr_pool);
579 NET_BUF_POOL_INIT(sdp_client_pool);
580 #endif /* CONFIG_BT_BREDR */
581
582 if (argc == 3) {
583 err = str2bt_addr_le(argv[1], argv[2], &addr);
584
585 if (err) {
586 printf("Invalid address\n");
587 return err;
588 }
589
590 init.dev_addr = &addr;
591 }
592
593 err = ble_stack_init(&init);
594
595 if (err) {
596 printf("Bluetooth init failed (err %d)\n", err);
597 return err;
598 }
599
600 err = ble_stack_setting_load();
601
602 if (err) {
603 printf("Bluetooth load failed (err %d)\n", err);
604 return err;
605 }
606
607 err = ble_stack_event_register(NULL);
608 TEST_ASSERT_EQUAL(-1, err, 1, "ble_stack event_register fail");
609
610 err = ble_stack_event_register(&ble_cb);
611 TEST_ASSERT_EQUAL(0, err, 1, "ble_stack_event_register fail");
612
613 if (err == 0) {
614 printf("Bluetooth stack init success\n");
615 }
616
617 if (fail_count == 0) {
618 printf("BLE_INIT TEST PASS\n");
619 } else {
620 fail_count = 0;
621 printf("BLE_INIT TEST FAILED\n");
622 }
623
624 return 0;
625 }
626 }
627 #if defined(CONFIG_BT_HCI) || defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
hexdump(const u8_t * data,size_t len)628 void hexdump(const u8_t *data, size_t len)
629 {
630 int n = 0;
631
632 while (len--) {
633 if (n % 16 == 0) {
634 printf("%08X ", n);
635 }
636
637 printf("%02X ", *data++);
638
639 n++;
640
641 if (n % 8 == 0) {
642 if (n % 16 == 0) {
643 printf("\n");
644 } else {
645 printf(" ");
646 }
647 }
648 }
649
650 if (n % 16) {
651 printf("\n");
652 }
653 }
654 #endif /* CONFIG_BT_HCI || CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */
655
656 #if defined(CONFIG_BT_HCI)
cmd_hci_cmd(int argc,char * argv[])657 static int cmd_hci_cmd(int argc, char *argv[])
658 {
659 u8_t ogf;
660 u16_t ocf;
661 struct net_buf *buf = NULL, *rsp;
662 int err;
663
664 if (argc < 3) {
665 return -EINVAL;
666 }
667
668 ogf = strtoul(argv[1], NULL, 16);
669 ocf = strtoul(argv[2], NULL, 16);
670
671 if (argc > 3) {
672 int i;
673
674 buf = bt_hci_cmd_create(BT_OP(ogf, ocf), argc - 3);
675
676 for (i = 3; i < argc; i++) {
677 net_buf_add_u8(buf, strtoul(argv[i], NULL, 16));
678 }
679 }
680
681 err = bt_hci_cmd_send_sync(BT_OP(ogf, ocf), buf, &rsp);
682
683 if (err) {
684 printf("HCI command failed (err %d)\n", err);
685 } else {
686 hexdump(rsp->data, rsp->len);
687 net_buf_unref(rsp);
688 }
689
690 return 0;
691 }
692 #endif /* CONFIG_BT_HCI */
693
cmd_name(int argc,char * argv[])694 static int cmd_name(int argc, char *argv[])
695 {
696 int err;
697
698 if (argc < 2) {
699 printf("Bluetooth Local Name: %s\n", bt_get_name());
700 return 0;
701 }
702
703 err = bt_set_name(argv[1]);
704
705 if (err) {
706 printf("Unable to set name %s (err %d)", argv[1], err);
707 }
708
709 return 0;
710 }
711
cmd_id_create(int argc,char * argv[])712 static int cmd_id_create(int argc, char *argv[])
713 {
714 dev_addr_t addr;
715 int err;
716
717 if (argc > 1) {
718 err = str2bt_addr_le(argv[1], "random", &addr);
719
720 if (err) {
721 printf("Invalid address\n");
722 return err;
723 }
724 } else {
725 bt_addr_le_copy((bt_addr_le_t *)&addr, BT_ADDR_LE_ANY);
726 }
727
728 err = bt_id_create((bt_addr_le_t *)&addr, NULL);
729
730 if (err < 0) {
731 printf("Creating new ID failed (err %d)\n", err);
732 return 0;
733 }
734
735 printf("New identity (%d) created: %s\n", err, addr_le_str((bt_addr_le_t *)&addr));
736
737 return 0;
738 }
739
cmd_id_reset(int argc,char * argv[])740 static int cmd_id_reset(int argc, char *argv[])
741 {
742 bt_addr_le_t addr;
743 u8_t id;
744 int err;
745
746 if (argc < 2) {
747 printf("Identity identifier not specified\n");
748 return -EINVAL;
749 }
750
751 id = strtol(argv[1], NULL, 10);
752
753 if (argc > 2) {
754 err = str2bt_addr_le(argv[2], "random", (dev_addr_t *)&addr);
755
756 if (err) {
757 printf("Invalid address\n");
758 return err;
759 }
760 } else {
761 bt_addr_le_copy(&addr, BT_ADDR_LE_ANY);
762 }
763
764 err = bt_id_reset(id, &addr, NULL);
765
766 if (err < 0) {
767 printf("Resetting ID %u failed (err %d)\n", id, err);
768 return 0;
769 }
770
771 printf("Identity %u reset: %s\n", id, addr_le_str(&addr));
772
773 return 0;
774 }
775
cmd_id_delete(int argc,char * argv[])776 static int cmd_id_delete(int argc, char *argv[])
777 {
778 u8_t id;
779 int err;
780
781 if (argc < 2) {
782 printf("Identity identifier not specified\n");
783 return -EINVAL;
784 }
785
786 id = strtol(argv[1], NULL, 10);
787
788 err = bt_id_delete(id);
789
790 if (err < 0) {
791 printf("Deleting ID %u failed (err %d)\n", id, err);
792 return 0;
793 }
794
795 printf("Identity %u deleted\n", id);
796
797 return 0;
798 }
799
cmd_id_show(int argc,char * argv[])800 static int cmd_id_show(int argc, char *argv[])
801 {
802 bt_addr_le_t addrs[CONFIG_BT_ID_MAX];
803 size_t i, count = CONFIG_BT_ID_MAX;
804
805 bt_id_get(addrs, &count);
806
807 for (i = 0; i < count; i++) {
808 printf("%s%zu: %s\n", i == selected_id ? "*" : " ", i,
809 addr_le_str(&addrs[i]));
810 }
811
812 return 0;
813 }
814
cmd_id_select(int argc,char * argv[])815 static int cmd_id_select(int argc, char *argv[])
816 {
817 bt_addr_le_t addrs[CONFIG_BT_ID_MAX];
818 size_t count = CONFIG_BT_ID_MAX;
819 u8_t id;
820
821 if (argc < 2) {
822 return -EINVAL;
823 }
824
825 id = strtol(argv[1], NULL, 10);
826
827 bt_id_get(addrs, &count);
828
829 if (count <= id) {
830 printf("Invalid identity\n");
831 return 0;
832 }
833
834 //printf("Selected identity: %s\n", addr_le_str(&addrs[id]));
835 selected_id = id;
836
837 return 0;
838 }
839
parse_ad(uint8_t * data,uint16_t len,int (* cb)(ad_data_t * data,void * arg),void * cb_arg)840 static inline int parse_ad(uint8_t *data, uint16_t len, int (* cb)(ad_data_t *data, void *arg), void *cb_arg)
841 {
842 int num = 0;
843 uint8_t *pdata = data;
844 ad_data_t ad = {0};
845 int ret;
846
847 while (len) {
848 if (pdata[0] == 0) {
849 return num;
850 }
851
852 if (len < pdata[0] + 1) {
853 return -1;
854 };
855
856 ad.len = pdata[0] - 1;
857
858 ad.type = pdata[1];
859
860 ad.data = &pdata[2];
861
862 if (cb) {
863 ret = cb(&ad, cb_arg);
864
865 if (ret) {
866 break;
867 }
868 }
869
870 num++;
871 len -= (pdata[0] + 1);
872 pdata += (pdata[0] + 1);
873 }
874
875 return num;
876 }
877
878 uint8_t *pscan_ad = NULL;
879 uint8_t *pscan_sd = NULL;
880
scan_ad_cmp(ad_data_t * ad,void * arg)881 static int scan_ad_cmp(ad_data_t *ad, void *arg)
882 {
883 ad_data_t *ad2 = arg;
884
885 return (ad->type == ad2->type && ad->len == ad2->len
886 && 0 == memcmp(ad->data, ad2->data, ad->len));
887 }
888
scan_ad_callback(ad_data_t * ad,void * arg)889 static int scan_ad_callback(ad_data_t *ad, void *arg)
890 {
891 evt_data_gap_dev_find_t *e = arg;
892 int ad_num;
893 uint8_t *pad = NULL;
894 int ret;
895
896 if (e->adv_len) {
897 if (e->adv_type == 0x04) {
898 pad = pscan_sd;
899 } else {
900 pad = pscan_ad;
901 }
902
903 ad_num = parse_ad(pad, 31, NULL, NULL);
904
905 ret = parse_ad(pad, 31, scan_ad_cmp, (void *)ad);
906
907 if (ret < ad_num) {
908 return 1;
909 }
910 }
911
912 return 0;
913 }
914
device_find(ble_event_en event,void * event_data)915 static void device_find(ble_event_en event, void *event_data)
916 {
917 evt_data_gap_dev_find_t *e = event_data;
918 int ad_num = parse_ad(e->adv_data, e->adv_len, NULL, NULL);
919 int ret;
920 char addr_str[32] = {0};
921
922 bt_addr2str(&e->dev_addr, addr_str, sizeof(addr_str));
923
924 if (pscan_ad || pscan_sd) {
925 ret = parse_ad(e->adv_data, e->adv_len, scan_ad_callback, event_data);
926
927 if (ret < ad_num) {
928 printf("[DEVICE]: %s, adv type %d, rssi %d, Raw data:%s\n", addr_str, e->adv_type, e->rssi, bt_hex(e->adv_data, e->adv_len));
929 }
930 } else {
931 printf("[DEVICE]: %s, adv type %d, rssi %d, Raw data:%s\n", addr_str, e->adv_type, e->rssi, bt_hex(e->adv_data, e->adv_len));
932 }
933 }
934
conn_param_req(ble_event_en event,void * event_data)935 static void conn_param_req(ble_event_en event, void *event_data)
936 {
937 evt_data_gap_conn_param_req_t *e = event_data;
938 printf("LE conn param req: int (0x%04x, 0x%04x) lat %d to %d\n",
939 e->param.interval_min, e->param.interval_max, e->param.latency,
940 e->param.timeout);
941
942 e->accept = 1;
943 }
944
conn_param_update(ble_event_en event,void * event_data)945 static void conn_param_update(ble_event_en event, void *event_data)
946 {
947 evt_data_gap_conn_param_update_t *e = event_data;
948
949 printf("LE conn param updated: int 0x%04x lat %d to %d\n", e->interval,
950 e->latency, e->timeout);
951 }
952
cmd_scan(int argc,char * argv[])953 static int cmd_scan(int argc, char *argv[])
954 {
955 int ret;
956 static uint8_t scan_ad[31] = {0};
957 static uint8_t scan_sd[31] = {0};
958
959 scan_param_t params = {
960 SCAN_PASSIVE,
961 SCAN_FILTER_DUP_DISABLE,
962 SCAN_FAST_INTERVAL,
963 SCAN_FAST_WINDOW,
964 };
965
966 if (argc < 2) {
967 return -EINVAL;
968 }
969
970 if (argc >= 2) {
971 if (!strcmp(argv[1], "active")) {
972 params.type = SCAN_ACTIVE;
973 } else if (!strcmp(argv[1], "off")) {
974 pscan_ad = NULL;
975 pscan_sd = NULL;
976 ret = ble_stack_scan_stop();
977
978 if (!ret) {
979 printf("Scan stop succ\n");
980 } else {
981 printf("Scan stop fail\n");
982 }
983
984 return ret;
985
986 } else if (!strcmp(argv[1], "passive")) {
987 params.type = SCAN_PASSIVE;
988 } else if (!strcmp(argv[1], "test")) {
989 scan_param_t param = {
990 SCAN_PASSIVE,
991 SCAN_FILTER_DUP_ENABLE,
992 SCAN_FAST_INTERVAL,
993 SCAN_FAST_WINDOW,
994 };
995
996 fail_count = 0;
997 //参数为NULL
998 ret = ble_stack_scan_start(NULL);
999 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1000
1001 if (ret == 0) {
1002 ble_stack_scan_stop();
1003 }
1004
1005 //测试扫描方式
1006 for (int i = 0; i < 2; i++) {
1007 param.type = i ;
1008 ret = ble_stack_scan_start(¶m);
1009 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1010
1011 if (ret == 0) {
1012 ble_stack_scan_stop();
1013 }
1014 }
1015
1016 param.type = 2 ;
1017 ret = ble_stack_scan_start(¶m);
1018 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1019
1020 if (ret == 0) {
1021 ble_stack_scan_stop();
1022 }
1023
1024 param.type = SCAN_PASSIVE;
1025
1026 //测试是否过滤重复包
1027 for (int i = 0 ; i < 2; i++) {
1028 param.filter_dup = i;
1029 ret = ble_stack_scan_start(¶m);
1030 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1031
1032 if (ret == 0) {
1033 ble_stack_scan_stop();
1034 }
1035 }
1036
1037 param.filter_dup = 2;
1038 ret = ble_stack_scan_start(¶m);
1039 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1040
1041 if (ret == 0) {
1042 ble_stack_scan_stop();
1043 }
1044
1045 //测试扫描间隔时间 0x0004~0x4000
1046 param.filter_dup = 0x00;
1047 param.interval = 0x0000; // interval设置为0
1048 ret = ble_stack_scan_start(¶m);
1049 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1050
1051 if (ret == 0) {
1052 ble_stack_scan_stop();
1053 }
1054
1055 param.interval = 0x0003; // interval设置为3
1056 ret = ble_stack_scan_start(¶m);
1057 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1058
1059 if (ret == 0) {
1060 ble_stack_scan_stop();
1061 }
1062
1063 param.interval = 0x0004; // interval设置为4
1064 param.window = 0x0004;
1065 ret = ble_stack_scan_start(¶m);
1066 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1067
1068 if (ret == 0) {
1069 ble_stack_scan_stop();
1070 }
1071
1072 param.interval = 0x4000;
1073 ret = ble_stack_scan_start(¶m);
1074 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1075
1076 if (ret == 0) {
1077 ble_stack_scan_stop();
1078 }
1079
1080 param.interval = 0x4001;
1081 ret = ble_stack_scan_start(¶m);
1082 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1083
1084 if (ret == 0) {
1085 ble_stack_scan_stop();
1086 }
1087
1088 param.interval = 0x0800; // interval设置为0x0800,对应的时间为1.28s
1089 ret = ble_stack_scan_start(¶m);
1090 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1091
1092 if (ret == 0) {
1093 ble_stack_scan_stop();
1094 }
1095
1096 //测试窗口持续时间
1097 param.window = 0x0000;
1098 ret = ble_stack_scan_start(¶m);
1099 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1100
1101 if (ret == 0) {
1102 ble_stack_scan_stop();
1103 }
1104
1105 param.window = 0x0001;
1106 ret = ble_stack_scan_start(¶m);
1107 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1108
1109 if (ret == 0) {
1110 ble_stack_scan_stop();
1111 }
1112
1113 param.window = 0x0004;
1114 ret = ble_stack_scan_start(¶m);
1115 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1116
1117 if (ret == 0) {
1118 ret = ble_stack_scan_stop();
1119 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_stop fail");
1120 } else {
1121 ret = ble_stack_scan_stop();
1122 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_stop fail");
1123 }
1124
1125 param.window = 0x4000;
1126 param.interval = 0x4000;
1127 ret = ble_stack_scan_start(¶m);
1128 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1129
1130 if (ret == 0) {
1131 ble_stack_scan_stop();
1132 }
1133
1134 param.window = 0x4001;
1135 ret = ble_stack_scan_start(¶m);
1136 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1137
1138 if (ret == 0) {
1139 ret = ble_stack_scan_stop();
1140 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_stop fail");
1141 } else {
1142 ret = ble_stack_scan_stop();
1143 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_scan_stop fail");
1144 }
1145
1146 param.type = SCAN_PASSIVE;
1147 param.filter_dup = SCAN_FILTER_DUP_ENABLE;
1148 param.interval = SCAN_FAST_INTERVAL;
1149 param.window = SCAN_FAST_WINDOW;
1150
1151 ret = ble_stack_scan_start(¶m);
1152 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_scan_start fail");
1153
1154 if (ret) {
1155 printf("scan start fail %d!", ret);
1156 } else {
1157 printf("scan start!");
1158 }
1159
1160 //test ble_stack_get_local_addr
1161 dev_addr_t addr = {0x00, {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}};
1162
1163 ret = ble_stack_get_local_addr(NULL);
1164 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_get_local_addr fail");
1165
1166 ret = ble_stack_get_local_addr(&addr);
1167 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_get_local_addr fail");
1168
1169 if (ret == 0) {
1170 printf("addr.type =%d\n", addr.type);
1171
1172 if (addr.type < 0 || addr.type > 1) {
1173 printf("ASSERTION Failed %s: %d", __FILE__, __LINE__);
1174 }
1175
1176 for (int i = 0; i < 6; i++) {
1177 printf("addr.val[%d] = %d\n", i, addr.val[i]);
1178 }
1179 }
1180
1181 ble_stack_scan_stop();
1182
1183 if (fail_count == 0) {
1184 printf("TEST PASS\n");
1185 } else {
1186 fail_count = 0;
1187 printf("TEST FAILED\n");
1188 }
1189
1190 return 0;
1191
1192 } else {
1193 return -EINVAL;
1194 }
1195 }
1196
1197 if (argc >= 3) {
1198 if (!strcmp(argv[2], "dups")) {
1199 params.filter_dup = SCAN_FILTER_DUP_DISABLE;
1200 } else if (!strcmp(argv[2], "nodups")) {
1201 params.filter_dup = SCAN_FILTER_DUP_ENABLE;
1202 } else {
1203 return -EINVAL;
1204 }
1205 }
1206
1207 if (argc >= 4) {
1208 params.interval = strtol(argv[3], NULL, 10);
1209 }
1210
1211 if (argc >= 5) {
1212 params.window = strtol(argv[4], NULL, 10);
1213 }
1214
1215 if (argc >= 6) {
1216 pscan_ad = scan_ad;
1217 memset(scan_ad, 0, sizeof(scan_ad));
1218 str2hex(scan_ad, argv[5], sizeof(scan_ad));
1219 }
1220
1221 if (argc >= 7) {
1222 pscan_sd = scan_sd;
1223 memset(scan_sd, 0, sizeof(scan_sd));
1224 str2hex(scan_sd, argv[6], sizeof(scan_sd));
1225 }
1226
1227 return ble_stack_scan_start(¶ms);
1228 }
1229
parse_ad_data(uint8_t * data,uint16_t len,ad_data_t * ad,uint8_t * ad_num)1230 static inline int parse_ad_data(uint8_t *data, uint16_t len, ad_data_t *ad, uint8_t *ad_num)
1231 {
1232 uint8_t num = 0;
1233 uint8_t *pdata = data;
1234
1235 while (len) {
1236 if (len < pdata[0] + 1) {
1237 *ad_num = 0;
1238 return -1;
1239 };
1240
1241 num++;
1242
1243 if (ad && num <= *ad_num) {
1244 ad->len = pdata[0] - 1;
1245 ad->type = pdata[1];
1246 ad->data = &pdata[2];
1247 }
1248
1249 len -= (pdata[0] + 1);
1250 pdata += (pdata[0] + 1);
1251
1252 if (ad) {
1253 ad++;
1254 }
1255 }
1256
1257 *ad_num = num;
1258 return 0;
1259 }
1260
adv_ad_callback(ad_data_t * ad,void * arg)1261 static inline int adv_ad_callback(ad_data_t *ad, void *arg)
1262 {
1263 ad_data_t **pad = (ad_data_t **)arg;
1264
1265 (*pad)->type = ad->type;
1266 (*pad)->len = ad->len;
1267 (*pad)->data = ad->data;
1268 (*pad)++;
1269 return 0;
1270 }
1271
cmd_advertise(int argc,char * argv[])1272 static int cmd_advertise(int argc, char *argv[])
1273 {
1274 int err;
1275 adv_param_t param3 = {0};
1276 uint8_t ad_hex[31] = {0};
1277 uint8_t sd_hex[31] = {0};
1278 ad_data_t *ad = NULL;
1279 uint8_t ad_num = 0;
1280 ad_data_t *sd = NULL;
1281 uint8_t sd_num = 0;
1282
1283
1284 if (argc < 2) {
1285 goto fail;
1286 }
1287
1288 if (!strcmp(argv[1], "stop")) {
1289 if (bt_le_adv_stop() < 0) {
1290 printf("Failed to stop advertising\n");
1291 } else {
1292 printf("Advertising stopped\n");
1293 }
1294
1295 return 0;
1296 }
1297
1298 if (!strcmp(argv[1], "test")) {
1299 fail_count = 0;
1300 int ret;
1301 ad_data_t ad[3] = {0};
1302 ad_data_t sd[1] = {0};
1303
1304 uint8_t flag = AD_FLAG_GENERAL | AD_FLAG_NO_BREDR;
1305
1306 ad[0].type = AD_DATA_TYPE_FLAGS;
1307 ad[0].data = (uint8_t *)&flag;
1308 ad[0].len = 1;
1309
1310 uint8_t uuid16_list[] = {0x0d, 0x18};
1311 ad[1].type = AD_DATA_TYPE_UUID16_ALL;
1312 ad[1].data = (uint8_t *)uuid16_list;
1313 ad[1].len = sizeof(uuid16_list);
1314
1315 ad[2].type = AD_DATA_TYPE_NAME_COMPLETE;
1316 ad[2].data = (uint8_t *)DEVICE_NAME;
1317 ad[2].len = strlen(DEVICE_NAME);
1318
1319 uint8_t manu_data[10] = {0x01, 0x02, 0x3, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10};
1320 sd[0].type = AD_DATA_TYPE_MANUFACTURER_DATA;
1321 sd[0].data = (uint8_t *)manu_data;
1322 sd[0].len = sizeof(manu_data);
1323
1324 adv_param_t param = {
1325 ADV_NONCONN_IND,
1326 ad,
1327 sd,
1328 BLE_ARRAY_NUM(ad),
1329 BLE_ARRAY_NUM(sd),
1330 ADV_FAST_INT_MIN_2,
1331 ADV_FAST_INT_MAX_2,
1332 };
1333 adv_param_t par = {
1334 ADV_NONCONN_IND,
1335 ad,
1336 sd,
1337 BLE_ARRAY_NUM(ad),
1338 BLE_ARRAY_NUM(sd),
1339 ADV_FAST_INT_MIN_2,
1340 ADV_FAST_INT_MAX_2,
1341 };
1342
1343 ret = ble_stack_adv_start(NULL);
1344 TEST_ASSERT_EQUAL(-1, ret, 1, "ble_stack_adv_start fail");
1345
1346 if (ret == 0) {
1347 ble_stack_adv_stop();
1348 }
1349
1350 //蓝牙广播属性测试
1351 for (int i = 0; i < 5; i++) {
1352 par.type = i;
1353
1354 if (i == 1 || i == 4) {
1355 ret = ble_stack_adv_start(&par);
1356 TEST_ASSERT_EQUAL(-2, ret, 1, "ble_stack_adv_start fail");
1357 ble_stack_adv_stop();
1358 } else if (i == 0) {
1359 par.sd = NULL;
1360 par.sd_num = 0;
1361 par.interval_min = ADV_FAST_INT_MIN_1;
1362 par.interval_max = ADV_FAST_INT_MAX_1;
1363 ret = ble_stack_adv_start(¶m);
1364 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_adv_start fail");
1365
1366 if (ret == 0) {
1367 ret = ble_stack_adv_stop();
1368 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_adv_stop fail");
1369 }
1370
1371 ble_stack_adv_stop();
1372
1373 } else if (i == 2) {
1374 par.sd = sd;
1375 par.sd_num = BLE_ARRAY_NUM(sd);
1376 par.interval_min = ADV_SCAN_INT_MIN_1;
1377 par.interval_max = ADV_SCAN_INT_MAX_1;
1378 ret = ble_stack_adv_start(¶m);
1379 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_adv_start fail");
1380
1381 if (ret == 0) {
1382 ret = ble_stack_adv_stop();
1383 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_adv_stop fail");
1384 }
1385
1386 ble_stack_adv_stop();
1387 } else if (i == 3) {
1388 par.sd = sd;
1389 par.sd_num = BLE_ARRAY_NUM(sd);
1390 par.interval_min = ADV_FAST_INT_MIN_2;
1391 par.interval_max = ADV_FAST_INT_MAX_2;
1392 ret = ble_stack_adv_start(¶m);
1393 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_adv_start fail");
1394
1395 if (ret == 0) {
1396 ret = ble_stack_adv_stop();
1397 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_adv_stop fail");
1398 }
1399
1400 ble_stack_adv_stop();
1401 }
1402 }
1403
1404 param.type = 5;
1405 ret = ble_stack_adv_start(¶m);
1406 TEST_ASSERT_EQUAL(-2, ret, 1, "ble_stack_adv_start fail");
1407
1408 if (ret == 0) {
1409 ble_stack_adv_stop();
1410 }
1411
1412 param.type = ADV_IND;
1413 param.ad = ad;
1414 param.sd = sd;
1415 param.ad_num = BLE_ARRAY_NUM(ad);
1416 param.sd_num = BLE_ARRAY_NUM(sd);
1417 param.interval_min = ADV_FAST_INT_MIN_1;
1418 param.interval_max = ADV_FAST_INT_MAX_1;
1419
1420 //ad=NULL
1421 param.type = ADV_IND;
1422 param.ad = NULL;
1423 ret = ble_stack_adv_start(¶m);
1424 TEST_ASSERT_EQUAL(-2, ret, 1, "ble_stack_adv_start fail");
1425
1426 if (ret == 0) {
1427 ble_stack_adv_stop();
1428 }
1429
1430 //ad不为NULL,ad_num=0
1431 param.ad = ad;
1432 param.ad_num = 0;
1433 ret = ble_stack_adv_start(¶m);
1434 TEST_ASSERT_EQUAL(-2, ret, 1, "ble_stack_adv_start fail");
1435
1436 if (ret == 0) {
1437 ble_stack_adv_stop();
1438 }
1439
1440 //sd=NULL
1441 param.ad_num = BLE_ARRAY_NUM(ad);
1442 param.sd = NULL;
1443 param.sd_num = BLE_ARRAY_NUM(sd);
1444 ret = ble_stack_adv_start(¶m);
1445 TEST_ASSERT_EQUAL(-2, ret, 1, "test_ble_stack_adv_start fail");
1446
1447 if (ret == 0) {
1448 ble_stack_adv_stop();
1449 }
1450
1451 //sd不为NULL,sd_num=0
1452 param.sd = sd;
1453 param.sd_num = 0;
1454 ret = ble_stack_adv_start(¶m);
1455 TEST_ASSERT_EQUAL(-2, ret, 1, "test_ble_stack_adv_start fail");
1456
1457 if (ret == 0) {
1458 ble_stack_adv_stop();
1459 }
1460
1461 //广播最小间隔时间<允许的最小值20ms
1462 param.sd_num = BLE_ARRAY_NUM(sd);
1463 param.interval_min = 0x001f; //允许的最小值0x0020(20ms)
1464 ret = ble_stack_adv_start(¶m);
1465 TEST_ASSERT_EQUAL(-3, ret, 1, "test_ble_stack_adv_start fail");
1466
1467 if (ret == 0) {
1468 ble_stack_adv_stop();
1469 }
1470
1471 ////广播最小间隔时间=允许的最小值20ms
1472 //param.interval_min = 0x0020; //允许的最小值0x0020(20ms)
1473 //ret = ble_stack_adv_start(¶m);
1474 //TEST_ASSERT_EQUAL(0,ret,1,"test_ble_stack_adv_start fail");
1475 //if (ret == 0){
1476 // ble_stack_adv_stop();
1477 //}
1478
1479 //广播最大间隔时间>允许的最大值10.24s(0x4000)
1480 param.interval_max = 0x4001;
1481 ret = ble_stack_adv_start(¶m);
1482 TEST_ASSERT_EQUAL(-3, ret, 1, "test_ble_stack_adv_start fail");
1483
1484 if (ret == 0) {
1485 ble_stack_adv_stop();
1486 }
1487
1488 ////广播最大间隔时间=允许的最大值10.24s(0x07C0)
1489 //param.interval_max = 0x4000;
1490 //ret = ble_stack_adv_start(¶m);
1491 //TEST_ASSERT_EQUAL(0,ret,1,"test_ble_stack_adv_start fail");
1492 //if (ret == 0){
1493 // ble_stack_adv_stop();
1494 //}
1495
1496 //广播最小间隔时间>最大间隔时间
1497 param.interval_min = 0x00f0;
1498 param.interval_max = 0x00a0;
1499 ret = ble_stack_adv_start(¶m);
1500 TEST_ASSERT_EQUAL(-3, ret, 1, "test_ble_stack_adv_start fail");
1501
1502 if (ret == 0) {
1503 ble_stack_adv_stop();
1504 }
1505
1506 //data的len的长度超出最大长度27+1+4
1507 param.interval_min = ADV_FAST_INT_MIN_1;
1508 param.interval_max = ADV_FAST_INT_MAX_1;
1509 uint8_t ad_data[] = {0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x01, 0x02, 0x3, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x01, 0x02, 0x3, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12};
1510 ad[1].data = (uint8_t *)ad_data;
1511 ad[1].len = sizeof(ad_data);
1512 ad[1].type = AD_DATA_TYPE_UUID16_ALL;
1513 param.ad_num = BLE_ARRAY_NUM(ad);
1514 param.ad = ad;
1515 ret = ble_stack_adv_start(¶m);
1516 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_adv_start fail");
1517
1518 if (ret == 0) {
1519 ble_stack_adv_stop();
1520 }
1521
1522 //*data为NULL
1523 ad_data_t add[1] = {0};
1524 ad_data_t sdd[1] = {0};
1525
1526 add[0].type = AD_DATA_TYPE_UUID16_ALL;
1527 add[0].data = NULL;
1528 add[0].len = 1;
1529
1530 sdd[0].type = AD_DATA_TYPE_MANUFACTURER_DATA;
1531 sdd[0].data = NULL;
1532 sdd[0].len = 0;
1533
1534 adv_param_t param2 = {
1535 ADV_IND,
1536 add,
1537 sdd,
1538 BLE_ARRAY_NUM(add),
1539 BLE_ARRAY_NUM(sdd),
1540 ADV_FAST_INT_MIN_1,
1541 ADV_FAST_INT_MAX_1,
1542 };
1543
1544 ret = ble_stack_adv_start(¶m2);
1545 TEST_ASSERT_NOT_EQUAL(0, ret, 1, "test_ble_stack_adv_start fail");
1546
1547 if (fail_count == 0) {
1548 printf("BLE_ADV TEST PASS\n");
1549 } else {
1550 fail_count = 0;
1551 printf("BLE_ADV TEST FAILED\n");
1552 }
1553
1554 if (ret == 0) {
1555 ble_stack_adv_stop();
1556 printf("adv start!");
1557 } else {
1558 printf("adv start fail %d!", ret);
1559 }
1560
1561 return 0;
1562 }
1563
1564 if (!strcmp(argv[1], "adv_nonconn_ind")) {
1565 param3.type = ADV_NONCONN_IND;
1566 } else if (!strcmp(argv[1], "adv_ind")) {
1567 param3.type = ADV_IND;
1568 } else if (!strcmp(argv[1], "scan_ind")) {
1569 param3.type = ADV_SCAN_IND;
1570 }
1571
1572
1573 if (argc > 2) {
1574 if (strlen(argv[2]) > 62) {
1575 printf("max len\n");
1576 goto fail;
1577 }
1578
1579 str2hex(ad_hex, argv[2], sizeof(ad_hex));
1580 ad_num = parse_ad(ad_hex, strlen(argv[2]) / 2, NULL, NULL);
1581
1582 if (ad_num < 0) {
1583 printf("ad formate error\n");
1584 goto fail;
1585 }
1586
1587 ad = malloc(sizeof(*ad) * ad_num);
1588
1589 if (ad == NULL) {
1590 printf("ad malloc fail\n");
1591 goto fail;
1592 }
1593
1594 ad_data_t *pad = ad;
1595 parse_ad(ad_hex, strlen(argv[2]) / 2, adv_ad_callback, (void *)&pad);
1596 }
1597
1598 if (argc > 3) {
1599 if (strlen(argv[3]) > 62) {
1600 printf("max len\n");
1601 goto fail;
1602 }
1603
1604 str2hex(sd_hex, argv[3], sizeof(sd_hex));
1605 sd_num = parse_ad(sd_hex, strlen(argv[3]) / 2, NULL, NULL);
1606
1607 if (sd_num < 0) {
1608 printf("sd formate error\n");
1609 goto fail;
1610 }
1611
1612 sd = malloc(sizeof(*sd) * sd_num);
1613
1614 if (sd == NULL) {
1615 printf("sd malloc fail\n");
1616 goto fail;
1617 }
1618
1619 ad_data_t *psd = sd;
1620 parse_ad(sd_hex, strlen(argv[3]) / 2, adv_ad_callback, (void *)&psd);
1621 param3.type = ADV_SCAN_IND;
1622 }
1623
1624 if (param3.type == ADV_NONCONN_IND) {
1625 param3.ad = ad;
1626 param3.sd = sd;
1627 param3.ad_num = ad_num;
1628 param3.sd_num = sd_num;
1629 param3.interval_min = ADV_FAST_INT_MIN_2;
1630 param3.interval_max = ADV_FAST_INT_MAX_2;
1631
1632 err = ble_stack_adv_start(¶m3);
1633
1634 if (err < 0) {
1635 printf("Failed to start advertising nonconn_ind(err %d)\n", err);
1636 } else {
1637 printf("adv_type:%x;adv_interval_min:%d (*0.625)ms;adv_interval_max:%d (*0.625)ms\n", param3.type, (int)param3.interval_min, (int)param3.interval_max);
1638 printf("Advertising started\n");
1639 }
1640
1641 return 0;
1642 }
1643
1644 if (param3.type == ADV_IND) {
1645 param3.ad = ad;
1646 param3.sd = NULL;
1647 param3.ad_num = ad_num;
1648 param3.sd_num = 0;
1649 param3.interval_min = ADV_FAST_INT_MIN_1;
1650 param3.interval_max = ADV_FAST_INT_MAX_1;
1651
1652 err = ble_stack_adv_start(¶m3);
1653
1654 if (err < 0) {
1655 printf("Failed to start advertising adv_ind(err %d)\n", err);
1656 } else {
1657 printf("adv_type:%x;adv_interval_min:%d (*0.625)ms;adv_interval_max:%d (*0.625)ms\n", param3.type, (int)param3.interval_min, (int)param3.interval_max);
1658 printf("Advertising started\n");
1659 }
1660
1661 return 0;
1662 }
1663
1664 if (param3.type == ADV_SCAN_IND) {
1665 param3.ad = ad;
1666 param3.sd = sd;
1667 param3.ad_num = ad_num;
1668 param3.sd_num = sd_num;
1669 param3.interval_min = ADV_SCAN_INT_MIN_1;
1670 param3.interval_max = ADV_SCAN_INT_MAX_1;
1671
1672 err = ble_stack_adv_start(¶m3);
1673
1674 if (err < 0) {
1675 printf("Failed to start advertising scan_ind (err %d)\n", err);
1676 } else {
1677 printf("adv_type:%x;adv_interval_min:%d (*0.625)ms;adv_interval_max:%d (*0.625)ms\n", param3.type, (int)param3.interval_min, (int)param3.interval_max);
1678 printf("Advertising started\n");
1679 }
1680
1681 return 0;
1682 }
1683
1684 return 0;
1685
1686 fail:
1687 return -EINVAL;
1688 }
1689
1690 #if defined(CONFIG_BT_CONN)
cmd_connect_le(int argc,char * argv[])1691 static int cmd_connect_le(int argc, char *argv[])
1692 {
1693 int ret;
1694 dev_addr_t addr;
1695 int16_t conn_handle;
1696 conn_param_t param = {
1697 CONN_INT_MIN_INTERVAL,
1698 CONN_INT_MAX_INTERVAL,
1699 0,
1700 400,
1701 };
1702
1703 conn_param_t demo = {
1704 CONN_INT_MIN_INTERVAL,
1705 CONN_INT_MAX_INTERVAL,
1706 0,
1707 400,
1708 };
1709
1710 if (argc < 3) {
1711 return -EINVAL;
1712 }
1713
1714 if (argc >= 3) {
1715 ret = str2bt_addr_le(argv[1], argv[2], &addr);
1716
1717 if (ret) {
1718 printf("Invalid peer address (err %d)\n", ret);
1719 return 0;
1720 }
1721 }
1722
1723 if (!strcmp(argv[3], "test")) {
1724 fail_count = 0;
1725 //test ble_stack_connet
1726 ret = ble_stack_connect(NULL, ¶m, 0); //peer_addr=NULL
1727 TEST_ASSERT_EQUAL(-1, ret, 1, "test_ble_stack_connect fail");
1728
1729 if (ret == 0) {
1730 ble_stack_disconnect(ret);
1731 }
1732
1733 ret = ble_stack_connect(&addr, NULL, 0); //param=NULL
1734 TEST_ASSERT_EQUAL(-5, ret, 1, "test_ble_stack_connect fail");
1735
1736 if (ret == 0) {
1737 ble_stack_disconnect(ret);
1738 }
1739
1740 param.interval_min = 0x0006; //设为最小值min
1741 param.interval_max = 0x0006;
1742
1743 ret = ble_stack_connect(&addr, ¶m, 0);
1744 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_connect fail");
1745
1746 if (ret == 0) {
1747 ble_stack_disconnect(ret);
1748 }
1749
1750 param.interval_min = 0x0C80; //设为最大值
1751 param.interval_max = 0x0C80;
1752 param.timeout = 801;
1753 ret = ble_stack_connect(&addr, ¶m, 0);
1754 TEST_ASSERT_EQUAL(0, ret, 1, "test_ble_stack_connect fail");
1755
1756 if (ret == 0) {
1757 ble_stack_disconnect(ret);
1758 }
1759
1760 param.interval_min = 0x0C80; //min > max
1761 param.interval_max = 0x0C00;
1762 param.timeout = 801;
1763 ret = ble_stack_connect(&addr, ¶m, 0);
1764
1765 if (ret == 0) {
1766 ble_stack_disconnect(ret);
1767 }
1768
1769 TEST_ASSERT_EQUAL(-5, ret, 1, "test_ble_stack_connect fail");
1770
1771 //latency超出范围
1772 param.interval_min = 0x0018;
1773 param.interval_max = 0x0028;
1774 param.latency = 500;
1775 ret = ble_stack_connect(&addr, ¶m, 0);
1776 TEST_ASSERT_EQUAL(-5, ret, 1, "test_ble_stack_connect fail");
1777
1778 if (ret == 0) {
1779 ble_stack_disconnect(ret);
1780 }
1781
1782 //超时时间小于心跳,实际应大于心跳
1783 param.interval_min = 0x0018;
1784 param.interval_max = 0x0028;
1785 param.latency = 0;
1786 param.timeout = 3;
1787 ret = ble_stack_connect(&addr, ¶m, 0);
1788 TEST_ASSERT_EQUAL(-5, ret, 1, "test_ble_stack_connect fail");
1789
1790 if (ret == 0) {
1791 ble_stack_disconnect(ret);
1792 }
1793
1794 //timeout超出范围
1795 param.timeout = 3201;
1796 ret = ble_stack_connect(&addr, ¶m, 0);
1797 TEST_ASSERT_EQUAL(-5, ret, 1, "test_ble_stack_connect fail");
1798
1799 if (ret == 0) {
1800 ble_stack_disconnect(ret);
1801 }
1802
1803 //auto超出范围
1804 int ret2;
1805 param.interval_min = 0x0018;
1806 param.interval_max = 0x0028;
1807 param.latency = 0;
1808 param.timeout = 400;
1809 ret2 = ble_stack_connect(&addr, ¶m, 2);
1810 TEST_ASSERT_EQUAL(-2, ret2, 1, "test_ble_stack_connect fail");
1811
1812 if (ret2 != 0) {
1813 ret = ble_stack_disconnect(ret2);
1814 TEST_ASSERT_EQUAL(-2, ret2, 1, "test_ble_stack_disconnect fail");
1815 } else {
1816 ret = ble_stack_disconnect(ret2);
1817 TEST_ASSERT_EQUAL(0, ret2, 1, "test_ble_stack_disconnect fail");
1818 }
1819
1820 //auto == 1
1821 ret2 = ble_stack_connect(&addr, ¶m, 1);
1822 TEST_ASSERT_EQUAL(0, ret2, 1, "test_ble_stack_connect fail");
1823
1824 if (ret2 == 0) {
1825 ble_stack_disconnect(ret2);
1826 }
1827
1828 if (fail_count == 0) {
1829 printf("BLE_CONN TEST PASS\n");
1830 } else {
1831 fail_count = 0;
1832 printf("BLE_CONN TEST FAILED\n");
1833 }
1834
1835 return 0;
1836 }
1837
1838 if (argc >= 5) {
1839 param.interval_min = strtol(argv[3], NULL, 16);
1840 param.interval_max = strtol(argv[4], NULL, 16);
1841 }
1842
1843 if (argc >= 7) {
1844 param.latency = strtol(argv[5], NULL, 16);
1845 param.timeout = strtol(argv[6], NULL, 16);
1846 }
1847
1848 conn_handle = ble_stack_connect(&addr, &demo, 0);
1849
1850 if (conn_handle < 0) {
1851 printf("Connection failed\n");
1852 return -EIO;
1853 }
1854
1855 return 0;
1856 }
1857
cmd_disconnect(int argc,char * argv[])1858 static int cmd_disconnect(int argc, char *argv[])
1859 {
1860 int16_t conn_handle = 0;
1861 int err;
1862
1863 if (g_bt_conn_handle != -1 && argc < 2) {
1864 conn_handle = g_bt_conn_handle;
1865 } else {
1866 if (argc < 2) {
1867 return -EINVAL;
1868 }
1869
1870 conn_handle = strtol(argv[1], NULL, 10);
1871 }
1872
1873 err = ble_stack_disconnect(conn_handle);
1874
1875 if (err) {
1876 printf("Disconnection failed (err %d)\n", err);
1877 }
1878
1879 return 0;
1880 }
1881
cmd_auto_conn(int argc,char * argv[])1882 static int cmd_auto_conn(int argc, char *argv[])
1883 {
1884 dev_addr_t addr;
1885 conn_param_t param = {
1886 CONN_INT_MIN_INTERVAL,
1887 CONN_INT_MAX_INTERVAL,
1888 0,
1889 400,
1890 };
1891 int err;
1892 conn_param_t *pparam = NULL;
1893 uint8_t auto_conn = 1;
1894
1895 if (argc < 3) {
1896 return -EINVAL;
1897 }
1898
1899 err = str2bt_addr_le(argv[1], argv[2], &addr);
1900
1901 if (err) {
1902 printf("Invalid peer address (err %d)\n", err);
1903 return -EINVAL;
1904 }
1905
1906 if (argc > 3) {
1907 if (!strcmp(argv[3], "on")) {
1908 auto_conn = 1;
1909 pparam = ¶m;
1910 } else if (!strcmp(argv[3], "off")) {
1911 auto_conn = 0;
1912 pparam = NULL;
1913 } else {
1914 return -EINVAL;
1915 }
1916 } else {
1917 auto_conn = 1;
1918 pparam = ¶m;
1919 }
1920
1921 err = ble_stack_connect(&addr, pparam, auto_conn);
1922
1923 if (err < 0) {
1924 return err;
1925 }
1926
1927 printf("connect (%d) pending\n", err);
1928 return 0;
1929 }
1930
cmd_select(int argc,char * argv[])1931 static int cmd_select(int argc, char *argv[])
1932 {
1933 struct bt_conn *conn;
1934 bt_addr_le_t addr;
1935 int err;
1936
1937 if (argc < 3) {
1938 return -EINVAL;
1939 }
1940
1941 err = str2bt_addr_le(argv[1], argv[2], (dev_addr_t *)&addr);
1942
1943 if (err) {
1944 printf("Invalid peer address (err %d)\n", err);
1945 return 0;
1946 }
1947
1948 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &addr);
1949
1950 if (!conn) {
1951 printf("No matching connection found\n");
1952 return 0;
1953 }
1954
1955 if (default_conn) {
1956 bt_conn_unref(default_conn);
1957 }
1958
1959 default_conn = conn;
1960
1961 return 0;
1962 }
1963
cmd_conn_update(int argc,char * argv[])1964 static int cmd_conn_update(int argc, char *argv[])
1965 {
1966
1967 if (argc < 5 && argc != 2) {
1968 return -EINVAL;
1969 }
1970
1971 if (argc == 2 && !strcmp(argv[1], "test")) {
1972 int ret;
1973
1974 fail_count = 0;
1975 printf("******* test ble_stack_connect_param_update start ******\n");
1976 conn_param_t param;
1977 param.interval_min = 0x0028;
1978 param.interval_min = 0x0060;
1979 param.latency = 0;
1980 param.timeout = 400;
1981
1982 ret = ble_stack_connect_param_update(-1, ¶m);
1983 TEST_ASSERT_EQUAL(-2, ret, 1, "test_ble_stack_connect_param_update fail");
1984
1985 ret = ble_stack_connect_param_update(g_bt_conn_handle, NULL);
1986 TEST_ASSERT_EQUAL(-2, ret, 1, "test_ble_stack_connect_param_update fail");
1987
1988 param.interval_min = 0x0005;
1989 param.interval_max = 0x0006;
1990 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
1991 TEST_ASSERT_EQUAL(-22, ret, 1, "ble_stack_connect_param_update fail");
1992
1993 param.interval_min = 0x0006; //设为最小值min
1994 param.interval_max = 0x0006;
1995 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
1996 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_connect_param_update fail");
1997 aos_msleep(1000);
1998 param.interval_min = 0x0C80; //设为最大值
1999 param.interval_max = 0x0C80;
2000 param.timeout = 801;
2001 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
2002 TEST_ASSERT_EQUAL(0, ret, 1, "ble_stack_connect_param_update fail");
2003
2004 param.interval_min = 0x0C80; //min > max
2005 param.interval_max = 0x0C00;
2006 param.timeout = 801;
2007 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
2008 TEST_ASSERT_EQUAL(-22, ret, 1, "ble_stack_connect_param_update fail");
2009
2010 //latency超出范围
2011 param.interval_min = 0x0018;
2012 param.interval_max = 0x0028;
2013 param.latency = 500;
2014 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
2015 TEST_ASSERT_EQUAL(-22, ret, 1, "ble_stack_connect_param_update fail");
2016
2017 //超时时间小于心跳,实际应大于心跳
2018 param.interval_min = 0x0018;
2019 param.interval_max = 0x0028;
2020 param.latency = 0;
2021 param.timeout = 3;
2022 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
2023 TEST_ASSERT_EQUAL(-22, ret, 1, "ble_stack_connect_param_update fail");
2024
2025 //timeout超出范围
2026 param.timeout = 3201;
2027 ret = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
2028 TEST_ASSERT_EQUAL(-22, ret, 1, "ble_stack_connect_param_update fail");
2029 printf("******* test ble_stack_connect_param_update end ******\n");
2030
2031 if (fail_count == 0) {
2032 printf("TEST PASS\n");
2033 } else {
2034 printf("TEST FAIL\n");
2035 }
2036
2037 return 0;
2038 }
2039
2040 conn_param_t param;
2041 int err;
2042 param.interval_min = strtoul(argv[1], NULL, 16);
2043 param.interval_max = strtoul(argv[2], NULL, 16);
2044 param.latency = strtoul(argv[3], NULL, 16);
2045 param.timeout = strtoul(argv[4], NULL, 16);
2046
2047 err = ble_stack_connect_param_update(g_bt_conn_handle, ¶m);
2048
2049
2050 if (err) {
2051 printf("conn update failed (err %d).\n", err);
2052 } else {
2053 printf("conn update initiated.\n");
2054 }
2055
2056 return 0;
2057 }
2058
cmd_oob(int argc,char * argv[])2059 static int cmd_oob(int argc, char *argv[])
2060 {
2061 char addr[BT_ADDR_LE_STR_LEN];
2062 struct bt_le_oob oob;
2063 int err;
2064
2065 err = bt_le_oob_get_local(selected_id, &oob);
2066
2067 if (err) {
2068 printf("OOB data failed\n");
2069 return 0;
2070 }
2071
2072 bt_addr_le_to_str(&oob.addr, addr, sizeof(addr));
2073
2074 printf("OOB data:\n");
2075 printf(" addr %s\n", addr);
2076
2077 return 0;
2078 }
2079
cmd_clear(int argc,char * argv[])2080 static int cmd_clear(int argc, char *argv[])
2081 {
2082 bt_addr_le_t addr;
2083 int err;
2084
2085 if (argc < 2) {
2086 printf("Specify remote address or \"all\"\n");
2087 return 0;
2088 }
2089
2090 if (strcmp(argv[1], "all") == 0) {
2091 // err = bt_unpair(selected_id, NULL);
2092 err = ble_stack_dev_unpair(NULL);
2093
2094 if (err) {
2095 printf("Failed to clear pairings (err %d)\n", err);
2096 } else {
2097 printf("Pairings successfully cleared\n");
2098 }
2099
2100 return 0;
2101 }
2102
2103 if (argc < 3) {
2104 #if defined(CONFIG_BT_BREDR)
2105 addr.type = BT_ADDR_LE_PUBLIC;
2106 err = str2bt_addr(argv[1], &addr.a);
2107 #else
2108 printf("Both address and address type needed\n");
2109 return 0;
2110 #endif
2111 } else {
2112 err = str2bt_addr_le(argv[1], argv[2], (dev_addr_t *)&addr);
2113 }
2114
2115 if (err) {
2116 printf("Invalid address\n");
2117 return 0;
2118 }
2119
2120 //err = bt_unpair(selected_id, &addr);
2121 err = ble_stack_dev_unpair(&addr);
2122
2123 if (err) {
2124 printf("Failed to clear pairing (err %d)\n", err);
2125 } else {
2126 printf("Pairing successfully cleared\n");
2127 }
2128
2129 return 0;
2130 }
2131 #endif /* CONFIG_BT_CONN */
2132
2133 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
cmd_security(int argc,char * argv[])2134 static int cmd_security(int argc, char *argv[])
2135 {
2136 int err, sec;
2137 /*************API TEST************/
2138 int ret = 99;
2139
2140 if (!strcmp(argv[1], "test")) {
2141 printf("API exception parameter test start!\n");
2142 ret = ble_stack_security(-1, 0);
2143 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_security");
2144 printf("API exception parameter test end!\n");
2145 return 0;
2146 }
2147
2148 /*************shell****************/
2149
2150 if (g_bt_conn_handle == -1) {
2151 printf("Not connected\n");
2152 return 0;
2153 }
2154
2155 if (argc < 2) {
2156 return -EINVAL;
2157 }
2158
2159 sec = *argv[1] - '0';
2160
2161 err = ble_stack_security(g_bt_conn_handle, sec);
2162
2163 if (err) {
2164 printf("Setting security failed (err %d)\n", err);
2165 }
2166
2167 return 0;
2168 }
2169
smp_passkey_display(evt_data_smp_passkey_display_t * e)2170 static void smp_passkey_display(evt_data_smp_passkey_display_t *e)
2171 {
2172 char addr[32];
2173
2174 bt_addr2str(&e->peer_addr, addr, 32);
2175
2176 printf("Passkey for %s: %s\n", addr, e->passkey);
2177 }
2178
smp_passkey_confirm(evt_data_smp_passkey_confirm_t * e)2179 static void smp_passkey_confirm(evt_data_smp_passkey_confirm_t *e)
2180 {
2181 char addr[32];
2182
2183 bt_addr2str(&e->peer_addr, addr, 32);
2184
2185 printf("Pairing passkey for %s: %s\n", addr, e->passkey);
2186 }
2187
smp_passkey_entry(evt_data_smp_passkey_enter_t * e)2188 static void smp_passkey_entry(evt_data_smp_passkey_enter_t *e)
2189 {
2190 char addr[32];
2191
2192 bt_addr2str(&e->peer_addr, addr, 32);
2193
2194 printf("Enter passkey for %s\n", addr);
2195 }
2196
smp_cancel(evt_data_smp_cancel_t * e)2197 static void smp_cancel(evt_data_smp_cancel_t *e)
2198 {
2199 char addr[32];
2200
2201 bt_addr2str(&e->peer_addr, addr, 32);
2202
2203 printf("Pairing cancelled: %s\n", addr);
2204
2205 /* clear connection reference for sec mode 3 pairing */
2206 if (g_pairing_handle) {
2207 g_pairing_handle = -1;
2208 }
2209 }
2210
smp_pairing_confirm(evt_data_smp_pairing_confirm_t * e)2211 static void smp_pairing_confirm(evt_data_smp_pairing_confirm_t *e)
2212 {
2213 char addr[32];
2214
2215 bt_addr2str(&e->peer_addr, addr, 32);
2216
2217 printf("Confirm pairing for %s\n", addr);
2218 }
2219
smp_pairing_complete(evt_data_smp_pairing_complete_t * e)2220 static void smp_pairing_complete(evt_data_smp_pairing_complete_t *e)
2221 {
2222 char addr[32];
2223
2224 bt_addr2str(&e->peer_addr, addr, 32);
2225
2226 if (e->err) {
2227 printf("Pairing failed with %s, err %d\n", addr, e->err);
2228 } else {
2229 printf("%s with %s\n", e->bonded ? "Bonded" : "Paired", addr);
2230 }
2231 }
2232
smp_event(ble_event_en event,void * event_data)2233 static void smp_event(ble_event_en event, void *event_data)
2234 {
2235 switch (event) {
2236 case EVENT_SMP_PASSKEY_DISPLAY:
2237 smp_passkey_display(event_data);
2238 break;
2239
2240 case EVENT_SMP_PASSKEY_CONFIRM:
2241 smp_passkey_confirm(event_data);
2242 break;
2243
2244 case EVENT_SMP_PASSKEY_ENTER:
2245 smp_passkey_entry(event_data);
2246 break;
2247
2248 case EVENT_SMP_PAIRING_CONFIRM:
2249 smp_pairing_confirm(event_data);
2250 break;
2251
2252 case EVENT_SMP_PAIRING_COMPLETE:
2253 smp_pairing_complete(event_data);
2254 break;
2255
2256 case EVENT_SMP_CANCEL:
2257 smp_cancel(event_data);
2258 break;
2259
2260 default:
2261 break;
2262 }
2263 }
2264
cmd_iocap_set(int argc,char * argv[])2265 static int cmd_iocap_set(int argc, char *argv[])
2266 {
2267 uint8_t io_cap = 0;
2268
2269 /************API TEST****************/
2270 int ret = 99;
2271 int err = 99;
2272
2273 if (!strcmp(argv[1], "test")) {
2274 printf("API exception parameter test start!\n");
2275 ret = ble_stack_iocapability_set(0);
2276 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_iocapability_set1");
2277 ret = ble_stack_iocapability_set(8);
2278 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_iocapability_set2");
2279 ret = ble_stack_iocapability_set(13);
2280 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_iocapability_set3");
2281 ret = ble_stack_iocapability_set(15);
2282 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_iocapability_set4");
2283 printf("API exception parameter test end\n");
2284 return 0;
2285 }
2286
2287 /************API shell****************/
2288 if (argc < 3) {
2289 return -EINVAL;
2290 }
2291
2292 if (!strcmp(argv[1], "NONE")) {
2293 io_cap |= IO_CAP_IN_NONE;
2294 } else if (!strcmp(argv[1], "YESNO")) {
2295 io_cap |= IO_CAP_IN_YESNO;
2296 } else if (!strcmp(argv[1], "KEYBOARD")) {
2297 io_cap |= IO_CAP_IN_KEYBOARD;
2298 } else {
2299 return -EINVAL;
2300 }
2301
2302 if (!strcmp(argv[2], "NONE")) {
2303 io_cap |= IO_CAP_OUT_NONE;
2304 } else if (!strcmp(argv[2], "DISPLAY")) {
2305 io_cap |= IO_CAP_OUT_DISPLAY;
2306 } else {
2307 return -EINVAL;
2308 }
2309
2310 /****zhangyj add***********/
2311 err = ble_stack_iocapability_set(io_cap);
2312
2313 if (err) {
2314 printf("Set iocapability failed!(err %d)\n", err);
2315 } else {
2316 printf("Set iocapability success!\n");
2317 }
2318
2319 return 0;
2320 }
2321
cmd_auth_cancel(int argc,char * argv[])2322 static int cmd_auth_cancel(int argc, char *argv[])
2323 {
2324 int16_t conn_handle;
2325
2326 /************API TEST****************/
2327 if (!strcmp(argv[1], "test")) {
2328 int ret = 99;
2329 printf("API exception parameter test start!\n");
2330 ret = ble_stack_smp_cancel(-1);
2331 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_smp_cancel");
2332 printf("API exception parameter test end\n");
2333 return 0;
2334 }
2335
2336 /************shell*****************/
2337
2338 if (g_bt_conn_handle != -1) {
2339 conn_handle = g_bt_conn_handle;
2340 } else if (g_pairing_handle != -1) {
2341 conn_handle = g_pairing_handle;
2342 } else {
2343 conn_handle = 0;
2344 }
2345
2346 ble_stack_smp_cancel(conn_handle);
2347 return 0;
2348 }
2349
cmd_auth_passkey_confirm(int argc,char * argv[])2350 static int cmd_auth_passkey_confirm(int argc, char *argv[])
2351 {
2352 /*************API TEST************/
2353 if (!strcmp(argv[1], "test")) {
2354 printf("API exception parameter test start!\n");
2355 int ret = 99;
2356 ret = ble_stack_smp_passkey_confirm(-1);
2357 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_smp_passkey_confirm");
2358 printf("API exception parameter test end!\n");
2359 return 0;
2360 }
2361
2362 /*************shell**************/
2363
2364 if (g_bt_conn_handle == -1) {
2365 printf("Not connected\n");
2366 return 0;
2367 }
2368
2369 ble_stack_smp_passkey_confirm(g_bt_conn_handle);
2370 return 0;
2371 }
2372
cmd_auth_pairing_confirm(int argc,char * argv[])2373 static int cmd_auth_pairing_confirm(int argc, char *argv[])
2374 {
2375 /*************API TEST************/
2376 if (!strcmp(argv[1], "test")) {
2377 printf("API exception parameter test start!\n");
2378 int ret = 99;
2379 ret = ble_stack_smp_pairing_confirm(-1);
2380 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_smp_pairing_confirm");
2381 printf("API exception parameter test end\n");
2382 return 0;
2383 }
2384
2385 /*************shell**************/
2386 if (g_bt_conn_handle == -1) {
2387 printf("Not connected\n");
2388 return 0;
2389 }
2390
2391 ble_stack_smp_pairing_confirm(g_bt_conn_handle);
2392
2393 return 0;
2394 }
2395
2396 #if defined(CONFIG_BT_FIXED_PASSKEY)
cmd_fixed_passkey(int argc,char * argv[])2397 static int cmd_fixed_passkey(int argc, char *argv[])
2398 {
2399 unsigned int passkey;
2400 int err;
2401
2402 if (argc < 2) {
2403 bt_passkey_set(BT_PASSKEY_INVALID);
2404 printf("Fixed passkey cleared\n");
2405 return 0;
2406 }
2407
2408 passkey = atoi(argv[1]);
2409
2410 if (passkey > 999999) {
2411 printf("Passkey should be between 0-999999\n");
2412 return 0;
2413 }
2414
2415 err = bt_passkey_set(passkey);
2416
2417 if (err) {
2418 printf("Setting fixed passkey failed (err %d)\n", err);
2419 }
2420
2421 return 0;
2422 }
2423 #endif
2424
cmd_auth_passkey(int argc,char * argv[])2425 static int cmd_auth_passkey(int argc, char *argv[])
2426 {
2427 unsigned int passkey;
2428
2429 /*************API TEST************/
2430 if (!strcmp(argv[1], "test")) {
2431 printf("API exception parameter test start!\n");
2432 int ret = 99;
2433 ret = ble_stack_smp_passkey_entry(-1, passkey);
2434 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_smp_passkey_entry1");
2435
2436 ret = ble_stack_smp_passkey_entry(0, 100001);
2437 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_smp_passkey_entry2");
2438 printf("API exception parameter test end\n");
2439 return 0;
2440 }
2441
2442 /*************shell**************/
2443
2444 if (g_bt_conn_handle == -1) {
2445 printf("Not connected\n");
2446 return 0;
2447 }
2448
2449 if (argc < 2) {
2450 return -EINVAL;
2451 }
2452
2453 passkey = atoi(argv[1]);
2454
2455 if (passkey > 999999) {
2456 printf("Passkey should be between 0-999999\n");
2457 return 0;
2458 }
2459
2460 ble_stack_smp_passkey_entry(g_bt_conn_handle, passkey);
2461 return 0;
2462 }
2463
cmd_auth_get_keysize(int argc,char * argv[])2464 static int cmd_auth_get_keysize(int argc, char *argv[])
2465 {
2466 int size = 99;
2467
2468 /*************API TEST************/
2469 if (!strcmp(argv[1], "test")) {
2470 printf("API exception parameter test start!\n");
2471 int ret = 99;
2472 ret = ble_stack_enc_key_size_get(-1);
2473 TEST_ASSERT_EQUAL(-2, ret, 0, "ble_stack_enc_key_size_get");
2474 printf("API exception parameter test end\n");
2475 return 0;
2476 }
2477
2478 /*************shell**************/
2479 if (g_bt_conn_handle == -1) {
2480 printf("Not connected\n");
2481 return 0;
2482 }
2483
2484 size = ble_stack_enc_key_size_get(g_bt_conn_handle);
2485
2486 if (size >= 7 && size <= 16) {
2487 printf("Get key size corret!(%d)\n", size);
2488 } else {
2489 printf("Get key size wrong!(%d)\n", size);
2490 }
2491
2492 return 0;
2493
2494 }
2495 #endif /* CONFIG_BT_SMP) || CONFIG_BT_BREDR */
2496
2497 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
2498 static bt_u32_t l2cap_rate;
2499
l2cap_recv_metrics(struct bt_l2cap_chan * chan,struct net_buf * buf)2500 static void l2cap_recv_metrics(struct bt_l2cap_chan *chan, struct net_buf *buf)
2501 {
2502 return;
2503 }
2504
l2cap_recv(struct bt_l2cap_chan * chan,struct net_buf * buf)2505 static void l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
2506 {
2507 printf("Incoming data channel %p psm %d len %u\n", chan, chan->psm, buf->len);
2508
2509 if (buf->len) {
2510 hexdump(buf->data, buf->len);
2511 }
2512 }
2513
l2cap_connected(struct bt_l2cap_chan * chan)2514 static void l2cap_connected(struct bt_l2cap_chan *chan)
2515 {
2516 printf("Channel %p psm %d connected\n", chan, chan->psm);
2517 }
2518
l2cap_disconnected(struct bt_l2cap_chan * chan)2519 static void l2cap_disconnected(struct bt_l2cap_chan *chan)
2520 {
2521 printf("Channel %p psm %d disconnected\n", chan, chan->psm);
2522 }
2523
l2cap_alloc_buf(struct bt_l2cap_chan * chan)2524 static struct net_buf *l2cap_alloc_buf(struct bt_l2cap_chan *chan)
2525 {
2526 /* print if metrics is disabled */
2527 if (chan->ops->recv != l2cap_recv_metrics) {
2528 printf("Channel %p requires buffer\n", chan);
2529 }
2530
2531 return net_buf_alloc(&data_rx_pool, K_FOREVER);
2532 }
2533
2534 static struct bt_l2cap_chan_ops l2cap_ops = {
2535 .alloc_buf = l2cap_alloc_buf,
2536 .recv = l2cap_recv,
2537 .connected = l2cap_connected,
2538 .disconnected = l2cap_disconnected,
2539 };
2540
2541 static struct bt_l2cap_le_chan l2cap_chan[L2CAP_DYM_CHANNEL_NUM] = {
2542 0
2543 };
2544
l2cap_accept(struct bt_conn * conn,struct bt_l2cap_chan ** chan)2545 static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
2546 {
2547 printf("Incoming conn %p\n", conn);
2548
2549 int i;
2550
2551 for (i = 0; i < L2CAP_DYM_CHANNEL_NUM; i++) {
2552 if (l2cap_chan[i].chan.conn == NULL) {
2553 break;
2554 }
2555 }
2556
2557 if (i == L2CAP_DYM_CHANNEL_NUM) {
2558 printf("No channels available\n");
2559 return -ENOMEM;
2560 }
2561
2562 l2cap_chan[i].chan.ops = &l2cap_ops;
2563 l2cap_chan[i].rx.mtu = DATA_MTU;
2564
2565 *chan = &l2cap_chan[i].chan;
2566
2567 return 0;
2568 }
2569
2570 static struct bt_l2cap_server server[L2CAP_DYM_CHANNEL_NUM] = {
2571 0
2572 };
2573
2574
cmd_l2cap_register(int argc,char * argv[])2575 static int cmd_l2cap_register(int argc, char *argv[])
2576 {
2577 int i;
2578
2579 if (argc < 2) {
2580 return -EINVAL;
2581 }
2582
2583 for (i = 0; i < L2CAP_DYM_CHANNEL_NUM; i++) {
2584 if (server[i].psm == 0) {
2585 break;
2586 }
2587 }
2588
2589 if (i == L2CAP_DYM_CHANNEL_NUM) {
2590 printf("No more channel\n");
2591 return 0;
2592 }
2593
2594 server[i].accept = l2cap_accept;
2595 server[i].psm = strtoul(argv[1], NULL, 16);
2596
2597 if (argc > 2) {
2598 server[i].sec_level = strtoul(argv[2], NULL, 10);
2599 }
2600
2601 if (bt_l2cap_server_register(&server[i]) < 0) {
2602 printf("Unable to register psm\n");
2603 server[i].psm = 0;
2604 } else {
2605 printf("L2CAP psm %u sec_level %u registered\n", server[i].psm,
2606 server[i].sec_level);
2607 }
2608
2609 return 0;
2610 }
2611
cmd_l2cap_connect(int argc,char * argv[])2612 static int cmd_l2cap_connect(int argc, char *argv[])
2613 {
2614 u16_t psm;
2615 int err;
2616 int i;
2617
2618 if (g_bt_conn_handle == -1) {
2619 printf("Not connected\n");
2620 return 0;
2621 }
2622
2623 if (argc < 2) {
2624 return -EINVAL;
2625 }
2626
2627 for (i = 0; i < L2CAP_DYM_CHANNEL_NUM; i++) {
2628 if (l2cap_chan[i].chan.conn == NULL) {
2629 break;
2630 }
2631 }
2632
2633 if (i == L2CAP_DYM_CHANNEL_NUM) {
2634 printf("No more Channel\n");
2635 return -EINVAL;
2636 }
2637
2638 l2cap_chan[i].chan.ops = &l2cap_ops;
2639 l2cap_chan[i].rx.mtu = DATA_MTU;
2640
2641 psm = strtoul(argv[1], NULL, 16);
2642
2643 err = bt_l2cap_chan_connect(bt_conn_lookup_id(g_bt_conn_handle), &l2cap_chan[i].chan, psm);
2644
2645 if (err < 0) {
2646 printf("Unable to connect to psm %u (err %u)\n", psm, err);
2647 } else {
2648 printf("L2CAP connection pending\n");
2649 }
2650
2651 return 0;
2652 }
2653
cmd_l2cap_disconnect(int argc,char * argv[])2654 static int cmd_l2cap_disconnect(int argc, char *argv[])
2655 {
2656 int err;
2657 u16_t psm;
2658 int i;
2659
2660 psm = strtoul(argv[1], NULL, 16);
2661
2662 for (i = 0; i < L2CAP_DYM_CHANNEL_NUM; i++) {
2663 if (l2cap_chan[i].chan.psm == psm) {
2664 err = bt_l2cap_chan_disconnect(&l2cap_chan[i].chan);
2665
2666 if (err) {
2667 printf("Unable to disconnect: err %u\n", -err);
2668 }
2669
2670 return err;
2671 }
2672 }
2673
2674 return 0;
2675 }
2676
cmd_l2cap_send(int argc,char * argv[])2677 static int cmd_l2cap_send(int argc, char *argv[])
2678 {
2679 static u8_t buf_data[DATA_MTU] = { [0 ...(DATA_MTU - 1)] = 0xff };
2680 int ret, len, count = 1;
2681 struct net_buf *buf;
2682 u16_t psm = 0;
2683 int i;
2684
2685 if (argc > 1) {
2686 psm = strtoul(argv[1], NULL, 16);
2687 } else {
2688 return -EINVAL;
2689 }
2690
2691 if (argc > 2) {
2692 count = strtoul(argv[2], NULL, 10);
2693 }
2694
2695 for (i = 0; i < L2CAP_DYM_CHANNEL_NUM; i++) {
2696 if (l2cap_chan[i].chan.psm == psm) {
2697 break;
2698 }
2699 }
2700
2701 if (i == L2CAP_DYM_CHANNEL_NUM) {
2702 printf("Can't find channel\n");
2703 return -EINVAL;
2704 }
2705
2706 len = min(l2cap_chan[i].tx.mtu, DATA_MTU - BT_L2CAP_CHAN_SEND_RESERVE);
2707
2708 while (count--) {
2709 buf = net_buf_alloc(&data_tx_pool, K_FOREVER);
2710 net_buf_reserve(buf, BT_L2CAP_CHAN_SEND_RESERVE);
2711
2712 net_buf_add_mem(buf, buf_data, len);
2713 ret = bt_l2cap_chan_send(&l2cap_chan[i].chan, buf);
2714
2715 if (ret < 0) {
2716 printf("Unable to send: %d\n", -ret);
2717 net_buf_unref(buf);
2718 break;
2719 }
2720 }
2721
2722 return 0;
2723 }
2724
cmd_l2cap_metrics(int argc,char * argv[])2725 static int cmd_l2cap_metrics(int argc, char *argv[])
2726 {
2727 const char *action;
2728
2729 if (argc < 2) {
2730 printf("l2cap rate: %u bps.\n", l2cap_rate);
2731
2732 return 0;
2733 }
2734
2735 action = argv[1];
2736
2737 if (!strcmp(action, "on")) {
2738 l2cap_ops.recv = l2cap_recv_metrics;
2739 } else if (!strcmp(action, "off")) {
2740 l2cap_ops.recv = l2cap_recv;
2741 } else {
2742 return -EINVAL;
2743 }
2744
2745 printf("l2cap metrics %s.\n", action);
2746
2747 return 0;
2748 }
2749
2750 #endif
2751
2752 #if defined(CONFIG_BT_BREDR)
l2cap_bredr_recv(struct bt_l2cap_chan * chan,struct net_buf * buf)2753 static void l2cap_bredr_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
2754 {
2755 printf("Incoming data channel %p len %u\n", chan, buf->len);
2756 }
2757
l2cap_bredr_connected(struct bt_l2cap_chan * chan)2758 static void l2cap_bredr_connected(struct bt_l2cap_chan *chan)
2759 {
2760 printf("Channel %p connected\n", chan);
2761 }
2762
l2cap_bredr_disconnected(struct bt_l2cap_chan * chan)2763 static void l2cap_bredr_disconnected(struct bt_l2cap_chan *chan)
2764 {
2765 printf("Channel %p disconnected\n", chan);
2766 }
2767
l2cap_bredr_alloc_buf(struct bt_l2cap_chan * chan)2768 static struct net_buf *l2cap_bredr_alloc_buf(struct bt_l2cap_chan *chan)
2769 {
2770 printf("Channel %p requires buffer\n", chan);
2771
2772 return net_buf_alloc(&data_bredr_pool, K_FOREVER);
2773 }
2774
2775 static struct bt_l2cap_chan_ops l2cap_bredr_ops = {
2776 .alloc_buf = l2cap_bredr_alloc_buf,
2777 .recv = l2cap_bredr_recv,
2778 .connected = l2cap_bredr_connected,
2779 .disconnected = l2cap_bredr_disconnected,
2780 };
2781
2782 static struct bt_l2cap_br_chan l2cap_bredr_chan = {
2783 .chan.ops = &l2cap_bredr_ops,
2784 /* Set for now min. MTU */
2785 .rx.mtu = 48,
2786 };
2787
l2cap_bredr_accept(struct bt_conn * conn,struct bt_l2cap_chan ** chan)2788 static int l2cap_bredr_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
2789 {
2790 printf("Incoming BR/EDR conn %p\n", conn);
2791
2792 if (l2cap_bredr_chan.chan.conn) {
2793 printf("No channels available");
2794 return -ENOMEM;
2795 }
2796
2797 *chan = &l2cap_bredr_chan.chan;
2798
2799 return 0;
2800 }
2801
2802 static struct bt_l2cap_server br_server = {
2803 .accept = l2cap_bredr_accept,
2804 };
2805
cmd_bredr_l2cap_register(int argc,char * argv[])2806 static int cmd_bredr_l2cap_register(int argc, char *argv[])
2807 {
2808 if (argc < 2) {
2809 return -EINVAL;
2810 }
2811
2812 if (br_server.psm) {
2813 printf("Already registered\n");
2814 return 0;
2815 }
2816
2817 br_server.psm = strtoul(argv[1], NULL, 16);
2818
2819 if (bt_l2cap_br_server_register(&br_server) < 0) {
2820 printf("Unable to register psm\n");
2821 br_server.psm = 0;
2822 } else {
2823 printf("L2CAP psm %u registered\n", br_server.psm);
2824 }
2825
2826 return 0;
2827 }
2828
2829 #if defined(CONFIG_BT_RFCOMM)
rfcomm_bredr_recv(struct bt_rfcomm_dlc * dlci,struct net_buf * buf)2830 static void rfcomm_bredr_recv(struct bt_rfcomm_dlc *dlci, struct net_buf *buf)
2831 {
2832 printf("Incoming data dlc %p len %u\n", dlci, buf->len);
2833 }
2834
rfcomm_bredr_connected(struct bt_rfcomm_dlc * dlci)2835 static void rfcomm_bredr_connected(struct bt_rfcomm_dlc *dlci)
2836 {
2837 printf("Dlc %p connected\n", dlci);
2838 }
2839
rfcomm_bredr_disconnected(struct bt_rfcomm_dlc * dlci)2840 static void rfcomm_bredr_disconnected(struct bt_rfcomm_dlc *dlci)
2841 {
2842 printf("Dlc %p disconnected\n", dlci);
2843 }
2844
2845 static struct bt_rfcomm_dlc_ops rfcomm_bredr_ops = {
2846 .recv = rfcomm_bredr_recv,
2847 .connected = rfcomm_bredr_connected,
2848 .disconnected = rfcomm_bredr_disconnected,
2849 };
2850
2851 static struct bt_rfcomm_dlc rfcomm_dlc = {
2852 .ops = &rfcomm_bredr_ops,
2853 .mtu = 30,
2854 };
2855
rfcomm_bredr_accept(struct bt_conn * conn,struct bt_rfcomm_dlc ** dlc)2856 static int rfcomm_bredr_accept(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc)
2857 {
2858 printf("Incoming RFCOMM conn %p\n", conn);
2859
2860 if (rfcomm_dlc.session) {
2861 printf("No channels available");
2862 return -ENOMEM;
2863 }
2864
2865 *dlc = &rfcomm_dlc;
2866
2867 return 0;
2868 }
2869
2870 struct bt_rfcomm_server rfcomm_server = {
2871 .accept = &rfcomm_bredr_accept,
2872 };
2873
cmd_bredr_rfcomm_register(int argc,char * argv[])2874 static int cmd_bredr_rfcomm_register(int argc, char *argv[])
2875 {
2876 int ret;
2877
2878 if (rfcomm_server.channel) {
2879 printf("Already registered\n");
2880 return 0;
2881 }
2882
2883 rfcomm_server.channel = BT_RFCOMM_CHAN_SPP;
2884
2885 ret = bt_rfcomm_server_register(&rfcomm_server);
2886
2887 if (ret < 0) {
2888 printf("Unable to register channel %x\n", ret);
2889 rfcomm_server.channel = 0;
2890 } else {
2891 printf("RFCOMM channel %u registered\n", rfcomm_server.channel);
2892 bt_sdp_register_service(&spp_rec);
2893 }
2894
2895 return 0;
2896 }
2897
cmd_rfcomm_connect(int argc,char * argv[])2898 static int cmd_rfcomm_connect(int argc, char *argv[])
2899 {
2900 u8_t channel;
2901 int err;
2902
2903 if (!default_conn) {
2904 printf("Not connected\n");
2905 return 0;
2906 }
2907
2908 if (argc < 2) {
2909 return -EINVAL;
2910 }
2911
2912 channel = strtoul(argv[1], NULL, 16);
2913
2914 err = bt_rfcomm_dlc_connect(default_conn, &rfcomm_dlc, channel);
2915
2916 if (err < 0) {
2917 printf("Unable to connect to channel %d (err %u)\n",
2918 channel, err);
2919 } else {
2920 printf("RFCOMM connection pending\n");
2921 }
2922
2923 return 0;
2924 }
2925
cmd_rfcomm_send(int argc,char * argv[])2926 static int cmd_rfcomm_send(int argc, char *argv[])
2927 {
2928 u8_t buf_data[DATA_BREDR_MTU] = { [0 ...(DATA_BREDR_MTU - 1)] =
2929 0xff
2930 };
2931 int ret, len, count = 1;
2932 struct net_buf *buf;
2933
2934 if (argc > 1) {
2935 count = strtoul(argv[1], NULL, 10);
2936 }
2937
2938 while (count--) {
2939 buf = bt_rfcomm_create_pdu(&data_bredr_pool);
2940 /* Should reserve one byte in tail for FCS */
2941 len = min(rfcomm_dlc.mtu, net_buf_tailroom(buf) - 1);
2942
2943 net_buf_add_mem(buf, buf_data, len);
2944 ret = bt_rfcomm_dlc_send(&rfcomm_dlc, buf);
2945
2946 if (ret < 0) {
2947 printf("Unable to send: %d\n", -ret);
2948 net_buf_unref(buf);
2949 break;
2950 }
2951 }
2952
2953 return 0;
2954 }
2955
cmd_rfcomm_disconnect(int argc,char * argv[])2956 static int cmd_rfcomm_disconnect(int argc, char *argv[])
2957 {
2958 int err;
2959
2960 err = bt_rfcomm_dlc_disconnect(&rfcomm_dlc);
2961
2962 if (err) {
2963 printf("Unable to disconnect: %u\n", -err);
2964 }
2965
2966 return 0;
2967 }
2968
2969 #endif /* CONFIG_BT_RFCOMM) */
2970
cmd_bredr_discoverable(int argc,char * argv[])2971 static int cmd_bredr_discoverable(int argc, char *argv[])
2972 {
2973 int err;
2974 const char *action;
2975
2976 if (argc < 2) {
2977 return -EINVAL;
2978 }
2979
2980 action = argv[1];
2981
2982 if (!strcmp(action, "on")) {
2983 err = bt_br_set_discoverable(true);
2984 } else if (!strcmp(action, "off")) {
2985 err = bt_br_set_discoverable(false);
2986 } else {
2987 return -EINVAL;
2988 }
2989
2990 if (err) {
2991 printf("BR/EDR set/reset discoverable failed (err %d)\n", err);
2992 } else {
2993 printf("BR/EDR set/reset discoverable done\n");
2994 }
2995
2996 return 0;
2997 }
2998
cmd_bredr_connectable(int argc,char * argv[])2999 static int cmd_bredr_connectable(int argc, char *argv[])
3000 {
3001 int err;
3002 const char *action;
3003
3004 if (argc < 2) {
3005 return -EINVAL;
3006 }
3007
3008 action = argv[1];
3009
3010 if (!strcmp(action, "on")) {
3011 err = bt_br_set_connectable(true);
3012 } else if (!strcmp(action, "off")) {
3013 err = bt_br_set_connectable(false);
3014 } else {
3015 return -EINVAL;
3016 }
3017
3018 if (err) {
3019 printf("BR/EDR set/rest connectable failed (err %d)\n", err);
3020 } else {
3021 printf("BR/EDR set/reset connectable done\n");
3022 }
3023
3024 return 0;
3025 }
3026
cmd_bredr_oob(int argc,char * argv[])3027 static int cmd_bredr_oob(int argc, char *argv[])
3028 {
3029 char addr[BT_ADDR_STR_LEN];
3030 struct bt_br_oob oob;
3031 int err;
3032
3033 err = bt_br_oob_get_local(&oob);
3034
3035 if (err) {
3036 printf("BR/EDR OOB data failed\n");
3037 return 0;
3038 }
3039
3040 bt_addr_to_str(&oob.addr, addr, sizeof(addr));
3041
3042 printf("BR/EDR OOB data:\n");
3043 printf(" addr %s\n", addr);
3044
3045 return 0;
3046 }
3047
cmd_bredr_sdp_find_record(int argc,char * argv[])3048 static int cmd_bredr_sdp_find_record(int argc, char *argv[])
3049 {
3050 int err = 0, res;
3051 const char *action;
3052
3053 if (!default_conn) {
3054 printf("Not connected\n");
3055 return 0;
3056 }
3057
3058 if (argc < 2) {
3059 return -EINVAL;
3060 }
3061
3062 action = argv[1];
3063
3064 if (!strcmp(action, "HFPAG")) {
3065 discov = discov_hfpag;
3066 } else if (!strcmp(action, "A2SRC")) {
3067 discov = discov_a2src;
3068 } else {
3069 err = -EINVAL;
3070 }
3071
3072 if (err) {
3073 printf("SDP UUID to resolve not valid (err %d)\n", err);
3074 printf("Supported UUID are \'HFPAG\' \'A2SRC\' only\n");
3075 return err;
3076 }
3077
3078 printf("SDP UUID \'%s\' gets applied\n", action);
3079
3080 res = bt_sdp_discover(default_conn, &discov);
3081
3082 if (res) {
3083 printf("SDP discovery failed: result %d\n", res);
3084 } else {
3085 printf("SDP discovery started\n");
3086 }
3087
3088 return 0;
3089 }
3090 #endif
3091
3092 #define HELP_NONE "[none]"
3093 #define HELP_ADDR_LE "<address: XX:XX:XX:XX:XX:XX>or<test> <type: (public|random)>"
3094
3095 static const struct shell_cmd bt_commands[] = {
3096 { "init", cmd_init, HELP_ADDR_LE },
3097 #if defined(CONFIG_BT_HCI)
3098 { "hci-cmd", cmd_hci_cmd, "<ogf> <ocf> [data]" },
3099 #endif
3100 { "id-create", cmd_id_create, "[addr]" },
3101 { "id-reset", cmd_id_reset, "<id> [addr]" },
3102 { "id-delete", cmd_id_delete, "<id>" },
3103 { "id-show", cmd_id_show, HELP_NONE },
3104 { "id-select", cmd_id_select, "<id>" },
3105 { "name", cmd_name, "[name]" },
3106 {
3107 "scan", cmd_scan,
3108 "<value: active, passive, off,test> <dup filter: dups, nodups> "\
3109 "<scan interval> <scan window> "\
3110 "<ad(len|adtype|addata ...): 0xxxxxxxx> <sd(len|adtype|addata ...): 0xxxxxxxx>"
3111 },
3112 {
3113 "adv", cmd_advertise,
3114 "<type: stop, adv_ind, adv_nonconn_ind,scan_ind,test> <ad(len|adtype|addata ...): 0xxxxxxxx> <sd(len|adtype|addata ...): 0xxxxxxxx>"
3115 },
3116 #if defined(CONFIG_BT_CONN)
3117 {
3118 "connect", cmd_connect_le, HELP_ADDR_LE\
3119 " <addr> <addr_type>"\
3120 "<test> or <interval_min> <interval_max>"\
3121 " <latency> <timeout>"
3122 },
3123 { "disconnect", cmd_disconnect, "[conn_handle]" },
3124 { "auto-conn", cmd_auto_conn, HELP_ADDR_LE" <type: on|off>"},
3125 { "select", cmd_select, HELP_ADDR_LE },
3126 { "conn-update", cmd_conn_update, "<min> <max> <latency> <timeout>" },
3127 { "oob", cmd_oob },
3128 { "clear", cmd_clear },
3129 #if defined(CONFIG_BT_SMP) || defined(CONFIG_BT_BREDR)
3130 { "security", cmd_security, "<security level: 0, 1, 2, 3>" },
3131 {
3132 "io-capability", cmd_iocap_set,
3133 "<io input: NONE,YESNO, KEYBOARD> <io output: NONE,DISPLAY>"
3134 },
3135 { "auth-cancel", cmd_auth_cancel, HELP_NONE },
3136 { "auth-passkey", cmd_auth_passkey, "<passkey>" },
3137 { "auth-passkey-confirm", cmd_auth_passkey_confirm, HELP_NONE },
3138 { "auth-pairing-confirm", cmd_auth_pairing_confirm, HELP_NONE },
3139 { "auth-get-keysize", cmd_auth_get_keysize, HELP_NONE },
3140 #if defined(CONFIG_BT_FIXED_PASSKEY)
3141 { "fixed-passkey", cmd_fixed_passkey, "[passkey]" },
3142 #endif
3143 #if defined(CONFIG_BT_BREDR)
3144 { "auth-pincode", cmd_auth_pincode, "<pincode>" },
3145 #endif /* CONFIG_BT_BREDR */
3146 #endif /* CONFIG_BT_SMP || CONFIG_BT_BREDR) */
3147 #if defined(CONFIG_BT_GATT_CLIENT)
3148 { "gatt-exchange-mtu", cmd_gatt_exchange_mtu, HELP_NONE },
3149 {
3150 "gatt-discover-primary", cmd_gatt_discover,
3151 "<UUID> [start handle] [end handle]"
3152 },
3153 {
3154 "gatt-discover-secondary", cmd_gatt_discover,
3155 "<UUID> [start handle] [end handle]"
3156 },
3157 {
3158 "gatt-discover-include", cmd_gatt_discover,
3159 "[UUID] [start handle] [end handle]"
3160 },
3161 {
3162 "gatt-discover-characteristic", cmd_gatt_discover,
3163 "[UUID] [start handle] [end handle]"
3164 },
3165 {
3166 "gatt-discover-descriptor", cmd_gatt_discover,
3167 "[UUID] [start handle] [end handle]"
3168 },
3169 { "gatt-read", cmd_gatt_read, "<handle> [offset],<test>" },
3170 { "gatt-read-multiple", cmd_gatt_mread, "[<handle 1>,test] <handle 2> ..." },
3171 { "gatt-write", cmd_gatt_write, "<handle> <offset> <data> [length],<test>" },
3172 {
3173 "gatt-write-without-response", cmd_gatt_write_without_rsp,
3174 "<handle> <data> [length] [repeat]"
3175 },
3176 {
3177 "gatt-write-signed", cmd_gatt_write_without_rsp,
3178 "<handle> <data> [length] [repeat]"
3179 },
3180 {
3181 "gatt-subscribe", cmd_gatt_subscribe,
3182 "<CCC handle> [ind]"
3183 },
3184 { "gatt-unsubscribe", cmd_gatt_unsubscribe, "<CCC handle>"},
3185 #endif /* CONFIG_BT_GATT_CLIENT */
3186 { "gatt-show-db", cmd_gatt_show_db, HELP_NONE },
3187 {
3188 "gatt-register-service", cmd_gatt_register_test_svc,
3189 "register pre-predefined test service"
3190 },
3191 {
3192 "gatt-register-service2", cmd_gatt_register_test_svc,
3193 "register pre-predefined test2 service"
3194 },
3195 {
3196 "gatt-unregister-service", cmd_gatt_unregister_test_svc,
3197 "unregister pre-predefined test service"
3198 },
3199
3200 #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL)
3201 { "l2cap-register", cmd_l2cap_register, "<psm> [sec_level]" },
3202 { "l2cap-connect", cmd_l2cap_connect, "<psm>" },
3203 { "l2cap-disconnect", cmd_l2cap_disconnect, "<psm>" },
3204 { "l2cap-send", cmd_l2cap_send, "<psm> <number of packets>" },
3205 { "l2cap-metrics", cmd_l2cap_metrics, "<value on, off>" },
3206 #endif
3207 #if defined(CONFIG_BT_BREDR)
3208 { "br-iscan", cmd_bredr_discoverable, "<value: on, off>" },
3209 { "br-pscan", cmd_bredr_connectable, "value: on, off" },
3210 { "br-connect", cmd_connect_bredr, "<address>" },
3211 {
3212 "br-discovery", cmd_bredr_discovery,
3213 "<value: on, off> [length: 1-48] [mode: limited]"
3214 },
3215 { "br-l2cap-register", cmd_bredr_l2cap_register, "<psm>" },
3216 { "br-oob", cmd_bredr_oob },
3217 { "br-sdp-find", cmd_bredr_sdp_find_record, "<HFPAG>" },
3218 #if defined(CONFIG_BT_RFCOMM)
3219 { "br-rfcomm-register", cmd_bredr_rfcomm_register },
3220 { "br-rfcomm-connect", cmd_rfcomm_connect, "<channel>" },
3221 { "br-rfcomm-send", cmd_rfcomm_send, "<number of packets>"},
3222 { "br-rfcomm-disconnect", cmd_rfcomm_disconnect, HELP_NONE },
3223 #endif /* CONFIG_BT_RFCOMM */
3224 #endif /* CONFIG_BT_BREDR */
3225 #endif /* CONFIG_BT_CONN */
3226 #if defined(CONFIG_BT_CTLR_ADV_EXT)
3227 { "advx", cmd_advx, "<on off> [coded] [anon] [txp]" },
3228 { "scanx", cmd_scanx, "<on passive off> [coded]" },
3229 #endif /* CONFIG_BT_CTLR_ADV_EXT */
3230 #if defined(CONFIG_BT_CTLR_DTM)
3231 { "test_tx", cmd_test_tx, "<chan> <len> <type> <phy>" },
3232 { "test_rx", cmd_test_rx, "<chan> <phy> <mod_idx>" },
3233 { "test_end", cmd_test_end, HELP_NONE},
3234 #endif /* CONFIG_BT_CTLR_ADV_EXT */
3235 { NULL, NULL, NULL }
3236 };
3237
3238
cmd_ble_func(char * wbuf,int wbuf_len,int argc,char ** argv)3239 static void cmd_ble_func(char *wbuf, int wbuf_len, int argc, char **argv)
3240 {
3241 int i = 0;
3242 int err;
3243
3244 if (argc < 2) {
3245 printf("Ble support commands\n");
3246
3247 for (i = 0; bt_commands[i].cmd_name != NULL; i ++) {
3248 printf(" %s %s\n", bt_commands[i].cmd_name, bt_commands[i].help);
3249 }
3250
3251 return;
3252 }
3253
3254 for (i = 0; bt_commands[i].cmd_name != NULL; i ++) {
3255 if (strlen(bt_commands[i].cmd_name) == strlen(argv[1]) &&
3256 !strncmp(bt_commands[i].cmd_name, argv[1], strlen(bt_commands[i].cmd_name))) {
3257 if (bt_commands[i].cb) {
3258 err = bt_commands[i].cb(argc - 1, &argv[1]);
3259
3260 if (err) {
3261 printf("%s execute fail, %d\n", bt_commands[i].cmd_name, err);
3262 }
3263
3264 break;
3265 }
3266 }
3267 }
3268 }
3269
3270 #if AOS_COMP_CLI
cli_reg_cmd_ble(void)3271 void cli_reg_cmd_ble(void)
3272 {
3273 static const struct cli_command cmd_info = {
3274 "ble",
3275 "ble commands",
3276 cmd_ble_func,
3277 };
3278
3279 aos_cli_register_command(&cmd_info);
3280 }
3281 #endif /* AOS_COMP_CLI */
3282