1 /*
2 * Copyright (c) 2022 ASR Microelectronics (Shanghai) Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 ****************************************************************************************
18 *
19 * @file app.c
20 *
21 * @brief Application entry point
22 *
23 ****************************************************************************************
24 */
25
26 /**
27 ****************************************************************************************
28 * @addtogroup APP
29 * @{
30 ****************************************************************************************
31 */
32
33 /*
34 * INCLUDE FILES
35 ****************************************************************************************
36 */
37
38 #include <stdio.h>
39 #include "arch.h" // Application Definition
40 #include "sonata_gap.h"
41 #include "sonata_att.h"
42 #include "sonata_ble_api.h"
43 #include "sonata_gap_api.h"
44 #if !defined ALIOS_SUPPORT && !defined HARMONYOS_SUPPORT
45 #include "user_platform.h"
46 #endif
47 #include "sonata_ble_hook.h"
48 #include "sonata_gatt_api.h"
49 #include "sonata_api_task.h"
50 #include "sonata_gap.h"
51 #include "sonata_log.h"
52 #if !defined ALIOS_SUPPORT && !defined HARMONYOS_SUPPORT
53 #include "at_api.h"
54 #endif
55 #ifdef HARMONYOS_TEMP
56 #else
57
58 #endif
59 #include "app.h"
60 #if BLE_BATT_SERVER
61 #include "sonata_prf_bass_api.h"
62 #endif // BLE_BATT_SERVER
63 #ifdef SONATA_RTOS_SUPPORT
64 #include "lega_rtos.h"
65 #endif
66
67 /*
68 * DEFINES
69 ****************************************************************************************
70 */
71 #define APP_BLE_ADV_ON 1
72 #define APP_BLE_ADV_OFF 0
73 #define APP_BLE_DEVICE_NAME_LEN 255
74 #define APP_BLE_CONNECT_MAX 10
75 #define APP_BLE_INVALID_CONIDX 0xFF
76 #define APP_BLE_ADV_MAX 0xB
77 #define APP_BLE_INVALID_ADVIDX 0xFF
78 #define APP_MAX_SERVICE_NUM 5
79
80 typedef struct ble_gatt_att_reg_list {
81 uint16_t start_hdl;
82 uint8_t nb_att;
83 uint8_t state;
84 uint8_t perm;
85 uint8_t uuid[SONATA_ATT_UUID_128_LEN];
86 ble_gatt_att_opr_t *att_opr_list;
87 sonata_gatt_att_desc_t *att_desc;
88 } ble_gatt_att_reg_list_t;
89
90 typedef struct ble_gatt_att_manager {
91 uint8_t reg_nb;
92 uint8_t add_nb;
93 ble_gatt_att_reg_list_t *reg_list[MAX_SERVICE_NUM];
94 } ble_gatt_att_manager_t;
95
96 /*!
97 * @brief save local handle start index
98 */
99 // Mark for profile dis
100 uint8_t ble_adv_set_state = APP_BLE_ADV_OFF;
101 uint8_t app_connected_state = APP_STATE_DISCONNECTED;
102 uint8_t target_address[SONATA_GAP_BD_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
103 uint8_t ble_connect_id = 0xFF;
104 uint16_t read_handle = 0xFF;
105 uint16_t write_handle = 0xFF;
106 uint8_t write_uuid[16] = {0xF0, 0x80, 0x0};
107 enum BLE_ADV_STATE ble_adv_state = BLE_ADV_STATE_IDLE;
108 uint8_t read_uuid[16] = {0xF0, 0x80, 0x0};
109 uint8_t current_adv_id = 0;
110
111 bool bFound = false;
112 app_ble_scan_callback_t p_scan_cb = NULL;
113 static bool app_adv_bonding = false;
114 static uint8_t app_connection_state = 0;
115 static peer_conn_param_t app_peer_conn_param = {0};
116
117 static bool app_bond = false;
118 static uint8_t app_loc_irk[KEY_LEN] = {0}; // Get in app_gap_gen_random_number_callback()
119 // static uint8_t app_loc_irk[KEY_LEN]= {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16}; // Get in app_gap_gen_random_number_callback()
120
121 static uint8_t app_rand_cnt = 0;
122 static uint32_t app_passkey_pincode = 0;
123
124 uint8_t app_csrk[SONATA_GAP_KEY_LEN] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0};
125 uint8_t app_irk_addr[SONATA_GAP_BD_ADDR_LEN] = {0};
126 uint8_t app_irk_key[SONATA_GAP_KEY_LEN] = {0};
127
128 uint8_t app_loc_addr[SONATA_GAP_BD_ADDR_LEN] = {0x0C, 0x20, 0x18, 0xA7, 0x9F, 0xDD};
129 bonded_dev_info_list_t bonded_dev_info = {0};
130 uint8_t peer_dbaddr[SONATA_GAP_BD_ADDR_LEN] = {0};
131 uint8_t local_dev_name[APP_BLE_DEVICE_NAME_LEN] = "asr_ble_demo";
132 static connect_req_info_t connect_req_list [APP_BLE_CONNECT_MAX] = { 0 };
133 // static adv_idx_info_t adv_idx_tbl[APP_BLE_ADV_MAX];
134 static enum sonata_gap_io_cap app_iocap = SONATA_GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
135 static enum sonata_gap_auth app_auth = SONATA_GAP_AUTH_REQ_MITM_BOND;
136 static uint8_t app_req_auth = SONATA_GAP_AUTH_REQ_NO_MITM_NO_BOND;
137
138 static ble_gatt_att_manager_t service_reg_env;
139 ble_adv_data_set_t app_ble_adv_data;
140 ble_scan_data_set_t app_ble_scan_data;
141 static uint16_t app_duration = 0;
142 static uint8_t app_max_adv_evt = 0;
143 static app_core_evt_ind_cb app_evt_cb = NULL;
144 static app_sec_req_cb sec_req_call = NULL;
145 uint8_t adv_value[32] = {0x02, 0x01, 0x06, 0x06, 0x09, 0x6d, 0x69, 0x64, 0x64, 0x64, 0x12, 0xFF, 0xA8, 0x06, 0x01 \
146 , 0x31, 0x38, 0x32, 0x37, 0x33, 0x36, 0x34, 0x35, 0x46, 0x43, 0x30, 0x30, 0x30, 0x34
147 };
148 uint16_t adv_length = 29;
149 static struct sonata_gap_ltk app_ltk = { 0 };
150 static uint8_t need_connect_confirm = 0;
151 static app_env gAppEnv;
152
153 /*
154 * TYPE DEFINITIONS
155 ****************************************************************************************
156 */
157 static uint16_t app_ble_set_adv_data(uint8_t adv_id);
158
159 /*
160 * ENUMERATIONS
161 ****************************************************************************************
162 */
163 /*
164 void print_serv_env(void)
165 {
166
167 printf("service_reg_env.reg_nb %d %d\r\n",service_reg_env.reg_nb,service_reg_env.add_nb);
168 for(int i = 0; i < service_reg_env.reg_nb; i++)
169 {
170 printf("list :0x%lx %d\r\n",service_reg_env.reg_list[i],service_reg_env.reg_list[i]->nb_att);
171 }
172 }*/
173 /*!
174 * @brief
175 */
176 typedef enum {
177 // Peripheral Bonded
178 SONATA_TAG_PERIPH_BONDED = (APP_DATA_SAVE_TAG_FIRST + 0),
179 // Mouse NTF Cfg
180 SONATA_TAG_MOUSE_NTF_CFG,
181 // Mouse Timeout value
182 SONATA_TAG_MOUSE_TIMEOUT,
183 // Peer Device BD Address
184 SONATA_TAG_PEER_BD_ADDRESS,
185 // EDIV (2bytes), RAND NB (8bytes), LTK (16 bytes), Key Size (1 byte)
186 SONATA_TAG_LTK,
187 // app_ltk_key_in
188 SONATA_TAG_LTK_IN,
189 // app irk addr
190 SONATA_TAG_IRK_ADDR,
191 // app irk
192 SONATA_TAG_IRK,
193 // device address
194 SONATA_TAG_BD_ADDRESS,
195 // bonded dev info
196 SONATA_TAG_BONDED_DEV_INFO,
197 // start pair on boot
198 SONATA_TAG_PAIR_ON_BOOT,
199 } sonata_app_nvds_tag;
200
201 /*!
202 * @brief
203 */
204 typedef enum {
205 // Peripheral Bonded len
206 SONATA_LEN_PERIPH_BONDED = 1,
207 // Mouse NTF Cfg len
208 SONATA_LEN_MOUSE_NTF_CFG = 2,
209 // Mouse Timeout value len
210 SONATA_LEN_MOUSE_TIMEOUT = 2,
211 // Peer Device BD Address len
212 SONATA_LEN_PEER_BD_ADDRESS = 6,
213 // EDIV (2bytes), RAND NB (8bytes), LTK (16 bytes), Key Size (1 byte)
214 SONATA_LEN_LTK = 27,
215 // app_ltk_key_in len
216 SONATA_LEN_LTK_IN = 16,
217 // app irk addr len
218 SONATA_LEN_IRK_ADDR = 6,
219 // app irk len
220 SONATA_LEN_IRK = 16,
221 // device address
222 SONATA_LEN_BD_ADDRESS = 6,
223 // bonded dev info len
224 SONATA_LEN_BONDED_DEV_INFO = 218, // 218: 3, 290:4,
225 // start pair on boot
226 SONATA_LEN_PAIR_ON_BOOT = 1,
227 } sonata_app_nvds_len;
228
229 /*!
230 * @brief
231 */
232 typedef enum {
233 SONATA_SERVICE_INIT = 0,
234 SONATA_SERVICE_ENABLE,
235 SONATA_SERVICE_DISABLE
236 } sonata_serivice_state;
237
238 /*
239 * EXTERNAL FUNCTION DECLARATION
240 ****************************************************************************************
241 */
242 extern int __wrap_printf(const char *format, ...);
243 static uint8_t app_timer_handler(uint16_t id);
244
245 /*
246 * LOCAL FUNCTION DEFINITIONS
247 ****************************************************************************************
248 */
249
250 static sonata_app_timer_callback_t app_timer_callbacks = {
251 .timeout = app_timer_handler,
252 };
253
app_print_hex(uint8_t * hex,uint8_t len)254 static void app_print_hex(uint8_t *hex, uint8_t len)
255 {
256 for (int i = 0; i < len; i++) {
257 APP_TRC("%x%x", hex[i] >> 4, hex[i] & 0xf);
258 }
259 APP_TRC("\r\n");
260 }
261
app_data_init(void)262 void app_data_init(void)
263 {
264 memset(connect_req_list, 0xff, sizeof(connect_req_list));
265 // memset(adv_idx_tbl,0xff,sizeof(adv_idx_tbl));
266 }
267
app_connect_req_list_add(uint8_t * addr,uint8_t conidx)268 void app_connect_req_list_add(uint8_t *addr, uint8_t conidx)
269 {
270 for (int idx = 0; idx < APP_BLE_CONNECT_MAX; idx++) {
271 if (connect_req_list[idx].conidx == APP_BLE_INVALID_CONIDX) {
272 connect_req_list[idx].conidx = conidx;
273 memmove(connect_req_list[idx].bd_addr, addr, APP_BD_ADDR_LEN);
274 return;
275 }
276 }
277 APP_TRC("APP: %s no space\r\n", __FUNCTION__);
278 }
279
app_connect_req_list_del(uint8_t conidx)280 static void app_connect_req_list_del(uint8_t conidx)
281 {
282 for (int idx = 0; idx < APP_BLE_CONNECT_MAX; idx++) {
283 if (connect_req_list[idx].conidx == conidx) {
284 connect_req_list[idx].conidx = APP_BLE_INVALID_CONIDX;
285 return;
286 }
287 }
288 APP_TRC("APP: %s not found\r\n", __FUNCTION__);
289 }
290
app_get_conidx_by_addr(uint8_t * addr)291 static uint8_t app_get_conidx_by_addr(uint8_t *addr)
292 {
293 for (int idx = 0; idx < APP_BLE_CONNECT_MAX; idx++) {
294 if (!memcmp(connect_req_list[idx].bd_addr, addr, APP_BD_ADDR_LEN)) {
295 return connect_req_list[idx].conidx;
296 }
297 }
298 APP_TRC("APP: %s not found\r\n", __FUNCTION__);
299 return APP_BLE_INVALID_CONIDX;
300 }
301
app_get_addr_by_conidx(uint8_t conidx)302 static uint8_t *app_get_addr_by_conidx(uint8_t conidx)
303 {
304 for (int idx = 0; idx < APP_BLE_CONNECT_MAX; idx++) {
305 if (connect_req_list[idx].conidx == conidx) {
306 return connect_req_list[idx].bd_addr;
307 }
308 }
309 APP_TRC("APP: %s not found\r\n", __FUNCTION__);
310 return NULL;
311 }
312
app_ble_set_device_name(uint8_t * name,uint32_t len)313 void app_ble_set_device_name(uint8_t *name, uint32_t len)
314 {
315 APP_TRC("APP: %s %d\r\n", __FUNCTION__, len);
316 if (APP_BLE_DEVICE_NAME_LEN < len) {
317 return;
318 }
319 memmove(local_dev_name, name, len);
320 }
321
322 /*
323 uint8_t app_adv_idx_list_alloc(void)
324 {
325 for(int idx = 0; idx < APP_BLE_ADV_MAX; idx++)
326 {
327 if(adv_idx_tbl[idx].local_idx == APP_BLE_INVALID_ADVIDX)
328 {
329 adv_idx_tbl[idx].local_idx = idx;
330 return idx;
331 }
332 }
333 APP_TRC("APP: %s no space\r\n", __FUNCTION__);
334 }
335
336 void app_adv_idx_list_free(uint8_t lid)
337 {
338 if(lid < APP_BLE_ADV_MAX)
339 {
340 adv_idx_tbl[lid].local_idx = APP_BLE_INVALID_ADVIDX;
341 }
342 else APP_TRC("APP: %s not found\r\n", __FUNCTION__);
343 }
344
345 void app_adv_idx_list_set_advid(uint8_t lid,uint8_t adv_id)
346 {
347 if(lid < APP_BLE_ADV_MAX)
348 {
349 adv_idx_tbl[lid].adv_id = adv_id;
350 }
351 else APP_TRC("APP: %s not found\r\n", __FUNCTION__);
352 }
353
354 uint8_t app_get_adv_idx_by_lid(uint8_t lid)
355 {
356 for(int idx = 0; idx < APP_BLE_ADV_MAX; idx++)
357 {
358 if(adv_idx_tbl[idx].local_idx == lid)
359 {
360 return adv_idx_tbl[idx].adv_id;
361 }
362 }
363 APP_TRC("APP: %s not found\r\n", __FUNCTION__);
364 return APP_BLE_INVALID_CONIDX;
365 }
366 */
367 /*!
368 * @brief config legacy advertising
369 */
app_ble_config_legacy_advertising(void)370 void app_ble_config_legacy_advertising(void)
371 {
372 APP_TRC("APP: %s \r\n", __FUNCTION__);
373
374 sonata_gap_directed_adv_create_param_t param = {0};
375 param.disc_mode = SONATA_GAP_ADV_MODE_GEN_DISC;
376 param.prop = SONATA_GAP_ADV_PROP_UNDIR_CONN_MASK;
377 // param.max_tx_pwr = 0xE2;
378 param.filter_pol = SONATA_ADV_ALLOW_SCAN_ANY_CON_ANY;
379 // msg->adv_param.adv_param.peer_addr.addr.addr:00
380 param.addr_type = SONATA_GAP_STATIC_ADDR;
381 param.adv_intv_min = BLE_MCRC_MIN_INTERVAL;
382 param.adv_intv_max = BLE_MCRC_MIN_INTERVAL;
383 param.chnl_map = MS_BLE_CHANNEL_NUM;
384 param.phy = SONATA_GAP_PHY_LE_1MBPS;
385 ble_adv_state = BLE_ADV_STATE_CREATING;
386 uint16_t ret = sonata_ble_config_legacy_advertising(SONATA_GAP_STATIC_ADDR,
387 ¶m); // Next event:SONATA_GAP_CMP_ADVERTISING_CONFIG
388 if (ret != API_SUCCESS) {
389 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
390 ble_adv_state = BLE_ADV_STATE_IDLE;
391 }
392 }
393
app_ble_config_legacy_advertising_with_param(uint8_t own_addr_type,sonata_gap_directed_adv_create_param_t * param)394 void app_ble_config_legacy_advertising_with_param(uint8_t own_addr_type, sonata_gap_directed_adv_create_param_t *param)
395 {
396 APP_TRC("APP: %s \r\n", __FUNCTION__);
397
398 ble_adv_state = BLE_ADV_STATE_CREATING;
399 uint16_t ret = sonata_ble_config_legacy_advertising(own_addr_type, param); // Next event:SONATA_GAP_CMP_ADVERTISING_CONFIG
400 if (ret != API_SUCCESS) {
401 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
402 ble_adv_state = BLE_ADV_STATE_IDLE;
403 }
404 }
405
app_ble_start_advertising_with_param(sonata_gap_directed_adv_create_param_t * param,ble_adv_data_set_t * data,ble_scan_data_set_t * scan_data,uint8_t own_addr_type,uint16_t duration,uint8_t max_adv_evt)406 void app_ble_start_advertising_with_param(sonata_gap_directed_adv_create_param_t *param, ble_adv_data_set_t *data,
407 ble_scan_data_set_t *scan_data, uint8_t own_addr_type, uint16_t duration, uint8_t max_adv_evt)
408 {
409 APP_TRC("APP: %s \r\n", __FUNCTION__);
410 app_ble_adv_data.advdataLen = data->advdataLen;
411 memcpy((void *)app_ble_adv_data.advdata, (void *)data->advdata, data->advdataLen);
412 if (scan_data != NULL && scan_data->respdataLen != 0) {
413 app_ble_scan_data.respdataLen = scan_data->respdataLen;
414 memcpy((void *)app_ble_scan_data.respdata, (void *)scan_data->respdata, scan_data->respdataLen);
415 }
416
417 app_duration = duration;
418 app_max_adv_evt = max_adv_evt ;
419
420 ble_adv_set_state = APP_BLE_ADV_ON;
421
422 if ((ble_adv_state != BLE_ADV_STATE_IDLE) &&
423 (ble_adv_state != BLE_ADV_STATE_CREATED) && ble_adv_state != BLE_ADV_STATE_STARTED) {
424 return ;
425 }
426
427 if (ble_adv_state == BLE_ADV_STATE_CREATED) {
428 ble_adv_state = BLE_ADV_STATE_SETTING_ADV_DATA;
429 app_ble_set_adv_data(current_adv_id);
430 } else if (ble_adv_state == BLE_ADV_STATE_STARTED) {
431 app_ble_set_adv_data(current_adv_id);
432 } else {
433 app_ble_config_legacy_advertising_with_param(own_addr_type, param);
434 }
435 return ;
436
437 }
438
439 /*!
440 * @brief set advertising data
441 */
app_ble_set_adv_data(uint8_t adv_id)442 static uint16_t app_ble_set_adv_data(uint8_t adv_id)
443 {
444 APP_TRC("APP: %s \r\n", __FUNCTION__);
445
446 // Call API
447 uint16_t ret;
448
449 if (app_ble_adv_data.advdataLen >= 3) {
450 ret = sonata_ble_set_advertising_data_byid(adv_id, app_ble_adv_data.advdataLen - 3, &app_ble_adv_data.advdata[3]);
451 } else {
452 ret = sonata_ble_set_advertising_data_byid(adv_id, 0, &app_ble_adv_data.advdata[3]);
453 }
454 printf("adv_data:%d\r\n", adv_id);
455 // Next event:SONATA_GAP_CMP_SET_ADV_DATA
456 if (ret != API_SUCCESS) {
457 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
458 }
459 return ret;
460 }
461
app_ble_set_adv_data_default(void)462 void app_ble_set_adv_data_default(void)
463 {
464 APP_TRC("APP: %s \r\n", __FUNCTION__);
465 uint8_t advData[] = { // Advertising data format
466 8, SONATA_GAP_AD_TYPE_COMPLETE_NAME, 'A', 'S', 'R', '-', '0', '0', '0',
467 3, SONATA_GAP_AD_TYPE_COMPLETE_LIST_16_BIT_UUID, 0x12, 0x18,
468 3, SONATA_GAP_AD_TYPE_APPEARANCE, 0xC1, 0x03 // 0x03C1: HID Keyboard
469 };
470 // Call API
471 uint16_t ret = sonata_ble_set_advertising_data(sizeof(advData), advData);
472 // Next event:SONATA_GAP_CMP_SET_ADV_DATA
473 if (ret != API_SUCCESS) {
474 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
475 }
476 }
477
app_ble_set_scansponse_data(uint8_t adv_id)478 static uint16_t app_ble_set_scansponse_data(uint8_t adv_id)
479 {
480 APP_TRC("APP: %s \r\n", __FUNCTION__);
481
482 // Call API
483
484 uint16_t ret = sonata_ble_set_scan_response_data_byid(adv_id, app_ble_scan_data.respdataLen,
485 app_ble_scan_data.respdata);
486 // Next event:SONATA_GAP_CMP_SET_ADV_DATA
487 if (ret != API_SUCCESS) {
488 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
489 ble_adv_state = BLE_ADV_STATE_CREATED;
490 }
491 return ret;
492 }
app_get_adv_status()493 uint8_t app_get_adv_status()
494 {
495 if (ble_adv_state == BLE_ADV_STATE_IDLE || ble_adv_state == BLE_ADV_STATE_STOPPING
496 || ble_adv_state == BLE_ADV_STATE_CREATED) {
497 return 0;
498 }
499 return 1;
500
501 }
502
app_ble_print_info(void)503 static void app_ble_print_info(void)
504 {
505 // Print device info
506 // uint8_t dev_name_saved[APPNV_LEN_LOCAL_DEVICE_NAME] = {0};
507 // app_nv_get_local_device_name(dev_name_saved, true);
508 // printf("\r\n----BLE NAME[%s] ----\r\n", dev_name_saved + 1);
509 uint8_t *addr = sonata_get_bt_address();
510 printf("\r\n----BLE MAC[%02X:%02X:%02X:%02X:%02X:%02X] ----\r\n",
511 addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
512 printf("\r\n");
513
514 }
app_ble_start_advertising(uint8_t adv_id)515 uint16_t app_ble_start_advertising(uint8_t adv_id)
516 {
517 APP_TRC("APP: %s adv %d\r\n", __FUNCTION__, adv_id);
518 // Call api
519
520 uint16_t ret = sonata_ble_start_advertising_byid(adv_id, app_duration, app_duration);
521 // Next event:SONATA_GAP_CMP_ADVERTISING_START
522 if (ret != API_SUCCESS) {
523 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
524 }
525 // app_ble_print_info();
526 ble_adv_set_state = APP_BLE_ADV_ON;
527
528 return ret;
529
530 }
531
app_ble_advertising_stop(uint8_t adv_id)532 uint16_t app_ble_advertising_stop(uint8_t adv_id)
533 {
534 APP_TRC("APP: %s dv state %d \r\n", __FUNCTION__, ble_adv_state);
535 ble_adv_set_state = APP_BLE_ADV_OFF;
536
537 if (ble_adv_state != BLE_ADV_STATE_STARTED) {
538 return API_FAILURE;
539 }
540 // Call api
541 ble_adv_state = BLE_ADV_STATE_STOPPING;
542 uint16_t ret = sonata_ble_stop_advertising_byid(adv_id);
543 // Next event:SONATA_GAP_CMP_ADVERTISING_START
544 if (ret != API_SUCCESS) {
545 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
546 }
547 return ret;
548 }
549
app_ble_stop_adv(uint8_t adv_id)550 uint16_t app_ble_stop_adv(uint8_t adv_id)
551 {
552 APP_TRC("APP: %s dv state %d \r\n", __FUNCTION__, ble_adv_state);
553 ble_adv_set_state = APP_BLE_ADV_OFF;
554
555 if (ble_adv_state != BLE_ADV_STATE_STARTED) {
556 return API_FAILURE;
557 }
558 uint16_t ret = sonata_ble_stop_advertising_byid(adv_id);
559 // Next event:SONATA_GAP_CMP_ADVERTISING_START
560 if (ret != API_SUCCESS) {
561 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
562 }
563 return ret;
564 }
565
app_ble_stop_adv_without_id(void)566 uint16_t app_ble_stop_adv_without_id(void)
567 {
568 return app_ble_stop_adv(current_adv_id);
569 }
570
app_ble_advertising_start(uint8_t * adv_id,ble_adv_data_set_t * data,ble_scan_data_set_t * scan_data)571 int app_ble_advertising_start(uint8_t *adv_id, ble_adv_data_set_t *data, ble_scan_data_set_t *scan_data)
572 {
573
574 APP_TRC("app_ble_advertising_start!!!!!! %d %d %d\r\n", data->advdataLen, scan_data->respdataLen, *adv_id);
575 app_ble_adv_data.advdataLen = data->advdataLen;
576 app_ble_scan_data.respdataLen = scan_data->respdataLen;
577
578 memmove((void *)app_ble_adv_data.advdata, (void *)data->advdata, data->advdataLen);
579 memmove((void *)app_ble_scan_data.respdata, (void *)scan_data->respdata, scan_data->respdataLen);
580
581 ble_adv_set_state = APP_BLE_ADV_ON;
582
583 if ((ble_adv_state != BLE_ADV_STATE_IDLE) &&
584 (ble_adv_state != BLE_ADV_STATE_CREATED) && ble_adv_state != BLE_ADV_STATE_STARTED) {
585 return 0;
586 }
587
588 if (ble_adv_state == BLE_ADV_STATE_CREATED) {
589 ble_adv_state = BLE_ADV_STATE_SETTING_ADV_DATA;
590 app_ble_set_adv_data(current_adv_id);
591 } else if (ble_adv_state == BLE_ADV_STATE_STARTED) {
592 app_ble_set_adv_data(current_adv_id);
593 } else {
594 app_ble_config_legacy_advertising();
595 }
596 return 0;
597
598 }
599
600 /*!
601 * @brief Config scanning
602 */
app_ble_config_scanning(void)603 void app_ble_config_scanning(void)
604 {
605 APP_TRC("APP: %s \r\n", __FUNCTION__);
606 uint16_t ret = sonata_ble_config_scanning(SONATA_GAP_STATIC_ADDR);
607 // Next event:SONATA_GAP_CMP_SCANNING_CONFIG
608 if (ret != API_SUCCESS) {
609 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
610 }
611 }
612
613 /*!
614 * @brief Start scanning
615 */
app_ble_start_scanning(void)616 void app_ble_start_scanning(void)
617 {
618 APP_TRC("APP: %s \r\n", __FUNCTION__);
619 bFound = false;
620 sonata_gap_scan_param_t param = {0};
621 param.type = SONATA_GAP_SCAN_TYPE_OBSERVER;
622 // For continuous scan, use OBSERVER type, use duration to control scan timeer.
623 // if duration=0, will scan for ever until sonata_ble_stop_scanning() called
624 // param.type = SONATA_GAP_SCAN_TYPE_OBSERVER;
625 param.prop = SONATA_GAP_SCAN_PROP_ACTIVE_1M_BIT | SONATA_GAP_SCAN_PROP_PHY_1M_BIT; // 0x05
626 param.dup_filt_pol = SONATA_GAP_DUP_FILT_EN;
627 param.scan_param_1m.scan_intv = 0x0140;
628 param.scan_param_1m.scan_wd = 0x00A0;
629 param.scan_param_coded.scan_intv = 0x0140;
630 param.scan_param_coded.scan_wd = 0x00A0;
631 param.duration = 0;
632 param.period = 0;
633 uint16_t ret = sonata_ble_start_scanning(¶m);
634 // Scan result will show in app_gap_scan_result_callback()
635 if (ret != API_SUCCESS) {
636 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
637 }
638
639 }
640
app_ble_stop_scanning(void)641 void app_ble_stop_scanning(void)
642 {
643 sonata_ble_stop_scanning();
644 }
645
646 /*!
647 * @brief config initiating
648 */
app_ble_config_initiating(void)649 void app_ble_config_initiating(void)
650 {
651 APP_TRC("APP: %s \r\n", __FUNCTION__);
652 // Call api to config init
653 uint16_t ret = sonata_ble_config_initiating(SONATA_GAP_STATIC_ADDR);
654 // Next event:SONATA_GAP_CMP_INITIATING_CONFIG
655 if (ret != API_SUCCESS) {
656 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
657 }
658 }
659
660 /*!
661 * @brief Check MAC address
662 * @param address
663 * @return
664 */
app_ble_check_address(uint8_t * address)665 static bool app_ble_check_address(uint8_t *address)
666 {
667 uint8_t error_address[SONATA_GAP_BD_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
668 if (address == NULL) {
669 return false;
670 }
671 if (memcmp(address, error_address, SONATA_GAP_BD_ADDR_LEN) == 0) {
672 return false;
673 }
674 return true;
675 }
676
677 /*!
678 * @brief Start initiating
679 */
app_ble_start_initiating(uint8_t * target)680 void app_ble_start_initiating(uint8_t *target)
681 {
682 APP_TRC("APP: %s \r\n", __FUNCTION__);
683 if (app_ble_check_address(target) == false) {
684 APP_TRC("APP: %s, Target address is not right. Stop\r\n", __FUNCTION__);
685 return;
686 }
687 sonata_gap_init_param_t param = {0};
688 param.type = SONATA_GAP_INIT_TYPE_DIRECT_CONN_EST;
689 param.prop = SONATA_GAP_INIT_PROP_1M_BIT | SONATA_GAP_INIT_PROP_2M_BIT | SONATA_GAP_INIT_PROP_CODED_BIT;
690 param.conn_to = 0;
691 param.peer_addr.addr_type = SONATA_GAP_STATIC_ADDR; // Addr
692 memcpy(param.peer_addr.addr.addr, target, SONATA_GAP_BD_ADDR_LEN);
693
694 if (param.prop & SONATA_GAP_INIT_PROP_1M_BIT) {
695 APP_TRC("APP: %s (%02X)set SONATA_GAP_INIT_PROP_1M_BIT \r\n", __FUNCTION__, param.prop);
696 param.scan_param_1m.scan_intv = 0x0200;
697 param.scan_param_1m.scan_wd = 0x0100;
698 param.conn_param_1m.conn_intv_min = 0x0028;
699 param.conn_param_1m.conn_intv_max = 0x0028;
700 param.conn_param_1m.conn_latency = 0;
701 param.conn_param_1m.supervision_to = 0x02BC;
702 param.conn_param_1m.ce_len_min = 0x0003;
703 param.conn_param_1m.ce_len_max = 0x0003;
704 }
705 if (param.prop & SONATA_GAP_INIT_PROP_2M_BIT) {
706 APP_TRC("APP: %s (%02X)set SONATA_GAP_INIT_PROP_2M_BIT \r\n", __FUNCTION__, param.prop);
707
708 param.conn_param_2m.conn_intv_min = 0x0028;
709 param.conn_param_2m.conn_intv_max = 0x0028;
710 param.conn_param_2m.conn_latency = 0;
711 param.conn_param_2m.supervision_to = 0x02BC;
712 param.conn_param_2m.ce_len_min = 0x0003;
713 param.conn_param_2m.ce_len_max = 0x0003;
714 }
715 if (param.prop & SONATA_GAP_INIT_PROP_CODED_BIT) {
716 APP_TRC("APP: %s (%02X)set SONATA_GAP_INIT_PROP_CODED_BIT \r\n", __FUNCTION__, param.prop);
717 param.scan_param_coded.scan_intv = 0x0200;
718 param.scan_param_coded.scan_wd = 0x0100;
719 param.conn_param_coded.conn_intv_min = 0x0028;
720 param.conn_param_coded.conn_intv_max = 0x0028;
721 param.conn_param_coded.conn_latency = 0;
722 param.conn_param_coded.supervision_to = 0x02BC;
723 param.conn_param_coded.ce_len_min = 0003;
724 param.conn_param_coded.ce_len_max = 0003;
725 }
726
727 uint16_t ret = sonata_ble_start_initiating(¶m);
728 // Next event:If connected, SONATA_GAP_CMP_INITIATING_DELETE event will be received
729 if (ret != API_SUCCESS) {
730 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
731 }
732 }
733
734 /*!
735 * @brief
736 * @return
737 */
app_ble_stop_initiating(void)738 void app_ble_stop_initiating(void)
739 {
740 sonata_ble_stop_initiating();
741 }
742
app_ble_disconnect(uint8_t conidx)743 void app_ble_disconnect(uint8_t conidx)
744 {
745 app_connect_req_list_del(conidx);
746 sonata_ble_gap_disconnect(conidx, 0);
747 ble_connect_id = 0xFF;
748 }
749
app_get_connect_status(void)750 uint8_t app_get_connect_status(void)
751 {
752 if (app_connected_state == APP_STATE_CONNECTED) {
753 return 1;
754 }
755 return 0;
756 }
757
app_print_adv_status(void)758 void app_print_adv_status(void)
759 {
760 printf("adv_ble_state %d set state %d \r\n", ble_adv_state, ble_adv_set_state) ;
761 for (int i = 0; i < sizeof(write_uuid); i++) {
762 printf("%x", write_uuid[i]);
763 }
764 printf("uuid\r\n");
765 for (int i = 0; i < sizeof(write_uuid); i++) {
766 printf("%x", read_uuid[i]);
767 }
768 }
769
770 /*!
771 * @brief
772 */
app_ble_on(void)773 static void app_ble_on(void)
774 {
775 APP_TRC("APP: %s \r\n", __FUNCTION__);
776 sonata_gap_set_dev_config_cmd cmd = {0};
777 cmd.role = SONATA_GAP_ROLE_ALL;
778 cmd.gap_start_hdl = 0;
779 cmd.gatt_start_hdl = 0;
780 cmd.renew_dur = 0x0096;
781 cmd.privacy_cfg = 0;
782 cmd.pairing_mode = SONATA_GAP_PAIRING_SEC_CON | SONATA_GAP_PAIRING_LEGACY;
783 cmd.att_cfg = 0x0080;
784 cmd.max_mtu = 512;
785 cmd.max_mps = 0x02A0;
786 cmd.max_nb_lecb = 0x0A;
787 cmd.hl_trans_dbg = false;
788
789 // Get bond status from FS
790 uint8_t length = SONATA_LEN_PERIPH_BONDED;
791 if (sonata_fs_read(SONATA_TAG_PERIPH_BONDED, &length, &app_bond) != SONATA_FS_OK) {
792 // If read value is invalid, set status to not bonded
793 app_bond = 0;
794 }
795 if (app_bond == 1) {
796 memcpy(cmd.irk.key, app_loc_irk, sizeof(cmd.irk.key));
797 }
798 length = SONATA_LEN_BONDED_DEV_INFO;
799 if (sonata_fs_read(SONATA_TAG_BONDED_DEV_INFO, &length, (uint8_t *)&bonded_dev_info) != SONATA_FS_OK) {
800 APP_TRC("APP: %s not bonded device info \r\n", __FUNCTION__);
801 }
802
803 uint16_t ret = sonata_ble_on(&cmd); // Next event:SONATA_GAP_CMP_BLE_ON
804 if (ret != API_SUCCESS) {
805 APP_TRC("APP: %s ERROR:%02X\r\n", __FUNCTION__, ret);
806 }
807 }
808
809 extern void ble_reset_cmp(void);
810 /*
811 * LOCAL FUNCTION DEFINITIONS Callback functions
812 ****************************************************************************************
813 */
test_adv_h(void)814 static void test_adv_h(void)
815 {
816 sonata_gap_directed_adv_create_param_t param = {0};
817 param.disc_mode = SONATA_GAP_ADV_MODE_GEN_DISC;
818 param.prop = SONATA_GAP_ADV_PROP_UNDIR_CONN_MASK;
819 // param.max_tx_pwr = 0xE2;
820 param.filter_pol = SONATA_ADV_ALLOW_SCAN_ANY_CON_ANY;
821 // msg->adv_param.adv_param.peer_addr.addr.addr:00
822 param.addr_type = SONATA_GAP_STATIC_ADDR;
823 param.adv_intv_min = BLE_MCRC_MIN_INTERVAL;
824 param.adv_intv_max = BLE_MCRC_MIN_INTERVAL;
825 param.chnl_map = MS_BLE_CHANNEL_NUM;
826 param.phy = SONATA_GAP_PHY_LE_1MBPS;
827 ble_adv_data_set_t data_Set;
828 memmove(data_Set.advdata, adv_value, adv_length);
829 data_Set.advdataLen = adv_length;
830
831 app_ble_start_advertising_with_param(¶m, &data_Set, NULL, SONATA_GAP_STATIC_ADDR, 0, 0);
832 }
833 /*!
834 * @brief BLE complete event handler
835 * @param opt_id @see sonata_ble_complete_type
836 * @param status complete status
837 * @param param param and deparam will be difference according to difference complete event.
838 * @param dwparam param and deparam will be difference according to difference complete event.
839 * @return
840 */
app_ble_complete_event_handler(sonata_ble_complete_type opt_id,uint8_t status,uint16_t param,uint32_t dwparam)841 static uint16_t app_ble_complete_event_handler(sonata_ble_complete_type opt_id, uint8_t status, uint16_t param,
842 uint32_t dwparam)
843 {
844 APP_TRC("APP_COMPLETE: %s opt_id=%04X,status=%02X,param=%04X,dwparam=%lu\r\n", __FUNCTION__, opt_id, status, param,
845 dwparam);
846 uint16_t cb_result = CB_DONE;
847 switch (opt_id) {
848 case SONATA_GAP_CMP_BLE_ON: // 0x0F01
849 // ble_adv_set_state = APP_BLE_ADV_ON;
850 // test_adv_h();
851 if (ble_cb_fun != NULL) {
852 ble_cb_fun(MS_BLE_STACK_EVENT_STACK_READY);
853 }
854 break;
855 case SONATA_GAP_CMP_ADVERTISING_CONFIG: // 0x0F02
856 current_adv_id = param;
857 if (ble_adv_set_state == APP_BLE_ADV_ON) {
858 ble_adv_state = BLE_ADV_STATE_SETTING_ADV_DATA;
859 if (API_SUCCESS != app_ble_set_adv_data(current_adv_id)) {
860 ble_adv_state = BLE_ADV_STATE_CREATED;
861 }
862 } else {
863 ble_adv_state = BLE_ADV_STATE_CREATED;
864 if (ble_cb_fun != NULL) {
865 ble_cb_fun(MS_BLE_STACK_EVENT_ADV_OFF);
866 }
867 app_ble_set_adv_data_default();
868 }
869 break;
870 case SONATA_GAP_CMP_SET_ADV_DATA: // 0x01A9
871 if (ble_adv_set_state == APP_BLE_ADV_ON) {
872 if (API_SUCCESS == app_ble_set_scansponse_data(current_adv_id)) {
873 if (ble_adv_state == BLE_ADV_STATE_SETTING_ADV_DATA) {
874 ble_adv_state = BLE_ADV_STATE_SETTING_SCAN_RSP_DATA;
875 }
876 } else {
877
878 }
879 app_ble_start_advertising(0);
880
881 } else {
882 if (ble_adv_state == BLE_ADV_STATE_STARTED) {
883 if (API_SUCCESS == app_ble_stop_adv(current_adv_id)) {
884 ble_adv_state = BLE_ADV_STATE_STOPPING;
885 }
886 } else {
887 ble_adv_state = BLE_ADV_STATE_CREATED;
888 if (ble_cb_fun != NULL) {
889 ble_cb_fun(MS_BLE_STACK_EVENT_ADV_OFF);
890 }
891 }
892 app_ble_start_advertising(0);
893
894 }
895 break;
896 case SONATA_GAP_CMP_SET_SCAN_RSP_DATA:
897 if (ble_adv_set_state == APP_BLE_ADV_ON) {
898 if (ble_adv_state == BLE_ADV_STATE_SETTING_SCAN_RSP_DATA) {
899 if (API_SUCCESS == app_ble_start_advertising(current_adv_id)) {
900 ble_adv_state = BLE_ADV_STATE_STARTING;
901 } else {
902 ble_adv_state = BLE_ADV_STATE_CREATED;
903 }
904 } else {
905 // adv is on ,only update data
906 }
907 } else {
908
909 if (ble_adv_state == BLE_ADV_STATE_STARTED) {
910 if (API_SUCCESS == app_ble_stop_adv(current_adv_id)) {
911 ble_adv_state = BLE_ADV_STATE_STOPPING;
912 }
913 } else {
914 ble_adv_state = BLE_ADV_STATE_CREATED;
915 if (ble_cb_fun != NULL) {
916 ble_cb_fun(MS_BLE_STACK_EVENT_ADV_OFF);
917 }
918 }
919 }
920 break;
921 case SONATA_GAP_CMP_ADVERTISING_START: // 0x0F06
922
923 APP_TRC("ble_adv_state: %d set state %d\r\n", ble_adv_state, ble_adv_set_state);
924 ble_adv_state = BLE_ADV_STATE_STARTED;
925 if (ble_adv_set_state == APP_BLE_ADV_ON) {
926 if (ble_cb_fun != NULL) {
927 APP_TRC("ble_cb_fun\r\n");
928 ble_cb_fun(MS_BLE_STACK_EVENT_ADV_ON);
929
930 }
931 if (app_evt_cb != NULL) {
932 app_adv_status_ind_t status_ind;
933 status_ind.advId = param;
934 status_ind.status = status;
935 app_evt_cb(BLE_ADV_START, (void *)&status_ind);
936 }
937 } else {
938 if (API_SUCCESS == app_ble_stop_adv(current_adv_id)) {
939 ble_adv_state = BLE_ADV_STATE_STOPPING;
940 }
941 }
942 break;
943 case SONATA_GAP_CMP_ADVERTISING_STOP:
944 ble_adv_state = BLE_ADV_STATE_CREATED;
945 if (ble_adv_set_state == APP_BLE_ADV_OFF) {
946 if (ble_cb_fun != NULL) {
947 ble_cb_fun(MS_BLE_STACK_EVENT_ADV_OFF);
948 }
949 } else {
950 if (API_SUCCESS == app_ble_start_advertising(current_adv_id)) {
951 ble_adv_state = BLE_ADV_STATE_STARTING;
952 }
953 }
954 break;
955 case SONATA_GAP_CMP_ADVERTISING_DELETE:
956 APP_TRC("SONATA_GAP_CMP_ADVERTISING_DELETE %d!!!! \r\n", param);
957 ble_adv_state = BLE_ADV_STATE_IDLE;
958 break;
959 case SONATA_GAP_CMP_SCANNING_CONFIG: // 0x0F03
960 app_ble_start_scanning();
961 break;
962 case SONATA_GAP_CMP_SCANNING_START: // 0x0F07
963 APP_TRC("ACP: %s SONATA_GAP_CMP_SCANNING_START \r\n", __FUNCTION__);
964 // app_add_profiles();
965 break;
966 case SONATA_GAP_CMP_PROFILE_TASK_ADD: // 0x011B
967 break;
968 case SONATA_GAP_CMP_SCANNING_STOP: // 0x0F08
969 cb_result = CB_REJECT; // delete scan instance
970 break;
971 case SONATA_GAP_CMP_SCANNING_DELETE: // 0x0F0F
972 break;
973 case SONATA_GAP_CMP_INITIATING_CONFIG: // 0x0F04
974 app_ble_start_initiating(target_address);
975 break;
976 case SONATA_GAP_CMP_INITIATING_STOP:
977 cb_result = CB_REJECT; // delete scan instance
978 break;
979 case SONATA_GAP_CMP_INITIATING_DELETE: // 0x0F10
980 if (gAppEnv.appUuids.service != 0) {
981 sonata_ble_gatt_disc_all_characteristic(ble_connect_id, 1, 0XFFFF);
982 }
983 // sonata_ble_gatt_disc_all_descriptor(ble_connect_id, 1, 0XFFFF);
984 break;
985 case SONATA_GATT_CMP_NOTIFY:
986 APP_TRC("APP_COMPLETE: %s SONATA_GATT_CMP_NOTIFY, seq:%d \r\n", __FUNCTION__, (uint16_t)dwparam);
987 break;
988 case SONATA_GATT_CMP_DISC_ALL_SVC: // 0x0402
989 // sonata_ble_gatt_read_by_handle(param, demo_handle_id);
990 break;
991 case SONATA_GATT_CMP_READ: // 0x0408
992 break;
993 case SONATA_GAP_CMP_SECURITY_REQ:
994 APP_TRC("APP_COMPLETE: %s SONATA_GAP_CMP_SECURITY_REQ, seq:%d \r\n", __FUNCTION__, (uint16_t) dwparam);
995 break;
996 case SONATA_GAP_CMP_GEN_RAND_NB:
997 APP_TRC("APP_COMPLETE: %s SONATA_GAP_CMP_GEN_RAND_NB, \r\n", __FUNCTION__);
998 if (app_rand_cnt == 1) {
999 // Generate a second random number
1000 app_rand_cnt++;
1001 sonata_ble_gap_generate_random_number();
1002
1003 } else {
1004 app_rand_cnt = 0;
1005 sonata_ble_gap_set_irk(app_loc_irk);
1006
1007 }
1008 break;
1009 case SONATA_GAP_CMP_SET_IRK:
1010 APP_TRC("APP_COMPLETE: %s SONATA_GAP_CMP_SET_IRK, \r\n", __FUNCTION__);
1011 app_rand_cnt = 0;
1012 break;
1013 case SONATA_GATT_CMP_INDICATE:
1014 APP_TRC("APP_COMPLETE: %s SONATA_GATT_CMP_INDICATE %d, \r\n", __FUNCTION__, status);
1015 if (app_evt_cb != NULL) {
1016 app_ind_sent_ind_t status_ind;
1017 status_ind.connId = param;
1018 status_ind.status = status;
1019 app_evt_cb(BLE_IND_SENT, (void *)&status_ind);
1020 }
1021 break;
1022 case SONATA_GAP_CMP_RESET:
1023 // APP_TRC("APP_COMPLETE: %s SONATA_GAP_CMP_RESET, seq:%d \r\n",__FUNCTION__,(uint16_t)dwparam);
1024 ble_reset_cmp();
1025 break;
1026 default:
1027 break;
1028 }
1029 APP_TRC("ble_adv_state3: %d set state %d\r\n", ble_adv_state, ble_adv_set_state);
1030 return cb_result;
1031 }
1032
app_ble_gatt_add_srv_rsp_hand(uint16_t handle)1033 static void app_ble_gatt_add_srv_rsp_hand(uint16_t handle)
1034 {
1035 APP_TRC("app_ble_gatt_add_srv_rsp_hand\r\n");
1036 uint8_t reg_nb = service_reg_env.reg_nb;
1037 service_reg_env.reg_list[service_reg_env.reg_nb]->state = SONATA_SERVICE_ENABLE;
1038 service_reg_env.reg_list[service_reg_env.reg_nb]->start_hdl = handle;
1039 service_reg_env.reg_nb++;
1040 // print_serv_env();
1041 if (service_reg_env.add_nb != service_reg_env.reg_nb) {
1042 APP_TRC("add new service\r\n");
1043 uint8_t perm = service_reg_env.reg_list[service_reg_env.reg_nb]->perm;
1044 uint8_t *uuid = service_reg_env.reg_list[service_reg_env.reg_nb]->uuid;
1045 uint8_t nb_att = service_reg_env.reg_list[service_reg_env.reg_nb]->nb_att;
1046 sonata_gatt_att_desc_t *atts = service_reg_env.reg_list[service_reg_env.reg_nb]->att_desc;
1047 sonata_ble_gatt_add_service_request(service_reg_env.reg_list[service_reg_env.reg_nb]->start_hdl, perm, uuid, nb_att,
1048 &atts[1]);
1049 }
1050
1051 if (app_evt_cb != NULL) {
1052 app_reg_service_cmp_t status_ind;
1053 status_ind.len = SONATA_PERM_GET(service_reg_env.reg_list[reg_nb]->perm, SVC_UUID_LEN);
1054 memmove(status_ind.uuid, service_reg_env.reg_list[reg_nb]->uuid, SONATA_ATT_UUID_128_LEN);
1055 status_ind.status = 0;
1056 status_ind.handler = service_reg_env.reg_nb << 16;
1057 app_evt_cb(BLE_SERVICE_ADD_CMP, (void *)&status_ind);
1058 }
1059 }
1060
app_ble_rsp_event_handler(uint16_t opt_id,uint8_t status,uint16_t handle,uint16_t perm,uint16_t ext_perm,uint16_t length,void * param)1061 static uint16_t app_ble_rsp_event_handler(uint16_t opt_id, uint8_t status, uint16_t handle, uint16_t perm,
1062 uint16_t ext_perm, uint16_t length, void *param)
1063 {
1064 APP_TRC("APP_RESPONSE: %s opt_id=%04X, %d %d %d \r\n", __FUNCTION__, opt_id, perm, ext_perm, length);
1065 if (status != 0) {
1066 APP_TRC("APP_RESPONSE: %s ERROR=%04X,%x\r\n", __FUNCTION__, status, param);
1067 }
1068 switch (opt_id) {
1069 case SONATA_GATT_ADD_SVC_RSP: {
1070 APP_TRC("APP_RESPONSE: %s handle=%04X,\r\n", __FUNCTION__, handle);
1071 // Should save the start handle id for future use
1072 app_ble_gatt_add_srv_rsp_hand(handle);
1073 break;
1074 }
1075 default:
1076 break;
1077 }
1078
1079 return CB_DONE;
1080 }
1081
1082 /*!
1083 * @brief get devcie informations
1084 * @param info_type @see sonata_gap_local_dev_info
1085 * @param info
1086 */
app_get_dev_info_callback(sonata_gap_local_dev_info info_type,void * info)1087 static uint16_t app_get_dev_info_callback(sonata_gap_local_dev_info info_type, void *info)
1088 {
1089 switch (info_type) {
1090 case SONATA_GET_DEV_VERSION: {
1091 #if APP_DBG
1092 sonata_gap_dev_version_ind_t *dev_info = (sonata_gap_dev_version_ind_t *) info;
1093 APP_TRC("APP_CB: %s, hci_ver =0x%02X\r\n", __FUNCTION__, dev_info->hci_ver);
1094 APP_TRC("APP_CB: %s, lmp_ver =0x%02X\r\n", __FUNCTION__, dev_info->lmp_ver);
1095 APP_TRC("APP_CB: %s, host_ver =0x%02X\r\n", __FUNCTION__, dev_info->host_ver);
1096 APP_TRC("APP_CB: %s, hci_subver =0x%04X\r\n", __FUNCTION__, dev_info->hci_subver);
1097 APP_TRC("APP_CB: %s, lmp_subver =0x%04X\r\n", __FUNCTION__, dev_info->lmp_subver);
1098 APP_TRC("APP_CB: %s, host_subver =0x%04X\r\n", __FUNCTION__, dev_info->host_subver);
1099 APP_TRC("APP_CB: %s, manuf_name =0x%04X\r\n", __FUNCTION__, dev_info->manuf_name);
1100 #endif // SONATA_API_TASK_DBG
1101 }
1102 break;
1103 case SONATA_GET_DEV_BDADDR: {
1104 #if APP_DBG
1105 sonata_gap_dev_bdaddr_ind_t *param = (sonata_gap_dev_bdaddr_ind_t *) info;
1106 APP_TRC("APP_CB: %s, SONATA_GET_DEV_BDADDR:", __FUNCTION__);
1107 for (int i = 0; i < SONATA_GAP_BD_ADDR_LEN; ++i) {
1108 APP_TRC("%02X ", param->addr.addr.addr[i]);
1109 }
1110 APP_TRC("\r\n");
1111 #endif // SONATA_API_TASK_DBG
1112 }
1113 break;
1114
1115 case SONATA_GET_DEV_ADV_TX_POWER: {
1116 #if APP_DBG
1117 sonata_gap_dev_adv_tx_power_ind_t *param = (sonata_gap_dev_adv_tx_power_ind_t *) info;
1118 APP_TRC("APP_CB: %s, SONATA_GET_DEV_ADV_TX_POWER power_lvl =0x%02X\r\n", __FUNCTION__, param->power_lvl);
1119 #endif // SONATA_API_TASK_DBG
1120 }
1121 break;
1122 case SONATA_GET_WLIST_SIZE: {
1123 #if APP_DBG
1124 sonata_gap_list_size_ind_t *param = (sonata_gap_list_size_ind_t *) info;
1125 APP_TRC("APP_CB: %s, SONATA_GET_WLIST_SIZE size =0x%02X\r\n", __FUNCTION__, param->size);
1126 #endif // SONATA_API_TASK_DBG
1127
1128 break;
1129 }
1130 case SONATA_GET_ANTENNA_INFO: {
1131 #if APP_DBG
1132 sonata_gap_antenna_inf_ind_t *param = (sonata_gap_antenna_inf_ind_t *) info;
1133 APP_TRC(">>> SONATA_GET_ANTENNA_INFO supp_switching_sampl_rates =0x%02X, antennae_num =0x%02X, max_switching_pattern_len =0x%02X, max_cte_len =0x%02X\r\n",
1134 param->supp_switching_sampl_rates, param->antennae_num, param->max_switching_pattern_len, param->max_cte_len);
1135 #endif // SONATA_API_TASK_DBG
1136 }
1137 break;
1138
1139 case SONATA_GET_SUGGESTED_DFLT_LE_DATA_LEN: {
1140 #if APP_DBG
1141 sonata_gap_sugg_dflt_data_len_ind_t *param = (sonata_gap_sugg_dflt_data_len_ind_t *) info;
1142 APP_TRC(">>> SONATA_GET_SUGGESTED_DFLT_LE_DATA_LEN suggted_max_tx_octets =0x%02X, suggted_max_tx_time =0x%02X\r\n",
1143 param->suggted_max_tx_octets, param->suggted_max_tx_time);
1144 #endif // SONATA_API_TASK_DBG
1145 break;
1146 }
1147 case SONATA_GET_MAX_LE_DATA_LEN: {
1148 #if APP_DBG
1149 sonata_gap_max_data_len_ind_t *param = (sonata_gap_max_data_len_ind_t *) info;
1150 APP_TRC(">>> SONATA_GET_MAX_LE_DATA_LEN suppted_max_tx_octets =0x%04X, suppted_max_tx_time =0x%04X, suppted_max_rx_octets =0x%04X, suppted_max_rx_time =0x%04X\r\n",
1151 param->suppted_max_tx_octets, param->suppted_max_tx_time, param->suppted_max_rx_octets, param->suppted_max_rx_time);
1152 #endif // SONATA_API_TASK_DBG
1153 break;
1154 }
1155 case SONATA_GET_PAL_SIZE: {
1156 #if APP_DBG
1157 sonata_gap_list_size_ind_t *param = (sonata_gap_list_size_ind_t *) info;
1158 APP_TRC("APP_CB: %s, SONATA_GET_PAL_SIZE size =0x%02X\r\n", __FUNCTION__, param->size);
1159 #endif // SONATA_API_TASK_DBG
1160 break;
1161 }
1162 case SONATA_GET_RAL_SIZE: {
1163 #if APP_DBG
1164 sonata_gap_list_size_ind_t *param = (sonata_gap_list_size_ind_t *) info;
1165 APP_TRC("APP_CB: %s, SONATA_GET_RAL_SIZE size =0x%02X\r\n", __FUNCTION__, param->size);
1166 #endif // SONATA_API_TASK_DBG
1167 break;
1168 }
1169 case SONATA_GET_NB_ADV_SETS: {
1170 #if APP_DBG
1171 sonata_gap_nb_adv_sets_ind_t *param = (sonata_gap_nb_adv_sets_ind_t *) info;
1172 APP_TRC("APP_CB: %s, SONATA_GET_NB_ADV_SETS nb_adv_sets =0x%02X\r\n", __FUNCTION__, param->nb_adv_sets);
1173 #endif // SONATA_API_TASK_DBG
1174
1175 break;
1176 }
1177 case SONATA_GET_MAX_LE_ADV_DATA_LEN: {
1178 #if APP_DBG
1179 sonata_gap_max_adv_data_len_ind_t *param = (sonata_gap_max_adv_data_len_ind_t *) info;
1180 APP_TRC(">>> SONATA_GET_MAX_LE_ADV_DATA_LEN param->length=0x%02X\r\n", param->length);
1181 #endif // SONATA_API_TASK_DBG
1182 break;
1183 }
1184 case SONATA_GET_DEV_TX_PWR: {
1185 #if APP_DBG
1186 sonata_gap_dev_tx_pwr_ind_t *param = (sonata_gap_dev_tx_pwr_ind_t *) info;
1187 APP_TRC(">>> SONATA_GET_DEV_TX_PWR min_tx_pwr =0x%04X, max_tx_pwr =0x%04X\r\n",
1188 param->min_tx_pwr, param->max_tx_pwr);
1189 #endif // SONATA_API_TASK_DBG
1190 break;
1191 }
1192 case SONATA_GET_DEV_RF_PATH_COMP: {
1193 #if APP_DBG
1194 sonata_gap_dev_rf_path_comp_ind_t *param = (sonata_gap_dev_rf_path_comp_ind_t *) info;
1195 APP_TRC(">>> SONATA_GET_DEV_RF_PATH_COMP tx_path_comp =0x%04X, rx_path_comp =0x%04X\r\n",
1196 param->tx_path_comp, param->rx_path_comp);
1197 #endif // SONATA_API_TASK_DBG
1198 break;
1199 }
1200 default:
1201 APP_TRC("APP_CB: %s No progress for info_type=%02X\r\n", __FUNCTION__, info_type);
1202 break;
1203
1204 }
1205 return CB_DONE;
1206 }
1207
1208 /*!
1209 * @brief Deal with peer device get local information request.
1210 * @param opt @see asr_gap_dev_info
1211 */
app_gap_peer_get_local_info_callback(uint8_t conidx,sonata_gap_dev_info opt)1212 static uint16_t app_gap_peer_get_local_info_callback(uint8_t conidx, sonata_gap_dev_info opt)
1213 {
1214 APP_TRC("APP_CB: %s conidx=%02X\r\n", __FUNCTION__, conidx);
1215 switch (opt) {
1216 case SONATA_GAP_DEV_NAME: {
1217 sonata_ble_gap_send_get_dev_info_cfm_for_dev_name(conidx, sizeof(local_dev_name), local_dev_name);
1218 }
1219 break;
1220
1221 case SONATA_GAP_DEV_APPEARANCE: {
1222 uint16_t appearance = 0;
1223 sonata_ble_gap_send_get_dev_info_cfm_for_dev_appearance(conidx, appearance);
1224
1225 }
1226 break;
1227
1228 case SONATA_GAP_DEV_SLV_PREF_PARAMS: {
1229 sonata_ble_gap_send_get_dev_info_cfm_for_slv_pref_params(conidx, 8, 10, 0, 200);
1230
1231 }
1232 break;
1233
1234 default:
1235 break;
1236 }
1237
1238 return CB_DONE;
1239 }
1240
app_gap_set_scan_cb(app_ble_scan_callback_t cb)1241 void app_gap_set_scan_cb(app_ble_scan_callback_t cb)
1242 {
1243 p_scan_cb = cb;
1244 }
1245
1246 /*!
1247 * @brief GAP scan result callback
1248 * @param result
1249 */
app_gap_scan_result_callback(sonata_gap_ext_adv_report_ind_t * result)1250 static uint16_t app_gap_scan_result_callback(sonata_gap_ext_adv_report_ind_t *result)
1251 {
1252 if (p_scan_cb != NULL) {
1253
1254 for (int i = 0; i < result->length; ++i) {
1255 APP_TRC("%02X ", result->data[i]);
1256 }
1257 p_scan_cb(result->data, result->length);
1258 return CB_DONE;
1259 }
1260 APP_TRC("APP_CB: %s ", __FUNCTION__);
1261 APP_TRC("target_addr:");
1262 for (int i = 0; i < SONATA_GAP_BD_ADDR_LEN; ++i) {
1263 APP_TRC("%02X ", result->target_addr.addr.addr[i]);
1264 }
1265 APP_TRC(" trans_addr:");
1266 for (int i = 0; i < SONATA_GAP_BD_ADDR_LEN; ++i) {
1267 APP_TRC("%02X ", result->trans_addr.addr.addr[i]);
1268 }
1269 APP_TRC(" \r\n");
1270 return CB_DONE;
1271 }
app_active_delete(uint8_t conIdx)1272 void app_active_delete(uint8_t conIdx)
1273 {
1274 if (conIdx > APP_ACTIVE_MAX) {
1275 APP_TRC("APP: %s,ERROR:ACTIVE overflow\r\n", __FUNCTION__);
1276 return;
1277 }
1278 gAppEnv.act[conIdx].runing = false;
1279
1280 }
1281
1282 /*!
1283 * @brief
1284 * @param conidx
1285 * @param conhdl
1286 * @param reason
1287 * @return
1288 */
app_gap_disconnect_ind_callback(uint8_t conidx,uint16_t conhdl,uint8_t reason)1289 static uint16_t app_gap_disconnect_ind_callback(uint8_t conidx, uint16_t conhdl, uint8_t reason)
1290 {
1291 APP_TRC("APP_CB: %s conidx=0x%02X %d reason = %02x\r\n", __FUNCTION__, conidx, conhdl, reason);
1292 app_connected_state = APP_STATE_DISCONNECTED;
1293 if (ble_cb_fun != NULL) {
1294 ble_cb_fun(MS_BLE_STACK_EVENT_DISCONNECT);
1295 }
1296 if (app_evt_cb != NULL) {
1297 app_connect_status_ind_t status_ind;
1298 status_ind.connId = conidx;
1299 uint8_t *bd_addr = app_get_addr_by_conidx(conidx);
1300 if (NULL != bd_addr) {
1301 memmove(status_ind.addr, bd_addr, SONATA_GAP_BD_ADDR_LEN);
1302 }
1303 app_evt_cb(BLE_DEV_DISCONNECTED, (void *)&status_ind);
1304 }
1305 app_connect_req_list_del(conidx);
1306 app_active_delete(conidx);
1307 // test_adv_h();
1308 return CB_DONE;
1309 }
1310
app_ble_gatt_add_srv_rsp(uint16_t handle)1311 void app_ble_gatt_add_srv_rsp(uint16_t handle)
1312 {
1313 APP_TRC("app_ble_gatt_add_srv_rsp\r\n");
1314 APP_TRC("nb_att %d\r\n", service_reg_env.reg_list[service_reg_env.reg_nb]->nb_att);
1315
1316 service_reg_env.reg_list[service_reg_env.reg_nb]->state = SONATA_SERVICE_ENABLE;
1317 service_reg_env.reg_list[service_reg_env.reg_nb]->start_hdl = handle;
1318 if
1319 (NULL != service_reg_env.reg_list[service_reg_env.reg_nb]->att_desc) {
1320 sonata_api_free(service_reg_env.reg_list[service_reg_env.reg_nb]->att_desc);
1321 }
1322 service_reg_env.reg_nb++;
1323 if (service_reg_env.add_nb != service_reg_env.reg_nb) {
1324 APP_TRC("add new service\r\n");
1325 uint8_t perm = service_reg_env.reg_list[service_reg_env.reg_nb]->perm;
1326 uint8_t *uuid = service_reg_env.reg_list[service_reg_env.reg_nb]->uuid;
1327 uint8_t nb_att = service_reg_env.reg_list[service_reg_env.reg_nb]->nb_att;
1328 sonata_gatt_att_desc_t *atts = service_reg_env.reg_list[service_reg_env.reg_nb]->att_desc;
1329 sonata_ble_gatt_add_service_request(service_reg_env.reg_list[service_reg_env.reg_nb]->start_hdl, perm, uuid, nb_att,
1330 &atts[1]);
1331 }
1332 }
1333
app_ble_get_reg_list_by_handle(uint16_t handle)1334 ble_gatt_att_reg_list_t *app_ble_get_reg_list_by_handle(uint16_t handle)
1335 {
1336 // print_serv_env();
1337 for (int i = 0; i < service_reg_env.reg_nb; i++) {
1338 ble_gatt_att_reg_list_t *p_list = service_reg_env.reg_list[i];
1339 printf("nb_att:%d\r\n", p_list->nb_att);
1340 if (p_list->start_hdl <= handle && (p_list->start_hdl + p_list->nb_att) >= handle) {
1341 return p_list;
1342 }
1343 }
1344 // printf("[API]get null handle\r\n");
1345 return NULL;
1346 }
1347
app_ble_gatt_read_request_handler(uint16_t handle,uint16_t * p_length,uint8_t * p_value)1348 void app_ble_gatt_read_request_handler(uint16_t handle, uint16_t *p_length, uint8_t *p_value)
1349 {
1350 ble_gatt_att_reg_list_t *p_list = app_ble_get_reg_list_by_handle(handle);
1351 printf("[API]ble_gatt_read_request_handler %d\r\n", handle);
1352 if (NULL == p_list) {
1353 return;
1354 }
1355 uint16_t localhandle = handle - p_list->start_hdl - 1;
1356 if (p_list->att_opr_list[localhandle].read_request != NULL) {
1357 p_list->att_opr_list[localhandle].read_request(p_value, p_length);
1358 }
1359 }
1360
app_user_config_write_cb(uint16_t handle,uint8_t * data,uint16_t size)1361 void app_user_config_write_cb(uint16_t handle, uint8_t *data, uint16_t size)
1362 {
1363 static uint16_t s_indicateEnable = 0;
1364 // printf("user_config_write_cb\r\n");
1365 if (size != sizeof(s_indicateEnable)) { // Size check
1366 return ;
1367 }
1368 s_indicateEnable = *(uint16_t *)data;
1369 if (s_indicateEnable == 0x0002) {
1370 int32_t send_status = sonata_ble_gatt_send_indicate_event(0, handle, size, data); // 0x0200
1371 printf("send status %ld\r\n", send_status);
1372 }
1373 }
1374
app_ble_gatt_write_request_handler(uint16_t handle,uint16_t length,uint8_t * p_value)1375 void app_ble_gatt_write_request_handler(uint16_t handle, uint16_t length, uint8_t *p_value)
1376 {
1377 // printf("[API]ble_gatt_write_request_handler %d\r\n",handle);
1378
1379 ble_gatt_att_reg_list_t *p_list = app_ble_get_reg_list_by_handle(handle);
1380 if (NULL == p_list) {
1381 return;
1382 }
1383 uint16_t localhandle = handle - p_list->start_hdl - 1;
1384 if (p_list->att_opr_list[localhandle].write_request != NULL) {
1385 p_list->att_opr_list[localhandle].write_request(p_value, length);
1386 }
1387
1388 else {
1389 app_user_config_write_cb(handle, p_value, length);
1390 }
1391 }
1392
app_ble_gatt_get_att_info(uint16_t handle,uint16_t * p_length,uint8_t * p_status)1393 void app_ble_gatt_get_att_info(uint16_t handle, uint16_t *p_length, uint8_t *p_status)
1394 {
1395 printf("[API]ble_gatt_get_att_info %d\r\n", handle);
1396
1397 ble_gatt_att_reg_list_t *p_list = app_ble_get_reg_list_by_handle(handle);
1398 if (NULL == p_list) {
1399 *p_length = 0;
1400 *p_status = BLE_STATUS_FAILED;
1401 return;
1402 }
1403 *p_length = 200;
1404 *p_status = BLE_STATUS_SUCCESS;
1405 }
1406
app_gatt_disc_svc_callback(uint8_t connection_id,uint16_t start_hdl,uint16_t end_hdl,uint8_t uuid_len,uint8_t * uuid)1407 static uint16_t app_gatt_disc_svc_callback(uint8_t connection_id, uint16_t start_hdl, uint16_t end_hdl,
1408 uint8_t uuid_len, uint8_t *uuid)
1409 {
1410 uint16_t service_uuid = 0;
1411 // APP_TRC("APP_CB: %s, start_hdl=0x%04X, end_hdl =0x%04X, uuid=", __FUNCTION__, start_hdl, end_hdl);
1412
1413 for (int i = 0; i < uuid_len; ++i) {
1414 // APP_TRC("%02X", uuid[i]);
1415 if (i == 0) {
1416 service_uuid = uuid[i];
1417 }
1418 if (i == 1) {
1419 service_uuid = (uuid[i] << 8) | service_uuid;
1420 }
1421 }
1422 APP_TRC("\r\n");
1423 APP_TRC("APP_CB: %s,service_uuid = %04X, start=%02d, end=%02d,targetUUID= %04X\r\n", __FUNCTION__, service_uuid,
1424 start_hdl, end_hdl, gAppEnv.appUuids.service);
1425
1426 if (service_uuid == gAppEnv.appUuids.service) {
1427 sonata_ble_gatt_disc_all_characteristic(connection_id, start_hdl, end_hdl);
1428 }
1429
1430 return CB_DONE;
1431 }
1432
app_gatt_disc_char_callback(uint8_t conidx,uint16_t attr_hdl,uint16_t pointer_hdl,uint8_t prop,uint8_t uuid_len,uint8_t * uuid)1433 static uint16_t app_gatt_disc_char_callback(uint8_t conidx, uint16_t attr_hdl, uint16_t pointer_hdl, uint8_t prop,
1434 uint8_t uuid_len, uint8_t *uuid)
1435 {
1436 uint16_t char_uuid = 0;
1437 // APP_TRC("APP_CB: %s, attr_hdl=0x%04X, uuid=", __FUNCTION__, attr_hdl);
1438 for (int i = 0; i < uuid_len; ++i) {
1439 // APP_TRC("%02X", uuid[i]);
1440 if (i == 0) {
1441 char_uuid = uuid[i];
1442 }
1443 if (i == 1) {
1444 char_uuid = uuid[i] << 8 | char_uuid;
1445 }
1446 }
1447
1448 APP_TRC("APP_CB: %s,char_uuid = %04X,attr_hdl=%04X,prop=%02X, target Read:%04X, Write=%04X\r\n", __FUNCTION__,
1449 char_uuid, attr_hdl, prop,
1450 gAppEnv.appUuids.read, gAppEnv.appUuids.write);
1451
1452 if (char_uuid == gAppEnv.appUuids.read) {
1453 gAppEnv.attrHandle = attr_hdl;
1454 gAppEnv.targetReadHandle = attr_hdl + 1;
1455 APP_TRC("APP_CB: %s, ***Find targetReadHandle =%d, UUID=%04X\r\n", __FUNCTION__, gAppEnv.targetReadHandle, char_uuid);
1456 }
1457 if (char_uuid == gAppEnv.appUuids.write) {
1458 gAppEnv.targetWriteHandle = attr_hdl + 1;
1459 APP_TRC("APP_CB: %s, ***Find targetWriteHandle=%d, UUID=%04X\r\n", __FUNCTION__, gAppEnv.targetWriteHandle, char_uuid);
1460 }
1461 if (char_uuid == gAppEnv.appUuids.ntf) {
1462 gAppEnv.targetNtfHandle = attr_hdl + 2;
1463 APP_TRC("APP_CB: %s, ***Find targetNtfHandle =%d, UUID=%04X\r\n", __FUNCTION__, gAppEnv.targetNtfHandle, char_uuid);
1464 }
1465
1466 return CB_DONE;
1467 }
1468
app_gatt_disc_desc_callback(uint8_t conidx,uint16_t attr_hdl,uint8_t uuid_len,uint8_t * uuid)1469 static uint16_t app_gatt_disc_desc_callback(uint8_t conidx, uint16_t attr_hdl, uint8_t uuid_len, uint8_t *uuid)
1470 {
1471 uint16_t service_uuid = 0;
1472
1473 // APP_TRC("APP_CB: %s, attr_hdl=0x%04X, uuid=", __FUNCTION__, attr_hdl);
1474 for (int i = 0; i < uuid_len; ++i) {
1475 // APP_TRC("%02X", uuid[i]);
1476 if (i == 0) {
1477 service_uuid = uuid[i];
1478 }
1479 if (i == 1) {
1480 service_uuid = (uuid[i] << 8) | service_uuid;
1481 }
1482 }
1483
1484 if (service_uuid == SONATA_ATT_DESC_CLIENT_CHAR_CFG && attr_hdl > gAppEnv.attrHandle && gAppEnv.targetNtfHandle == 0) {
1485 gAppEnv.targetNtfHandle = attr_hdl;
1486 APP_TRC("\r\n");
1487 APP_TRC("APP_CB: %s,service_uuid = %04X, Find targetNtfHandle = %d\r\n", __FUNCTION__, service_uuid,
1488 gAppEnv.targetNtfHandle);
1489 }
1490 return CB_DONE;
1491 }
1492
app_gatt_event_callback(uint8_t conidx,uint16_t handle,uint16_t type,uint16_t length,uint8_t * value)1493 static uint16_t app_gatt_event_callback(uint8_t conidx, uint16_t handle, uint16_t type, uint16_t length, uint8_t *value)
1494 {
1495 APP_TRC("APP_CB: %s,handle = %04X, type = %04X,length = %04X", __FUNCTION__,
1496 handle, type, length);
1497
1498 APP_TRC("APP_CB: %s, Master get data form Slave. Data:", __FUNCTION__);
1499 for (int i = 0; i < length; ++i) {
1500 APP_TRC("%02X[%c] ", value[i], value[i]);
1501 }
1502 APP_TRC("\r\n");
1503
1504 return CB_DONE;
1505 }
1506
app_ble_gatt_data_send(uint16_t local_handle,uint16_t idx,uint16_t length,uint8_t * p_value)1507 void app_ble_gatt_data_send(uint16_t local_handle, uint16_t idx, uint16_t length, uint8_t *p_value)
1508 {
1509 if (local_handle > service_reg_env.add_nb) {
1510 return;
1511 }
1512 ble_gatt_att_reg_list_t *p_list = service_reg_env.reg_list[local_handle];
1513 if (NULL == p_list) {
1514 return;
1515 }
1516 // idx = 5;
1517 uint16_t localhandle = p_list->start_hdl + idx;
1518
1519 APP_TRC("localhandle %ld\r\n", localhandle);
1520 int32_t send_status = sonata_ble_gatt_send_indicate_event(0, localhandle, length, p_value);
1521 APP_TRC("send status %ld\r\n", send_status);
1522 return;
1523 }
1524
app_ble_gatt_data_send_notify(uint16_t local_handle,uint16_t idx,uint16_t length,uint8_t * p_value)1525 void app_ble_gatt_data_send_notify(uint16_t local_handle, uint16_t idx, uint16_t length, uint8_t *p_value)
1526 {
1527 if (local_handle > service_reg_env.add_nb) {
1528 return;
1529 }
1530 ble_gatt_att_reg_list_t *p_list = service_reg_env.reg_list[local_handle];
1531 if (NULL == p_list) {
1532 return;
1533 }
1534 // idx = 5;
1535 uint16_t localhandle = p_list->start_hdl + idx;
1536
1537 int32_t send_status = sonata_ble_gatt_send_notify_event(0, localhandle, length, p_value);
1538 APP_TRC("send status %ld\r\n", send_status);
1539 return;
1540 }
1541
app_ble_enable_service(uint16_t start_hdl,uint8_t perm)1542 static void app_ble_enable_service(uint16_t start_hdl, uint8_t perm)
1543 {
1544 APP_TRC("app_ble_enable_service,handle =%02X(X) %d", start_hdl, perm);
1545 sonata_ble_gatt_set_service_visibility(start_hdl, true);
1546 }
1547
app_ble_disable_service(uint16_t start_hdl,uint8_t perm)1548 static void app_ble_disable_service(uint16_t start_hdl, uint8_t perm)
1549 {
1550 APP_TRC("app_ble_disable_service,handle =%02X(X) %d", start_hdl, perm);
1551 sonata_ble_gatt_set_service_visibility(start_hdl, false);
1552 }
1553
app_ble_disable_service_by_handler(uint16_t start_hdl)1554 int app_ble_disable_service_by_handler(uint16_t start_hdl)
1555 {
1556 if (start_hdl > service_reg_env.add_nb) {
1557 return -1;
1558 }
1559 ble_gatt_att_reg_list_t *p_list = service_reg_env.reg_list[start_hdl];
1560 if (NULL == p_list) {
1561 return -1;
1562 }
1563 app_ble_disable_service(p_list->start_hdl, p_list->perm);
1564 return 0;
1565 }
1566
app_ble_search_svc(uint8_t * service_uuid)1567 static uint8_t app_ble_search_svc(uint8_t *service_uuid)
1568 {
1569 for (int idx = 0; idx < service_reg_env.add_nb; idx++) {
1570 if (!memcmp(service_uuid, service_reg_env.reg_list[idx]->uuid, SONATA_ATT_UUID_128_LEN)) {
1571 return idx;
1572 }
1573 }
1574 return MAX_SERVICE_NUM;
1575
1576 }
1577
app_ble_gatt_add_svc_helper(uint16_t * start_hdl,uint8_t nb_att,ble_gatt_att_reg_t * atts)1578 int app_ble_gatt_add_svc_helper(uint16_t *start_hdl, uint8_t nb_att, ble_gatt_att_reg_t *atts)
1579 {
1580 // printf("ble_gatt_add_svc_helper\r\n");
1581
1582 uint8_t perm = atts[0].att_desc.perm;
1583 // PERM_SET(perm, SVC_UUID_LEN,2);
1584 uint8_t uuid[SONATA_ATT_UUID_128_LEN];
1585 uint16_t svc_hdl = *start_hdl;
1586 uint8_t local_idx;
1587 APP_TRC("nb_att %d\r\n", nb_att);
1588 memmove(uuid, atts[0].att_desc.uuid, SONATA_ATT_UUID_128_LEN); // the first should servicce attr!!!
1589 local_idx = app_ble_search_svc(uuid);
1590 if (MAX_SERVICE_NUM != local_idx) {
1591 APP_TRC("found service %d\r\n", local_idx);
1592 if (service_reg_env.reg_list[local_idx]->state == SONATA_SERVICE_DISABLE) {
1593 app_ble_enable_service(service_reg_env.reg_list[local_idx]->start_hdl, service_reg_env.reg_list[local_idx]->perm);
1594 return BLE_STATUS_SUCCESS;
1595 }
1596
1597 else if (service_reg_env.reg_list[local_idx]->state == SONATA_SERVICE_ENABLE) {
1598 APP_TRC("duplicate add service %d\r\n", local_idx);
1599 return BLE_STATUS_FAILED;
1600 }
1601 }
1602 APP_TRC("struc %d %d\r\n", sizeof(ble_gatt_att_reg_list_t), sizeof(ble_gatt_att_manager_t));
1603 ble_gatt_att_reg_list_t *p_list = (ble_gatt_att_reg_list_t *) sonata_api_malloc(sizeof(ble_gatt_att_opr_t) *
1604 (nb_att - 1) + sizeof(ble_gatt_att_reg_list_t));
1605 memset(p_list, 0, sizeof(ble_gatt_att_opr_t) * (nb_att - 1) + sizeof(ble_gatt_att_reg_list_t));
1606 p_list->att_opr_list = (ble_gatt_att_opr_t *)((uint8_t *)p_list + sizeof(ble_gatt_att_reg_list_t));
1607 p_list->nb_att = nb_att - 1;
1608 APP_TRC("nb_att %d\r\n", p_list->nb_att);
1609
1610 for (int i = 1; i < nb_att; i++) {
1611 memmove(p_list->att_opr_list + i - 1, &atts[i].att_opr, sizeof(ble_gatt_att_opr_t));
1612 };
1613 memmove(p_list->uuid, atts[0].att_desc.uuid, SONATA_ATT_UUID_128_LEN);
1614 p_list->perm = perm;
1615 sonata_gatt_att_desc_t *att_desc = sonata_api_malloc(nb_att * sizeof(sonata_gatt_att_desc_t));
1616 for (int i = 0; i < nb_att; ++i) {
1617
1618 att_desc[i].perm = atts[i].att_desc.perm;
1619 att_desc[i].max_len = atts[i].att_desc.max_len;
1620 att_desc[i].ext_perm = atts[i].att_desc.ext_perm;
1621 // PERM_SET(msg->svc_desc.atts[i].ext_perm, UUID_LEN,2);
1622 memcpy(att_desc[i].uuid, atts[i].att_desc.uuid, SONATA_ATT_UUID_128_LEN);
1623 }
1624 APP_TRC("nb_att %d\r\n", p_list->nb_att);
1625
1626 #if (defined ALIOS_SUPPORT) || (defined HARMONYOS_SUPPORT)
1627 lega_rtos_declare_critical();
1628 lega_rtos_enter_critical();
1629 #endif
1630 uint8_t add_nb = service_reg_env.add_nb;
1631 service_reg_env.add_nb ++;
1632 service_reg_env.reg_list[add_nb] = p_list;
1633 *start_hdl = add_nb;
1634 if (service_reg_env.add_nb != service_reg_env.reg_nb + 1) {
1635 service_reg_env.reg_list[add_nb]->att_desc = att_desc;
1636 APP_TRC("service adding %d %d\r\n", service_reg_env.add_nb, service_reg_env.reg_nb);
1637 #if (defined ALIOS_SUPPORT) || (defined HARMONYOS_SUPPORT)
1638 lega_rtos_exit_critical();
1639 #endif
1640 return BLE_STATUS_FAILED;
1641 }
1642 #if (defined ALIOS_SUPPORT) || (defined HARMONYOS_SUPPORT)
1643 lega_rtos_exit_critical();
1644 #endif
1645 // print_serv_env();
1646
1647 sonata_ble_gatt_add_service_request(svc_hdl, perm, uuid, nb_att - 1, &att_desc[1]);
1648 sonata_api_free(att_desc);
1649 return BLE_STATUS_SUCCESS;
1650 }
1651
app_set_security_io_cap(uint8_t cap)1652 int app_set_security_io_cap(uint8_t cap)
1653 {
1654 APP_TRC("app_set_security_io_cap,cap=%02X(X)", cap);
1655 app_iocap = cap;
1656 return 0;
1657 }
1658
app_set_security_auth_req(uint8_t auth_req)1659 int app_set_security_auth_req(uint8_t auth_req)
1660 {
1661 APP_TRC("app_set_security_auth_req,auth_req=%02X(X)", auth_req);
1662 app_auth = auth_req;
1663 return 0;
1664 }
1665
app_get_connection_state(void)1666 uint8_t app_get_connection_state(void)
1667 {
1668 return app_connection_state;
1669 }
1670
app_set_connection_state(uint8_t state)1671 void app_set_connection_state(uint8_t state)
1672 {
1673 app_connection_state = state;
1674 }
1675
print_peer_bond_request(struct sonata_gap_bond_req_ind * request)1676 static void print_peer_bond_request(struct sonata_gap_bond_req_ind *request)
1677 {
1678 switch (request->request) {
1679 case SONATA_GAP_PAIRING_REQ:
1680 APP_TRC("PEER_PAIR: SONATA_GAP_PAIRING_REQ,auth_req=%02X(X)", request->data.auth_req);
1681 switch (request->data.auth_req) {
1682 case SONATA_GAP_AUTH_REQ_NO_MITM_NO_BOND:
1683 APP_TRC(" (GAP_AUTH_REQ_NO_MITM_NO_BOND)\r\n");
1684 break;
1685 case SONATA_GAP_AUTH_REQ_NO_MITM_BOND:
1686 APP_TRC(" (GAP_AUTH_REQ_NO_MITM_BOND)\r\n");
1687 break;
1688 case SONATA_GAP_AUTH_REQ_MITM_NO_BOND:
1689 APP_TRC(" (GAP_AUTH_REQ_MITM_NO_BOND)\r\n");
1690 break;
1691 case SONATA_GAP_AUTH_REQ_MITM_BOND:
1692 APP_TRC(" (GAP_AUTH_REQ_MITM_BOND)\r\n");
1693 break;
1694 case SONATA_GAP_AUTH_REQ_SEC_CON_NO_BOND:
1695 APP_TRC(" (GAP_AUTH_REQ_SEC_CON_NO_BOND)\r\n");
1696 break;
1697 case SONATA_GAP_AUTH_REQ_SEC_CON_BOND:
1698 APP_TRC(" (GAP_AUTH_REQ_SEC_CON_BOND)\r\n");
1699 break;
1700 default:
1701 APP_TRC(" (Default)\r\n");
1702 break;
1703
1704 }
1705 break;
1706 case SONATA_GAP_TK_EXCH:
1707 APP_TRC("PEER_PAIR: SONATA_GAP_TK_EXCH,tk_type=%02X(X)\r\n", request->data.tk_type);
1708 switch (request->data.auth_req) {
1709 case SONATA_GAP_TK_OOB:
1710 APP_TRC(" (GAP_TK_OOB)\r\n");
1711 break;
1712 case SONATA_GAP_TK_DISPLAY:
1713 APP_TRC(" (GAP_TK_DISPLAY)\r\n");
1714 break;
1715 case SONATA_GAP_TK_KEY_ENTRY:
1716 APP_TRC(" (GAP_TK_KEY_ENTRY)\r\n");
1717 break;
1718 default:
1719 APP_TRC(" (Default)\r\n");
1720 break;
1721 }
1722 break;
1723 case SONATA_GAP_LTK_EXCH:
1724 APP_TRC("PEER_PAIR: SONATA_GAP_LTK_EXCH,key_size=%02X(X)\r\n", request->data.key_size);
1725 break;
1726 case SONATA_GAP_OOB_EXCH:
1727 APP_TRC("PEER_PAIR: \r\n");
1728 break;
1729 case SONATA_GAP_NC_EXCH:
1730 APP_TRC("PEER_PAIR: SONATA_GAP_NC_EXCH,NC Value:%02X %02X %02X %02X\r\n", request->data.nc_data.value[0],
1731 request->data.nc_data.value[1],
1732 request->data.nc_data.value[2], request->data.nc_data.value[3]);
1733 break;
1734
1735 }
1736 }
1737
app_gap_notify_pair_request_rsp(uint8_t * bd_addr,uint8_t accept)1738 void app_gap_notify_pair_request_rsp(uint8_t *bd_addr, uint8_t accept)
1739 {
1740 uint8_t key_size = SONATA_GAP_SMP_MAX_ENC_SIZE_LEN;
1741 enum sonata_gap_oob_auth oob = SONATA_GAP_OOB_AUTH_DATA_NOT_PRESENT;
1742 enum sonata_gap_kdist ikey_dist = SONATA_GAP_KDIST_LINKKEY; // Initiator key distribution
1743 enum sonata_gap_kdist rkey_dist = SONATA_GAP_KDIST_NONE; // Responder key distribution
1744 enum sonata_gap_sec_req sec_req = SONATA_GAP_NO_SEC;
1745 // ikey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY;
1746 // ikey_dist = GAP_KDIST_NONE;
1747 // rkey_dist = GAP_KDIST_NONE;
1748 ikey_dist = SONATA_GAP_KDIST_ENCKEY | SONATA_GAP_KDIST_IDKEY; // Initiator key distribution
1749 rkey_dist = SONATA_GAP_KDIST_ENCKEY | SONATA_GAP_KDIST_IDKEY; // Responder key distribution
1750 sec_req = SONATA_GAP_NO_SEC;
1751 uint8_t conidx = app_get_conidx_by_addr(bd_addr);
1752 sonata_ble_gap_send_bond_cfm_for_pairing_req(conidx, NULL, accept,
1753 app_iocap, oob, app_auth, key_size, ikey_dist, rkey_dist, sec_req);
1754 if (accept) {
1755 app_set_connection_state(APP_BONDING);
1756 } else {
1757 APP_TRC("APP_CB: %s accept %d\r\n", __FUNCTION__, accept);
1758 }
1759 }
1760
app_gap_notify_pair_request(void)1761 static void app_gap_notify_pair_request(void)
1762 {
1763 if (sec_req_call == NULL) {
1764 app_gap_notify_pair_request_rsp(target_address, 1);
1765 } else {
1766 sec_req_call(target_address);
1767 }
1768 }
1769
app_gap_bond_req_callback(uint8_t conidx,struct sonata_gap_bond_req_ind * request)1770 static uint16_t app_gap_bond_req_callback(uint8_t conidx, struct sonata_gap_bond_req_ind *request)
1771 {
1772 APP_TRC("APP_CB: %s request->request=%d\r\n", __FUNCTION__, request->request);
1773 print_peer_bond_request(request);
1774 switch (request->request) {
1775 case SONATA_GAP_PAIRING_REQ: {
1776 APP_TRC("APP_CB: %s SONATA_GAP_PAIRING_REQ\r\n", __FUNCTION__);
1777 app_req_auth = request->data.auth_req;
1778 app_gap_notify_pair_request();
1779 }
1780 break;
1781 case SONATA_GAP_LTK_EXCH: {
1782 APP_TRC("APP_CB: %s SONATA_GAP_LTK_EXCH\r\n", __FUNCTION__);
1783 uint8_t counter = 0;
1784 struct sonata_gap_ltk data_ltk = {0};
1785 uint8_t accept = 1;
1786 // uint8_t request = SONATA_GAP_LTK_EXCH;
1787
1788 // Generate all the values
1789 data_ltk.ediv = (uint16_t)util_rand_word();
1790 for (counter = 0; counter < SONATA_GAP_RAND_NB_LEN; counter++) {
1791 data_ltk.ltk.key[counter] = (uint8_t)util_rand_word();
1792 data_ltk.randnb.nb[counter] = (uint8_t)util_rand_word();
1793 }
1794 for (counter = SONATA_GAP_RAND_NB_LEN; counter < SONATA_GAP_KEY_LEN; counter++) {
1795 data_ltk.ltk.key[counter] = (uint8_t)util_rand_word();
1796 }
1797 APP_TRC("APP_CB %s, app_ltk_key :", __FUNCTION__);
1798 for (int i = 0; i < SONATA_GAP_KEY_LEN; ++i) {
1799 APP_TRC("%02X ", data_ltk.ltk.key[i]);
1800 }
1801 APP_TRC("\r\n");
1802 APP_TRC("APP_CB %s, app_randnb_nb:", __FUNCTION__);
1803 for (int i = 0; i < SONATA_GAP_RAND_NB_LEN; ++i) {
1804 APP_TRC("%02X ", data_ltk.randnb.nb[i]);
1805 }
1806 APP_TRC("\r\n");
1807 if (sonata_fs_write(SONATA_TAG_LTK, SONATA_LEN_LTK, &data_ltk) != SONATA_FS_OK) {
1808 APP_TRC("LTK Save fail!!!\r\n");
1809 }
1810 sonata_ble_gap_send_bond_cfm_for_ltk_exchange(conidx,
1811 accept,
1812 data_ltk.ediv,
1813 data_ltk.randnb.nb,
1814 SONATA_GAP_KEY_LEN,
1815 data_ltk.ltk.key);
1816
1817 APP_TRC(" bonded_dev_info.current_dev_index = %d \r\n", bonded_dev_info.current_dev_index);
1818 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].peer_addr, peer_dbaddr, APP_BD_ADDR_LEN);
1819 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk.ltk, data_ltk.ltk.key,
1820 SONATA_GAP_KEY_LEN);
1821 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk.randnb, data_ltk.randnb.nb, 8);
1822 bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk.ediv = data_ltk.ediv;
1823
1824 // Store the bonded dev info value in FS
1825 if (sonata_fs_write(SONATA_TAG_BONDED_DEV_INFO, SONATA_LEN_BONDED_DEV_INFO,
1826 (uint8_t *)&bonded_dev_info) != SONATA_FS_OK) {
1827 ASSERT_ERR(3695, 0);
1828 }
1829
1830 }
1831 break;
1832 case SONATA_GAP_IRK_EXCH: {
1833 APP_TRC("APP_CB: %s SONATA_GAP_IRK_EXCH \r\n", __FUNCTION__);
1834 // Store the peer addr into FS
1835 uint8_t accept = true;
1836
1837 uint8_t *local_addr = sonata_get_bt_address();
1838 uint8_t addr_type = (local_addr[5] & 0xC0) ? SONATA_ADDR_RAND : SONATA_ADDR_PUBLIC;
1839 sonata_ble_gap_send_bond_cfm_for_irk_exchange(conidx, accept, app_loc_irk, addr_type, local_addr);
1840 }
1841 break;
1842 case SONATA_GAP_TK_EXCH: {
1843 APP_TRC("APP_CB: %s SONATA_GAP_TK_EXCH\r\n", __FUNCTION__);
1844
1845 uint8_t data_tk[SONATA_GAP_KEY_LEN] = {0};
1846 // Generate a PIN Code- (Between 100000 and 999999)
1847 uint32_t pin_code = (100000 + (util_rand_word() % 900000));
1848 uint8_t accept = true;
1849
1850 data_tk[0] = (uint8_t) ((pin_code & 0x000000FF) >> 0);
1851 data_tk[1] = (uint8_t) ((pin_code & 0x0000FF00) >> 8);
1852 data_tk[2] = (uint8_t) ((pin_code & 0x00FF0000) >> 16);
1853 data_tk[3] = (uint8_t) ((pin_code & 0xFF000000) >> 24);
1854 sonata_ble_gap_send_bond_cfm_for_tk_exchange(conidx, accept, data_tk);
1855 APP_TRC("APP_CB: %s pin_code=%lu,", __FUNCTION__, pin_code);
1856 APP_TRC(" TKey:");
1857
1858 for (int i = 0; i < SONATA_GAP_KEY_LEN; ++i) {
1859 APP_TRC("%02X ", data_tk[i]);
1860 }
1861 APP_TRC("\r\n");
1862
1863 }
1864 break;
1865 case SONATA_GAP_NC_EXCH: {
1866 APP_TRC("APP_CB: %s SONATA_GAP_NC_EXCH\r\n", __FUNCTION__);
1867 APP_TRC("APP_CB %s, NC Value:", __FUNCTION__);
1868 for (int i = 0; i < 4; ++i) {
1869 APP_TRC("%02X ", request->data.nc_data.value[i]);
1870 }
1871 APP_TRC("\r\n");
1872 uint8_t accept = 1;
1873 sonata_ble_gap_send_bond_cfm_for_nc_exchange(conidx, accept);
1874
1875 }
1876 break;
1877 case SONATA_GAP_CSRK_EXCH:
1878 APP_TRC("APP_CB: %s SONATA_GAP_CSRK_EXCH\r\n", __FUNCTION__);
1879 uint8_t accept = true;
1880 sonata_ble_gap_send_bond_cfm_for_csrk_exchange(conidx, accept, app_csrk);
1881
1882 break;
1883 case SONATA_GAP_OOB_EXCH:
1884 APP_TRC("APP_CB: %s SONATA_GAP_OOB_EXCH\r\n", __FUNCTION__);
1885
1886 break;
1887 }
1888
1889 return CB_DONE;
1890
1891 }
1892
app_gap_bond_callback(uint8_t conidx,struct sonata_gap_bond_ind * ind)1893 static uint16_t app_gap_bond_callback(uint8_t conidx, struct sonata_gap_bond_ind *ind)
1894 {
1895 APP_TRC("APP_CB: %s \r\n", __FUNCTION__);
1896 switch (ind->info) {
1897 case SONATA_GAP_PAIRING_SUCCEED:
1898 APP_TRC("APP_CB: %s SONATA_GAP_PAIRING_SUCCEED,", __FUNCTION__);
1899 APP_TRC(" app_bond = 1,");
1900 app_bond = 1;
1901 if (sonata_fs_write(SONATA_TAG_PERIPH_BONDED, SONATA_LEN_PERIPH_BONDED, &app_bond) != SONATA_FS_OK) {
1902 // An error has occurred during access to the FS
1903 ASSERT_ERR(3697, 0);
1904 }
1905 struct sonata_gap_bdaddr *bdaddr = sonata_ble_gap_get_bdaddr(conidx, SONATA_GAP_SMP_INFO_PEER);
1906 if (sonata_fs_write(SONATA_TAG_PEER_BD_ADDRESS, SONATA_LEN_PEER_BD_ADDRESS, bdaddr->addr.addr) != SONATA_FS_OK) {
1907 // An error has occurred during access to the FS
1908 // ASSERT_ERR(3694, 0);
1909 } else {
1910 APP_TRC("peer_addr:");
1911 for (int i = SONATA_GAP_BD_ADDR_LEN - 1; i >= 0; --i) {
1912 APP_TRC("%02X ", bdaddr->addr.addr[i]);
1913 }
1914 APP_TRC(" \r\n");
1915 }
1916
1917 switch (ind->data.auth.info) {
1918 case SONATA_GAP_AUTH_REQ_NO_MITM_NO_BOND:
1919 APP_TRC("Auth:GAP_AUTH_REQ_NO_MITM_NO_BOND \r\n");
1920 break;
1921 case SONATA_GAP_AUTH_REQ_NO_MITM_BOND:
1922 APP_TRC("Auth:GAP_AUTH_REQ_NO_MITM_BOND \r\n");
1923 break;
1924 case SONATA_GAP_AUTH_REQ_MITM_NO_BOND:
1925 APP_TRC("Auth:GAP_AUTH_REQ_MITM_NO_BOND \r\n");
1926 break;
1927 case SONATA_GAP_AUTH_REQ_MITM_BOND:
1928 APP_TRC("Auth:GAP_AUTH_REQ_MITM_BOND \r\n");
1929 break;
1930 case SONATA_GAP_AUTH_REQ_SEC_CON_NO_BOND:
1931 APP_TRC("Auth:GAP_AUTH_REQ_SEC_CON_NO_BOND \r\n");
1932 break;
1933 case SONATA_GAP_AUTH_REQ_SEC_CON_BOND:
1934 APP_TRC("Auth:GAP_AUTH_REQ_SEC_CON_BOND \r\n");
1935 break;
1936 }
1937 app_set_connection_state(APP_BONDED);
1938 if (bonded_dev_info.current_dev_index < MAX_BONDED_DEV_INDEX) {
1939 bonded_dev_info.current_dev_index++;
1940 } else if (bonded_dev_info.current_dev_index == MAX_BONDED_DEV_INDEX) {
1941 bonded_dev_info.current_dev_index = 0;
1942 }
1943 break;
1944 case SONATA_GAP_PAIRING_FAILED:
1945 // Reason see (SONATA_GAP_SMP_REM_ERR_MASK|smp_pair_fail_reason)
1946 APP_TRC("APP_CB: %s SONATA_GAP_PAIRING_FAILED,Reason:%02X(X)\r\n", __FUNCTION__, ind->data.reason);
1947 // app_ble_config_scanning();
1948 // app_stop_scan_timer_start();
1949 // sonata_ble_gap_start_security(conidx, GAP_AUTH_REQ_MITM_BOND);
1950 sonata_ble_gap_disconnect(conidx, SONATA_CO_ERROR_CONN_REJ_SECURITY_REASONS);
1951 break;
1952 case SONATA_GAP_LTK_EXCH:
1953 APP_TRC("APP_CB: %s SONATA_GAP_LTK_EXCH\r\n", __FUNCTION__);
1954 if ((app_req_auth & SONATA_GAP_AUTH_SEC_CON) && (app_auth & SONATA_GAP_AUTH_SEC_CON)) {
1955 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk.ltk, ind->data.ltk.ltk.key,
1956 SONATA_GAP_KEY_LEN);
1957 }
1958 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk_in, ind->data.ltk.ltk.key,
1959 SONATA_GAP_KEY_LEN);
1960 // memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk.randnb, ind->data.randnb.nb, 8);
1961 // bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].ltk.ediv = ind->data.ediv;
1962 // Store the app_ltk_key_in value in FS
1963 if (sonata_fs_write(SONATA_TAG_BONDED_DEV_INFO, SONATA_LEN_BONDED_DEV_INFO,
1964 (uint8_t *)&bonded_dev_info) != SONATA_FS_OK) {
1965 ASSERT_ERR(3698, 0);
1966 }
1967 APP_TRC("AAA %s, app_ltk_key_in:", __FUNCTION__);
1968 for (int i = 0; i < SONATA_GAP_KEY_LEN; ++i) {
1969 APP_TRC("%02X ", ind->data.ltk.ltk.key[i]);
1970 }
1971 APP_TRC("\r\n");
1972
1973 break;
1974 case SONATA_GAP_IRK_EXCH:
1975 APP_TRC("APP_CB: %s SONATA_GAP_IRK_EXCH\r\n", __FUNCTION__);
1976 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].irk.irk_addr, ind->data.irk.addr.addr.addr,
1977 SONATA_GAP_BD_ADDR_LEN);
1978 memcpy(bonded_dev_info.bonded_device_info[bonded_dev_info.current_dev_index].irk.irk, ind->data.irk.irk.key,
1979 SONATA_GAP_KEY_LEN);
1980 // Store the irk addr value in FS
1981 if (sonata_fs_write(SONATA_TAG_BONDED_DEV_INFO, SONATA_LEN_BONDED_DEV_INFO,
1982 (uint8_t *)&bonded_dev_info) != SONATA_FS_OK) {
1983 ASSERT_ERR(3700, 0);
1984 }
1985 break;
1986 case SONATA_GAP_CSRK_EXCH:
1987 APP_TRC("APP_CB: %s SONATA_GAP_CSRK_EXCH\r\n", __FUNCTION__);
1988 break;
1989 case SONATA_GAP_REPEATED_ATTEMPT:
1990 APP_TRC("APP_CB: %s SONATA_GAP_REPEATED_ATTEMPT\r\n", __FUNCTION__);
1991 sonata_ble_gap_disconnect(conidx, SONATA_HL_LL_ERR_REMOTE_USER_TERM_CON);
1992 break;
1993 }
1994 return CB_DONE;
1995 }
1996
app_check_device_isbonded(uint16_t in_ediv,uint8_t * in_nb)1997 uint8_t app_check_device_isbonded(uint16_t in_ediv, uint8_t *in_nb)
1998 {
1999 APP_TRC("APP_CB: %s \r\n", __FUNCTION__);
2000 // check the latest device first
2001 for (int i = bonded_dev_info.current_dev_index; i < MAX_BONDED_DEV_NUM; i++) {
2002 if (in_ediv == bonded_dev_info.bonded_device_info[i].ltk.ediv &&
2003 !memcmp(&in_nb[0], bonded_dev_info.bonded_device_info[i].ltk.randnb, SONATA_GAP_RAND_NB_LEN)) {
2004 APP_TRC("APP_CB: %s 00 i = %d\r\n", __FUNCTION__, i);
2005 return i;
2006 }
2007 }
2008 for (int i = 0; i < bonded_dev_info.current_dev_index; i++) {
2009 if (in_ediv == bonded_dev_info.bonded_device_info[i].ltk.ediv &&
2010 !memcmp(&in_nb[0], bonded_dev_info.bonded_device_info[i].ltk.randnb, SONATA_GAP_RAND_NB_LEN)) {
2011 APP_TRC("APP_CB: %s 11 i = %d\r\n", __FUNCTION__, i);
2012 return i;
2013 }
2014 }
2015 return INVALID_BONDED_INDEX;
2016 }
2017
app_gap_encrypt_req_callback(uint8_t conidx,uint16_t in_ediv,uint8_t * in_nb)2018 static uint16_t app_gap_encrypt_req_callback(uint8_t conidx, uint16_t in_ediv, uint8_t *in_nb)
2019 {
2020 APP_TRC("APP_CB: %s in_ediv=%X(x), in_nb:", __FUNCTION__, in_ediv);
2021 for (int i = 0; i < SONATA_GAP_RAND_NB_LEN; ++i) {
2022 APP_TRC("%02X ", in_nb[i]);
2023 }
2024 APP_TRC("\r\n");
2025 uint8_t length = SONATA_LEN_PERIPH_BONDED;
2026 if (sonata_fs_read(SONATA_TAG_PERIPH_BONDED, &length, &app_bond) != SONATA_FS_OK) {
2027 app_bond = 0;
2028 }
2029 if (app_bond) {
2030 uint8_t found = 0;
2031 uint16_t keySize = SONATA_GAP_KEY_LEN;
2032 length = SONATA_LEN_BONDED_DEV_INFO;
2033
2034 if (sonata_fs_read(SONATA_TAG_BONDED_DEV_INFO, &length, (uint8_t *)&bonded_dev_info) == SONATA_FS_OK) {
2035 // Check if the provided EDIV and Rand Nb values match with the stored values
2036 uint8_t index = app_check_device_isbonded(in_ediv, in_nb);
2037 if (index > INVALID_BONDED_INDEX) {
2038 APP_TRC("APP_CB: %s, found, send encrypt confirm, key:", __FUNCTION__);
2039 for (int i = 0; i < SONATA_GAP_KEY_LEN; ++i) {
2040 APP_TRC("%02X ", bonded_dev_info.bonded_device_info[index].ltk.ltk[i]);
2041 }
2042 APP_TRC("\r\n");
2043 found = true;
2044 sonata_ble_gap_send_encrypt_cfm(conidx, found, keySize, bonded_dev_info.bonded_device_info[index].ltk.ltk);
2045 app_set_connection_state(APP_BONDED);
2046 } else {
2047 APP_TRC("APP_CB: %s, not found, send encrypt confirm\r\n", __FUNCTION__);
2048 uint8_t app_ltk_key_zero[SONATA_GAP_KEY_LEN] = {0};
2049 sonata_ble_gap_send_encrypt_cfm(conidx, found, keySize, app_ltk_key_zero);
2050 }
2051 } else {
2052 return CB_REJECT;
2053 APP_TRC("Error when read LTK in FS!!!\r\n");
2054 }
2055 } else {
2056 APP_TRC("APP_CB: %s, not bond, send encrypt confirm\r\n", __FUNCTION__);
2057 uint8_t app_ltk_key_zero[SONATA_GAP_KEY_LEN] = {0};
2058 sonata_ble_gap_send_encrypt_cfm(conidx, false, 0, app_ltk_key_zero);
2059 }
2060
2061 return CB_DONE;
2062 }
2063
app_gap_gen_random_number_callback(uint8_t * number)2064 static uint16_t app_gap_gen_random_number_callback(uint8_t *number)
2065 {
2066 APP_TRC("APP_CB: %s \r\n", __FUNCTION__);
2067 if (app_rand_cnt == 1) { // First part of IRK
2068 memcpy(&app_loc_irk[0], number, 8);
2069 } else if (app_rand_cnt == 2) { // Second part of IRK
2070 memcpy(&app_loc_irk[8], number, 8);
2071 }
2072 APP_TRC("app_loc_irk :");
2073 for (int i = 0; i < KEY_LEN; ++i) {
2074 APP_TRC("%02X ", app_loc_irk[i]);
2075 }
2076 APP_TRC("\r\n");
2077 return CB_DONE;
2078 }
2079
app_gap_security_callback(uint8_t conidx,uint8_t auth_level)2080 static uint16_t app_gap_security_callback(uint8_t conidx, uint8_t auth_level)
2081 {
2082 APP_TRC("APP_CB: %s auth_level=%02X(x)\r\n", __FUNCTION__, auth_level);
2083
2084 return CB_DONE;
2085
2086 }
2087
app_gap_encrypt_callback(uint8_t conidx,uint8_t auth_level)2088 static uint16_t app_gap_encrypt_callback(uint8_t conidx, uint8_t auth_level)
2089 {
2090 APP_TRC("APP_CB: %s auth_level=%02X(x)\r\n", __FUNCTION__, auth_level);
2091
2092 return CB_DONE;
2093 }
2094
app_gap_le_pke_size_callback(uint8_t conidx,uint16_t max_tx_octets,uint16_t max_tx_time,uint16_t max_rx_octets,uint16_t max_rx_time)2095 static uint16_t app_gap_le_pke_size_callback(uint8_t conidx, uint16_t max_tx_octets, uint16_t max_tx_time,
2096 uint16_t max_rx_octets, uint16_t max_rx_time)
2097 {
2098 APP_TRC("APP_CB: %s %d max_tx_octets=%d(d), max_rx_octets=%d(d) time %d %d\r\n", __FUNCTION__, conidx, max_tx_octets,
2099 max_rx_octets, max_tx_time, max_rx_time);
2100
2101 return CB_DONE;
2102 }
app_gap_resolving_address_callback(uint8_t operation,uint8_t addr_type,uint8_t * addr)2103 static uint16_t app_gap_resolving_address_callback(uint8_t operation, uint8_t addr_type, uint8_t *addr)
2104 {
2105 APP_TRC("APP_CB: %s operation=%d(d), addr_type=%d(d)\r\n", __FUNCTION__, operation, addr_type);
2106 if (NULL == addr) {
2107 APP_TRC("ERROR\r\n");
2108 }
2109 return CB_DONE;
2110 }
2111
app_ble_print_peer_info(uint8_t * name,uint16_t nameLen,uint8_t * mac)2112 static void app_ble_print_peer_info(uint8_t *name, uint16_t nameLen, uint8_t *mac)
2113 {
2114 printf("\r\n----PEER BLE Connected ----");
2115 printf("\r\n----PEER BLE NAME[%s] ----\r\n", name);
2116 printf("----PEER BLE MAC[%02X:%02X:%02X:%02X:%02X:%02X] ----\r\n",
2117 mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
2118 printf("\r\n");
2119
2120 }
2121
2122 /*!
2123 * @brief
2124 * @param info
2125 */
app_gap_peer_att_info_callback(uint8_t conidx,sonata_gap_peer_att_info_ind_t * info)2126 static uint16_t app_gap_peer_att_info_callback(uint8_t conidx, sonata_gap_peer_att_info_ind_t *info)
2127 {
2128 APP_TRC("APP_CB: %s conidx=%02X\r\n", __FUNCTION__, conidx);
2129 sonata_gap_peer_att_info_ind_t *att_info = (sonata_gap_peer_att_info_ind_t *) info;
2130 APP_TRC("APP_CB: %s, req =0x%02X\r\n", __FUNCTION__, att_info->req);
2131 APP_TRC("APP_CB: %s, handle =0x%02X\r\n", __FUNCTION__, att_info->handle);
2132 switch (att_info->req) {
2133 case SONATA_GAP_DEV_NAME: {
2134 APP_TRC("APP %s, Name:", __FUNCTION__);
2135 for (int i = 0; i < att_info->info.name.length; ++i) {
2136 APP_TRC("%c", att_info->info.name.value[i]);
2137 }
2138 APP_TRC("\r\n");
2139 uint8_t len = att_info->info.name.length > 20 ? 20 : att_info->info.name.length;
2140 memcpy(gAppEnv.act[conidx].name, att_info->info.name.value, len);
2141 app_ble_print_peer_info(att_info->info.name.value, len, gAppEnv.act[conidx].peer);
2142 }
2143 break;
2144 case SONATA_GAP_DEV_APPEARANCE: {
2145 APP_TRC("APP_CB: %s, appearance =0x%04X\r\n", __FUNCTION__, att_info->info.appearance);
2146 }
2147 break;
2148 case SONATA_GAP_DEV_SLV_PREF_PARAMS: {
2149 APP_TRC("APP_CB: %s, con_intv_min =0x%02X\r\n", __FUNCTION__, att_info->info.slv_pref_params.con_intv_min);
2150 APP_TRC("APP_CB: %s, con_intv_max =0x%02X\r\n", __FUNCTION__, att_info->info.slv_pref_params.con_intv_max);
2151 APP_TRC("APP_CB: %s, slave_latency =0x%02X\r\n", __FUNCTION__, att_info->info.slv_pref_params.slave_latency);
2152 APP_TRC("APP_CB: %s, conn_timeout =0x%02X\r\n", __FUNCTION__, att_info->info.slv_pref_params.conn_timeout);
2153 }
2154 break;
2155 case SONATA_GAP_DEV_CTL_ADDR_RESOL: {
2156 APP_TRC("APP_CB: %s, ctl_addr_resol =0x%02X\r\n", __FUNCTION__, att_info->info.ctl_addr_resol);
2157 }
2158 break;
2159
2160 default:
2161 break;
2162
2163 }
2164 return CB_DONE;
2165 }
2166
app_gap_peer_info_callback(uint8_t conidx,sonata_gap_peer_info_ind_t * info)2167 static uint16_t app_gap_peer_info_callback(uint8_t conidx, sonata_gap_peer_info_ind_t *info)
2168 {
2169 APP_TRC("APP_CB: %s conidx=%02X, info_type=%02X\r\n", __FUNCTION__, conidx, info->req);
2170 switch (info->req) {
2171 case SONATA_GET_PEER_VERSION:
2172 APP_TRC("APP_CB: SONATA_GET_PEER_VERSION, compid:%04X,lmp_subvers:%04X,lmp_vers:%02X,\r\n",
2173 info->info.version.compid, info->info.version.lmp_subvers, info->info.version.lmp_vers);
2174 break;
2175 case SONATA_GET_PEER_FEATURES:
2176 APP_TRC("APP_CB: SONATA_GET_PEER_FEATURES, features:");
2177 for (int i = 0; i < SONATA_GAP_LE_FEATS_LEN; ++i) {
2178 APP_TRC("%02x ", info->info.features.features[i]);
2179 }
2180 APP_TRC("\r\n");
2181 break;
2182 case SONATA_GET_PEER_CON_RSSI:
2183 APP_TRC("APP_CB: SONATA_GET_PEER_CON_RSSI, rssi:%04X\r\n", info->info.rssi.rssi);
2184
2185 break;
2186 case SONATA_GET_PEER_CON_CHANNEL_MAP:
2187 APP_TRC("APP_CB: SONATA_GET_PEER_CON_CHANNEL_MAP, map:");
2188 for (int i = 0; i < SONATA_GAP_LE_CHNL_MAP_LEN; ++i) {
2189 APP_TRC("%02x ", info->info.channel_map.ch_map.map[i]);
2190 }
2191 APP_TRC("\r\n");
2192 break;
2193 case SONATA_GET_LE_PING_TO:
2194 APP_TRC("APP_CB: SONATA_GET_LE_PING_TO, timeout:%04X,\r\n", info->info.ping_to_value.timeout);
2195 break;
2196 case SONATA_GET_PHY:
2197 APP_TRC("APP_CB: SONATA_GET_PHY, tx_phy:%02X, rx_phy:%02X\r\n", info->info.le_phy.tx_phy, info->info.le_phy.rx_phy);
2198 break;
2199 case SONATA_GET_CHAN_SEL_ALGO:
2200 APP_TRC("APP_CB: SONATA_GET_CHAN_SEL_ALGO, chan_sel_algo:%04X,\r\n", info->info.sel_algo.chan_sel_algo);
2201 break;
2202 default:
2203 break;
2204 }
2205
2206 return CB_DONE;
2207 }
2208
2209 /*!
2210 * @brief
2211 * @param conidx
2212 * @param intv_min
2213 * @param intv_max
2214 * @param latency
2215 * @param time_out
2216 */
app_gap_param_update_req_callback(uint8_t conidx,uint16_t intv_min,uint16_t intv_max,uint16_t latency,uint16_t time_out)2217 static uint16_t app_gap_param_update_req_callback(uint8_t conidx, uint16_t intv_min, uint16_t intv_max,
2218 uint16_t latency, uint16_t time_out)
2219 {
2220 APP_TRC("APP_CB: %s conidx=%02X,intv_min=%04X,intv_max=%04X,latency=%04X,time_out=%04X\r\n", __FUNCTION__, conidx,
2221 intv_min, intv_max, latency, time_out);
2222 sonata_ble_gap_send_param_update_cfm(conidx, true, 2, 4);
2223 return CB_DONE;
2224 }
2225
2226 /*!
2227 * @brief
2228 * @param conidx
2229 * @param con_interval
2230 * @param con_latency
2231 * @param sup_to
2232 * @return
2233 */
app_gap_param_updated_callback(uint8_t conidx,uint16_t con_interval,uint16_t con_latency,uint16_t sup_to)2234 static uint16_t app_gap_param_updated_callback(uint8_t conidx, uint16_t con_interval, uint16_t con_latency,
2235 uint16_t sup_to)
2236 {
2237 APP_TRC("APP_CB: %s conidx=%02X,con_interval=%04X,con_latency=%04X,sup_to=%04X\r\n", __FUNCTION__, conidx,
2238 con_interval, con_latency, sup_to);
2239
2240 return CB_DONE;
2241
2242 }
2243
2244 /*!
2245 * @brief
2246 * @param conidx
2247 * @param length
2248 * @param name
2249 * @return
2250 */
app_gap_peer_set_local_device_name_callback(uint8_t conidx,uint16_t length,uint8_t * name)2251 static uint16_t app_gap_peer_set_local_device_name_callback(uint8_t conidx, uint16_t length, uint8_t *name)
2252 {
2253 sonata_ble_gap_send_set_dev_name_cfm(conidx, SONATA_GAP_ERR_REJECTED);
2254 APP_TRC("name:");
2255 for (int i = 0; i < length; ++i) {
2256 APP_TRC("%02X ", name[i]);
2257 }
2258 APP_TRC(" \r\n");
2259 return CB_DONE;
2260 }
2261
app_set_connect_flag(uint8_t vaule)2262 void app_set_connect_flag(uint8_t vaule)
2263 {
2264 need_connect_confirm = vaule;
2265 }
2266
app_gap_send_connection_confirm(uint8_t conidx,uint8_t auth)2267 static void app_gap_send_connection_confirm(uint8_t conidx, uint8_t auth)
2268 {
2269 sonata_gap_connection_cfm_t connectionCfm = {0};
2270 // Get bond status from FS
2271 if (app_bond == 1) {
2272 connectionCfm.auth = SONATA_GAP_AUTH_REQ_NO_MITM_BOND;
2273 APP_TRC("APP: %s connectionCfm.auth=GAP_AUTH_REQ_NO_MITM_BOND\r\n", __FUNCTION__);
2274 } else {
2275 connectionCfm.auth = SONATA_GAP_AUTH_REQ_NO_MITM_NO_BOND;
2276 APP_TRC("APP: %s connectionCfm.auth=GAP_AUTH_REQ_SEC_CON_BOND\r\n", __FUNCTION__);
2277
2278 }
2279 memcpy(connectionCfm.lcsrk.key, app_csrk, SONATA_GAP_KEY_LEN);
2280 connectionCfm.auth = auth;
2281
2282 sonata_ble_gap_send_connection_cfm(conidx, &connectionCfm);
2283 }
2284
app_gap_connect_confirm(uint8_t * addr,uint8_t auth)2285 void app_gap_connect_confirm(uint8_t *addr, uint8_t auth)
2286 {
2287 uint8_t conidx = app_get_conidx_by_addr(addr);
2288 APP_TRC("APP_CB: %s ", __FUNCTION__);
2289 sonata_ble_gap_start_security(conidx, auth);
2290 APP_TRC("id %d auth %d:", conidx, auth);
2291 }
2292
app_active_update(uint8_t conIdx,uint8_t * mac)2293 void app_active_update(uint8_t conIdx, uint8_t *mac)
2294 {
2295 if (conIdx > APP_ACTIVE_MAX) {
2296 APP_TRC("APP: %s,ERROR:ACTIVE overflow\r\n", __FUNCTION__);
2297 return;
2298 }
2299 if (gAppEnv.act[conIdx].runing == true) {
2300 APP_TRC("APP: %s,ERROR:ACTIVE id error\r\n", __FUNCTION__);
2301 return;
2302 }
2303 gAppEnv.act[conIdx].runing = true;
2304 gAppEnv.act[conIdx].assign_id = conIdx;
2305 memcpy(gAppEnv.act[conIdx].peer, mac, SONATA_GAP_BD_ADDR_LEN);
2306 }
2307
app_gap_connection_req_callback(uint8_t conidx,sonata_gap_connection_req_ind_t * req)2308 static uint16_t app_gap_connection_req_callback(uint8_t conidx, sonata_gap_connection_req_ind_t *req)
2309 {
2310 APP_TRC("APP_CB: %s ", __FUNCTION__);
2311 APP_TRC("peer_addr:");
2312 for (int i = 0; i < SONATA_GAP_BD_ADDR_LEN; ++i) {
2313 APP_TRC("%02X ", req->peer_addr.addr[i]);
2314 }
2315 APP_TRC(" \r\n");
2316 app_active_update(conidx, req->peer_addr.addr);
2317
2318 memmove(target_address, req->peer_addr.addr, SONATA_GAP_BD_ADDR_LEN);
2319 ble_connect_id = conidx;
2320 app_connect_req_list_add(req->peer_addr.addr, conidx);
2321 APP_TRC("ble_connect_id %d \r\n", ble_connect_id);
2322 // sonata_ble_gatt_exchange_mtu(conidx);
2323 app_connected_state = APP_STATE_CONNECTED;
2324 if (ble_cb_fun != NULL) {
2325 ble_cb_fun(MS_BLE_STACK_EVENT_CONNECTED);
2326 }
2327
2328 if (app_evt_cb != NULL) {
2329 app_connect_status_ind_t status_ind;
2330 status_ind.connId = conidx;
2331 memmove(status_ind.addr, req->peer_addr.addr, SONATA_GAP_BD_ADDR_LEN);
2332 app_evt_cb(BLE_DEV_CONNECTED, (void *) &status_ind);
2333 }
2334
2335 if (app_bond) {
2336 sonata_gap_connection_cfm_t connectionCfm = {0};
2337
2338 memcpy(connectionCfm.lcsrk.key, app_csrk, SONATA_GAP_KEY_LEN);
2339 connectionCfm.auth = SONATA_GAP_AUTH_REQ_SEC_CON_BOND;
2340
2341 sonata_ble_gap_send_connection_cfm(conidx, &connectionCfm);
2342 return CB_DONE; // SDK will send connection confirm message
2343 } else {
2344 sonata_gap_connection_cfm_t connectionCfm = {0};
2345 connectionCfm.auth = SONATA_GAP_AUTH_REQ_NO_MITM_NO_BOND;
2346 sonata_ble_gap_send_connection_cfm(conidx, &connectionCfm);
2347 sonata_ble_gap_get_peer_info(conidx, SONATA_GET_PEER_NAME);
2348 return CB_DONE;
2349 }
2350 }
2351
2352 /*!
2353 * @brief
2354 * @param connection_id
2355 * @param handle
2356 * @return
2357 */
app_gatt_read_request_callback(uint8_t connection_id,uint16_t handle)2358 static uint16_t app_gatt_read_request_callback(uint8_t connection_id, uint16_t handle)
2359 {
2360 // APP_TRC("APP_CB: %s, handle=0x%04X,custom_svc_start_handle=0x%04X", __FUNCTION__,handle,custom_svc_start_handle);
2361 APP_TRC("APP_CB: %s, handle=0x%04X,\r\n", __FUNCTION__, handle);
2362 uint16_t length = 250;
2363 uint8_t *value = sonata_api_malloc(length);
2364 app_ble_gatt_read_request_handler(handle, &length, value);
2365 sonata_ble_gatt_send_read_confirm(connection_id, handle, SONATA_GAP_ERR_NO_ERROR, length, value);
2366 sonata_api_free(value);
2367 return CB_REJECT;
2368 }
2369
app_gatt_read_callback(uint8_t conidx,uint16_t handle,uint16_t offset,uint16_t length,uint8_t * value)2370 static uint16_t app_gatt_read_callback(uint8_t conidx, uint16_t handle, uint16_t offset, uint16_t length,
2371 uint8_t *value)
2372 {
2373 // APP_TRC("APP_CB: %s, handle=0x%04X,custom_svc_start_handle=0x%04X", __FUNCTION__,handle,custom_svc_start_handle);
2374 APP_TRC("APP_CB: %s, handle=0x%04X,\r\n", __FUNCTION__, handle);
2375 return CB_REJECT;
2376 }
2377
2378 /*!
2379 * @brief
2380 * @param connection_id
2381 * @param handle
2382 * @param offset
2383 * @param length
2384 * @param value
2385 * @return
2386 */
app_gatt_write_request_callback(uint8_t connection_id,uint16_t handle,uint16_t offset,uint16_t length,uint8_t * value)2387 static uint16_t app_gatt_write_request_callback(uint8_t connection_id, uint16_t handle, uint16_t offset,
2388 uint16_t length, uint8_t *value)
2389 {
2390 // APP_TRC("APP_CB: %s, handle=0x%04X,custom_svc_start_handle=0x%04X", __FUNCTION__,handle,custom_svc_start_handle);
2391 APP_TRC("APP_CB: %s, handle=0x%04X offset %d\r\n", __FUNCTION__, handle, offset);
2392
2393 sonata_ble_gatt_send_write_confirm(connection_id, handle, SONATA_GAP_ERR_NO_ERROR);
2394 app_ble_gatt_write_request_handler(handle, length, value);
2395
2396 return CB_DONE;
2397 }
2398
2399 /*!
2400 * @brief
2401 * @param connection_id
2402 * @param mtu
2403 * @return
2404 */
app_gatt_mtu_changed_callback(uint8_t connection_id,uint16_t mtu)2405 static uint16_t app_gatt_mtu_changed_callback(uint8_t connection_id, uint16_t mtu)
2406 {
2407 APP_TRC("APP_CB: %s, mtu=0x%04X\r\n", __FUNCTION__, mtu);
2408 if (app_evt_cb != NULL) {
2409 app_mtu_change_ind_t status_ind;
2410 status_ind.connId = connection_id;
2411 status_ind.mtu = mtu;
2412 app_evt_cb(BLE_MTU_CHANGE, (void *)&status_ind);
2413 }
2414 return CB_DONE;
2415 }
2416
2417 /*!
2418 * @brief
2419 * @param connection_id
2420 * @param handle
2421 * @param offset
2422 * @param length
2423 * @param value
2424 * @return
2425 */
app_gatt_att_info_req_ind_callback(uint8_t connection_id,uint16_t handle)2426 static uint16_t app_gatt_att_info_req_ind_callback(uint8_t connection_id, uint16_t handle)
2427 {
2428 // APP_TRC("APP_CB: %s, handle=0x%04X,custom_svc_start_handle=0x%04X", __FUNCTION__,handle,custom_svc_start_handle);
2429 APP_TRC("APP_CB: %s, handle=0x%04X\r\n", __FUNCTION__, handle);
2430 uint16_t length = 0;
2431 uint8_t status;
2432 length = 200;
2433 status = SONATA_GAP_ERR_NO_ERROR;
2434 sonata_ble_gatt_send_att_info_confirm(connection_id, handle, length, status);
2435 return CB_DONE;
2436 }
2437
app_ble_master_write_data(uint8_t conidx,uint16_t length,uint8_t * data)2438 bool app_ble_master_write_data(uint8_t conidx, uint16_t length, uint8_t *data)
2439 {
2440 if (gAppEnv.targetWriteHandle != 0) {
2441 APP_TRC("APP: %s,targetWriteHandle=%d, dataLen=%d\r\n", __FUNCTION__, gAppEnv.targetWriteHandle, length);
2442 sonata_ble_gatt_write(conidx, gAppEnv.targetWriteHandle, 0, 0, length, data);
2443 } else {
2444 APP_TRC("ERR: %s,targetWriteHandle [%d] is wrong, can't write data\r\n", __FUNCTION__, gAppEnv.targetWriteHandle);
2445
2446 }
2447 return false;
2448 }
2449
app_ble_master_read_data(uint8_t conidx,uint16_t length,uint8_t * data)2450 bool app_ble_master_read_data(uint8_t conidx, uint16_t length, uint8_t *data)
2451 {
2452 if (gAppEnv.targetReadHandle != 0) {
2453 sonata_ble_gatt_read_by_handle(conidx, gAppEnv.targetReadHandle);
2454 } else {
2455 APP_TRC_ERROR("ERR: %s,targetReadHandle [%d] is wrong, can't read data\r\n", __FUNCTION__, gAppEnv.targetWriteHandle);
2456 }
2457 return false;
2458 }
2459
app_ble_master_turn_ntf(uint8_t conidx,bool on)2460 bool app_ble_master_turn_ntf(uint8_t conidx, bool on)
2461 {
2462 if (gAppEnv.targetNtfHandle != 0) {
2463 APP_TRC("APP: %s,targetNtfHandle=%d, on=%d\r\n", __FUNCTION__, gAppEnv.targetNtfHandle, on);
2464
2465 uint8_t ntf_cfg[2] = {0};
2466 if (on) {
2467 ntf_cfg[0] = 1;
2468 } else {
2469 ntf_cfg[0] = 0;
2470 }
2471 sonata_ble_gatt_write(conidx, gAppEnv.targetNtfHandle, 0, 0, 2, ntf_cfg);
2472 return true;
2473 } else {
2474 APP_TRC_ERROR("ERR: %s,targetNtfHandle [%d] is wrong, can't opt NTF\r\n", __FUNCTION__, gAppEnv.targetNtfHandle);
2475 }
2476 return false;
2477 }
2478
2479 /*!
2480 * @brief: app profile api init
2481 * @param none
2482 * @return none
2483 */
app_prf_api_init(void)2484 void app_prf_api_init(void)
2485 {
2486 #if BLE_MESH
2487 sonata_mesh_api_init();
2488 #endif
2489 #if BLE_DIS_SERVER
2490 sonata_prf_diss_init();
2491 #endif
2492 #if BLE_BATT_SERVER
2493 sonata_prf_bass_init();
2494 #endif
2495 }
2496
2497 #if !defined ALIOS_SUPPORT && !defined HARMONYOS_SUPPORT
app_at_cmd_handler(void * p_param)2498 static uint8_t app_at_cmd_handler(void *p_param)
2499 {
2500 at_command_process_ble();
2501
2502 return API_SUCCESS;
2503 }
2504 #endif
2505
2506 /*
2507 * LOCAL VARIABLES DEFINITIONS
2508 ****************************************************************************************
2509 */
2510
2511 sonata_ble_hook_t app_hook = {
2512 assert_err,
2513 assert_param,
2514 assert_warn,
2515 app_init,
2516 platform_reset,
2517 get_stack_usage,
2518 #if defined ALIOS_SUPPORT || defined HARMONYOS_SUPPORT
2519 printf,
2520 #else
2521 __wrap_printf,
2522 #endif
2523 app_prf_api_init,
2524 #ifdef SONATA_RTOS_SUPPORT
2525 (void *)lega_rtos_init_semaphore,
2526 (void *)lega_rtos_get_semaphore,
2527 (void *)lega_rtos_set_semaphore,
2528 #endif
2529
2530 };
gap_active_stopped_callback(uint8_t actv_idx,uint8_t type,uint8_t reason,uint8_t per_adv_stop)2531 uint16_t gap_active_stopped_callback(uint8_t actv_idx, uint8_t type, uint8_t reason, uint8_t per_adv_stop)
2532 {
2533 APP_TRC("APP_CB: %s, reason=0x%04X\r\n", __FUNCTION__, reason);
2534 if (SONATA_GAP_ACTV_TYPE_ADV == type) {
2535 ble_adv_state = BLE_ADV_STATE_CREATED;
2536 if (app_evt_cb != NULL) {
2537 app_adv_status_ind_t status_ind;
2538 status_ind.advId = actv_idx;
2539 status_ind.status = reason;
2540 app_evt_cb(BLE_ADV_STOP, (void *)&status_ind);
2541 }
2542 }
2543 if (SONATA_GAP_ACTV_TYPE_SCAN == type) {
2544 return CB_REJECT; // delete scan instance
2545 }
2546 if (SONATA_GAP_ACTV_TYPE_INIT == type) {
2547 return CB_REJECT; // delete init instance
2548 }
2549 return CB_DONE;
2550 }
2551
2552 static ble_gap_callback ble_gap_callbacks = {
2553 /*************** GAP Manager's callback ***************/
2554
2555 // Must if use scan function, peer's information will show in this callback
2556 .gap_scan_result = app_gap_scan_result_callback,
2557 // Optional, use for get local devcie informations when call sonata_ble_get_dev_info()
2558 .get_local_dev_info = app_get_dev_info_callback,
2559
2560 /*************** GAP Controller's callback ***************/
2561 // Optional
2562 .gap_param_update_req = app_gap_param_update_req_callback,
2563 // Optional
2564 .gap_param_updated = app_gap_param_updated_callback,
2565 // Optional, used for get peer att information when call sonata_ble_gap_get_peer_info()
2566 .gap_get_peer_info = app_gap_peer_info_callback,
2567 // Optional, used for get peer att information when call sonata_ble_gap_get_peer_info()
2568 .gap_get_peer_att_info = app_gap_peer_att_info_callback,
2569 // Optional, if peer device get local device's information, app can deal with it in this callback
2570 .gap_peer_get_local_info = app_gap_peer_get_local_info_callback,
2571 // Optional
2572 .gap_disconnect_ind = app_gap_disconnect_ind_callback,
2573 // Optional, if peer device set local device's name, app can deal with it in this callback
2574 .gap_peer_set_local_device_name = app_gap_peer_set_local_device_name_callback,
2575 // Optional, app can save peer mac address in this callback when connected
2576 .gap_connection_req = app_gap_connection_req_callback,
2577 .gap_active_stopped = gap_active_stopped_callback,
2578 .gap_bond_req = app_gap_bond_req_callback,
2579 .gap_bond = app_gap_bond_callback,
2580 .gap_encrypt_req = app_gap_encrypt_req_callback,
2581 .gap_gen_random_number = app_gap_gen_random_number_callback,
2582 .gap_security = app_gap_security_callback,
2583 .gap_encrypt = app_gap_encrypt_callback,
2584 .gap_le_pkt_size = app_gap_le_pke_size_callback,
2585
2586 };
2587
2588 static ble_gatt_callback ble_gatt_callbacks = {
2589 // Optional, add this callback if app need to save changed mtu value
2590 .gatt_mtu_changed = app_gatt_mtu_changed_callback,
2591 // Must,If app add custom service, app should add this callback to deal with peer device read request
2592 .gatt_read_req = app_gatt_read_request_callback,
2593 .gatt_read = app_gatt_read_callback,
2594 // Must,If app add custom service, app should add this callback to deal with peer device write request
2595 .gatt_write_req = app_gatt_write_request_callback,
2596 // Must if use discovery all servcie function
2597 .gatt_disc_svc = app_gatt_disc_svc_callback,
2598 // Must if use discovery all characteristic function
2599 .gatt_disc_char = app_gatt_disc_char_callback,
2600 // Must if use discovery all description function
2601 .gatt_disc_char_desc = app_gatt_disc_desc_callback,
2602 .gatt_event = app_gatt_event_callback,
2603 .gatt_att_info_req = app_gatt_att_info_req_ind_callback,
2604 };
2605
2606 static ble_complete_callback ble_complete_callbacks = {
2607 // Must, app can do next operation in this callback
2608 .ble_complete_event = app_ble_complete_event_handler,
2609 };
2610
2611 static ble_response_callback ble_rsp_callbacks = {
2612 // Must,IF app add custom service, add should save this service's start handler id,
2613 // this id will be used in app_gatt_read_request_callback() and app_gatt_write_request_callback()
2614 .ble_rsp_event = app_ble_rsp_event_handler,
2615 };
2616
2617 #if !defined ALIOS_SUPPORT && !defined HARMONYOS_SUPPORT
2618 sonata_api_app_msg_t app_at_cmd_msg = {
2619 .operation = APP_MSG_AT_CMD,
2620 .function = app_at_cmd_handler,
2621 };
2622 #endif
2623
2624 /*
2625 * GLOBAL VARIABLE DEFINITIONS
2626 ****************************************************************************************
2627 */
2628
2629 /*
2630 * GLOBAL FUNCTION DEFINITIONS
2631 ****************************************************************************************
2632 */
app_init(void)2633 void app_init(void)
2634 {
2635 APP_TRC("APP: %s \r\n", __FUNCTION__);
2636 sonata_log_level_set(SONATA_LOG_VERBOSE);
2637
2638 sonata_ble_register_gap_callback(&ble_gap_callbacks);
2639 sonata_ble_register_gatt_callback(&ble_gatt_callbacks);
2640 sonata_ble_register_complete_callback(&ble_complete_callbacks);
2641 sonata_ble_register_response_callback(&ble_rsp_callbacks);
2642 app_data_init();
2643 app_ble_on();
2644
2645 sonata_api_register_app_timer_callback(&app_timer_callbacks);
2646
2647 #if !defined ALIOS_SUPPORT && !defined HARMONYOS_SUPPORT
2648 // at command init
2649 at_init();
2650
2651 // register app message
2652 sonata_api_app_msg_register(&app_at_cmd_msg);
2653 #endif
2654 }
2655
2656 uint16_t test_count = 0;
2657 uint16_t test_interval = 0;
2658 uint8_t write_value[128] = {0x1, 0x2, 0x3, 0x4, 0x5};
2659 bool ble_test_mode = false;
2660
app_is_ble_test_mode(void)2661 bool app_is_ble_test_mode(void)
2662 {
2663 return ble_test_mode;
2664 }
2665
app_set_ble_test_mode(bool mode)2666 void app_set_ble_test_mode(bool mode)
2667 {
2668 ble_test_mode = mode;
2669 }
2670
app_ble_set_test_count(uint16_t counter)2671 void app_ble_set_test_count(uint16_t counter)
2672 {
2673 test_count = counter;
2674 }
2675
app_ble_set_test_target(uint8_t * target)2676 void app_ble_set_test_target(uint8_t *target)
2677 {
2678 APP_TRC("APP: %s \r\n", __FUNCTION__);
2679
2680 memcpy(target_address, target, SONATA_GAP_BD_ADDR_LEN);
2681 for (int i = 0 ; i < SONATA_GAP_BD_ADDR_LEN; i++) {
2682 APP_TRC("%x ", target_address[i]);
2683 }
2684 APP_TRC("\r\n ");
2685 }
2686
app_ble_set_test_write_uuid(uint8_t * uuid)2687 void app_ble_set_test_write_uuid(uint8_t *uuid)
2688 {
2689 APP_TRC("APP: %s \r\n", __FUNCTION__);
2690
2691 memcpy(write_uuid, uuid, 2);
2692 for (int i = 0 ; i < 2; i++) {
2693 APP_TRC("%x ", write_uuid[i]);
2694 }
2695 APP_TRC("\r\n ");
2696 }
2697
app_ble_set_test_read_uuid(uint8_t * uuid)2698 void app_ble_set_test_read_uuid(uint8_t *uuid)
2699 {
2700 APP_TRC("APP: %s \r\n", __FUNCTION__);
2701
2702 memcpy(read_uuid, uuid, 2);
2703 for (int i = 0 ; i < 2; i++) {
2704 APP_TRC("%x ", read_uuid[i]);
2705 }
2706 APP_TRC("\r\n ");
2707 }
2708
app_ble_set_test_interval(uint16_t interval)2709 void app_ble_set_test_interval(uint16_t interval)
2710 {
2711 test_interval = interval;
2712 }
2713
app_timer_handler(uint16_t id)2714 static uint8_t app_timer_handler(uint16_t id)
2715 {
2716 APP_TRC("APP: %s . id=%d\r\n", __FUNCTION__, id);
2717
2718 if (id == 6) {
2719 static uint8_t adv = 0;
2720 if (test_count > 0) {
2721 if (!adv) {
2722 adv_value[9] = test_count;
2723 #ifdef HARMONYOS_TEMP
2724 #else
2725 #endif
2726 } else {
2727 #ifdef HARMONYOS_TEMP
2728 #else
2729 #endif
2730 }
2731 adv = 1 - adv;
2732 test_count--;
2733 sonata_api_app_timer_set(6, 20);
2734 sonata_api_app_timer_active(6);
2735 } else {
2736
2737 APP_TRC("APP: %s . id=%d test done \r\n", __FUNCTION__, id);
2738 sonata_api_app_timer_clear(1);
2739 }
2740
2741 }
2742 if (id == 7) {
2743 static uint8_t flag = 0;
2744 if (test_count > 0) {
2745 if (flag == 0) {
2746 flag = 1;
2747 } else {
2748 test_count--;
2749
2750 }
2751
2752 adv_value[9] = test_count;
2753 sonata_ble_set_advertising_data(adv_length - 3, adv_value + 3);
2754 sonata_api_app_timer_set(7, 20);
2755 sonata_api_app_timer_active(7);
2756 } else {
2757
2758 flag = 0;
2759 APP_TRC("APP: %s . id=%d test done \r\n", __FUNCTION__, id);
2760 sonata_api_app_timer_clear(2);
2761 }
2762 }
2763
2764 if (id == 8) {
2765 static uint8_t scan_flag = 0;
2766
2767 if (scan_flag == 0) {
2768 scan_flag = 1;
2769 app_ble_config_scanning();
2770 sonata_api_app_timer_set(8, 100);
2771 sonata_api_app_timer_active(8);
2772 } else {
2773 app_ble_start_scanning();
2774
2775 scan_flag = 0;
2776 sonata_api_app_timer_clear(8);
2777 }
2778 }
2779
2780 if (id == 3) {
2781 app_ble_config_initiating();
2782 }
2783
2784 if (id == 4) {
2785 sonata_ble_gatt_write(ble_connect_id, write_handle + 1, 0, 0, 128, write_value);
2786
2787 sonata_api_app_timer_set(4, test_interval);
2788 sonata_api_app_timer_active(4);
2789 }
2790 if (id == 5) {
2791 sonata_api_app_timer_set(5, 500);
2792 sonata_api_app_timer_active(5);
2793 }
2794 return 0;
2795
2796 }
2797
2798 extern int init_ble_task(void);
2799 extern int deinit_ble_task(void);
2800
2801 uint32_t ble_open = 0;
2802
2803 // 连接相关
app_ble_stack_start(ble_stack_opr_module_id_t module)2804 int app_ble_stack_start(ble_stack_opr_module_id_t module)
2805 {
2806
2807 if (0 != ble_open) {
2808 ble_open |= (1UL << module);
2809 return 0;
2810 }
2811 ble_open |= (1UL << module);
2812 init_ble_task();
2813 return 0;
2814 }
2815
app_ble_stack_stop(ble_stack_opr_module_id_t module)2816 int app_ble_stack_stop(ble_stack_opr_module_id_t module)
2817 {
2818
2819 ble_open &= ~(1UL << module);
2820 if (0 != ble_open) {
2821 return 0;
2822 }
2823 APP_TRC("APP: %s \r\n", __FUNCTION__);
2824 ble_close();
2825 return 0;
2826 }
2827
app_ble_disconnect_by_addr(uint8_t * addr)2828 int app_ble_disconnect_by_addr(uint8_t *addr)
2829 {
2830 uint8_t conidx = app_get_conidx_by_addr(addr);
2831 if (conidx != ble_connect_id) {
2832 APP_TRC("APP: %s not found device\r\n", __FUNCTION__);
2833 app_print_hex(addr, APP_BD_ADDR_LEN);
2834 }
2835 app_ble_disconnect(ble_connect_id);
2836 return 0;
2837 }
2838
app_ble_set_target_address(uint8_t * target)2839 void app_ble_set_target_address(uint8_t *target)
2840 {
2841 APP_TRC("APP: %s \r\n", __FUNCTION__);
2842
2843 memcpy(target_address, target, SONATA_GAP_BD_ADDR_LEN);
2844 for (int i = 0 ; i < SONATA_GAP_BD_ADDR_LEN; i++) {
2845 APP_TRC("%x ", target_address[i]);
2846 }
2847 APP_TRC("\r\n ");
2848 }
2849
app_ble_set_uuids(uint16_t service,uint16_t read,uint16_t write,uint16_t ntf)2850 void app_ble_set_uuids(uint16_t service, uint16_t read, uint16_t write, uint16_t ntf)
2851 {
2852 APP_TRC("APP: %s service=0x%04X,read=0x%04X,write=0x%04X,ntf=0x%04X\r\n", __FUNCTION__, service, read, write, ntf);
2853
2854 gAppEnv.appUuids.service = service;
2855 gAppEnv.appUuids.read = read;
2856 gAppEnv.appUuids.write = write;
2857 gAppEnv.appUuids.ntf = ntf;
2858 }
2859
app_ble_get_uuids()2860 app_uuids *app_ble_get_uuids()
2861 {
2862 return &gAppEnv.appUuids;
2863 }
2864
app_get_active()2865 actives *app_get_active()
2866 {
2867 return gAppEnv.act;
2868 }
2869
app_register_core_evt_ind(app_core_evt_ind_cb cb)2870 void app_register_core_evt_ind(app_core_evt_ind_cb cb)
2871 {
2872 app_evt_cb = cb;
2873 }
2874
app_register_sec_cb(app_sec_req_cb cb)2875 void app_register_sec_cb(app_sec_req_cb cb)
2876 {
2877 sec_req_call = cb;
2878 }
2879
2880 extern CRITICAL_FUNC_SEG void sonata_ble_isr(void);
BLE_IRQHandler(void)2881 CRITICAL_FUNC_SEG void BLE_IRQHandler(void)
2882 {
2883 sonata_ble_isr();
2884 }
2885
2886 // @} APP
2887