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(¶m);
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