1 #include <stdio.h>
2 #include <bt_errno.h>
3 #include <ble_os.h>
4 //#include <aos/osal_debug.h>
5 #include <aos/kernel.h>
6 #include <aos/ble.h>
7 //#include <aos/aos.h>
8 #include "yoc/uart_client.h"
9
10
11
12 #define UUID_COMPARE_LENGTH 10
13 #define MAX_DEV_SURVIVE_TIME 10000 //ms
14
15
16 enum {
17 DISC_IDLE = 0,
18 DISC_SRV,
19 DISC_CHAR,
20 DISC_DES,
21 };
22
23 typedef struct _report_dev {
24 dev_addr_t addr;
25 long long time_found;
26 } report_dev;
27
28 typedef struct {
29 uint8_t front;
30 uint8_t rear;
31 uint8_t length;
32 report_dev dev[10];
33 } dev_data_queue;
34
35 typedef struct _bt_uuid {
36 uint8_t type;
37 } bt_uuid;
38
39 struct bt_uuid_128 {
40 bt_uuid uuid;
41 uint16_t val[16];
42 };
43
44 static ble_uart_client_t *g_uart_dev = NULL;
45 static dev_data_queue g_dev_list;
46 static client_config *g_cli_config = NULL;
47 static uint8_t g_disconn_flag = 0;
48 static dev_addr_t g_conn_last;
49 static uint8_t g_conn_same_flag = 0;
50
conn_change(ble_event_en event,void * event_data)51 static void conn_change(ble_event_en event, void *event_data)
52 {
53
54 evt_data_gap_conn_change_t *e = (evt_data_gap_conn_change_t *)event_data;
55
56 ble_uart_client_t *node = g_uart_dev;
57
58 if (!node) {
59 return;
60 }
61
62 if (e->connected == CONNECTED) {
63 ble_stack_gatt_mtu_exchange(e->conn_handle);
64 node->conn_handle = e->conn_handle;
65 connect_info_t info = {0};
66 ble_stack_connect_info_get(e->conn_handle, &info);
67
68 if (!memcmp(&info.peer_addr, &g_conn_last, sizeof(dev_addr_t))) {
69 g_conn_same_flag = 1;
70 } else {
71 memcpy(&g_conn_last, &info.peer_addr, sizeof(dev_addr_t));
72 }
73 } else {
74 node->conn_handle = -1;
75 }
76
77 node->uart_event_callback(event, event_data);
78
79 }
80
81
82
mtu_exchange(ble_event_en event,void * event_data)83 static void mtu_exchange(ble_event_en event, void *event_data)
84 {
85 evt_data_gatt_mtu_exchange_t *e = (evt_data_gatt_mtu_exchange_t *)event_data;
86
87 ble_uart_client_t *node = g_uart_dev;
88
89 if (!node) {
90 return;
91 }
92
93 if (e->err == 0) {
94 if (node->conn_handle == e->conn_handle) {
95 node->mtu_exchanged = 1;
96 node->mtu = ble_stack_gatt_mtu_get(node->conn_handle);
97
98 if (!g_conn_same_flag) {
99 ble_stack_gatt_discovery_primary(node->conn_handle, YOC_UART_SERVICE_UUID, 0x0001, 0xFFFF);
100 } else {
101 uint8_t ccc_enable = CCC_VALUE_NOTIFY;
102 int ret = ble_stack_gatt_write_response(e->conn_handle, node->client_data.uart_profile.uart_ccc_handle, &ccc_enable, sizeof(ccc_enable), 0);
103
104 if (ret < 0) {
105 return;
106 }
107
108 node->client_data.uart_profile.notify_enabled = 1;
109
110 if ((node->update_param_flag || node->conn_update_def_on) && node->conn_param != NULL) {
111 ble_stack_connect_param_update(node->conn_handle, (conn_param_t *)node->conn_param);
112 }
113 }
114 }
115
116 node->uart_event_callback(event, event_data);
117 }
118 }
119
120
find_uart_uuid_by_ad(uint8_t * data,uint16_t len)121 int find_uart_uuid_by_ad(uint8_t *data, uint16_t len)
122 {
123 uint8_t *pdata = data;
124 ad_data_t ad = {0};
125 uint8_t uuid_temp[16] = {0x7e, 0x31, 0x35, 0xd4, 0x12, 0xf3, 0x11, 0xe9, 0xab, 0x14, 0xd6, 0x63, 0xbd, 0x87, 0x3d, 0x93};
126
127 while (len) {
128 if (pdata[0] == 0) {
129 return -1;
130 }
131
132 if (len < pdata[0] + 1) {
133 return -1;
134 };
135
136 ad.len = pdata[0] - 1;
137
138 ad.type = pdata[1];
139
140 ad.data = &pdata[2];
141
142 if (ad.type == AD_DATA_TYPE_UUID128_ALL && ad.len == 16) {
143 if (!memcmp(ad.data, uuid_temp, 10)) {
144 return 0;
145 }
146 }
147
148 len -= (pdata[0] + 1);
149 pdata += (pdata[0] + 1);
150 }
151
152 return -1;
153 }
154
155
is_dev_data_queue_empty(dev_data_queue * queue)156 static bool is_dev_data_queue_empty(dev_data_queue *queue)
157 {
158 return queue->front == queue->rear;
159 }
160
is_dev_data_queue_full(dev_data_queue * queue)161 static bool is_dev_data_queue_full(dev_data_queue *queue)
162 {
163 if ((queue->rear + 1) % 10 == queue->front) {
164 return true;
165 } else {
166 return false;
167 }
168 }
169
get_dev_data(dev_data_queue * queue)170 static report_dev *get_dev_data(dev_data_queue *queue)
171 {
172 if (is_dev_data_queue_empty(queue)) {
173 return NULL;
174 } else {
175 report_dev *data = &queue->dev[queue->front];
176 queue->front = (queue->front + 1) % 10;
177 return data;
178 }
179 }
180
181
put_dev_data(dev_data_queue * queue,dev_addr_t * dev)182 static int put_dev_data(dev_data_queue *queue, dev_addr_t *dev)
183 {
184 if (!queue || !dev) {
185 return -1;
186 }
187
188 if (is_dev_data_queue_full(queue)) {
189 return -1;
190 }
191
192 for (int i = queue->front; i < queue->rear ; i++) {
193 if (!memcmp(&queue->dev[i].addr, dev, sizeof(dev_addr_t))) {
194 return 0;
195 }
196 }
197
198 memcpy(&queue->dev[queue->rear].addr, dev, sizeof(dev_addr_t));
199 queue->dev[queue->rear].time_found = aos_now_ms();
200 queue->rear = (queue->rear + 1) % 10;
201 return 0;
202 }
203
204
found_dev_get()205 dev_addr_t *found_dev_get()
206 {
207 report_dev *dev = NULL;
208 long long time_now = 0;
209 long long survive_time = 0;
210
211 do {
212 dev = get_dev_data(&g_dev_list);
213
214 if (dev) {
215 time_now = aos_now_ms();
216 survive_time = time_now - dev->time_found;
217 }
218
219 } while (dev && survive_time > MAX_DEV_SURVIVE_TIME);
220
221 if (!dev) {
222 return NULL;
223 } else {
224 return &dev->addr;
225 }
226 }
227
device_find(ble_event_en event,void * event_data)228 static void device_find(ble_event_en event, void *event_data)
229 {
230 int ret = -1;
231 int uuid_peer = -1;
232 evt_data_gap_dev_find_t ee;
233 evt_data_gap_dev_find_t *e;
234 uint8_t find_dev = 0;
235 memcpy(&ee, event_data, sizeof(evt_data_gap_dev_find_t));////
236
237 e = ⅇ
238 conn_param_t param = {
239 0x06, //interval min 7.5ms
240 0x06, //interval max 7.5ms
241 0,
242 100, //supervision timeout 1s
243 };
244
245 if (!g_cli_config) {
246 return;
247 }
248
249 if (e->adv_type != ADV_IND) {
250 return;
251 }
252
253 if (e->adv_len > 31) {
254 return;
255 }
256
257 uuid_peer = find_uart_uuid_by_ad(e->adv_data, e->adv_len);
258
259 if (uuid_peer < 0) {
260 return;
261 }
262
263 put_dev_data(&g_dev_list, &e->dev_addr);
264
265 if (g_disconn_flag) {
266 return;
267 }
268
269 if (!g_cli_config->conn_def_on) {
270 if (!memcmp(&g_cli_config->temp_conn_dev_set, &e->dev_addr, sizeof(g_cli_config->temp_conn_dev_set))) {
271 find_dev = 1;
272 }
273 } else {
274 if (g_cli_config->auto_conn_mac_size > 0) {
275 for (int i = 0; i < g_cli_config->auto_conn_mac_size; i++) {
276 if (!memcmp((uint8_t *)&g_cli_config->auto_conn_mac[i], (uint8_t *)&e->dev_addr, sizeof(dev_addr_t))) {
277 find_dev = 1;
278 break;
279 }
280 }
281 } else if (!uuid_peer) {
282 find_dev = 1;
283 }
284 }
285
286 if (find_dev) {
287 ble_stack_scan_stop();
288 ret = ble_stack_connect(&e->dev_addr, ¶m, 0);
289
290 if (ret < 0) {
291 uart_client_scan_start();
292 return;
293 }
294 }
295 }
296
297
UUID_EQUAL_LEN(uuid_t * uuid1,uuid_t * uuid2,uint8_t comp_len)298 static uint8_t UUID_EQUAL_LEN(uuid_t *uuid1, uuid_t *uuid2, uint8_t comp_len)
299 {
300 if (UUID_TYPE(uuid1) != UUID_TYPE(uuid2)) {
301 return false;
302 }
303
304 comp_len = comp_len < UUID_LEN(uuid1) ? comp_len : UUID_LEN(uuid1);
305 return (0 == memcmp(&((struct bt_uuid_128 *)uuid1)->val, &((struct bt_uuid_128 *)uuid2)->val, comp_len));
306 }
307
308
service_discovery(ble_event_en event,void * event_data)309 static void service_discovery(ble_event_en event, void *event_data)
310 {
311 int ret;
312
313 static uint8_t discovery_state = 0;
314 ble_uart_client_t *uart = g_uart_dev;
315
316 if (!uart) {
317 return;
318 }
319
320
321 if (event == EVENT_GATT_DISCOVERY_COMPLETE) {
322 evt_data_gatt_discovery_complete_t *e = event_data;
323
324 if (discovery_state == DISC_SRV) {
325 ble_stack_gatt_discovery_char(e->conn_handle, YOC_UART_RX_UUID, uart->client_data.uart_profile.uart_handle + 1, uart->client_data.uart_profile.uart_end_handle);
326 } else if (discovery_state == DISC_CHAR) {
327 ble_stack_gatt_discovery_descriptor(e->conn_handle, UUID_GATT_CCC, uart->client_data.uart_profile.uart_char_handle + 1, 0xffff);
328 } else if (discovery_state == DISC_DES) {
329 uint8_t ccc_enable = CCC_VALUE_NOTIFY;
330 ret = ble_stack_gatt_write_response(e->conn_handle, uart->client_data.uart_profile.uart_ccc_handle, &ccc_enable, sizeof(ccc_enable), 0);
331
332 if (ret < 0) {
333 return;
334 }
335
336 uart->client_data.uart_profile.notify_enabled = 1;
337
338 if ((uart->update_param_flag || uart->conn_update_def_on) && uart->conn_param != NULL) {
339 ble_stack_connect_param_update(uart->conn_handle, (conn_param_t *)uart->conn_param);
340 }
341
342 return;
343 }
344 }
345
346 if (event == EVENT_GATT_DISCOVERY_SVC) {
347 evt_data_gatt_discovery_svc_t *e = event_data;
348 discovery_state = DISC_SRV;
349
350 if (UUID_EQUAL_LEN(&e->uuid, YOC_UART_SERVICE_UUID, UUID_COMPARE_LENGTH)) {
351 uart->client_data.uart_profile.uart_handle = e->start_handle;
352 uart->client_data.uart_profile.uart_end_handle = e->end_handle;
353 }
354 }
355
356 if (event == EVENT_GATT_DISCOVERY_CHAR) {
357 evt_data_gatt_discovery_char_t *e = event_data;
358 uart->client_data.uart_profile.uart_char_handle = e->val_handle;
359 discovery_state = DISC_CHAR;
360 }
361
362 if (event == EVENT_GATT_DISCOVERY_CHAR_DES) {
363 evt_data_gatt_discovery_char_des_t *e = event_data;
364 uart->client_data.uart_profile.uart_ccc_handle = e->attr_handle;
365 discovery_state = DISC_DES;
366
367 }
368 }
369
event_notify(ble_event_en event,void * event_data)370 static void event_notify(ble_event_en event, void *event_data)
371 {
372 evt_data_gatt_notify_t *e = (evt_data_gatt_notify_t *)event_data;
373 ble_uart_client_t *uart = g_uart_dev;
374
375 if (!uart) {
376 return;
377 }
378
379 if (uart->conn_handle == e->conn_handle) {
380 e->len = e->len < RX_MAX_LEN ? e->len : RX_MAX_LEN;
381 uart->uart_recv(e->data, e->len);
382 }
383 }
384
uart_event_callback(ble_event_en event,void * event_data)385 static int uart_event_callback(ble_event_en event, void *event_data)
386 {
387
388 switch (event) {
389 case EVENT_GAP_CONN_CHANGE:
390 conn_change(event, event_data);
391 break;
392
393 case EVENT_GATT_MTU_EXCHANGE:
394 mtu_exchange(event, event_data);
395 break;
396
397 case EVENT_GAP_DEV_FIND:
398 device_find(event, event_data);
399 break;
400
401 case EVENT_GATT_DISCOVERY_SVC:
402 case EVENT_GATT_DISCOVERY_CHAR:
403 case EVENT_GATT_DISCOVERY_CHAR_DES:
404 case EVENT_GATT_DISCOVERY_COMPLETE:
405 service_discovery(event, event_data);
406 break;
407
408 case EVENT_GATT_CHAR_CCC_CHANGE: {
409 break;
410 }
411
412 case EVENT_GATT_NOTIFY: {
413 event_notify(event, event_data);
414 break;
415 }
416
417 default:
418 break;
419 }
420
421 return 0;
422 }
423
424
425
uart_client_scan_start()426 int uart_client_scan_start()
427 {
428 int ret;
429 scan_param_t param = {
430 SCAN_PASSIVE,
431 SCAN_FILTER_DUP_ENABLE,
432 SCAN_FAST_INTERVAL,
433 SCAN_FAST_WINDOW,
434 };
435
436 ret = ble_stack_scan_start(¶m);
437
438 if (ret) {
439 return ret;
440 }
441
442 return 0;
443 }
444
445
446 static ble_event_cb_t ble_cb = {
447 .callback = uart_event_callback,
448 };
449
uart_client_send(uart_handle_t handle,const char * data,int length,bt_uart_send_cb * cb)450 int uart_client_send(uart_handle_t handle, const char *data, int length, bt_uart_send_cb *cb)
451 {
452 uint32_t count = length;
453 int ret = 0;
454 uint16_t wait_timer = 0;
455
456 ble_uart_client_t *uart = handle;
457
458 if (data == NULL || length <= 0 || !uart || uart->conn_handle < 0 || !uart->client_data.uart_profile.notify_enabled) {
459 return -1;
460 }
461
462 if (cb != NULL && cb->start != NULL) {
463 cb->start(0, NULL);
464 }
465
466 while (count) {
467 uint16_t send_count = (uart->mtu - 3) < count ? (uart->mtu - 3) : count;
468 ret = ble_stack_gatt_write_no_response(uart->conn_handle, uart->client_data.uart_profile.uart_handle + 2, (uint8_t *)data, send_count, 0);
469
470 if (ret == -ENOMEM) {
471 wait_timer++;
472
473 if (wait_timer >= 500) {
474 return -1;
475 }
476
477 aos_msleep(1);
478 continue;
479 }
480
481 if (ret) {
482 if (cb != NULL && cb->end != NULL) {
483 cb->end(ret, NULL);
484 }
485
486 return ret;
487 }
488
489 data += send_count;
490 count -= send_count;
491 }
492
493 if (cb != NULL && cb->end != NULL) {
494 cb->end(0, NULL);
495 }
496
497 return 0;
498 }
499
uart_client_conn(dev_addr_t * conn_mac,conn_param_t * conn_param)500 int uart_client_conn(dev_addr_t *conn_mac, conn_param_t *conn_param)
501 {
502 if (!g_cli_config) {
503 return -1;
504 }
505
506 memcpy(g_cli_config->temp_conn_dev_set.val, conn_mac->val, sizeof(g_cli_config->temp_conn_dev_set.val));
507 g_cli_config->temp_conn_dev_set.type = conn_mac->type;
508
509 if (conn_param) {
510 g_cli_config->temp_conn_param = conn_param;
511 }
512
513 g_disconn_flag = 0;
514 return 0;
515 }
516
517
uart_client_disconn(uart_handle_t handle)518 int uart_client_disconn(uart_handle_t handle)
519 {
520 ble_uart_client_t *uart = handle;
521
522 if (!uart) {
523 return -1;
524 }
525
526 if (ble_stack_disconnect(uart->conn_handle)) {
527 return -1;
528 }
529
530 uart->client_data.client_conf.conn_def_on = 0;
531 g_disconn_flag = 1;
532
533 return 0;
534 }
535
536
uart_client_init(ble_uart_client_t * service)537 uart_handle_t uart_client_init(ble_uart_client_t *service)
538 {
539 int ret = 0;
540
541 if (service == NULL) {
542 return NULL;
543 }
544
545 ret = ble_stack_event_register(&ble_cb);
546
547 if (ret) {
548 return NULL;
549 }
550
551 service->conn_handle = -1;
552 g_cli_config = &service->client_data.client_conf;
553 g_uart_dev = service;
554 g_dev_list.front = 0;
555 g_dev_list.rear = 0;
556 g_dev_list.length = 10;
557
558 return service;
559 }
560
uart_client_conn_param_update(uart_handle_t handle,conn_param_t * param)561 int uart_client_conn_param_update(uart_handle_t handle, conn_param_t *param)
562 {
563 ble_uart_client_t *uart = (ble_uart_client_t *)handle;
564
565 if (!uart) {
566 return -1;
567 }
568
569 uart->conn_param->interval_min = param->interval_min;
570 uart->conn_param->interval_max = param->interval_max;
571 uart->conn_param->latency = param->latency;
572 uart->conn_param->timeout = param->timeout;
573
574 if (uart->conn_handle < 0) {
575 uart->update_param_flag = 1;
576 } else {
577 return ble_stack_connect_param_update(uart->conn_handle, param);
578 }
579
580 return 0;
581 }
582
583
584
585