Dialog的DA145XX系列BLE芯片可以配置允许多连接,需要修改SDK,下面主要说明如何实现多连接配置。
1、新增宏定义:__EXCLUDE_ROM_APP_TASK__
用于取消ROM里关于APP部分函数的调用,改为使用自定义的函数
2、部分宏定义(DA1458x_config_basic.h文件):
修改宏定义,配置支持的连接数,1453X系列最多支持3个连接:
/****************************************************************************************************************/
/* Determines maximum concurrent connections supported by application. It configures the heap memory allocated */
/* to service multiple connections. It is used for GAP central role applications. For GAP peripheral role it */
/* should be set to 1 for optimizing memory utilization. */
/* - MAX value for DA14535: 3 */
/****************************************************************************************************************/
#define CFG_MAX_CONNECTIONS (2)
新增宏定义:
/****************************************************************************************************************/
/* Enable multiple connections configuration */
/****************************************************************************************************************/
#if CFG_MAX_CONNECTIONS > (1)#define CFG_ENABLE_MULTIPLE_CONN
#endif
3、app_task.h里修改宏定义:
/// Number of APP Task Instances
#ifndef CFG_ENABLE_MULTIPLE_CONN
#define APP_IDX_MAX (1)
#else
#define APP_IDX_MAX (APP_EASY_MAX_ACTIVE_CONNECTION)
#endif
4、app.h里修改宏定义:
/// Max connections supported by application task
#ifdef CFG_ENABLE_MULTIPLE_CONN
#define APP_EASY_MAX_ACTIVE_CONNECTION (BLE_CONNECTION_MAX)
#else
#define APP_EASY_MAX_ACTIVE_CONNECTION (1)
#endif
5、APP_task.c 修改部分函数:使用__WEAK关键字,用于在其它区域覆盖该函数,主要更改连接和断连两个回调函数:
gapc_disconnect_ind_handler
gapc_connection_req_ind_handler
/******************************************************************************************* @brief Handles connection complete event from the GAP. Will enable profile.* @param[in] msgid Id of the message received.* @param[in] param Pointer to the parameters of the message.* @param[in] dest_id ID of the receiving task instance (TASK_GAP).* @param[in] src_id ID of the sending task instance.* @return If the message was consumed or not.*****************************************************************************************/
#ifdef CFG_ENABLE_MULTIPLE_CONN
__WEAK int 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)
#else
static int 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)
#endif
{// Connection Indexif (ke_state_get(dest_id) == APP_CONNECTABLE){uint8_t conidx = KE_IDX_GET(src_id);ASSERT_WARNING(conidx < APP_EASY_MAX_ACTIVE_CONNECTION);app_env[conidx].conidx = conidx;if (conidx != GAP_INVALID_CONIDX){app_env[conidx].connection_active = true;ke_state_set(TASK_APP, APP_CONNECTED);// Retrieve the connection info from the parametersapp_env[conidx].conhdl = param->conhdl;app_env[conidx].peer_addr_type = param->peer_addr_type;memcpy(app_env[conidx].peer_addr.addr, param->peer_addr.addr, BD_ADDR_LEN);#if (BLE_APP_SEC)// send connection confirmationapp_easy_gap_confirm(conidx, (enum gap_auth) app_sec_env[conidx].auth, 1);#elseapp_easy_gap_confirm(conidx, GAP_AUTH_REQ_NO_MITM_NO_BOND, 1);#endif}CALLBACK_ARGS_2(user_app_callbacks.app_on_connection, conidx, param)}else{// APP_CONNECTABLE state is used to wait the GAP_LE_CREATE_CONN_REQ_CMP_EVT messageASSERT_ERROR(0);}return (KE_MSG_CONSUMED);
}
/******************************************************************************************* @brief Handles disconnection complete event from the GAP.* @param[in] msgid Id of the message received.* @param[in] param Pointer to the parameters of the message.* @param[in] dest_id ID of the receiving task instance (TASK_GAP).* @param[in] src_id ID of the sending task instance.* @return If the message was consumed or not.*****************************************************************************************/
#ifdef CFG_ENABLE_MULTIPLE_CONN
__WEAK int 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)
#else
static int 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)
#endif
{uint8_t state = ke_state_get(dest_id);uint8_t conidx = KE_IDX_GET(src_id);if (state == APP_CONNECTED){app_env[conidx].conidx = GAP_INVALID_CONIDX;app_env[conidx].connection_active = false;CALLBACK_ARGS_1(user_app_callbacks.app_on_disconnect, param)}else{// We are not in Connected StateASSERT_ERROR(0);}return (KE_MSG_CONSUMED);
}
6、app.c里修改部分函数:主要是根据CFG_ENABLE_MULTIPLE_CONN宏定义是否开启,来重新配置函数app_db_init_start和app_db_init_next
/******************************************************************************************* @brief Initialize the database for all the included profiles.* @return true if succeeded, else false*****************************************************************************************/
#if (!defined (__DA14531__) || defined (__EXCLUDE_ROM_APP_TASK__)) && !defined (CFG_ENABLE_MULTIPLE_CONN)
static bool app_db_init_next(void)
#else
bool app_db_init_next(void)
#endif
{static uint8_t i __SECTION_ZERO("retention_mem_area0"); //@RETENTION MEMORY;static uint8_t k __SECTION_ZERO("retention_mem_area0"); //@RETENTION MEMORY;// initialise the databases for all the included profileswhile(user_prf_funcs[k].task_id != TASK_ID_INVALID){if (user_prf_funcs[k].db_create_func != NULL){user_prf_funcs[k++].db_create_func();return false;}else k++;}// initialise the databases for all the included profileswhile(prf_funcs[i].task_id != TASK_ID_INVALID){if ((prf_funcs[i].db_create_func != NULL)&& (!app_task_in_user_app(prf_funcs[i].task_id))) //case that the this task has an entry in the user_prf as well{prf_funcs[i++].db_create_func();return false;}else i++;}#if (BLE_CUSTOM_SERVER){static uint8_t j __SECTION_ZERO("retention_mem_area0"); //@RETENTION MEMORY;while(cust_prf_funcs[j].task_id != TASK_ID_INVALID){if(cust_prf_funcs[j].db_create_func != NULL){cust_prf_funcs[j++].db_create_func();return false;}else j++;}j = 0;}
#endifk = 0;i = 0;return true;
}
#if !defined (__DA14531__) || defined (__EXCLUDE_ROM_APP_TASK__)
#if !defined (CFG_ENABLE_MULTIPLE_CONN)
bool app_db_init_start(void)
{// Indicate if more services need to be added in the databasebool end_db_create;// We are now in Initialization Stateke_state_set(TASK_APP, APP_DB_INIT);end_db_create = app_db_init_next();return end_db_create;
}
#endif
7、在工程自定义的其它文件中重新实现前面在ROM里不支持多连接的函数,使其支持多连接:
/******************************************************************************************* @brief Handles connection complete event from the GAP. Will enable profile.* Custom function for multi-connection peripheral* @param[in] msgid Id of the message received.* @param[in] param Pointer to the parameters of the message.* @param[in] dest_id ID of the receiving task instance (TASK_GAP).* @param[in] src_id ID of the sending task instance.* @return If the message was consumed or not.*****************************************************************************************/
int 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, // dest_id -> TASK_APPke_task_id_t const src_id) // src_id -> TASK_GAPC
{uint8_t conidx = KE_IDX_GET(src_id);uint8_t current_state = ke_state_get(KE_BUILD_ID(KE_TYPE_GET(dest_id), conidx));// Connection Indexif (current_state == APP_CONNECTABLE){ASSERT_WARNING(conidx < APP_EASY_MAX_ACTIVE_CONNECTION);app_env[conidx].conidx = conidx;if (conidx != GAP_INVALID_CONIDX){app_env[conidx].connection_active = true;ke_state_set(KE_BUILD_ID(KE_TYPE_GET(dest_id), conidx), APP_CONNECTED); //SUPBLE_6975// Retrieve the connection info from the parametersapp_env[conidx].conhdl = param->conhdl;app_env[conidx].peer_addr_type = param->peer_addr_type;memcpy(app_env[conidx].peer_addr.addr, param->peer_addr.addr, BD_ADDR_LEN);#if (BLE_APP_SEC)// send connection confirmationapp_easy_gap_confirm(conidx, (enum gap_auth) app_sec_env[conidx].auth, 1);#elseapp_easy_gap_confirm(conidx, GAP_AUTH_REQ_NO_MITM_NO_BOND, 1);#endif}CALLBACK_ARGS_2(user_app_callbacks.app_on_connection, conidx, param)}else{// APP_CONNECTABLE state is used to wait the GAP_LE_CREATE_CONN_REQ_CMP_EVT messageASSERT_ERROR(0);}return (KE_MSG_CONSUMED);
}/******************************************************************************************* @brief Handles disconnection complete event from the GAP. Custom function for the * multiconnection.* @param[in] msgid Id of the message received.* @param[in] param Pointer to the parameters of the message.* @param[in] dest_id ID of the receiving task instance (TASK_GAP).* @param[in] src_id ID of the sending task instance.* @return If the message was consumed or not.*****************************************************************************************/
int 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)
{uint8_t conidx = KE_IDX_GET(src_id);uint8_t state = ke_state_get(KE_BUILD_ID(KE_TYPE_GET(dest_id), conidx));if (state == APP_CONNECTED){app_env[conidx].conidx = GAP_INVALID_CONIDX;app_env[conidx].connection_active = false;ke_state_set(KE_BUILD_ID(KE_TYPE_GET(dest_id), conidx), APP_CONNECTABLE);CALLBACK_ARGS_1(user_app_callbacks.app_on_disconnect, param);}else{// We are not in Connected StateASSERT_ERROR(0);}return (KE_MSG_CONSUMED);
}/******************************************************************************************* @brief Start placing services in the database.* @return true if succeeded, else false*****************************************************************************************/
bool app_db_init_start(void)
{// Indicate if more services need to be added in the databasebool end_db_create;// We are now in Initialization Statefor(uint8_t idx = 0; idx < APP_IDX_MAX; idx++)ke_state_set(KE_BUILD_ID(TASK_APP, idx), APP_DB_INIT);end_db_create = app_db_init_next();return end_db_create;
}
8、修改da145xx_symbols.txt文件(在sdk\common_project_files\misc目录下),去除app.c、app_entry_point.c、app_task.c部分函数引用
原先为:
; app.c (controlled by __EXCLUDE_ROM_APP_TASK__)
0x07f22b35 T app_db_init_start
0x07f22b51 T app_db_init
0x07f22b5d T app_easy_gap_confirm
0x07f22b89 T append_device_name
0x07f22bad T app_easy_gap_update_adv_data
0x07f22bf5 T active_conidx_to_conhdl
0x07f22c19 T active_conhdl_to_conidx
0x07f22c55 T app_easy_gap_disconnect
0x07f22c91 T app_easy_gap_advertise_stop
0x07f22cad T app_timer_set
0x07f22cc9 T app_easy_gap_set_data_packet_length
0x07f22d09 T get_user_prf_srv_perm
0x07f22d31 T app_set_prf_srv_perm
0x07f22d61 T prf_init_srv_perm
0x07f22d85 T app_gattc_svc_changed_cmd_send
0x07f231fd T app_gap_process_handler; app_entry_point.c (controlled by __EXCLUDE_ROM_APP_TASK__)
0x07f23219 T app_entry_point_handler
0x07f23261 T app_std_process_event; app_task.c (controlled by __EXCLUDE_ROM_APP_TASK__)
0x07f23b98 D app_default_handler
更改为:
; app.c (controlled by __EXCLUDE_ROM_APP_TASK__)
0x07f23515 T append_device_name
;0x07f23715 T app_gattc_svc_changed_cmd_send ; app_entry_point.c (controlled by __EXCLUDE_ROM_APP_TASK__)
;0x07f23219 T app_entry_point_handler
;0x07f23261 T app_std_process_event; app_task.c (controlled by __EXCLUDE_ROM_APP_TASK__)
;0x07f23b98 D app_default_handler
至此修改完毕。