BLE芯片DA145XX系列:配置SDK支持多连接

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 Index
    if (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 parameters
            app_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 confirmation
                app_easy_gap_confirm(conidx, (enum gap_auth) app_sec_env[conidx].auth, 1);
            #else
                app_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 message
        ASSERT_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 State
        ASSERT_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 profiles
    while(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 profiles
    while(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;
    }
#endif

    k = 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 database
    bool end_db_create;

    // We are now in Initialization State
    ke_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_APP
                                           ke_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 Index
    if (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 parameters
            app_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 confirmation
                app_easy_gap_confirm(conidx, (enum gap_auth) app_sec_env[conidx].auth, 1);
            #else
                app_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 message
        ASSERT_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 State
        ASSERT_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 database
    bool end_db_create;

    // We are now in Initialization State
    for(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

 至此修改完毕。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值