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 = &ee;
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, &param, 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(&param);
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