1 /*
2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., 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 #include "ble_ip_config.h" // SW configuration
17 #include "ble_hl_config.h"
18
19 #if (BLE_APP_PRESENT)
20
21 #include "app_present_task.h" // Application Manager Task API
22 #include "app_present.h" // Application Manager Definition
23 #include "hal_gapc_task.h" // GAP Controller Task API
24 #include "hal_gapm_task.h" // GAP Manager Task API
25 #include "arch.h" // Platform Definitions
26 #include <string.h>
27 #include "ble_common_utils.h"
28 #include "ble_ke_timer.h" // Kernel timer
29 #include "csble.h"
30
31 #if (BLE_APP_SEC)
32 #include "app_present_sec.h" // Security Module Definition
33 #endif //(BLE_APP_SEC)
34
35 #if (BLE_APP_HT)
36 #include "app_ht.h" // Health Thermometer Module Definition
37 #include "htpt_task.h"
38 #endif //(BLE_APP_HT)
39
40 #if (BLE_APP_DIS)
41 #include "app_dis.h" // Device Information Module Definition
42 #include "diss_task.h"
43 #endif //(BLE_APP_DIS)
44
45 #if (BLE_APP_BATT)
46 #include "app_batt.h" // Battery Module Definition
47 #endif //(BLE_APP_BATT)
48
49 #if (BLE_APP_HID)
50 #include "app_hid.h" // HID Module Definition
51 #include "hid_over_gatt_task.h"
52 #endif //(BLE_APP_HID)
53
54 #if (BLE_APP_AM0)
55 #include "app_am0.h" // Audio Mode 0 Application
56 #endif //(BLE_APP_AM0)
57
58 #if (BLE_APP_SMARTCONFIG)
59 #include "app_smartconfig.h" // Smart Config Module Definition
60 #include "smartconfig_task.h"
61 #endif // (BLE_APP_SMARTCONFIG)
62
63 #if (DISPLAY_SUPPORT)
64 #include "app_display.h" // Application Display Definition
65 #endif //(DISPLAY_SUPPORT)
66
67 #include "flash_api.h"
68
69 /*
70 * LOCAL FUNCTION DEFINITIONS
71 ****************************************************************************************
72 */
73
app_get_handler(const struct app_subtask_handlers * handler_list_desc,ke_msg_id_t msgid,void * param,ke_task_id_t src_id)74 static uint8_t app_get_handler(const struct app_subtask_handlers *handler_list_desc,
75 ke_msg_id_t msgid,
76 void *param,
77 ke_task_id_t src_id)
78 {
79 // Counter
80 uint8_t counter;
81
82 // Get the message handler function by parsing the message table
83 for (counter = handler_list_desc->msg_cnt; 0 < counter; counter--)
84 {
85 struct ke_msg_handler handler
86 = (struct ke_msg_handler)(*(handler_list_desc->p_msg_handler_tab + counter - 1));
87
88 if ((handler.id == msgid) ||
89 (handler.id == KE_MSG_DEFAULT_HANDLER))
90 {
91 // If handler is NULL, message should not have been received in this state
92 ASSERT_ERR(handler.func);
93
94 return (uint8_t)(handler.func(msgid, param, TASK_APP, src_id));
95 }
96 }
97
98 // If we are here no handler has been found, drop the message
99 return (KE_MSG_CONSUMED);
100 }
101
102 /*
103 * MESSAGE HANDLERS
104 ****************************************************************************************
105 */
106
107 /**
108 ****************************************************************************************
109 * @brief Handles GAPM_ACTIVITY_CREATED_IND event
110 *
111 * @param[in] msgid Id of the message received.
112 * @param[in] param Pointer to the parameters of the message.
113 * @param[in] dest_id ID of the receiving task instance.
114 * @param[in] src_id ID of the sending task instance.
115 *
116 * @return If the message was consumed or not.
117 ****************************************************************************************
118 */
gapm_activity_created_ind_handler(ke_msg_id_t const msgid,struct gapm_activity_created_ind const * p_param,ke_task_id_t const dest_id,ke_task_id_t const src_id)119 static int gapm_activity_created_ind_handler(ke_msg_id_t const msgid,
120 struct gapm_activity_created_ind const *p_param,
121 ke_task_id_t const dest_id,
122 ke_task_id_t const src_id)
123 {
124 if (app_env.adv_state == APP_ADV_STATE_CREATING)
125 {
126 // Store the advertising activity index
127 app_env.adv_actv_idx = p_param->actv_idx;
128 }
129
130 if (app_env.scan_state == APP_SCAN_STATE_CREATING)
131 {
132 // Store the scan activity index
133 app_env.scan_actv_idx = p_param->actv_idx;
134 dbg("%s ,actv_idx = %x\n",__func__,app_env.scan_actv_idx);
135 }
136
137 return (KE_MSG_CONSUMED);
138 }
139
140 /**
141 ****************************************************************************************
142 * @brief Handles GAPM_ACTIVITY_STOPPED_IND event.
143 *
144 * @param[in] msgid Id of the message received.
145 * @param[in] param Pointer to the parameters of the message.
146 * @param[in] dest_id ID of the receiving task instance.
147 * @param[in] src_id ID of the sending task instance.
148 *
149 * @return If the message was consumed or not.
150 ****************************************************************************************
151 */
gapm_activity_stopped_ind_handler(ke_msg_id_t const msgid,struct gapm_activity_stopped_ind const * p_param,ke_task_id_t const dest_id,ke_task_id_t const src_id)152 static int gapm_activity_stopped_ind_handler(ke_msg_id_t const msgid,
153 struct gapm_activity_stopped_ind const *p_param,
154 ke_task_id_t const dest_id,
155 ke_task_id_t const src_id)
156 {
157 if (app_env.adv_state == APP_ADV_STATE_STARTED)
158 {
159 // Act as if activity had been stopped by the application
160 app_env.adv_state = APP_ADV_STATE_STOPPING;
161 dbg("## %s app_env.adv_state %d\r\n", __func__, app_env.adv_state);
162
163 #if (!BLE_APP_SMARTCONFIG)
164 // Perform next operation
165 appm_adv_fsm_next();
166 #else
167 user_sleep_allow(0);
168 #endif // !BLE_APP_SMARTCONFIG
169 }
170 if (app_env.scan_state == APP_SCAN_STATE_STARTED)
171 {
172 // Act as if activity had been stopped by the application
173 app_env.scan_state = APP_SCAN_STATE_STOPPING;
174 dbg("## %s app_env.scan_state %d\r\n", __func__, app_env.scan_state);
175
176 #if (!BLE_APP_SMARTCONFIG)
177 // Perform next operation
178 appm_scan_fsm_next();
179 #else
180 user_sleep_allow(0);
181 #endif // !BLE_APP_SMARTCONFIG
182 }
183
184 if (app_env.adv_state == APP_ADV_STATE_STOPPING)
185 {
186 if (ble_callback) {
187 ble_callback(APP_DEINIT_FLAG_ADV, p_param->reason);
188 }
189 }
190
191 if (app_env.scan_state == APP_SCAN_STATE_STOPPING)
192 {
193 if (ble_callback) {
194 ble_callback(APP_DEINIT_FLAG_SCAN, p_param->reason);
195 }
196 }
197 return (KE_MSG_CONSUMED);
198 }
199
200 /**
201 ****************************************************************************************
202 * @brief Handles GAPM_PROFILE_ADDED_IND event
203 *
204 * @param[in] msgid Id of the message received.
205 * @param[in] param Pointer to the parameters of the message.
206 * @param[in] dest_id ID of the receiving task instance.
207 * @param[in] src_id ID of the sending task instance.
208 *
209 * @return If the message was consumed or not.
210 ****************************************************************************************
211 */
gapm_profile_added_ind_handler(ke_msg_id_t const msgid,struct gapm_profile_added_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)212 static int gapm_profile_added_ind_handler(ke_msg_id_t const msgid,
213 struct gapm_profile_added_ind *param,
214 ke_task_id_t const dest_id,
215 ke_task_id_t const src_id)
216 {
217 // Current State
218 ke_state_t state = ke_state_get(dest_id);
219 dbg("%s\n",__func__);
220 if (state == APPM_CREATE_DB)
221 {
222 switch (param->prf_task_id)
223 {
224 #if (BLE_APP_AM0)
225 case (TASK_ID_AM0_HAS):
226 {
227 app_am0_set_prf_task(param->prf_task_nb);
228 } break;
229 #endif //(BLE_APP_AM0)
230
231 default: /* Nothing to do */ break;
232 }
233 }
234 else
235 {
236 ASSERT_INFO(0, state, src_id);
237 }
238
239 if (ble_user_info.user_app_callback->app_on_init_complete) {
240 ble_user_info.user_app_callback->app_on_init_complete();
241 }
242
243 return KE_MSG_CONSUMED;
244 }
245
246 /**
247 ****************************************************************************************
248 * @brief Handles GAP manager command complete events.
249 *
250 * @param[in] msgid Id of the message received.
251 * @param[in] param Pointer to the parameters of the message.
252 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
253 * @param[in] src_id ID of the sending task instance.
254 *
255 * @return If the message was consumed or not.
256 ****************************************************************************************
257 */
gapm_cmp_evt_handler(ke_msg_id_t const msgid,struct gapm_cmp_evt const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)258 static int gapm_cmp_evt_handler(ke_msg_id_t const msgid,
259 struct gapm_cmp_evt const *param,
260 ke_task_id_t const dest_id,
261 ke_task_id_t const src_id)
262 {
263 #if (NVDS_SUPPORT)
264 uint8_t key_len = KEY_LEN;
265 #endif //(NVDS_SUPPORT)
266 uint8_t need_do_process = 0;
267 uint8_t need_clean_op = 0;
268
269 switch(param->operation)
270 {
271 // Reset completed
272 case (GAPM_RESET):
273 {
274
275 if(param->status == GAP_ERR_NO_ERROR)
276 {
277 #if (NVDS_SUPPORT)
278 nvds_tag_len_t len;
279 #endif //(NVDS_SUPPORT)
280 #if (BLE_APP_HID)
281 app_hid_start_mouse();
282 #endif //(BLE_APP_HID)
283
284 // Set Device configuration
285 struct gapm_set_dev_config_cmd* cmd = KE_MSG_ALLOC(GAPM_SET_DEV_CONFIG_CMD,
286 TASK_GAPM, TASK_APP,
287 gapm_set_dev_config_cmd);
288 // Set the operation
289 cmd->operation = GAPM_SET_DEV_CONFIG;
290 // Set the device role - Peripheral
291 cmd->role = GAP_ROLE_ALL;
292
293 #if (BLE_APP_SEC_CON)
294 // The Max MTU is increased to support the Public Key exchange
295 // HOWEVER, with secure connections enabled you cannot sniff the
296 // LEAP and LEAS protocols
297 cmd->max_mtu = 160;
298 cmd->pairing_mode = GAPM_PAIRING_SEC_CON | GAPM_PAIRING_LEGACY;
299 #else // !(BLE_APP_SEC_CON)
300 // Do not support secure connections
301 cmd->pairing_mode = GAPM_PAIRING_LEGACY;
302 cmd->max_mtu = 512;
303 //cmd->att_cfg = 0;
304 cmd->att_cfg |= GAPM_MASK_ATT_SVC_CHG_EN;
305 #endif //(BLE_APP_SEC_CON)
306
307 // Set Data length parameters
308 cmd->sugg_max_tx_octets = BLE_MIN_OCTETS;
309 cmd->sugg_max_tx_time = BLE_MIN_TIME;
310
311 #if (BLE_APP_HID)
312 // Enable Slave Preferred Connection Parameters present
313 cmd->att_cfg |= GAPM_MASK_ATT_SLV_PREF_CON_PAR_EN;
314 #endif //(BLE_APP_HID)
315
316 // Host privacy enabled by default
317 cmd->privacy_cfg = 0;
318
319 #if (NVDS_SUPPORT)
320 if (nvds_get(NVDS_TAG_BD_ADDRESS, &len, &cmd->addr.addr[0]) == NVDS_OK)
321 {
322 // Check if address is a static random address
323 if (cmd->addr.addr[5] & 0xC0)
324 {
325 // Host privacy enabled by default
326 cmd->privacy_cfg |= GAPM_PRIV_CFG_PRIV_ADDR_BIT;
327 }
328 }
329 #else
330 memcpy(&cmd->addr.addr[0], &ble_user_info.own_addr.addr[0], BD_ADDR_LEN);
331 if (cmd->addr.addr[5] & 0xC0)
332 {
333 // Host privacy enabled by default
334 cmd->privacy_cfg |= GAPM_PRIV_CFG_PRIV_ADDR_BIT;
335 }
336 #endif //(NVDS_SUPPORT)
337
338 #if (BLE_APP_AM0)
339 cmd->audio_cfg = GAPM_MASK_AUDIO_AM0_SUP;
340 cmd->att_cfg |= GAPM_MASK_ATT_SVC_CHG_EN;
341 #endif //(BLE_APP_AM0)
342
343
344 #if (NVDS_SUPPORT)
345 if ((app_sec_get_bond_status()==true) &&
346 (nvds_get(NVDS_TAG_LOC_IRK, &key_len, app_env.loc_irk) == NVDS_OK))
347 {
348 memcpy(cmd->irk.key, app_env.loc_irk, 16);
349 }
350 else
351 #endif //(NVDS_SUPPORT)
352
353 if (app_sec_get_bond_status()==true) {
354 flash_btdm_le_loc_irk_read((uint8_t *)&app_env.loc_irk);
355 memcpy(cmd->irk.key, app_env.loc_irk, 16);
356 }
357 else
358 {
359 memset((void *)&cmd->irk.key[0], 0x00, KEY_LEN);
360 }
361 // Send message
362 ke_msg_send(cmd);
363 }
364 else
365 {
366 ASSERT_ERR(0);
367 }
368 }
369 break;
370
371 case (GAPM_PROFILE_TASK_ADD):
372 {
373 if (app_sec_get_bond_status()==true)
374 {
375 flash_btdm_le_loc_irk_read((uint8_t *)&app_env.loc_irk);
376 // Set the IRK in the GAP
377 struct gapm_set_irk_cmd *cmd = KE_MSG_ALLOC(GAPM_SET_IRK_CMD,
378 TASK_GAPM, TASK_APP,
379 gapm_set_irk_cmd);
380 /// - GAPM_SET_IRK:
381 cmd->operation = GAPM_SET_IRK;
382 memcpy(&cmd->irk.key[0], &app_env.loc_irk[0], KEY_LEN);
383 ke_msg_send(cmd);
384 }
385 else // Need to start the generation of new IRK
386 {
387 struct gapm_gen_rand_nb_cmd *cmd = KE_MSG_ALLOC(GAPM_GEN_RAND_NB_CMD,
388 TASK_GAPM, TASK_APP,
389 gapm_gen_rand_nb_cmd);
390 cmd->operation = GAPM_GEN_RAND_NB;
391 app_env.rand_cnt = 1;
392 ke_msg_send(cmd);
393 }
394 }
395 break;
396
397 case (GAPM_GEN_RAND_NB) :
398 {
399 if (app_env.rand_cnt == 1)
400 {
401 // Generate a second random number
402 app_env.rand_cnt++;
403 struct gapm_gen_rand_nb_cmd *cmd = KE_MSG_ALLOC(GAPM_GEN_RAND_NB_CMD,
404 TASK_GAPM, TASK_APP,
405 gapm_gen_rand_nb_cmd);
406 cmd->operation = GAPM_GEN_RAND_NB;
407 ke_msg_send(cmd);
408 }
409 else
410 {
411 struct gapm_set_irk_cmd *cmd = KE_MSG_ALLOC(GAPM_SET_IRK_CMD,
412 TASK_GAPM, TASK_APP,
413 gapm_set_irk_cmd);
414 app_env.rand_cnt=0;
415 /// - GAPM_SET_IRK
416 cmd->operation = GAPM_SET_IRK;
417 memcpy(&cmd->irk.key[0], &app_env.loc_irk[0], KEY_LEN);
418 ke_msg_send(cmd);
419 }
420 }
421 break;
422
423 case (GAPM_SET_IRK):
424 {
425 // ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->operation, param->status);
426
427 // If not Bonded already store the generated value in NVDS
428 if (app_sec_get_bond_status()==false)
429 {
430 flash_btdm_le_loc_irk_write((uint8_t *)&app_env.loc_irk);
431 #if (NVDS_SUPPORT)
432 if (nvds_put(NVDS_TAG_LOC_IRK, KEY_LEN, (uint8_t *)&app_env.loc_irk) != NVDS_OK)
433 #endif //(NVDS_SUPPORT)
434 }
435
436 app_env.rand_cnt = 0;
437 // Add the next requested service
438 if (!appm_add_svc())
439 {
440 // Go to the ready state
441 ke_state_set(TASK_APP, APPM_READY);
442
443 // No more service to add, start advertising
444 appm_update_adv_state(true);
445 }
446 }
447 break;
448
449 // Device Configuration updated
450 case (GAPM_SET_DEV_CONFIG):
451 {
452 bool ret = false;
453 ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->operation, param->status);
454
455 // Go to the create db state
456 ke_state_set(TASK_APP, APPM_CREATE_DB);
457
458 // Add the first required service in the database
459 // and wait for the PROFILE_ADDED_IND
460 ret = appm_add_svc();
461 if(ret == false){
462 if (ble_user_info.user_app_callback->app_on_init_complete) {
463 ble_user_info.user_app_callback->app_on_init_complete();
464 }
465 }
466 }
467 break;
468
469 case (GAPM_CREATE_ADV_ACTIVITY):
470 case (GAPM_CREATE_SCAN_ACTIVITY):
471 case (GAPM_STOP_ACTIVITY):
472 case (GAPM_START_ACTIVITY):
473 case (GAPM_DELETE_ACTIVITY):
474 case (GAPM_SET_ADV_DATA):
475 case (GAPM_SET_SCAN_RSP_DATA):
476 {
477 dbg("%s op 0x%x, scan_op %x\n",__func__,param->operation,app_env.scan_op);
478 if(app_env.adv_op != GAPM_NO_OP){
479 if ((app_env.adv_op != param->operation) || (param->status != GAP_ERR_NO_ERROR)) {
480 ASSERT_INFO(app_env.adv_op == param->operation, app_env.adv_op, param->operation);
481 ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->status, app_env.adv_op);
482 dbg("error, adv operation error, operation %d-%d, status %d\r\n", param->operation, app_env.adv_op, param->status);
483 if (ble_user_info.user_app_callback->app_on_adv_status) {
484 ble_user_info.user_app_callback->app_on_adv_status(param);
485 }
486 } else {
487 // Perform next operation
488 need_do_process |= 1;
489 }
490 need_clean_op |= 1;
491 }
492 if(app_env.scan_op != GAPM_NO_OP){
493 need_do_process |= (1<<1);
494 need_clean_op |= (1<<1);
495 }
496 } break;
497
498 case (GAPM_DELETE_ALL_ACTIVITIES) :
499 {
500 // Re-Invoke Advertising
501 app_env.adv_state = APP_ADV_STATE_IDLE;
502 need_do_process = 1;
503 need_clean_op = 1;
504 } break;
505
506
507 default:
508 {
509 // Drop the message
510 need_clean_op = 0;
511 }
512 break;
513 }
514 //dbg("%s ,op 0x%x, 0x%x,0x%x,%x\n",__func__,param->operation,need_clean_op,need_do_process,app_env.adv_state);
515 if(need_clean_op){
516 if(need_clean_op & (1<<1)){
517 app_env.scan_op = GAPM_NO_OP;
518 }else{
519 app_env.adv_op = GAPM_NO_OP;
520 }
521 }
522 if(need_do_process){
523 if(need_do_process & (1<<1)){
524 appm_scan_fsm_next();
525 }else{
526 appm_adv_fsm_next();
527 }
528 }else{
529 app_ble_check_oplist();
530 }
531 if(param->operation == GAPM_START_ACTIVITY){
532 //ke_timer_set(APP_TEST_TIMER, TASK_APP, 1000);
533 }
534 return (KE_MSG_CONSUMED);
535 }
536
gapc_get_dev_info_req_ind_handler(ke_msg_id_t const msgid,struct gapc_get_dev_info_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)537 static int gapc_get_dev_info_req_ind_handler(ke_msg_id_t const msgid,
538 struct gapc_get_dev_info_req_ind const *param,
539 ke_task_id_t const dest_id,
540 ke_task_id_t const src_id)
541 {
542 switch(param->req)
543 {
544 case GAPC_DEV_NAME:
545 {
546 struct gapc_get_dev_info_cfm * cfm = KE_MSG_ALLOC_DYN(GAPC_GET_DEV_INFO_CFM,
547 src_id, dest_id,
548 gapc_get_dev_info_cfm, APP_DEVICE_NAME_MAX_LEN);
549 cfm->req = param->req;
550 cfm->info.name.length = appm_get_dev_name(cfm->info.name.value);
551
552 // Send message
553 ke_msg_send(cfm);
554 } break;
555
556 case GAPC_DEV_APPEARANCE:
557 {
558 // Allocate message
559 struct gapc_get_dev_info_cfm *cfm = KE_MSG_ALLOC(GAPC_GET_DEV_INFO_CFM,
560 src_id, dest_id,
561 gapc_get_dev_info_cfm);
562 cfm->req = param->req;
563 // Set the device appearance
564 #if (BLE_APP_HT)
565 // Generic Thermometer
566 cfm->info.appearance = GAPC_APPEARANCE_GENERIC_THERMOMETER;
567 #elif (BLE_APP_HID)
568 // HID Mouse
569 cfm->info.appearance = GAPC_APPEARANCE_HID_MOUSE;
570 #else
571 // No appearance
572 cfm->info.appearance = GAPC_APPEARANCE_UNKNOWN;
573 #endif
574
575 // Send message
576 ke_msg_send(cfm);
577 } break;
578
579 case GAPC_DEV_SLV_PREF_PARAMS:
580 {
581 // Allocate message
582 struct gapc_get_dev_info_cfm *cfm = KE_MSG_ALLOC(GAPC_GET_DEV_INFO_CFM,
583 src_id, dest_id,
584 gapc_get_dev_info_cfm);
585 cfm->req = param->req;
586 // Slave preferred Connection interval Min
587 cfm->info.slv_pref_params.con_intv_min = 8;
588 // Slave preferred Connection interval Max
589 cfm->info.slv_pref_params.con_intv_max = 10;
590 // Slave preferred Connection latency
591 cfm->info.slv_pref_params.slave_latency = 0;
592 // Slave preferred Link supervision timeout
593 cfm->info.slv_pref_params.conn_timeout = 200; // 2s (500*10ms)
594
595 // Send message
596 ke_msg_send(cfm);
597 } break;
598
599 default: /* Do Nothing */ break;
600 }
601
602 return (KE_MSG_CONSUMED);
603 }
604 /**
605 ****************************************************************************************
606 * @brief Handles GAPC_SET_DEV_INFO_REQ_IND message.
607 *
608 * @param[in] msgid Id of the message received.
609 * @param[in] param Pointer to the parameters of the message.
610 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
611 * @param[in] src_id ID of the sending task instance.
612 *
613 * @return If the message was consumed or not.
614 ****************************************************************************************
615 */
gapc_set_dev_info_req_ind_handler(ke_msg_id_t const msgid,struct gapc_set_dev_info_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)616 static int gapc_set_dev_info_req_ind_handler(ke_msg_id_t const msgid,
617 struct gapc_set_dev_info_req_ind const *param,
618 ke_task_id_t const dest_id,
619 ke_task_id_t const src_id)
620 {
621 uint8_t status = GAP_ERR_REJECTED;
622
623 appm_set_dev_info(param, &status);
624
625 // Set Device configuration
626 struct gapc_set_dev_info_cfm* cfm = KE_MSG_ALLOC(GAPC_SET_DEV_INFO_CFM, src_id, dest_id,
627 gapc_set_dev_info_cfm);
628 // Reject to change parameters
629 cfm->status = status;
630 cfm->req = param->req;
631 // Send message
632 ke_msg_send(cfm);
633
634 return (KE_MSG_CONSUMED);
635 }
636
637 /**
638 ****************************************************************************************
639 * @brief Handles connection complete event from the GAP. Enable all required profiles
640 *
641 * @param[in] msgid Id of the message received.
642 * @param[in] param Pointer to the parameters of the message.
643 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
644 * @param[in] src_id ID of the sending task instance.
645 *
646 * @return If the message was consumed or not.
647 ****************************************************************************************
648 */
gapc_connection_req_ind_handler(ke_msg_id_t const msgid,struct gapc_connection_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)649 static int gapc_connection_req_ind_handler(ke_msg_id_t const msgid,
650 struct gapc_connection_req_ind const *param,
651 ke_task_id_t const dest_id,
652 ke_task_id_t const src_id)
653 {
654 app_env.conidx = KE_IDX_GET(src_id);
655
656 // Check if the received Connection Handle was valid
657 if (app_env.conidx != GAP_INVALID_CONIDX)
658 {
659 // Retrieve the connection info from the parameters
660 app_env.conhdl = param->conhdl;
661
662 // Send connection confirmation
663 struct gapc_connection_cfm *cfm = KE_MSG_ALLOC(GAPC_CONNECTION_CFM,
664 KE_BUILD_ID(TASK_GAPC, app_env.conidx), TASK_APP,
665 gapc_connection_cfm);
666
667 #if(BLE_APP_SEC)
668 cfm->auth = app_sec_get_bond_status() ? GAP_AUTH_REQ_NO_MITM_BOND : GAP_AUTH_REQ_NO_MITM_NO_BOND; // TODO [FBE] restore valid data
669 #else // !(BLE_APP_SEC)
670 cfm->auth = GAP_AUTH_REQ_NO_MITM_NO_BOND;
671 #endif // (BLE_APP_SEC)
672 // Send the message
673 ke_msg_send(cfm);
674
675 #if DISPLAY_SUPPORT
676 // Update displayed information
677 app_display_set_adv(false);
678 app_display_set_con(true);
679 #endif //(DISPLAY_SUPPORT)
680
681 /*--------------------------------------------------------------
682 * ENABLE REQUIRED PROFILES
683 *--------------------------------------------------------------*/
684 if (ble_user_info.user_app_callback->app_on_enable_prf) {
685 ble_user_info.user_app_callback->app_on_enable_prf(app_env.conhdl);
686 }
687 // We are now in connected State
688 ke_state_set(dest_id, APPM_CONNECTED);
689
690 #if (BLE_APP_SEC && !defined(BLE_APP_AM0))
691 if (app_sec_get_bond_status())
692 {
693 // Ask for the peer device to either start encryption
694 app_sec_send_security_req(app_env.conidx);
695 }
696 #endif // (BLE_APP_SEC && !defined(BLE_APP_AM0))
697
698 }
699 else
700 {
701 // No connection has been established, restart advertising
702 appm_update_adv_state(true);
703 }
704
705 if (ble_user_info.user_app_callback->app_on_connection) {
706 ble_user_info.user_app_callback->app_on_connection(app_env.conidx, param);
707 }
708
709 return (KE_MSG_CONSUMED);
710 }
711
712 /**
713 ****************************************************************************************
714 * @brief Handles connection complete event from the GAP. Enable all required profiles
715 *
716 * @param[in] msgid Id of the message received.
717 * @param[in] param Pointer to the parameters of the message.
718 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
719 * @param[in] src_id ID of the sending task instance.
720 *
721 * @return If the message was consumed or not.
722 ****************************************************************************************
723 */
gapc_param_update_req_ind_handler(ke_msg_id_t const msgid,struct gapc_param_update_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)724 static int gapc_param_update_req_ind_handler(ke_msg_id_t const msgid,
725 struct gapc_param_update_req_ind const *param,
726 ke_task_id_t const dest_id,
727 ke_task_id_t const src_id)
728 {
729 app_env.conidx = KE_IDX_GET(src_id);
730
731 // Check if the received Connection Handle was valid
732 if (app_env.conidx != GAP_INVALID_CONIDX)
733 {
734
735 // Send connection confirmation
736 struct gapc_param_update_cfm *cfm = KE_MSG_ALLOC(GAPC_PARAM_UPDATE_CFM,
737 KE_BUILD_ID(TASK_GAPC, app_env.conidx), TASK_APP,
738 gapc_param_update_cfm);
739
740 cfm->accept = true;
741 cfm->ce_len_min = 2;
742 cfm->ce_len_max = 4;
743
744 // Send message
745 ke_msg_send(cfm);
746
747 }
748 else
749 {
750 // No connection has been established, restart advertising
751 appm_update_adv_state(true);
752 }
753
754 if (ble_user_info.user_app_callback->app_on_update_params_request) {
755 ble_user_info.user_app_callback->app_on_update_params_request(param);
756 }
757
758 return (KE_MSG_CONSUMED);
759 }
760
761 /**
762 ****************************************************************************************
763 * @brief Handles GAP controller command complete events.
764 *
765 * @param[in] msgid Id of the message received.
766 * @param[in] param Pointer to the parameters of the message.
767 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
768 * @param[in] src_id ID of the sending task instance.
769 *
770 * @return If the message was consumed or not.
771 ****************************************************************************************
772 */
gapc_cmp_evt_handler(ke_msg_id_t const msgid,struct gapc_cmp_evt const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)773 static int gapc_cmp_evt_handler(ke_msg_id_t const msgid,
774 struct gapc_cmp_evt const *param,
775 ke_task_id_t const dest_id,
776 ke_task_id_t const src_id)
777 {
778 switch(param->operation)
779 {
780 case (GAPC_UPDATE_PARAMS):
781 {
782 if (param->status != GAP_ERR_NO_ERROR)
783 {
784 // appm_disconnect();
785 }
786 } break;
787
788 default:
789 {
790 } break;
791 }
792
793 return (KE_MSG_CONSUMED);
794 }
795
796 /**
797 ****************************************************************************************
798 * @brief Handles disconnection complete event from the GAP.
799 *
800 * @param[in] msgid Id of the message received.
801 * @param[in] param Pointer to the parameters of the message.
802 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
803 * @param[in] src_id ID of the sending task instance.
804 *
805 * @return If the message was consumed or not.
806 ****************************************************************************************
807 */
gapc_disconnect_ind_handler(ke_msg_id_t const msgid,struct gapc_disconnect_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)808 static int gapc_disconnect_ind_handler(ke_msg_id_t const msgid,
809 struct gapc_disconnect_ind const *param,
810 ke_task_id_t const dest_id,
811 ke_task_id_t const src_id)
812 {
813 // Go to the ready state
814 ke_state_set(TASK_APP, APPM_READY);
815
816 #if (BLE_APP_HT)
817 // Stop interval timer
818 app_stop_timer();
819 #endif //(BLE_APP_HT)
820
821 #if (DISPLAY_SUPPORT)
822 // Update Connection State screen
823 app_display_set_con(false);
824 #endif //(DISPLAY_SUPPORT)
825
826 #if (BLE_ISO_MODE_0_PROTOCOL)
827 app_env.adv_state = APP_ADV_STATE_CREATING;
828 #endif //(BLE_ISO_MODE_0_PROTOCOL)
829
830 if (ble_user_info.user_app_callback->app_on_disconnect) {
831 ble_user_info.user_app_callback->app_on_disconnect(param);
832 }
833
834 app_env.conhdl = 0;
835 app_env.conidx = 0;
836
837 {
838 if (ble_callback) {
839 ble_callback(APP_DEINIT_FLAG_CON, GAP_ERR_NO_ERROR);
840 }
841 }
842 return (KE_MSG_CONSUMED);
843 }
844
845 /**
846 ****************************************************************************************
847 * @brief Handles reception of all messages sent from the lower layers to the application
848 * @param[in] msgid Id of the message received.
849 * @param[in] param Pointer to the parameters of the message.
850 * @param[in] dest_id ID of the receiving task instance
851 * @param[in] src_id ID of the sending task instance.
852 *
853 * @return If the message was consumed or not.
854 ****************************************************************************************
855 */
appm_msg_handler(ke_msg_id_t const msgid,void * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)856 static int appm_msg_handler(ke_msg_id_t const msgid,
857 void *param,
858 ke_task_id_t const dest_id,
859 ke_task_id_t const src_id)
860 {
861 // Retrieve identifier of the task from received message
862 ke_task_id_t src_task_id = BLE_MSG_T(msgid);
863 // Message policy
864 uint8_t msg_pol = KE_MSG_CONSUMED;
865
866 switch (src_task_id)
867 {
868 case (TASK_ID_GAPC):
869 {
870 #if (BLE_APP_SEC)
871 if ((msgid >= GAPC_BOND_CMD) &&
872 (msgid <= GAPC_SECURITY_IND))
873 {
874 // Call the Security Module
875 msg_pol = app_get_handler(&app_sec_handlers, msgid, param, src_id);
876 }
877 #endif //(BLE_APP_SEC)
878 // else drop the message
879 } break;
880
881 case (TASK_ID_GATTC):
882 {
883 // Service Changed - Drop
884 } break;
885
886 #if (BLE_APP_HT)
887 case (TASK_ID_HTPT):
888 {
889 // Call the Health Thermometer Module
890 msg_pol = app_get_handler(&app_ht_handlers, msgid, param, src_id);
891 } break;
892 #endif //(BLE_APP_HT)
893
894 #if (BLE_APP_DIS)
895 case (TASK_ID_DISS):
896 {
897 // Call the Device Information Module
898 msg_pol = app_get_handler(&app_dis_handlers, msgid, param, src_id);
899 } break;
900 #endif //(BLE_APP_DIS)
901
902 #if (BLE_APP_HID)
903 case (TASK_ID_HOGPD):
904 {
905 // Call the HID Module
906 msg_pol = app_get_handler(&app_hid_handlers, msgid, param, src_id);
907 } break;
908 #endif //(BLE_APP_HID)
909
910 #if (BLE_APP_BATT)
911 case (TASK_ID_BASS):
912 {
913 // Call the Battery Module
914 msg_pol = app_get_handler(&app_batt_handlers, msgid, param, src_id);
915 } break;
916 #endif //(BLE_APP_BATT)
917
918 #if (BLE_APP_AM0)
919 case (TASK_ID_AM0):
920 {
921 // Call the Audio Mode 0 Module
922 msg_pol = app_get_handler(&app_am0_handlers, msgid, param, src_id);
923 } break;
924
925 case (TASK_ID_AM0_HAS):
926 {
927 // Call the Audio Mode 0 Module
928 msg_pol = app_get_handler(&app_am0_has_handlers, msgid, param, src_id);
929 } break;
930 #endif //(BLE_APP_AM0)
931
932 #if (BLE_APP_SMARTCONFIG)
933 case (TASK_ID_SMARTCONFIG):
934 {
935 // Call the Smart Config
936 msg_pol = app_get_handler(&app_smartconfig_handlers, msgid, param, src_id);
937 } break;
938 #endif //(BLE_APP_SMARTCONFIG)
939
940 default:
941 {
942 #if (BLE_APP_HT)
943 if (msgid == APP_HT_MEAS_INTV_TIMER)
944 {
945 msg_pol = app_get_handler(&app_ht_handlers, msgid, param, src_id);
946 }
947 #endif //(BLE_APP_HT)
948
949 #if (BLE_APP_HID)
950 if (msgid == APP_HID_MOUSE_TIMEOUT_TIMER || msgid == APP_HID_MOUSE_TEST_TIMER)
951 {
952 msg_pol = app_get_handler(&app_hid_handlers, msgid, param, src_id);
953 }
954 #endif //(BLE_APP_HID)
955 } break;
956 }
957
958 return (msg_pol);
959 }
960
961 /**
962 ****************************************************************************************
963 * @brief Handles reception of random number generated message
964 *
965 * @param[in] msgid Id of the message received.
966 * @param[in] param Pointer to the parameters of the message.
967 * @param[in] dest_id ID of the receiving task instance
968 * @param[in] src_id ID of the sending task instance.
969 *
970 * @return If the message was consumed or not.
971 ****************************************************************************************
972 */
gapm_gen_rand_nb_ind_handler(ke_msg_id_t const msgid,struct gapm_gen_rand_nb_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)973 static int gapm_gen_rand_nb_ind_handler(ke_msg_id_t const msgid, struct gapm_gen_rand_nb_ind *param,
974 ke_task_id_t const dest_id, ke_task_id_t const src_id)
975 {
976 if (app_env.rand_cnt==1) // First part of IRK
977 {
978 memcpy(&app_env.loc_irk[0], ¶m->randnb.nb[0], 8);
979 }
980 else if (app_env.rand_cnt==2) // Second part of IRK
981 {
982 memcpy(&app_env.loc_irk[8], ¶m->randnb.nb[0], 8);
983 }
984
985 return KE_MSG_CONSUMED;
986 }
987
988 /**
989 ****************************************************************************************
990 * @brief Function called when the APP_HID_MOUSE_TEST_TIMER expires.
991 *
992 * @param[in] msgid Id of the message received.
993 * @param[in] param Pointer to the parameters of the message.
994 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
995 * @param[in] src_id ID of the sending task instance.
996 *
997 * @return If the message was consumed or not.
998 ****************************************************************************************
999 */
app_test_timer_handler(ke_msg_id_t const msgid,void const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)1000 static int app_test_timer_handler(ke_msg_id_t const msgid,
1001 void const *param,
1002 ke_task_id_t const dest_id,
1003 ke_task_id_t const src_id)
1004 {
1005 uint32_t timer_val = 1000;
1006 dbg("%s ,%d\n",__func__,ke_time());
1007 ke_timer_set(APP_TEST_TIMER, TASK_APP, timer_val);
1008
1009 return (KE_MSG_CONSUMED);
1010 }
1011
1012 /**
1013 ****************************************************************************************
1014 * @brief Function called when the APP_HID_MOUSE_TEST_TIMER expires.
1015 *
1016 * @param[in] msgid Id of the message received.
1017 * @param[in] param Pointer to the parameters of the message.
1018 * @param[in] dest_id ID of the receiving task instance (TASK_GAP).
1019 * @param[in] src_id ID of the sending task instance.
1020 *
1021 * @return If the message was consumed or not.
1022 ****************************************************************************************
1023 */
app_adv_report_handler(ke_msg_id_t const msgid,struct gapm_ext_adv_report_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)1024 static int app_adv_report_handler(ke_msg_id_t const msgid,
1025 struct gapm_ext_adv_report_ind *param,
1026 ke_task_id_t const dest_id,
1027 ke_task_id_t const src_id)
1028 {
1029 dbg("%s \n",__func__);
1030 dbg("actv_idx %x, info %x\n",param->actv_idx,param->info);
1031 dbg("trans_addr.addr_type %x, addr %x,%x,%x,%x,%x,%x \n",param->trans_addr.addr_type,param->trans_addr.addr.addr[0],param->trans_addr.addr.addr[1]\
1032 ,param->trans_addr.addr.addr[2],param->trans_addr.addr.addr[3],param->trans_addr.addr.addr[4],param->trans_addr.addr.addr[5]);
1033 dbg("target_addr.addr_type %x, addr %x,%x,%x,%x,%x,%x \n",param->target_addr.addr_type,param->target_addr.addr.addr[0],param->target_addr.addr.addr[1]\
1034 ,param->target_addr.addr.addr[2],param->target_addr.addr.addr[3],param->target_addr.addr.addr[4],param->target_addr.addr.addr[5]);
1035 dbg("tx_pwr %x, rssi %d,phy_prim %x, phy_prim %x,phy_second %x,adv_sid %x,period_adv_intv %x\n"\
1036 ,param->tx_pwr,param->rssi,param->phy_prim,param->phy_second,param->adv_sid,param->period_adv_intv);
1037 dbg("length %d,data %x,%x,%x,%x,%x,%x,%x\n",param->length,param->data[0],param->data[1],param->data[2],param->data[3],param->data[4],param->data[5],param->data[6]);
1038
1039 uint16_t total_len = param->length;
1040 uint8_t *data;
1041 uint8_t ele_len;
1042 uint8_t ele_type;
1043 uint8_t *ele_data;
1044
1045 data = param->data;
1046 while(total_len){
1047 ele_len = data[0];
1048 ele_type = data[1];
1049 ele_data = &data[2];
1050 dbg("ele_type=0x%x,ele_len=%d\n",ele_type,ele_len);
1051 if(ele_type == 0x16 && ele_len >= 11 ){
1052 uint16_t uuid;
1053 uint16_t frame_cntl;
1054 uint16_t product_id;
1055 uint8_t frame_counter;
1056 uint16_t pair_id;
1057 uint16_t sn;
1058
1059
1060 uuid = (uint16_t)ele_data[0]|((uint16_t)ele_data[1]<<8);
1061 dbg("uuid=0x%x\n",uuid);
1062 if(uuid == 0x1379){
1063 frame_cntl = (uint16_t)ele_data[2]|((uint16_t)ele_data[3]<<8);
1064 product_id = (uint16_t)ele_data[4]|((uint16_t)ele_data[5]<<8);
1065 frame_counter = ele_data[6];
1066 pair_id = (uint16_t)ele_data[7]|((uint16_t)ele_data[8]<<8);
1067 sn = (uint16_t)ele_data[9]|((uint16_t)ele_data[10]<<8);
1068 dbg("frame_cntl=0x%x,product_id=0x%x,frame_counter=0x%x,pair_id=0x%x,sn=0x%x,\n"\
1069 ,frame_cntl,product_id,frame_counter,pair_id,sn);
1070 if(product_id == 0x0001){
1071 uint16_t obj_id;
1072 uint8_t obj_len;
1073 uint8_t key_bit;
1074 obj_id = (uint16_t)ele_data[11]|((uint16_t)ele_data[12]<<8);
1075 obj_len = ele_data[13];
1076 key_bit = ele_data[14];
1077 dbg("obj_id=0x%x,obj_len=0x%x,key_bit=0x%x\n",obj_id,obj_len,key_bit);
1078 switch(obj_id){
1079 case 0x2001:
1080 if(key_bit & (1<<0)){
1081 //bit0 wakeup.
1082 }
1083 break;
1084 case 0x2002:
1085 //key
1086 break;
1087 default:
1088 break;
1089 }
1090 }
1091 }
1092 }
1093 total_len -= (ele_len+1);
1094 data += (ele_len+1);
1095 }
1096 return (KE_MSG_CONSUMED);
1097 }
1098 /*
1099 * GLOBAL VARIABLES DEFINITION
1100 ****************************************************************************************
1101 */
1102
1103 /* Default State handlers definition. */
KE_MSG_HANDLER_TAB(appm)1104 KE_MSG_HANDLER_TAB(appm)
1105 {
1106 // Note: first message is latest message checked by kernel so default is put on top.
1107 {KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)appm_msg_handler},
1108
1109 // GAPM messages
1110 {GAPM_PROFILE_ADDED_IND, (ke_msg_func_t)gapm_profile_added_ind_handler},
1111 {GAPM_ACTIVITY_CREATED_IND, (ke_msg_func_t)gapm_activity_created_ind_handler},
1112 {GAPM_ACTIVITY_STOPPED_IND, (ke_msg_func_t)gapm_activity_stopped_ind_handler},
1113 {GAPM_CMP_EVT, (ke_msg_func_t)gapm_cmp_evt_handler},
1114 {GAPM_GEN_RAND_NB_IND, (ke_msg_func_t)gapm_gen_rand_nb_ind_handler},
1115
1116 // GAPC messages
1117 {GAPC_GET_DEV_INFO_REQ_IND, (ke_msg_func_t)gapc_get_dev_info_req_ind_handler},
1118 {GAPC_SET_DEV_INFO_REQ_IND, (ke_msg_func_t)gapc_set_dev_info_req_ind_handler},
1119 {GAPC_CONNECTION_REQ_IND, (ke_msg_func_t)gapc_connection_req_ind_handler},
1120 {GAPC_PARAM_UPDATE_REQ_IND, (ke_msg_func_t)gapc_param_update_req_ind_handler},
1121 {GAPC_CMP_EVT, (ke_msg_func_t)gapc_cmp_evt_handler},
1122 {GAPC_DISCONNECT_IND, (ke_msg_func_t)gapc_disconnect_ind_handler},
1123 {APP_TEST_TIMER, (ke_msg_func_t)app_test_timer_handler},
1124 {GAPM_EXT_ADV_REPORT_IND, (ke_msg_func_t)app_adv_report_handler}
1125 };
1126
1127 /* Defines the place holder for the states of all the task instances. */
1128 ke_state_t appm_state[APP_IDX_MAX];
1129
1130 // Application task descriptor
1131 const struct ke_task_desc TASK_DESC_APP = {appm_msg_handler_tab, appm_state, APP_IDX_MAX, ARRAY_LEN(appm_msg_handler_tab)};
1132
1133 #endif //(BLE_APP_PRESENT)
1134