1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "blecfg_pub.h"
6 
7 #define UUID_VENDOR_SERVICE                      UUID16_DECLARE(0xFFA0)
8 #define UUID_VENDOR_CHAR_READ                    UUID16_DECLARE(0xFFA1)
9 #define UUID_VENDOR_CHAR_WRITE                   UUID16_DECLARE(0xFFA2)
10 #define UUID_VENDOR_CHAR_NOTIFY                  UUID16_DECLARE(0xFFA3)
11 
12 enum {
13     BLE_NETCFG_IDX_SVC,
14     BLE_NETCFG_IDX_CHAR1,
15     BLE_NETCFG_IDX_CHAR1_VAL,
16     BLE_NETCFG_IDX_CHAR2,
17     BLE_NETCFG_IDX_CHAR2_VAL,
18     BLE_NETCFG_IDX_CHAR3,
19     BLE_NETCFG_IDX_CHAR3_VAL,
20     BLE_NETCFG_IDX_CHAR3_CCC,
21 
22     BLE_NETCFG_IDX_MAX,
23 };
24 
25 char g_blecfg_devname[128];
26 
27 typedef struct {
28     uint8_t inited;
29     uint8_t started;
30     ble_event_cb_t stack_cb;
31     BleCfg_msg_cb  miniapp_msg_cb;
32     int16_t conn_handle;
33     uint32_t gatt_svc_handle;
34 }BleCfg_Info;
35 
36 gatt_service g_BLE_netCfg_gatt_service;
37 static  gatt_attr_t g_BLE_netCfg_gatt_attrs[] = {
38     [BLE_NETCFG_IDX_SVC] = GATT_PRIMARY_SERVICE_DEFINE(UUID_VENDOR_SERVICE),
39 
40     [BLE_NETCFG_IDX_CHAR1] = GATT_CHAR_DEFINE(UUID_VENDOR_CHAR_READ, GATT_CHRC_PROP_READ),
41     [BLE_NETCFG_IDX_CHAR1_VAL] = GATT_CHAR_VAL_DEFINE(UUID_VENDOR_CHAR_READ, GATT_PERM_READ),
42 
43     [BLE_NETCFG_IDX_CHAR2] = GATT_CHAR_DEFINE(UUID_VENDOR_CHAR_WRITE, GATT_CHRC_PROP_WRITE | GATT_CHRC_PROP_WRITE_WITHOUT_RESP),
44     [BLE_NETCFG_IDX_CHAR2_VAL] = GATT_CHAR_VAL_DEFINE(UUID_VENDOR_CHAR_WRITE,  GATT_PERM_WRITE),
45 
46     [BLE_NETCFG_IDX_CHAR3] = GATT_CHAR_DEFINE(UUID_VENDOR_CHAR_NOTIFY, GATT_CHRC_PROP_READ | GATT_CHRC_PROP_NOTIFY),
47     [BLE_NETCFG_IDX_CHAR3_VAL] = GATT_CHAR_VAL_DEFINE(UUID_VENDOR_CHAR_NOTIFY,  GATT_PERM_READ),
48     [BLE_NETCFG_IDX_CHAR3_CCC] = GATT_CHAR_CCC_DEFINE(),
49 };
50 
51 uint8_t g_BLE_netCfg_gatt_read_char[16] = "NetCfg Read";
52 
53 uint8_t g_BLE_netCfg_adv_flag = 0x06;
54 uint16_t g_BLE_netCfg_uuid16_list[] = {0xFFA0};
55 
56 static BleCfg_Info g_BLE_netCfg_info;
57 
BleCfg_get_info(void)58 static BleCfg_Info *BleCfg_get_info(void)
59 {
60     return &g_BLE_netCfg_info;
61 }
62 
BleCfg_start_adv(void)63 static int BleCfg_start_adv(void)
64 {
65     int ret;
66     ad_data_t ad[2] = {0};
67     adv_param_t param = {
68         .type = ADV_IND,
69         .ad = ad,
70         .sd = NULL,
71         .ad_num = BLE_ARRAY_NUM(ad),
72         .sd_num = 0,
73         .interval_min = ADV_FAST_INT_MIN_1,
74         .interval_max = ADV_FAST_INT_MAX_1,
75         .filter_policy = 0,
76         .channel_map = 7,
77         .direct_peer_addr = {0, {0}},
78     };
79 
80     /* setup ADV Flags */
81     ad[0].type = AD_DATA_TYPE_FLAGS;
82     ad[0].data = (uint8_t *)&g_BLE_netCfg_adv_flag;
83     ad[0].len = sizeof(g_BLE_netCfg_adv_flag);
84 
85     /* setup ADV UUIDS */
86     ad[1].type = AD_DATA_TYPE_UUID16_ALL;
87     ad[1].data = (uint8_t *)g_BLE_netCfg_uuid16_list;
88     ad[1].len = sizeof(g_BLE_netCfg_uuid16_list);
89 
90     /* call ADV start API */
91     ret = ble_stack_adv_start(&param);
92     if (ret) {
93         BLECFG_LOG_ERROR("adv start fail %d!\r\n", ret);
94     } else {
95         BLECFG_LOG_INFO("adv start!\r\n");
96     }
97 
98     return ret;
99 }
100 
BleCfg_stop_adv(void)101 static void BleCfg_stop_adv(void)
102 {
103     int ret;
104 
105     /* call ADV start API */
106     ret = ble_stack_adv_stop();
107     if (ret) {
108         BLECFG_LOG_ERROR("adv stop fail %d!\r\n", ret);
109     } else {
110         BLECFG_LOG_INFO("adv stop!\r\n");
111     }
112 }
113 
BleCfg_event_conn_change(ble_event_en event,void * event_data)114 static void BleCfg_event_conn_change(ble_event_en event, void *event_data)
115 {
116     evt_data_gap_conn_change_t *e = (evt_data_gap_conn_change_t *)event_data;
117     BleCfg_Info *netCfg_info = BleCfg_get_info();
118 
119     BLECFG_LOG_INFO("%s, connected = %d\r\n", __func__, e->connected);
120 
121     /* check if connect or disconnect */
122     if (e->connected == CONNECTED && e->err == 0) {
123         netCfg_info->conn_handle = e->conn_handle;
124     } else {
125         netCfg_info->conn_handle = -1;
126         BleCfg_start_adv();
127     }
128 }
129 
BleCfg_event_pairing_passkey_display(ble_event_en event,void * event_data)130 static void BleCfg_event_pairing_passkey_display(ble_event_en event, void *event_data)
131 {
132     /* UNDO: this is BLE SMP passkey event, not used in this demo */
133     BLECFG_LOG_INFO("%s\r\n", __func__);
134 }
135 
BleCfg_event_smp_complete(ble_event_en event,void * event_data)136 static void BleCfg_event_smp_complete(ble_event_en event, void *event_data)
137 {
138     /* UNDO: this is BLE SMP complete event, not used in this demo */
139     BLECFG_LOG_INFO("%s\r\n", __func__);
140 }
141 
BleCfg_event_smp_cancel(ble_event_en event,void * event_data)142 static void BleCfg_event_smp_cancel(ble_event_en event, void *event_data)
143 {
144     /* UNDO: this is BLE SMP cancel event, not used in this demo */
145     BLECFG_LOG_INFO("%s\r\n", __func__);
146 }
147 
BleCfg_event_smp_pairing_confirm(ble_event_en event,void * event_data)148 static void BleCfg_event_smp_pairing_confirm(ble_event_en event, void *event_data)
149 {
150     evt_data_smp_pairing_confirm_t *e = (evt_data_smp_pairing_confirm_t *)event_data;
151     BleCfg_Info *netCfg_info = BleCfg_get_info();
152 
153     /* this is BLE SMP pair confirm event */
154     BLECFG_LOG_INFO("%s, conn_handle = %d\r\n", __func__, e->conn_handle);
155     /* handle stack SMP pair confirm event */
156     ble_stack_smp_passkey_confirm(netCfg_info->conn_handle);
157 }
158 
BleCfg_event_conn_security_change(ble_event_en event,void * event_data)159 static void BleCfg_event_conn_security_change(ble_event_en event, void *event_data)
160 {
161     /* UNDO: this is BLE connection security change event, not used in this demo */
162     BLECFG_LOG_INFO("%s\r\n", __func__);
163 }
164 
BleCfg_event_conn_param_update(ble_event_en event,void * event_data)165 static void BleCfg_event_conn_param_update(ble_event_en event, void *event_data)
166 {
167     /* UNDO: this is BLE connect parameters update event, not used in this demo */
168     BLECFG_LOG_INFO("%s\r\n", __func__);
169 }
170 
BleCfg_event_mtu_exchange(ble_event_en event,void * event_data)171 static void BleCfg_event_mtu_exchange(ble_event_en event, void *event_data)
172 {
173     /* UNDO: this is BLE SMP cancel event, not used in this demo */
174     BLECFG_LOG_INFO("%s\r\n", __func__);
175 }
176 
BleCfg_event_adv_timeout(ble_event_en event,void * event_data)177 static void BleCfg_event_adv_timeout(ble_event_en event, void *event_data)
178 {
179     BleCfg_Info *netCfg_info = BleCfg_get_info();
180 
181     /* this is BLE adv timeout event, restart adv */
182     BLECFG_LOG_INFO("%s\r\n", __func__);
183     //aos_msleep(100);
184     BleCfg_start_adv();
185 }
186 
BleCfg_event_char_read(ble_event_en event,void * event_data)187 static int BleCfg_event_char_read(ble_event_en event, void *event_data)
188 {
189     evt_data_gatt_char_read_t *e = (evt_data_gatt_char_read_t *)event_data;
190     int16_t handle_offset = 0;
191     BleCfg_Info *netCfg_info = BleCfg_get_info();
192 
193     BLE_CHAR_RANGE_CHECK(netCfg_info->gatt_svc_handle, BLE_NETCFG_IDX_MAX, e->char_handle, handle_offset);
194     BLECFG_LOG_INFO("%s: conn_handle =%d, char_handle %d, len =%d, offset =%d\r\n",
195                     __func__, e->conn_handle, e->char_handle, e->len, e->offset);
196 
197     /* check connection handle */
198     if (netCfg_info->conn_handle == e->conn_handle) {
199         switch (handle_offset) {
200             case BLE_NETCFG_IDX_CHAR1_VAL:
201                 /* if read length bigger than read char value length, return error */
202                 if (e->len > sizeof(g_BLE_netCfg_gatt_read_char)) {
203                     e->len = -ATT_ERR_INVALID_ATTRIBUTE_LEN;
204                     return 0;
205                 }
206 
207                 /* if read length+offset bigger than read char value length, return error */
208                 if (e->offset + e->len > sizeof(g_BLE_netCfg_gatt_read_char)) {
209                     e->len = -ATT_ERR_INVALID_OFFSET;
210                     return 0;
211                 }
212 
213                 /* data copy */
214                 memcpy(e->data, g_BLE_netCfg_gatt_read_char + e->offset, BLE_MIN(e->len, sizeof(g_BLE_netCfg_gatt_read_char)));
215                 e->len = BLE_MIN(e->len, sizeof(g_BLE_netCfg_gatt_read_char));
216                 break;
217             default:
218                 e->len = 0;
219                 break;
220         }
221     }
222     return 0;
223 }
224 
BleCfg_event_char_write(ble_event_en event,void * event_data)225 static int BleCfg_event_char_write(ble_event_en event, void *event_data)
226 {
227     evt_data_gatt_char_write_t *e = (evt_data_gatt_char_write_t *)event_data;
228     int16_t handle_offset = 0;
229     static int w_len = 0;
230     BleCfg_Info *netCfg_info = BleCfg_get_info();
231 
232     BLE_CHAR_RANGE_CHECK(netCfg_info->gatt_svc_handle, BLE_NETCFG_IDX_MAX, e->char_handle, handle_offset);
233     BLECFG_LOG_INFO("%s: conn_handle = %d, char_handle = %d, len = %d, offset = %d\r\n",
234                     __func__, e->conn_handle, e->char_handle, e->len, e->offset);
235 
236     BLECFG_LOG_INFO("%s: netCfg_info->conn_handle = %d, e->conn_handle = %d, handle_offset = %d, need = %d\r\n",
237                     __func__, netCfg_info->conn_handle, e->conn_handle, handle_offset, BLE_NETCFG_IDX_CHAR2_VAL);
238 
239     /* check connection handle */
240     if (netCfg_info->conn_handle == e->conn_handle) {
241         switch (handle_offset) {
242             case BLE_NETCFG_IDX_CHAR2_VAL:
243                 if (netCfg_info->miniapp_msg_cb != NULL ) {
244                     netCfg_info->miniapp_msg_cb(e->data, e->len);
245                 }
246                 break;
247             default:
248                 e->len = 0;
249                 break;
250         }
251     }
252 
253     return 0;
254 }
255 
BleCfg_event_char_ccc_change(ble_event_en event,void * event_data)256 static void BleCfg_event_char_ccc_change(ble_event_en event, void *event_data)
257 {
258     BLECFG_LOG_INFO("%s\r\n", __func__);
259 }
260 
BleCfg_event_callback(ble_event_en event,void * event_data)261 static int BleCfg_event_callback(ble_event_en event, void *event_data)
262 {
263     BLECFG_LOG_INFO("%s, event = %x\r\n", __func__, event);
264 
265     /* handle stack events */
266     switch (event) {
267         case EVENT_GAP_CONN_CHANGE:
268             BleCfg_event_conn_change(event, event_data);
269             break;
270         case EVENT_GAP_CONN_PARAM_UPDATE:
271             BleCfg_event_conn_param_update(event, event_data);
272             break;
273         case EVENT_SMP_PASSKEY_DISPLAY:
274             BleCfg_event_pairing_passkey_display(event, event_data);
275             break;
276         case EVENT_SMP_PAIRING_COMPLETE:
277             BleCfg_event_smp_complete(event, event_data);
278             break;
279         case EVENT_SMP_PAIRING_CONFIRM:
280             BleCfg_event_smp_pairing_confirm(event, event_data);
281             break;
282         case EVENT_SMP_CANCEL:
283             BleCfg_event_smp_cancel(event, event_data);
284             break;
285         case EVENT_GAP_CONN_SECURITY_CHANGE:
286             BleCfg_event_conn_security_change(event, event_data);
287             break;
288         case EVENT_GATT_MTU_EXCHANGE:
289             BleCfg_event_mtu_exchange(event, event_data);
290             break;
291         case EVENT_GAP_ADV_TIMEOUT:
292             BleCfg_event_adv_timeout(event, event_data);
293             break;
294         case EVENT_GATT_CHAR_READ:
295             BleCfg_event_char_read(event, event_data);
296             break;
297         case EVENT_GATT_CHAR_WRITE:
298             BleCfg_event_char_write(event, event_data);
299             break;
300         case EVENT_GATT_CHAR_CCC_CHANGE:
301             BleCfg_event_char_ccc_change(event, event_data);
302             break;
303         default:
304             break;
305     }
306 
307     return 0;
308 }
309 
BleCfg_gatt_init(void)310 static int BleCfg_gatt_init(void)
311 {
312     int ret;
313     BleCfg_Info *netCfg_info = BleCfg_get_info();
314 
315     /* register gatt service */
316     ret = ble_stack_gatt_registe_service(&g_BLE_netCfg_gatt_service,
317                                         g_BLE_netCfg_gatt_attrs,
318                                         BLE_ARRAY_NUM(g_BLE_netCfg_gatt_attrs));
319     if (ret < 0) {
320         BLECFG_LOG_INFO("%s failed!, ret = %x\r\n", __func__, ret);
321         return ret;
322     }
323     netCfg_info->gatt_svc_handle = ret;
324 
325     return 0;
326 }
327 
BleCfg_stack_init(BleCfg_msg_cb msg_callback)328 BLECFG_STATE BleCfg_stack_init(BleCfg_msg_cb msg_callback)
329 {
330     int ret;
331     BleCfg_Info *netCfg_info = BleCfg_get_info();
332     uint8_t mac[6];
333     init_param_t init = {
334         .dev_name = NULL,
335         .dev_addr = NULL,   //&addr,
336         .conn_num_max = 1,
337     };
338     int fd;
339 
340     if (netCfg_info->inited) {
341         BLECFG_LOG_ERROR("%s: already initial, ret = %x\r\n", __func__, ret);
342         return BLECFG_ALREADY;
343     }
344 
345     fd = open("/dev/wifi0", O_RDWR);
346     if (fd < 0) {
347         return BLECFG_COMMON_FAILED;
348     }
349 
350     ioctl(fd, WIFI_DEV_CMD_GET_MAC, (unsigned long)mac);
351 
352     snprintf(g_blecfg_devname, sizeof(g_blecfg_devname), "HaaS-%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
353     init.dev_name = g_blecfg_devname;
354 
355     BLECFG_LOG_INFO("%s: dev_name is '%s'\r\n", __func__, g_blecfg_devname);
356 
357     /* bt stack init */
358     ret = ble_stack_init(&init);
359     if (ret) {
360         BLECFG_LOG_ERROR("%s: stack init, ret = %x\r\n", __func__, ret);
361         return BLECFG_COMMON_FAILED;
362     }
363 
364     /* register callback function to stack */
365     netCfg_info->stack_cb.callback = BleCfg_event_callback;
366     ret = ble_stack_event_register(&(netCfg_info->stack_cb));
367     if(ret) {
368         BLECFG_LOG_ERROR("%s: stack event register, ret = %x\r\n", __func__, ret);
369         return BLECFG_COMMON_FAILED;
370     }
371 
372     netCfg_info->miniapp_msg_cb = msg_callback;
373 
374 #ifdef CHIP_HAAS1000
375     extern int netdev_set_epta_params(int wlan_duration, int bt_duration, int hw_epta_enable);
376     netdev_set_epta_params(60000, 40000, 0);
377 #endif
378 
379     /* gatt service init */
380     ret = BleCfg_gatt_init();
381     if(ret) {
382         BLECFG_LOG_ERROR("%s: gatt init, ret = %x\r\n", __func__, ret);
383         return BLECFG_COMMON_FAILED;
384     }
385 
386     netCfg_info->inited = 1;
387 
388     return BLECFG_SUCCESS;
389 }
390 
BleCfg_stack_start(void)391 BLECFG_STATE BleCfg_stack_start(void)
392 {
393     BleCfg_Info *netCfg_info = BleCfg_get_info();
394 
395     if (netCfg_info->inited == 0) {
396         BLECFG_LOG_ERROR("%s: component not initialed\r\n", __func__);
397         return BLECFG_COMMON_FAILED;
398     }
399 
400     BLECFG_LOG_DEBUG("%s: state = %d\r\n", __func__, netCfg_info->started);
401     if (netCfg_info->started == 0) {
402         BleCfg_start_adv();
403         netCfg_info->started = 1;
404     }
405 
406     return BLECFG_SUCCESS;
407 }
408 
BleCfg_stack_stop(void)409 BLECFG_STATE BleCfg_stack_stop(void)
410 {
411     BleCfg_Info *netCfg_info = BleCfg_get_info();
412 
413     if (netCfg_info->inited == 0) {
414         BLECFG_LOG_ERROR("%s: component not initialed\r\n", __func__);
415         return -1;
416     }
417 
418     BLECFG_LOG_DEBUG("%s: state = %d\r\n", __func__, netCfg_info->started);
419     if (netCfg_info->started == 1) {
420         BleCfg_stop_adv();
421         netCfg_info->started = 0;
422     }
423 
424     return BLECFG_SUCCESS;
425 }
426 
427 /* ble断连,协议栈回自动回到adv广播模式 */
BleCfg_stack_disconnect(void)428 BLECFG_STATE BleCfg_stack_disconnect(void)
429 {
430     BleCfg_Info *netCfg_info = BleCfg_get_info();
431 
432     if (netCfg_info->inited == 0) {
433         BLECFG_LOG_ERROR("%s: component not initialed\r\n", __func__);
434         return -1;
435     }
436 
437     if (netCfg_info->conn_handle != -1) {
438         ble_stack_disconnect(netCfg_info->conn_handle);
439         BLECFG_LOG_INFO("%s: ble_stack_disconnect\r\n", __func__);
440     }
441 
442     return BLECFG_SUCCESS;
443 
444 }
445 
BleCfg_notificate(const uint8_t * data,uint16_t size)446 BLECFG_STATE BleCfg_notificate(const uint8_t *data, uint16_t size)
447 {
448     BleCfg_Info *netCfg_info = BleCfg_get_info();
449     int ret;
450     BLECFG_STATE state = BLECFG_COMMON_FAILED;
451 
452     ret = ble_stack_gatt_notificate(netCfg_info->conn_handle, netCfg_info->gatt_svc_handle + BLE_NETCFG_IDX_CHAR3_VAL, data, size);
453     if (ret == 0) {
454         state = BLECFG_SUCCESS;
455     }
456     BLECFG_LOG_DEBUG("%s: ret  = %d", __func__, ret);
457 
458     return state;
459 }
460 
461