Files
hpw421/project/example/ble/ble_central/app/src/app_task.c
T
2026-07-03 18:08:25 +08:00

1019 lines
37 KiB
C

/**
****************************************************************************************
*
* @file app_task.c
*
* @brief RW APP Task implementation
*
* Copyright (C) RivieraWaves 2009-2015
*
*
****************************************************************************************
*/
#include "app_task.h" // Application Manager Task API
#include "timer.h"
#include "xc_drv_timer.h"
#include "lld_int.h"
extern struct lld_env_tag lld_env;
__RAM_EM struct conn_dev_info conn_dev[CONNECT_DEV_NUM] = {0};
extern struct ADV_INFO adv_info;
/// Application Task Descriptor
const struct ke_task_desc TASK_DESC_APP;
/// Application Environment Structure
__RAM_EM struct app_env_tag app_env = {
.adv_actv_idx = INVALID_DATA,
.scan_actv_idx = INVALID_DATA,
.init_actv_idx = INVALID_DATA,
.slave_conidx = INVALID_DATA,
.master_conidx = INVALID_DATA,
.slave_connected = false,
.master_connected = false,
};
bool connect_idle=true;
static uint8_t gapc_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id);
static uint8_t gapm_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id);
struct app_env_tag *get_app_env(void) { return &app_env; }
uint8_t find_conn_dev(uint8_t *addr)
{
uint8_t find_idx = 0xFF;
for (uint8_t i = 0; i < CONNECT_DEV_NUM; i++) {
if (memcmp(&(conn_dev[i].addr[0]), &addr[0], GAP_BD_ADDR_LEN) == 0) {
find_idx = i;
break;
}
}
return find_idx;
}
uint8_t calc_conn_num(void)
{
uint8_t num = 0;
for(uint8_t i = 0; i <CONNECT_DEV_NUM ;i++)
{
if(conn_dev[i].connnectd)
{
num++;
}
}
return num;
}
void printf_conn_dev(void)
{
for(uint8_t i = 0; i <CONNECT_DEV_NUM ;i++)
{
LOGI(" idx :%d condix :%d addr:%x %x %x %x %x %x connectd:%d \r\n",i,conn_dev[i].conidx,conn_dev[i].addr[0],conn_dev[i].addr[1],conn_dev[i].addr[2],conn_dev[i].addr[3],conn_dev[i].addr[4],conn_dev[i].addr[5],conn_dev[i].connnectd);
}
}
uint8_t find_conn_dev_idx(uint8_t conidx)
{
uint8_t find_idx = 0xFF;
for (uint8_t i = 0; i < CONNECT_DEV_NUM; i++) {
if (conn_dev[i].conidx == conidx) {
find_idx = i;
break;
}
}
return find_idx;
}
uint8_t add_conn_dev(uint8_t *addr)
{
uint8_t add_idx = 0xFF;
uint8_t invild_addr[6] = {0, 0, 0, 0, 0, 0};
for (uint8_t i = 0; i < CONNECT_DEV_NUM; i++) {
if (memcmp(&(conn_dev[i].addr[0]), &invild_addr[0], GAP_BD_ADDR_LEN) ==
0) {
memcpy(&(conn_dev[i].addr[0]), &addr[0], GAP_BD_ADDR_LEN);
add_idx = i;
break;
}
}
return add_idx;
}
void app_init()
{
// Reset the application manager environment
// memset(&app_env, 0, sizeof(app_env));
// Create APP task
ke_task_create(TASK_APP, &TASK_DESC_APP);
// Initialize Task state
ke_state_set(TASK_APP, APP_INIT);
#if (NVDS_SUPPORT)
// Get the Device Name to add in the Advertising Data (Default one or NVDS
// one)
// app_env.dev_name_len = APP_DEVICE_NAME_MAX_LEN;
// if (nvds_get(NVDS_TAG_DEVICE_NAME, &(app_env.dev_name_len),
// app_env.dev_name) != NVDS_OK)
#endif //(NVDS_SUPPORT)
{
// Get default Device Name (No name if not enough space)
memcpy(app_env.dev_name, APP_DFLT_DEVICE_NAME,
APP_DFLT_DEVICE_NAME_LEN);
app_env.dev_name_len = APP_DFLT_DEVICE_NAME_LEN;
}
// Reset the stack
xc_ble_gapm_reset();
for(uint8_t i = 0;i<CONNECT_DEV_NUM;i++)
{
conn_dev[i].conidx =0xff;
}
}
uint8_t app_get_dev_name(uint8_t *name)
{
if ((app_env.dev_name_len > 0) &&
(app_env.dev_name_len <= APP_DEVICE_NAME_MAX_LEN) && (name != NULL)) {
// copy name to provided pointer
memcpy(name, app_env.dev_name, APP_DFLT_DEVICE_NAME_LEN);
// return name length
return app_env.dev_name_len;
} else {
return 0;
}
}
void app_set_dev_name(uint8_t *name, uint8_t name_len)
{
if ((name_len > 0) && (name_len <= APP_DEVICE_NAME_MAX_LEN) &&
(name != NULL)) {
memcpy(app_env.dev_name, name, name_len);
app_env.dev_name_len = name_len;
}
}
#if MULTI_ROLE_TEST
// adv
void app_create_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_IDLE) {
struct gapm_activity_create_adv_cmd param = {0};
param.own_addr_type = GAPM_STATIC_ADDR;
param.adv_param.type = GAPM_ADV_TYPE_LEGACY;
param.adv_param.disc_mode = GAPM_ADV_MODE_GEN_DISC;
param.adv_param.prop = GAPM_ADV_PROP_UNDIR_CONN_MASK;
param.adv_param.max_tx_pwr = APP_MAX_TX_POWER;
param.adv_param.filter_pol = ADV_ALLOW_SCAN_ANY_CON_ANY;
param.adv_param.prim_cfg.adv_intv_min = APP_ADV_INT_MIN;
param.adv_param.prim_cfg.adv_intv_max = APP_ADV_INT_MAX;
param.adv_param.prim_cfg.chnl_map = APP_ADV_CHMAP;
param.adv_param.prim_cfg.phy = GAP_PHY_1MBPS;
xc_ble_advertise_create(&param);
app_env.adv_state = APP_ADV_STATE_STARTING;
}
}
void app_set_adv_data(void)
{
if (app_env.adv_state == APP_ADV_STATE_STARTING) {
uint8_t adv_data[ADV_DATA_MAX_LENGTH] = {0};
adv_data[0] = APP_DFLT_DEVICE_NAME_LEN + 1;
adv_data[1] = GAP_AD_TYPE_COMPLETE_NAME;
memcpy(&adv_data[2], APP_DFLT_DEVICE_NAME, APP_DFLT_DEVICE_NAME_LEN);
xc_ble_set_adv_data(app_env.adv_actv_idx, APP_DFLT_DEVICE_NAME_LEN + 2,
adv_data);
adv_info.name_length= APP_SINGLEOTA_DEVICE_NAME_LEN;
memcpy(&adv_info.name,APP_SINGLEOTA_DEVICE_NAME,APP_SINGLEOTA_DEVICE_NAME_LEN);
app_env.adv_state = APP_ADV_STATE_SETTING_ADV_DATA;
}
}
void app_set_scan_rsp_data(void)
{
if (app_env.adv_state == APP_ADV_STATE_SETTING_ADV_DATA) {
uint8_t scan_rsp_data[ADV_DATA_MAX_LENGTH] = {0};
scan_rsp_data[0] = MANUFACTURER_DATA_LEN + 1;
scan_rsp_data[1] = GAP_AD_TYPE_MANU_SPECIFIC_DATA;
memcpy(&scan_rsp_data[2], MANUFACTURER_DATA, MANUFACTURER_DATA_LEN);
xc_ble_set_scan_rsp_data(app_env.adv_actv_idx,
MANUFACTURER_DATA_LEN + 2, scan_rsp_data);
app_env.adv_state = APP_ADV_STATE_SETTING_SCAN_RSP_DATA;
}
}
void app_start_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_SETTING_ADV_DATA ||
app_env.adv_state == APP_ADV_STATE_SETTING_SCAN_RSP_DATA ||
app_env.adv_state == APP_ADV_STATE_STOPPED) {
struct gapm_activity_start_cmd param = {0};
param.actv_idx = app_env.adv_actv_idx;
param.u_param.adv_add_param.duration = ADV_DURATION;
xc_ble_advertise_start(&param);
app_env.adv_state = APP_ADV_STATE_STARTING;
}
}
void app_stop_advertising(void)
{
if (app_env.adv_state == APP_ADV_STATE_STARTING) {
xc_ble_activity_stop(app_env.adv_actv_idx);
app_env.adv_state = APP_ADV_STATE_STOPPING;
}
}
#endif
// scan
void app_create_scan(void)
{
if (app_env.scan_state == APP_SCAN_STATE_IDLE) {
struct gapm_activity_create_cmd param = {
.own_addr_type = GAPM_STATIC_ADDR,
};
xc_ble_scan_create(&param);
app_env.scan_state = APP_SCAN_STATE_CREATING;
}
}
void app_start_scan(void)
{
if (app_env.scan_state == APP_SCAN_STATE_CREATING ||
app_env.scan_state == APP_SCAN_STATE_STOPPED) {
struct gapm_activity_start_cmd scan_param = {0};
struct gapm_scan_param *param = &scan_param.u_param.scan_param;
scan_param.actv_idx = app_env.scan_actv_idx;
param->type = GAPM_SCAN_TYPE_OBSERVER;
param->prop = GAPM_SCAN_PROP_PHY_1M_BIT | GAPM_SCAN_PROP_ACTIVE_1M_BIT;
param->dup_filt_pol = GAPM_DUP_FILT_DIS;
param->scan_param_1m.scan_intv = 0xa0; // 20*0.625 ms
param->scan_param_1m.scan_wd = 0x50; // 15*0.625 ms
param->duration = 0;
xc_ble_scan_start(&scan_param);
app_env.scan_state = APP_SCAN_STATE_STARTING;
}
}
void app_stop_scanning(void)
{
if (app_env.scan_state == APP_SCAN_STATE_STARTING) {
xc_ble_activity_stop(app_env.scan_actv_idx);
app_env.scan_state = APP_SCAN_STATE_STOPPING;
}
}
// init
void app_create_init(void)
{
if (app_env.init_state == APP_INIT_STATE_IDLE) {
struct gapm_activity_create_cmd param = {
.own_addr_type = GAPM_STATIC_ADDR,
};
xc_ble_init_create(&param);
app_env.init_state = APP_INIT_STATE_CREATING;
}
}
void app_start_init(uint8_t addr_type, uint8_t *addr)
{
LOGI(" start init state :%d \r\n", app_env.init_state);
#if !WHITE_LIST_TEST
if (app_env.init_state == APP_INIT_STATE_CREATING ||
app_env.init_state == APP_INIT_STATE_STOPPED)
#else
#endif
{
struct gapm_activity_start_cmd init_param = {0};
struct gapm_init_param *param = &init_param.u_param.init_param;
init_param.actv_idx = app_env.init_actv_idx;
#if WHITE_LIST_TEST
param->type = GAPM_INIT_TYPE_AUTO_CONN_EST;
#else
param->type = GAPM_INIT_TYPE_DIRECT_CONN_EST;
#endif
param->prop = GAPM_INIT_PROP_1M_BIT;
param->conn_to = APP_CONN_EST_TIME_OUT;
param->scan_param_1m.scan_intv = APP_CONN_SCNA_INTV;
param->scan_param_1m.scan_wd = APP_CONN_SCAN_WD;
param->conn_param_1m.conn_intv_min = APP_CONN_INTV_MIN;
param->conn_param_1m.conn_intv_max = APP_CONN_INTV_MIN;
param->conn_param_1m.conn_latency = APP_CONN_LATENCY;
param->conn_param_1m.supervision_to = APP_CONN_TIME_OUT;
param->peer_addr.addr_type = addr_type;
memcpy(param->peer_addr.addr, addr, GAP_BD_ADDR_LEN);
xc_ble_init_start(&init_param);
app_env.init_state = APP_INIT_STATE_STARTING;
}
}
void app_stop_init(void)
{
if (app_env.init_state == APP_INIT_STATE_STARTING) {
xc_ble_activity_stop(app_env.init_actv_idx);
app_env.init_state = APP_INIT_STATE_STOPPING;
}
}
static uint8_t
app_get_handler(const struct app_subtask_handlers *handler_list_desc,
ke_msg_id_t msgid, void *p_param, ke_task_id_t src_id)
{
// Counter
uint8_t counter;
// Get the message handler function by parsing the message table
for (counter = handler_list_desc->msg_cnt; 0 < counter; counter--) {
struct ke_msg_handler handler = (struct ke_msg_handler)(
*(handler_list_desc->p_msg_handler_tab + counter - 1));
if ((handler.id == msgid) || (handler.id == KE_MSG_DEFAULT_HANDLER)) {
// If handler is NULL, message should not have been received in this
// state
ASSERT_ERR(handler.func);
return (uint8_t)(handler.func(msgid, p_param, TASK_APP, src_id));
}
}
// If we are here no handler has been found, drop the message
return (KE_MSG_CONSUMED);
}
/**
****************************************************************************************
* @brief Handles reception of all messages sent from the lower layers to the
*application
* @param[in] msgid Id of the message received.
* @param[in] p_param Pointer to the parameters of the message.
* @param[in] dest_id ID of the receiving task instance
* @param[in] src_id ID of the sending task instance.
*
* @return If the message was consumed or not.
****************************************************************************************
*/
static int app_msg_handler(ke_msg_id_t const msgid, void *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Retrieve identifier of the task from received message
ke_task_id_t src_task_id = MSG_T(msgid);
// Message policy
uint8_t msg_pol = KE_MSG_CONSUMED;
switch (src_task_id) {
case TASK_ID_GAPM: {
msg_pol = gapm_callback(msgid, p_param, dest_id, src_id);
} break;
case TASK_ID_GAPC: {
if ((msgid >= GAPC_BOND_CMD) && (msgid <= GAPC_BOND_DATA_UPDATE_IND)) {
// Call the Security Module
msg_pol =
app_get_handler(&app_sec_handlers, msgid, p_param, src_id);
} else {
msg_pol = gapc_callback(msgid, p_param, dest_id, src_id);
}
} break;
case TASK_ID_GATT: {
} break;
#if (BLE_APP_HT)
case (TASK_ID_HTPT): {
// Call the Health Thermometer Module
msg_pol = app_get_handler(&app_ht_handlers, msgid, p_param, src_id);
} break;
#endif //(BLE_APP_HT)
#if (BLE_APP_DIS)
case (TASK_ID_DISS): {
// Call the Device Information Module
msg_pol = app_get_handler(&app_dis_handlers, msgid, p_param, src_id);
} break;
#endif //(BLE_APP_DIS)
#if (BLE_APP_HID)
case (TASK_ID_HOGPD): {
// Call the HID Module
msg_pol = app_get_handler(&app_hid_handlers, msgid, p_param, src_id);
} break;
#endif //(BLE_APP_HID)
default:
break;
}
return (msg_pol);
}
#define IP_DIAGCNTL_ADDR 0x53000050
__INLINE void ip_diagcntl_pack(uint8_t diag3en, uint8_t diag3, uint8_t diag2en, uint8_t diag2, uint8_t diag1en, uint8_t diag1, uint8_t diag0en, uint8_t diag0)
{
ASSERT_ERR((((uint32_t)diag3en << 31) & ~((uint32_t)0x80000000)) == 0);
ASSERT_ERR((((uint32_t)diag3 << 24) & ~((uint32_t)0x3F000000)) == 0);
ASSERT_ERR((((uint32_t)diag2en << 23) & ~((uint32_t)0x00800000)) == 0);
ASSERT_ERR((((uint32_t)diag2 << 16) & ~((uint32_t)0x003F0000)) == 0);
ASSERT_ERR((((uint32_t)diag1en << 15) & ~((uint32_t)0x00008000)) == 0);
ASSERT_ERR((((uint32_t)diag1 << 8) & ~((uint32_t)0x00003F00)) == 0);
ASSERT_ERR((((uint32_t)diag0en << 7) & ~((uint32_t)0x00000080)) == 0);
ASSERT_ERR((((uint32_t)diag0 << 0) & ~((uint32_t)0x0000003F)) == 0);
REG_IP_WR(IP_DIAGCNTL_ADDR, ((uint32_t)diag3en << 31) | ((uint32_t)diag3 << 24) | ((uint32_t)diag2en << 23) | ((uint32_t)diag2 << 16) | ((uint32_t)diag1en << 15) | ((uint32_t)diag1 << 8) | ((uint32_t)diag0en << 7) | ((uint32_t)diag0 << 0));
}
/**
****************************************************************************************
* @brief Handles GAP manager command complete events.
*
* @param[in] msgid Id of the message received.
* @param[in] p_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.
****************************************************************************************
*/
static void gapm_cmp_evt(ke_msg_id_t const msgid,
struct gapm_cmp_evt const *p_param,
ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
LOGI(
" app gapm_cmp_evt operation:0x%02x, act_id:0x%02x status :0x%02x\r\n",
p_param->operation, p_param->actv_idx, p_param->status);
if (p_param->status == GAP_ERR_NO_ERROR) {
switch (p_param->operation) {
// Reset completed
case GAPM_RESET: {
struct gapm_set_dev_config_cmd cfg_param = {
.role = GAP_ROLE_ALL,
.pairing_mode = GAPM_PAIRING_SEC_CON | GAPM_PAIRING_LEGACY,
.sugg_max_tx_octets = BLE_MIN_OCTETS,
.sugg_max_tx_time = BLE_MIN_TIME,
};
// SETF(cfg_param.att_cfg, GAPM_ATT_SLV_PREF_CON_PAR_EN, 1);
xc_ble_set_dev_config(&cfg_param);
#if (FLASH_TEST_IN_TASK || FLASH_TEST_IN_BLUETOOTH_GAP)
ke_timer_set(ONE_SEC_TIMER_MSG, TASK_APP, 1000);
#endif // #if (FLASH_TEST_IN_TASK || FLASH_TEST_IN_BLUETOOTH_GAP)
#if (CENTRAL_SEND_TEST_DATA)
ke_timer_set(CENTRAL_SEND_DATA_TIMER, TASK_APP, 1000);
#endif // (CENTRAL_SEND_TEST_DATA)
if (CFG_CON > 1) {
extern uint8_t rwip_prog_delay;
rwip_prog_delay = 6;
}
lld_env.dft_slave_md = 0;
// ip_diagcntl_pack(0,0,0,0,1,0x7c,1,0x3);
} break;
case GAPM_SET_DEV_CONFIG: {
#if WHITE_LIST_TEST
gap_bdaddr_t wl_info[10] = {0};
uint8_t addr1[6] = {0x89, 0x23, 0x33, 0x46, 0x55, 0x88};
uint8_t addr2[6] = {0x21 ,0x9c, 0xe4 ,0xd2 ,0xe6 ,0x02};
uint8_t addr3[6] = {0x21 ,0x9c, 0xb8 ,0xd3 ,0x0e ,0x13 };
uint8_t addr4[6] = {0x21 ,0x9c, 0xe4 ,0xd2 ,0x7d ,0x02 };
// wl_info[0].addr_type = 1;
// wl_info[1].addr_type = 1;
// wl_info[2].addr_type = 1;
memcpy(&wl_info[0].addr[0],&addr1[0],6);
memcpy(&wl_info[1].addr[0],&addr2[0],6);
memcpy(&wl_info[2].addr[0],&addr3[0],6);
memcpy(&wl_info[3].addr[0],&addr4[0],6);
xc_ble_set_white_list(4, &wl_info[0]);
#endif
// xc_ble_gen_random_nb();
// xc_ble_gen_random_nb();
// } break;
// case GAPM_GEN_RAND_NB: {
// if (app_env.rand_cnt == 2) {
gap_sec_key_t irk = {0};
memcpy(&irk.key[0], &app_env.loc_irk[0], GAP_KEY_LEN);
xc_ble_set_irk(&irk);
// app_env.rand_cnt = 0;
if (!app_cli_register()) {
app_create_scan();
app_create_init();
}
#if MULTI_ROLE_TEST
if (!custom_svc_add()) {
app_create_advertising();
}
#endif
// }
} break;
case GAPM_SET_ADV_DATA: {
#if MULTI_ROLE_TEST
app_start_advertising();
#endif
} break;
default:
break;
}
} else {
ASSERT_ERR(0);
}
}
static void gapc_get_device_info_req_ind(
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)
{
uint8_t conidx = KE_IDX_GET(src_id);
struct gapc_get_dev_info_cfm *pcfm = NULL;
switch (param->req) {
case GAPC_DEV_NAME: {
pcfm = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, DEVICE_NAME_MAX_LEN);
pcfm->req = param->req;
pcfm->token = param->token;
pcfm->status = GAP_ERR_NO_ERROR;
pcfm->info.name.value_length = app_get_dev_name(pcfm->info.name.value);
} break;
case GAPC_DEV_APPEARANCE: {
pcfm = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, 0);
pcfm->req = param->req;
pcfm->info.appearance = DEV_APPEARANCE;
pcfm->token = param->token;
pcfm->status = GAP_ERR_NO_ERROR;
} break;
case GAPC_DEV_SLV_PREF_PARAMS: {
pcfm = KE_MSG_ALLOC_DYN(
GAPC_GET_DEV_INFO_CFM, KE_BUILD_ID(TASK_GAPC, conidx), TASK_APP,
gapc_get_dev_info_cfm, 0);
pcfm->req = param->req;
pcfm->info.slv_pref_params.con_intv_min = BLE_UAPDATA_MIN_INTVALUE;
// Slave preferred Connection interval Max
pcfm->info.slv_pref_params.con_intv_max = BLE_UAPDATA_MAX_INTVALUE;
// Slave preferred Connection latency
pcfm->info.slv_pref_params.slave_latency = BLE_UAPDATA_LATENCY;
// Slave preferred Link supervision timeout
pcfm->info.slv_pref_params.conn_timeout = BLE_UAPDATA_TIMEOUT;
pcfm->token = param->token;
pcfm->status = GAP_ERR_NO_ERROR;
} break;
default:
break;
}
if (pcfm) {
xc_ble_get_dev_info_cfm(conidx, pcfm);
}
}
static void gapm_profile_add_ind(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapm_profile_added_ind *p_param =
(struct gapm_profile_added_ind *)param;
// Current State
ke_state_t state = ke_state_get(dest_id);
LOGI("gapm_profile_add_ind profile_task_id:0x%x,state=0x%x\r\n",
p_param->prf_task_id, state);
switch (p_param->prf_task_id) {
case TASK_ID_BASS: {
} break;
case TASK_ID_BASC: {
} break;
default:
break;
}
}
static void gapm_activity_created_ind(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapm_activity_created_ind *p_param =
(struct gapm_activity_created_ind *)param;
LOGI(" gapm_activity_created_ind actv_idx = %d,actv_type = %d ",
p_param->actv_idx, p_param->actv_type);
switch (p_param->actv_type) {
case GAPM_ACTV_TYPE_SCAN: {
app_env.scan_actv_idx = p_param->actv_idx;
app_start_scan();
} break;
case GAPM_ACTV_TYPE_INIT: {
app_env.init_actv_idx = p_param->actv_idx;
} break;
case GAPM_ACTV_TYPE_ADV: {
#if MULTI_ROLE_TEST
app_env.adv_actv_idx = p_param->actv_idx;
app_set_adv_data();
#endif
} break;
default:
break;
}
}
static void gapm_activity_stop_ind(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
struct gapm_activity_stopped_ind *p_param =
(struct gapm_activity_stopped_ind *)param;
LOGI(" activity stop actv_id=%d actv_type=%d, reason=0x%x\r\n",
p_param->actv_idx, p_param->actv_type, p_param->reason);
if (p_param->actv_idx == app_env.scan_actv_idx) {
app_env.scan_state = APP_SCAN_STATE_STOPPED;
} else if (p_param->actv_idx == app_env.init_actv_idx) {
app_env.init_state = APP_INIT_STATE_STOPPED;
#if WHITE_LIST_TEST
app_start_init(0,NULL);
#endif
} else if (p_param->actv_idx == app_env.adv_actv_idx) {
app_env.adv_state = APP_ADV_STATE_STOPPED;
}
}
static uint8_t gapm_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
switch (msgid) {
case GAPM_CMP_EVT:
gapm_cmp_evt(msgid, param, dest_id, src_id);
break;
case GAPM_DEV_BDADDR_IND: {
struct gapm_dev_bdaddr_ind *p_param =
(struct gapm_dev_bdaddr_ind *)param;
LOGI("GAPM_DEV_BDADDR_IND\r\n");
LOGI("app_gapm_dev_bdaddr_ind_handler addr type:0x%x, addr:0x%x "
"0x%x 0x%x 0x%x 0x%x 0x%x \r\n",
p_param->addr.addr_type, p_param->addr.addr[0],
p_param->addr.addr[1], p_param->addr.addr[2],
p_param->addr.addr[3], p_param->addr.addr[4],
p_param->addr.addr[5]);
} break;
case GAPM_GEN_RAND_NB_IND: {
struct gapm_gen_rand_nb_ind *p_param =
(struct gapm_gen_rand_nb_ind *)param;
// First part of IRK
if (app_env.rand_cnt == 0) {
memcpy(&app_env.loc_irk[0], &p_param->randnb.nb[0], 8);
}
// Second part of IRK
else if (app_env.rand_cnt == 1) {
memcpy(&app_env.loc_irk[8], &p_param->randnb.nb[0], 8);
}
app_env.rand_cnt++;
} break;
case GAPM_ACTIVITY_CREATED_IND: {
gapm_activity_created_ind(msgid, param, dest_id, src_id);
} break;
case GAPM_ACTIVITY_STOPPED_IND: {
gapm_activity_stop_ind(msgid, param, dest_id, src_id);
} break;
case GAPM_SCAN_REQUEST_IND:
LOGI("GAPM_SCAN_REQUEST_IND\r\n");
break;
case GAPM_PROFILE_ADDED_IND: {
gapm_profile_add_ind(msgid, param, dest_id, src_id);
} break;
case GAPM_ADDR_SOLVED_IND: {
LOGI("======== GAPM_ADDR_SOLVED_IND ========\r\n");
struct gapm_addr_solved_ind *p_param =
(struct gapm_addr_solved_ind *)param;
LOGI("addr: %x %x %x %x %x %x \r\n", p_param->addr.addr[0],
p_param->addr.addr[1], p_param->addr.addr[2],
p_param->addr.addr[3], p_param->addr.addr[4],
p_param->addr.addr[5]);
for (uint8_t i = 0; i < 16; i++) {
LOGI(" %x ", p_param->irk.key[i]);
}
} break;
case GAPM_EXT_ADV_REPORT_IND: {
struct gapm_ext_adv_report_ind *p_param =
(struct gapm_ext_adv_report_ind *)param;
#if (SCAN_RSSI_DEBUG)
LOGI("rssi=%d\n",p_param->rssi);
#endif
#if WHITE_LIST_TEST
app_start_init(0,NULL);
#else
uint8_t addr2[6] = {0x58, 0x1f, 0x05, 0x00, 0x76, 0x01};
uint8_t addr3[6] = {0xe1, 0x4c, 0x15, 0x00, 0x3e, 0x00};
uint8_t addr4[6] = {0xe7, 0xbc, 0x58, 0x00, 0xa4, 0x01};
uint8_t addr5[6] = {0xe1, 0xb9, 0x27, 0x00, 0xc5, 0x00};
if ((memcmp(p_param->trans_addr.addr, addr2,
GAP_BD_ADDR_LEN) == 0) ||(memcmp(p_param->trans_addr.addr, addr3,
GAP_BD_ADDR_LEN) == 0) ||(memcmp(p_param->trans_addr.addr, addr4,
GAP_BD_ADDR_LEN) == 0) ||(memcmp(p_param->trans_addr.addr, addr5,
GAP_BD_ADDR_LEN) == 0))
{
LOGI("find target device \r\n");
LOGI("addr_type :%d ,addr :%x %x %x %x %x %x \r\n",p_param->trans_addr.addr_type,p_param->trans_addr.addr[0],p_param->trans_addr.addr[1],p_param->trans_addr.addr[2],p_param->trans_addr.addr[3],p_param->trans_addr.addr[4],p_param->trans_addr.addr[5]);
uint8_t find_idx = find_conn_dev(&(p_param->trans_addr.addr[0]));
if(find_idx != 0xff)
{
if(conn_dev[find_idx].connnectd == false)
{
LOGI(" dddd1 find_idx :%d ,connect dev addr :%x %x %x %x %x %x \r\n",find_idx,p_param->trans_addr.addr[0],p_param->trans_addr.addr[1],p_param->trans_addr.addr[2],p_param->trans_addr.addr[3],p_param->trans_addr.addr[4],p_param->trans_addr.addr[5]);
// printf_conn_dev();
if(connect_idle==true)
{
connect_idle=false;
app_start_init(p_param->trans_addr.addr_type, p_param->trans_addr.addr);
}
}
}
else
{
LOGI("dddd2 find_idx :%d,conn dev addr :%x %x %x %x %x %x \r\n",find_idx,p_param->trans_addr.addr[0],p_param->trans_addr.addr[1],p_param->trans_addr.addr[2],p_param->trans_addr.addr[3],p_param->trans_addr.addr[4],p_param->trans_addr.addr[5]);
// printf_conn_dev();
if(connect_idle==true)
{
connect_idle=false;
app_start_init(p_param->trans_addr.addr_type,
p_param->trans_addr.addr);
}
}
}
#endif
} break;
default:
break;
}
return (KE_MSG_CONSUMED);
}
static uint8_t gapc_callback(ke_msg_id_t const msgid, void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint8_t conidx = KE_IDX_GET(src_id);
switch (msgid) {
case GAPC_CMP_EVT: {
struct gapc_cmp_evt const *p_param = (struct gapc_cmp_evt const *)param;
LOGI("GAPC_CMP_EVT operation = 0x%x, status = 0x%x conidx = "
"0x%x\r\n",
p_param->operation, p_param->status, conidx);
} break;
case GAPC_CONNECTION_REQ_IND: {
struct gapc_connection_req_ind *p_param =
(struct gapc_connection_req_ind *)param;
LOGI(" ======= GAPC_CONNECTION_REQ_IND conhdl = x%x, conidx = 0x%x ",
p_param->conhdl, conidx);
LOGI("conn_intv:%d, role=%d addr: ", p_param->con_interval,
p_param->role);
// DUMP_DATA_PRINTF(&(p_param->peer_addr.addr[0]), GAP_BD_ADDR_LEN);
for (uint8_t i = 0; i < GAP_BD_ADDR_LEN; i++) {
LOGI(" %02x ", p_param->peer_addr.addr[i]);
}
LOGI("\r\n");
// Check if the received connection index is valid
if (conidx != GAP_INVALID_CONIDX) {
struct gapc_connection_cfm cfm = {0};
cfm.pairing_lvl = GAP_PAIRING_UNAUTH;
xc_ble_conn_cfm(conidx, &cfm);
}
uint8_t find_idx = find_conn_dev(&(p_param->peer_addr.addr[0]));
if (find_idx != 0xff) {
conn_dev[find_idx].connnectd = true;
LOGI(" debug conn_dev[find_idx].conidx :%d conidx :%d \r\n ",
conn_dev[find_idx].conidx, conidx);
conn_dev[find_idx].conidx = conidx;
conn_dev[find_idx].role = p_param->role;
} else {
uint8_t add_idx = add_conn_dev(&(p_param->peer_addr.addr[0]));
if (add_idx == 0xff) {
LOGI("==== add dev error===\r\n");
} else {
conn_dev[add_idx].conidx = conidx;
conn_dev[add_idx].connnectd = true;
conn_dev[add_idx].role = p_param->role;
}
}
printf_conn_dev();
LOGI("--------- connect num :%d --------\r\n",calc_conn_num());
if (p_param->role == GAPM_ROLE_SLAVE) {
app_env.slave_conidx = conidx;
app_env.slave_connected = true;
}
// device as master
if (p_param->role == GAPM_ROLE_MASTER) {
//app_stop_scanning();
app_env.master_conidx = conidx;
app_env.master_connected = true;
#if (BOND_TEST)
struct gapc_bond_cmd bond_param = {0};
bond_param.pairing.auth =
GAP_AUTH_REQ_NO_MITM_BOND; // GAP_AUTH_REQ_MITM_BOND;//GAP_AUTH_REQ_MITM_BOND;
bond_param.pairing.iocap =
GAP_IO_CAP_NO_INPUT_NO_OUTPUT; // GAP_IO_CAP_KB_ONLY;//GAP_IO_CAP_DISPLAY_ONLY;//GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
bond_param.pairing.key_size = 16;
bond_param.pairing.oob = GAP_OOB_AUTH_DATA_NOT_PRESENT;
bond_param.pairing.sec_req =
GAP_SEC1_NOAUTH_PAIR_ENC; // GAP_SEC1_AUTH_PAIR_ENC;//GAP_NO_SEC;
bond_param.pairing.rkey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY;
bond_param.pairing.ikey_dist = GAP_KDIST_ENCKEY | GAP_KDIST_IDKEY;
xc_ble_bond(conidx, &bond_param);
#endif // (BOND_TEST)
usr_cli_feat_enable(conidx);
}
} break;
case GAPC_DISCONNECT_IND: {
struct gapc_disconnect_ind *p_param =
(struct gapc_disconnect_ind *)param;
LOGI("******* GAPC_DISCONNECT_IND conidx = 0x%x, reason = 0x%x "
"conhdl = 0x%x,\r\n",
conidx, p_param->reason, p_param->conhdl);
uint8_t find_idx = find_conn_dev_idx(conidx);
if (find_idx == 0xff) {
LOGI("debug find condix error\r\n");
} else {
conn_dev[find_idx].connnectd = false;
conn_dev[find_idx].conidx = 0xff;
}
printf_conn_dev();
LOGI("--------- connect num :%d --------\r\n",calc_conn_num());
#if !WHITE_LIST_TEST
if (conidx == app_env.master_conidx) {
app_env.master_conidx = INVALID_DATA;
app_env.master_connected = false;
// app_start_scan();
}
#else
app_start_init(0,NULL);
#endif
#if MULTI_ROLE_TEST
if (conidx == app_env.slave_conidx) {
app_env.slave_conidx = INVALID_DATA;
app_env.slave_connected = false;
app_start_advertising();
}
#endif
} break;
case GAPC_GET_DEV_INFO_REQ_IND: {
gapc_get_device_info_req_ind(msgid, param, dest_id, src_id);
} break;
case GAPC_SET_DEV_INFO_REQ_IND: {
struct gapc_set_dev_info_req_ind *p_param =
(struct gapc_set_dev_info_req_ind *)param;
struct gapc_set_dev_info_cfm cfm = {0};
LOGI("GAPC_SET_DEV_INFO_REQ_IND param->req=0x%x,conidx=0x%x\r\n",
p_param->req, conidx);
xc_ble_set_dev_info_cfm(conidx, &cfm);
} break;
case GAPC_PARAM_UPDATE_REQ_IND: {
struct gapc_param_update_req_ind *p_param =
(struct gapc_param_update_req_ind *)param;
struct gapc_param_update_cfm cfm = {0};
LOGI("GAPC_PARAM_UPDATE_REQ_IND "
"conidx=0x%x,intv_max=0x%x,intv_min=0x%x",
conidx, p_param->intv_max, p_param->intv_min);
LOGI("latency=0x%x,time_out=0x%x\r\n", p_param->latency,
p_param->time_out);
// Check if the received Connection Handle was valid
if (app_env.conidx != GAP_INVALID_CONIDX) {
cfm.accept = true;
cfm.ce_len_min = CE_LEN_MIN;
cfm.ce_len_max = CE_LEN_MAX;
xc_ble_param_update_cfm(conidx, &cfm);
}
} break;
case GAPC_PARAM_UPDATED_IND: {
struct gapc_param_updated_ind *p_param =
(struct gapc_param_updated_ind *)param;
LOGI("GAPC_PARAM_UPDATED_IND "
"conidx=0x%x,con_interval=0x%x,con_latency=0x%x ",
conidx, p_param->con_interval, p_param->con_latency);
LOGI("sup_to=0x%x\r\n", p_param->sup_to);
} break;
case GAPC_LE_PKT_SIZE_IND: {
struct gapc_le_pkt_size_ind *p_param =
(struct gapc_le_pkt_size_ind *)param;
LOGI("GAPC_LE_PKT_SIZE_IND "
"conidx=0x%x, max_rx_octets:%d",
conidx, p_param->max_rx_octets);
LOGI("max_rx_time:%d,max_tx_octets:%d, "
"max_tx_time :%d\r\n",
p_param->max_rx_time, p_param->max_tx_octets,
p_param->max_tx_time);
} break;
case GAPC_CON_RSSI_IND: {
struct gapc_con_rssi_ind *p_param = (struct gapc_con_rssi_ind *)param;
LOGI("GAPC_CON_RSSI_IND conidx=0x%x,rssi = %d\r\n", conidx,
p_param->rssi);
} break;
case GAPC_LE_PHY_IND: {
struct gapc_le_phy_ind *p_param = (struct gapc_le_phy_ind *)param;
LOGI("GAPC_LE_PHY_IND conidx=0x%x tx phy:%d rx phy:%d \r\n", conidx,
p_param->tx_phy, p_param->rx_phy);
} break;
case GAPC_BOND_REQ_IND:
// gapc_bond_req_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_BOND_IND:
// gapc_bond_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_SECURITY_IND:
// gapc_security_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_ENCRYPT_REQ_IND:
// gapc_encrypt_req_ind_handler(msgid, p_param, dest_id,src_id)
break;
case GAPC_ENCRYPT_IND:
// gapc_encrypt_ind_handler(msgid, p_param, dest_id,src_id)
break;
default:
break;
}
return (KE_MSG_CONSUMED);
}
#if (FLASH_TEST_IN_TASK || FLASH_TEST_IN_BLUETOOTH_GAP)
static int one_sec_timer_handler(ke_msg_id_t const msgid, void *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
ke_timer_set(ONE_SEC_TIMER_MSG, TASK_APP, 1000);
#if (FLASH_TEST_IN_TASK)
flash_test_in_task();
#endif // (FLASH_TEST_IN_TASK)
#if (FLASH_TEST_IN_BLUETOOTH_GAP)
flash_test_in_bluetooth_gap();
#endif // (FLASH_TEST_IN_BLUETOOTH_GAP)
return (KE_MSG_CONSUMED);
}
#endif // #if (FLASH_TEST_IN_TASK || FLASH_TEST_IN_BLUETOOTH_GAP)
#if (CENTRAL_SEND_TEST_DATA)
static int central_send_data_timer_handler(ke_msg_id_t const msgid, void *p_param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
ke_timer_set(CENTRAL_SEND_DATA_TIMER, TASK_APP, 1000);
LOGI("send idx\n");
for(uint8_t i = 0; i <CONNECT_DEV_NUM ;i++)
{
if(conn_dev[i].connnectd && conn_dev[i].role == GAPM_ROLE_MASTER){
send_data(conn_dev[i].conidx);
LOGI("send idx :%d condix :%d addr:%x %x %x %x %x %x \r\n",i,conn_dev[i].conidx,conn_dev[i].addr[0],conn_dev[i].addr[1],conn_dev[i].addr[2],conn_dev[i].addr[3],conn_dev[i].addr[4],conn_dev[i].addr[5]);
}
}
return (KE_MSG_CONSUMED);
}
#endif // (CENTRAL_SEND_TEST_DATA)
/* Default State handlers definition. */
KE_MSG_HANDLER_TAB(app){
#if (FLASH_TEST_IN_TASK || FLASH_TEST_IN_BLUETOOTH_GAP)
{ONE_SEC_TIMER_MSG, (ke_msg_func_t)one_sec_timer_handler},
#endif // #if (FLASH_TEST_IN_TASK || FLASH_TEST_IN_BLUETOOTH_GAP)
#if (CENTRAL_SEND_TEST_DATA)
{CENTRAL_SEND_DATA_TIMER, (ke_msg_func_t)central_send_data_timer_handler},
#endif // (CENTRAL_SEND_TEST_DATA)
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_msg_handler},
};
/* Defines the place holder for the states of all the task instances. */
ke_state_t app_state[APP_IDX_MAX];
// Application task descriptor
const struct ke_task_desc TASK_DESC_APP = {app_msg_handler_tab, app_state,
APP_IDX_MAX,
ARRAY_LEN(app_msg_handler_tab)};
/// @} APPTASK