75381150fd
Formatting Pass 1 Lots of fixups to adding stdint and stdbool all over the place Formatting Pass 2 Formatting Pass 3 Formatting Pass 4 Update app_bt_stream.cpp
1116 lines
35 KiB
C
1116 lines
35 KiB
C
/***************************************************************************
|
|
*
|
|
* Copyright 2015-2019 BES.
|
|
* All rights reserved. All unpublished rights reserved.
|
|
*
|
|
* No part of this work may be used or reproduced in any form or by any
|
|
* means, or stored in a database or retrieval system, without prior written
|
|
* permission of BES.
|
|
*
|
|
* Use of this work is governed by a license granted by BES.
|
|
* This work contains confidential and proprietary information of
|
|
* BES. which is protected by copyright, trade secret,
|
|
* trademark and other intellectual property rights.
|
|
*
|
|
****************************************************************************/
|
|
/**
|
|
****************************************************************************************
|
|
* @addtogroup APPTASK
|
|
* @{
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/*
|
|
* INCLUDE FILES
|
|
****************************************************************************************
|
|
*/
|
|
|
|
#include "rwip_config.h" // SW configuration
|
|
|
|
#if (BLE_APP_PRESENT)
|
|
|
|
#include "../l2cm/l2cm_int.h"
|
|
#include "app.h" // Application Manager Definition
|
|
#include "app_ble_include.h"
|
|
#include "app_task.h" // Application Manager Task API
|
|
#include "arch.h" // Platform Definitions
|
|
#include "gapc_task.h" // GAP Controller Task API
|
|
#include "gapm_task.h" // GAP Manager Task API
|
|
#include "gattc_task.h"
|
|
#include "ke_timer.h" // Kernel timer
|
|
#include <string.h>
|
|
|
|
#include "co_utils.h"
|
|
#if (BLE_APP_SEC)
|
|
#include "app_sec.h" // Security Module Definition
|
|
#endif //(BLE_APP_SEC)
|
|
|
|
#if (BLE_APP_HT)
|
|
#include "app_ht.h" // Health Thermometer Module Definition
|
|
#include "htpt_task.h"
|
|
#endif //(BLE_APP_HT)
|
|
|
|
#if (BLE_APP_DIS)
|
|
#include "app_dis.h" // Device Information Module Definition
|
|
#include "diss_task.h"
|
|
#endif //(BLE_APP_DIS)
|
|
|
|
#if (BLE_APP_BATT)
|
|
#include "app_batt.h" // Battery Module Definition
|
|
#include "bass_task.h"
|
|
#endif //(BLE_APP_BATT)
|
|
|
|
#if (BLE_APP_HID)
|
|
#include "app_hid.h" // HID Module Definition
|
|
#include "hogpd_task.h"
|
|
#endif //(BLE_APP_HID)
|
|
|
|
#if (BLE_APP_HR)
|
|
#include "app_hrps.h"
|
|
#endif
|
|
|
|
#if (BLE_APP_VOICEPATH)
|
|
#include "app_voicepath_ble.h" // Voice Path Module Definition
|
|
#endif // (BLE_APP_VOICEPATH)
|
|
|
|
#if (BLE_APP_DATAPATH_SERVER)
|
|
#include "app_datapath_server.h" // Data Path Server Module Definition
|
|
#include "datapathps_task.h"
|
|
#endif // (BLE_APP_DATAPATH_SERVER)
|
|
|
|
#if (BLE_APP_AI_VOICE)
|
|
#include "app_ai_ble.h" // ama Voice Module Definition
|
|
#endif // (BLE_APP_AI_VOICE)
|
|
|
|
#if (BLE_APP_OTA)
|
|
#include "app_ota.h" // OTA Module Definition
|
|
#include "ota_task.h"
|
|
#endif // (BLE_APP_OTA)
|
|
|
|
#if (BLE_APP_TOTA)
|
|
#include "app_tota_ble.h" // TOTA Module Definition
|
|
#include "tota_task.h"
|
|
#endif // (BLE_APP_TOTA)
|
|
|
|
#if (BLE_APP_ANCC)
|
|
#include "ancc_task.h"
|
|
#include "app_ancc.h" // ANC Module Definition
|
|
#include "app_ancc_task.h"
|
|
#endif // (BLE_APP_ANCC)
|
|
|
|
#if (BLE_APP_AMS)
|
|
#include "amsc_task.h"
|
|
#include "app_amsc.h" // AMS Module Definition
|
|
#include "app_amsc_task.h"
|
|
#endif // (BLE_APP_AMS)
|
|
#if (BLE_APP_GFPS)
|
|
#include "app_gfps.h" // google fast pair service provider
|
|
#include "gfps_provider_task.h"
|
|
#endif // (BLE_APP_GFPS)
|
|
#ifdef BLE_APP_AM0
|
|
#include "am0_app.h" // Audio Mode 0 Application
|
|
#endif // defined(BLE_APP_AM0)
|
|
|
|
#if (DISPLAY_SUPPORT)
|
|
#include "app_display.h" // Application Display Definition
|
|
#endif //(DISPLAY_SUPPORT)
|
|
|
|
#include "app_fp_rfcomm.h"
|
|
#include "ble_app_dbg.h"
|
|
#include "bt_drv_interface.h"
|
|
#include "nvrecord_ble.h"
|
|
|
|
#if (BLE_APP_TILE)
|
|
#include "tile_gatt_server.h"
|
|
#include "tile_target_ble.h"
|
|
#endif
|
|
|
|
/*
|
|
* LOCAL FUNCTION DEFINITIONS
|
|
****************************************************************************************
|
|
*/
|
|
#define APP_CONN_PARAM_INTERVEL_MIN (20)
|
|
|
|
uint8_t ble_stack_ready = 0;
|
|
|
|
extern bool app_factorymode_get(void);
|
|
|
|
static uint8_t appm_get_handler(const struct ke_state_handler *handler_list,
|
|
ke_msg_id_t msgid, void *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->msg_cnt; 0 < counter; counter--) {
|
|
struct ke_msg_handler handler =
|
|
(struct ke_msg_handler)(*(handler_list->msg_table + 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, param, TASK_APP, src_id));
|
|
}
|
|
}
|
|
|
|
// If we are here no handler has been found, drop the message
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
/*
|
|
* MESSAGE HANDLERS
|
|
****************************************************************************************
|
|
*/
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief
|
|
*
|
|
* @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.
|
|
****************************************************************************************
|
|
*/
|
|
static int app_adv_timeout_handler(ke_msg_id_t const msgid, void const *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
#if (BLE_APP_HID)
|
|
#else
|
|
// Stop advertising
|
|
appm_stop_advertising();
|
|
#endif
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Handles ready indication from the GAP. - Reset the stack
|
|
*
|
|
* @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.
|
|
****************************************************************************************
|
|
*/
|
|
static int gapm_device_ready_ind_handler(ke_msg_id_t const msgid,
|
|
void const *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
if (ble_stack_ready) {
|
|
return KE_MSG_CONSUMED;
|
|
}
|
|
|
|
#ifdef __FACTORY_MODE_SUPPORT__
|
|
if (app_factorymode_get()) {
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
#endif
|
|
|
|
BLE_APP_FUNC_ENTER();
|
|
|
|
// Application has not been initialized
|
|
ASSERT_ERR(ke_state_get(dest_id) == APPM_INIT);
|
|
|
|
ble_stack_ready = 1;
|
|
|
|
// Reset the stack
|
|
struct gapm_reset_cmd *cmd =
|
|
KE_MSG_ALLOC(GAPM_RESET_CMD, TASK_GAPM, TASK_APP, gapm_reset_cmd);
|
|
|
|
cmd->operation = GAPM_RESET;
|
|
|
|
ke_msg_send(cmd);
|
|
|
|
BLE_APP_FUNC_LEAVE();
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Handles GAP manager command complete events.
|
|
*
|
|
* @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.
|
|
****************************************************************************************
|
|
*/
|
|
static int 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) {
|
|
BLE_APP_FUNC_ENTER();
|
|
BLE_APP_DBG("param->operation: %d status is %d app_env.next_svc is %d",
|
|
param->operation, param->status, app_env.next_svc);
|
|
|
|
switch (param->operation) {
|
|
// Reset completed
|
|
case (GAPM_RESET): {
|
|
if (param->status == GAP_ERR_NO_ERROR) {
|
|
#if (BLE_APP_HID)
|
|
app_hid_start_mouse();
|
|
#endif //(BLE_APP_HID)
|
|
|
|
// Set Device configuration
|
|
struct gapm_set_dev_config_cmd *cmd =
|
|
KE_MSG_ALLOC(GAPM_SET_DEV_CONFIG_CMD, TASK_GAPM, TASK_APP,
|
|
gapm_set_dev_config_cmd);
|
|
// Set the operation
|
|
cmd->operation = GAPM_SET_DEV_CONFIG;
|
|
// Set the device role - Peripheral
|
|
cmd->role = GAP_ROLE_ALL;
|
|
// Set Data length parameters
|
|
cmd->sugg_max_tx_octets = APP_MAX_TX_OCTETS;
|
|
cmd->sugg_max_tx_time = APP_MAX_TX_TIME;
|
|
cmd->pairing_mode = GAPM_PAIRING_LEGACY;
|
|
#ifdef CFG_SEC_CON
|
|
cmd->pairing_mode |= GAPM_PAIRING_SEC_CON;
|
|
#endif
|
|
cmd->max_mtu = 512;
|
|
cmd->att_cfg = 0;
|
|
cmd->att_cfg |= GAPM_MASK_ATT_SVC_CHG_EN;
|
|
#if (BLE_APP_HID)
|
|
// Enable Slave Preferred Connection Parameters present
|
|
cmd->att_cfg |= GAPM_MASK_ATT_SLV_PREF_CON_PAR_EN;
|
|
#endif //(BLE_APP_HID)
|
|
|
|
#ifdef BLE_APP_AM0
|
|
cmd->addr_type = GAPM_CFG_ADDR_HOST_PRIVACY;
|
|
cmd->audio_cfg = GAPM_MASK_AUDIO_AM0_SUP;
|
|
#endif // BLE_APP_AM0
|
|
|
|
// load IRK
|
|
memcpy(cmd->irk.key, app_env.loc_irk, KEY_LEN);
|
|
|
|
// Send message
|
|
ke_msg_send(cmd);
|
|
} else {
|
|
ASSERT_ERR(0);
|
|
}
|
|
} break;
|
|
case (GAPM_PROFILE_TASK_ADD): {
|
|
// ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->operation,
|
|
// param->status); Add the next requested service
|
|
if (!appm_add_svc()) {
|
|
// Go to the ready state
|
|
ke_state_set(TASK_APP, APPM_READY);
|
|
|
|
// No more service to add
|
|
app_ble_system_ready();
|
|
}
|
|
} break;
|
|
// Device Configuration updated
|
|
case (GAPM_SET_DEV_CONFIG): {
|
|
ASSERT_INFO(param->status == GAP_ERR_NO_ERROR, param->operation,
|
|
param->status);
|
|
|
|
// Go to the create db state
|
|
ke_state_set(TASK_APP, APPM_CREATE_DB);
|
|
|
|
// Add the first required service in the database
|
|
// and wait for the PROFILE_ADDED_IND
|
|
appm_add_svc();
|
|
} break;
|
|
|
|
case (GAPM_ADV_NON_CONN):
|
|
case (GAPM_ADV_UNDIRECT):
|
|
#if !(BLE_APP_HID)
|
|
case (GAPM_ADV_DIRECT):
|
|
#endif // !(BLE_APP_HID)
|
|
case (GAPM_ADV_DIRECT_LDC): {
|
|
LOG_I("adv evt cmp status 0x%x", param->status);
|
|
ASSERT(GAP_ERR_ADV_DATA_INVALID != param->status,
|
|
"The BLE adv data or scan rsp data is invalid! Better check their "
|
|
"length.");
|
|
|
|
if (GAP_ERR_CANCELED == param->status) {
|
|
app_advertising_stopped();
|
|
} else if (GAP_ERR_NO_ERROR == param->status) {
|
|
if (ke_state_get(TASK_APP) == APPM_ADVERTISING) {
|
|
app_advertising_started();
|
|
} else {
|
|
app_advertising_stopped();
|
|
}
|
|
} else {
|
|
app_advertising_starting_failed();
|
|
}
|
|
|
|
break;
|
|
}
|
|
case GAPM_UPDATE_ADVERTISE_DATA: {
|
|
app_adv_data_updated();
|
|
break;
|
|
}
|
|
case GAPM_SCAN_ACTIVE:
|
|
case GAPM_SCAN_PASSIVE: {
|
|
LOG_I("scan evt cmp status %d", param->status);
|
|
if (GAP_ERR_CANCELED == param->status) {
|
|
app_scanning_stopped();
|
|
} else if (GAP_ERR_NO_ERROR == param->status) {
|
|
app_scanning_started();
|
|
} else {
|
|
app_scanning_starting_failed();
|
|
}
|
|
} break;
|
|
case GAPM_CONNECTION_DIRECT:
|
|
case GAPM_CONNECTION_AUTO:
|
|
case GAPM_CONNECTION_SELECTIVE:
|
|
case GAPM_CONNECTION_NAME_REQUEST:
|
|
case GAPM_CONNECTION_GENERAL: {
|
|
BLE_GAP_DBG("connecting cmp status %d", param->status);
|
|
if (GAP_ERR_CANCELED == param->status) {
|
|
app_connecting_stopped();
|
|
} else if (GAP_ERR_NO_ERROR == param->status) {
|
|
app_connecting_started();
|
|
} else {
|
|
app_connecting_failed();
|
|
}
|
|
} break;
|
|
|
|
#if (BLE_APP_HID)
|
|
case (GAPM_ADV_DIRECT): {
|
|
if (param->status == GAP_ERR_TIMEOUT) {
|
|
ke_state_set(TASK_APP, APPM_READY);
|
|
}
|
|
} break;
|
|
#endif //(BLE_APP_HID)
|
|
case GAPM_RESOLV_ADDR: {
|
|
LOG_I("Resolve result %d", param->status);
|
|
if (GAP_ERR_NOT_FOUND == param->status) {
|
|
appm_random_ble_addr_solved(false, NULL);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
// Drop the message
|
|
} break;
|
|
}
|
|
|
|
BLE_APP_FUNC_LEAVE();
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static int 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) {
|
|
switch (param->req) {
|
|
case GAPC_DEV_NAME: {
|
|
struct gapc_get_dev_info_cfm *cfm =
|
|
KE_MSG_ALLOC_DYN(GAPC_GET_DEV_INFO_CFM, src_id, dest_id,
|
|
gapc_get_dev_info_cfm, APP_DEVICE_NAME_MAX_LEN);
|
|
cfm->req = param->req;
|
|
cfm->info.name.length = appm_get_dev_name(cfm->info.name.value);
|
|
|
|
// Send message
|
|
ke_msg_send(cfm);
|
|
} break;
|
|
|
|
case GAPC_DEV_APPEARANCE: {
|
|
// Allocate message
|
|
struct gapc_get_dev_info_cfm *cfm = KE_MSG_ALLOC(
|
|
GAPC_GET_DEV_INFO_CFM, src_id, dest_id, gapc_get_dev_info_cfm);
|
|
cfm->req = param->req;
|
|
// Set the device appearance
|
|
#if (BLE_APP_HT)
|
|
// Generic Thermometer - TODO: Use a flag
|
|
cfm->info.appearance = 728;
|
|
#elif (BLE_APP_HID)
|
|
// HID Mouse
|
|
cfm->info.appearance = 962;
|
|
#else
|
|
// No appearance
|
|
cfm->info.appearance = 0;
|
|
#endif
|
|
|
|
// Send message
|
|
ke_msg_send(cfm);
|
|
} break;
|
|
|
|
case GAPC_DEV_SLV_PREF_PARAMS: {
|
|
// Allocate message
|
|
struct gapc_get_dev_info_cfm *cfm = KE_MSG_ALLOC(
|
|
GAPC_GET_DEV_INFO_CFM, src_id, dest_id, gapc_get_dev_info_cfm);
|
|
cfm->req = param->req;
|
|
// Slave preferred Connection interval Min
|
|
cfm->info.slv_params.con_intv_min = 8;
|
|
// Slave preferred Connection interval Max
|
|
cfm->info.slv_params.con_intv_max = 10;
|
|
// Slave preferred Connection latency
|
|
cfm->info.slv_params.slave_latency = 0;
|
|
// Slave preferred Link supervision timeout
|
|
cfm->info.slv_params.conn_timeout = 200; // 2s (500*10ms)
|
|
|
|
// Send message
|
|
ke_msg_send(cfm);
|
|
} break;
|
|
|
|
default: /* Do Nothing */
|
|
break;
|
|
}
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Handles GAPC_SET_DEV_INFO_REQ_IND message.
|
|
*
|
|
* @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.
|
|
****************************************************************************************
|
|
*/
|
|
static int 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) {
|
|
// Set Device configuration
|
|
struct gapc_set_dev_info_cfm *cfm = KE_MSG_ALLOC(
|
|
GAPC_SET_DEV_INFO_CFM, src_id, dest_id, gapc_set_dev_info_cfm);
|
|
// Reject to change parameters
|
|
cfm->status = GAP_ERR_REJECTED;
|
|
cfm->req = param->req;
|
|
// Send message
|
|
ke_msg_send(cfm);
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static void POSSIBLY_UNUSED gapc_refresh_remote_dev_feature(uint8_t conidx) {
|
|
// Send a GAPC_GET_INFO_CMD in order to read the device name characteristic
|
|
// value
|
|
struct gapc_get_info_cmd *p_cmd =
|
|
KE_MSG_ALLOC(GAPC_GET_INFO_CMD, KE_BUILD_ID(TASK_GAPC, conidx), TASK_GAPM,
|
|
gapc_get_info_cmd);
|
|
|
|
// request peer device name.
|
|
p_cmd->operation = GAPC_GET_PEER_FEATURES;
|
|
|
|
// send command
|
|
ke_msg_send(p_cmd);
|
|
}
|
|
|
|
static void POSSIBLY_UNUSED gpac_exchange_data_packet_length(uint8_t conidx) {
|
|
#if defined(CHIP_BEST2300) || defined(CHIP_BEST2300P)
|
|
return;
|
|
#endif
|
|
|
|
struct gapc_set_le_pkt_size_cmd *set_le_pakt_size_req =
|
|
KE_MSG_ALLOC(GAPC_SET_LE_PKT_SIZE_CMD, KE_BUILD_ID(TASK_GAPC, conidx),
|
|
TASK_APP, gapc_set_le_pkt_size_cmd);
|
|
|
|
set_le_pakt_size_req->operation = GAPC_SET_LE_PKT_SIZE;
|
|
set_le_pakt_size_req->tx_octets = APP_MAX_TX_OCTETS;
|
|
set_le_pakt_size_req->tx_time = APP_MAX_TX_TIME;
|
|
// Send message
|
|
ke_msg_send(set_le_pakt_size_req);
|
|
}
|
|
|
|
static int gapc_peer_features_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapc_peer_features_ind *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
LOG_I("Peer dev feature is:");
|
|
DUMP8("0x%02x ", param->features, GAP_LE_FEATS_LEN);
|
|
uint8_t conidx = KE_IDX_GET(src_id);
|
|
|
|
if (param->features[0] & GAPC_EXT_DATA_LEN_MASK) {
|
|
gpac_exchange_data_packet_length(conidx);
|
|
}
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
void app_exchange_remote_feature(uint8_t conidx) {
|
|
APP_BLE_CONN_CONTEXT_T *pContext = &(app_env.context[conidx]);
|
|
|
|
LOG_I("connectStatus:%d, isFeatureExchanged:%d, isGotSolvedBdAddr:%d",
|
|
pContext->connectStatus, pContext->isFeatureExchanged,
|
|
pContext->isGotSolvedBdAddr);
|
|
|
|
if ((BLE_CONNECTED == pContext->connectStatus) &&
|
|
!pContext->isFeatureExchanged) {
|
|
if (pContext->isGotSolvedBdAddr) {
|
|
gapc_refresh_remote_dev_feature(conidx);
|
|
pContext->isFeatureExchanged = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Handles connection complete event from the GAP. Enable all required
|
|
*profiles
|
|
*
|
|
* @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.
|
|
****************************************************************************************
|
|
*/
|
|
static int gapc_connection_req_ind_handler(
|
|
ke_msg_id_t const msgid, struct gapc_connection_req_ind *param,
|
|
ke_task_id_t const dest_id, ke_task_id_t const src_id) {
|
|
uint8_t conidx = KE_IDX_GET(src_id);
|
|
|
|
APP_BLE_CONN_CONTEXT_T *pContext = &(app_env.context[conidx]);
|
|
|
|
pContext->connectStatus = BLE_CONNECTED;
|
|
|
|
APP_BLE_NEGOTIATED_CONN_PARAM_T connParam;
|
|
connParam.con_interval = param->con_interval;
|
|
connParam.sup_to = param->sup_to;
|
|
connParam.con_latency = param->con_latency;
|
|
app_ble_save_negotiated_conn_param(conidx, &connParam);
|
|
|
|
ke_state_set(dest_id, APPM_CONNECTED);
|
|
|
|
app_env.conn_cnt++;
|
|
|
|
if (app_is_resolving_ble_bd_addr()) {
|
|
LOG_I("A ongoing ble addr solving is in progress, refuse the new "
|
|
"connection.");
|
|
appm_disconnect(conidx);
|
|
return KE_MSG_CONSUMED;
|
|
}
|
|
|
|
LOG_I("[CONNECT]device info:");
|
|
LOG_I("peer addr:");
|
|
DUMP8("%02x ", param->peer_addr.addr, 6);
|
|
LOG_I("peer addr type:%d", param->peer_addr_type);
|
|
LOG_I("connection index:%d, isGotSolvedBdAddr:%d", conidx,
|
|
pContext->isGotSolvedBdAddr);
|
|
LOG_I("conn interval:%d, timeout:%d", param->con_interval, param->sup_to);
|
|
|
|
BLE_APP_FUNC_ENTER();
|
|
|
|
// Check if the received Connection Handle was valid
|
|
if (conidx != GAP_INVALID_CONIDX) {
|
|
pContext->peerAddrType = param->peer_addr_type;
|
|
memcpy(pContext->bdAddr, param->peer_addr.addr, BD_ADDR_LEN);
|
|
|
|
// Retrieve the connection info from the parameters
|
|
pContext->conhdl = param->conhdl;
|
|
|
|
if (BLE_RANDOM_ADDR == pContext->peerAddrType) {
|
|
pContext->isGotSolvedBdAddr = false;
|
|
} else {
|
|
pContext->isGotSolvedBdAddr = true;
|
|
}
|
|
|
|
// Clear the advertising timeout timer
|
|
if (ke_timer_active(APP_ADV_TIMEOUT_TIMER, TASK_APP)) {
|
|
ke_timer_clear(APP_ADV_TIMEOUT_TIMER, TASK_APP);
|
|
}
|
|
|
|
#if (BLE_APP_SEC)
|
|
app_sec_reset_env_on_connection();
|
|
#endif
|
|
|
|
// Send connection confirmation
|
|
struct gapc_connection_cfm *cfm =
|
|
KE_MSG_ALLOC(GAPC_CONNECTION_CFM, KE_BUILD_ID(TASK_GAPC, conidx),
|
|
TASK_APP, gapc_connection_cfm);
|
|
|
|
#if (BLE_APP_SEC)
|
|
cfm->auth = app_sec_get_bond_status() ? BLE_AUTHENTICATION_LEVEL
|
|
: GAP_AUTH_REQ_NO_MITM_NO_BOND;
|
|
#else // !(BLE_APP_SEC)
|
|
cfm->auth = GAP_AUTH_REQ_NO_MITM_NO_BOND;
|
|
#endif // (BLE_APP_SEC)
|
|
// Send the message
|
|
ke_msg_send(cfm);
|
|
|
|
// We are now in connected State
|
|
ke_state_set(dest_id, APPM_CONNECTED);
|
|
app_exchange_remote_feature(conidx);
|
|
|
|
app_ble_connected_evt_handler(conidx, param->peer_addr.addr);
|
|
}
|
|
|
|
#if (BLE_APP_TILE)
|
|
app_tile_connected_evt_handler(conidx, param);
|
|
#endif
|
|
|
|
app_env.context[conidx].connInterval = param->con_interval;
|
|
|
|
app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_DEFAULT, true);
|
|
BLE_APP_FUNC_LEAVE();
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
/**
|
|
****************************************************************************************
|
|
* @brief Handles GAP controller command complete events.
|
|
*
|
|
* @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.
|
|
****************************************************************************************
|
|
*/
|
|
static int 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) {
|
|
switch (param->operation) {
|
|
case (GAPC_UPDATE_PARAMS): {
|
|
if (param->status != GAP_ERR_NO_ERROR) {
|
|
// appm_disconnect();
|
|
}
|
|
} break;
|
|
|
|
default: {
|
|
} break;
|
|
}
|
|
|
|
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.
|
|
****************************************************************************************
|
|
*/
|
|
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) {
|
|
LOG_I("[DISCONNECT] device info:");
|
|
uint8_t conidx = KE_IDX_GET(src_id);
|
|
LOG_I("connection index:%d, reason:0x%x", conidx, param->reason);
|
|
|
|
app_env.context[conidx].isBdAddrResolvingInProgress = false;
|
|
app_env.context[conidx].isGotSolvedBdAddr = false;
|
|
|
|
app_env.context[conidx].connectStatus = BLE_DISCONNECTED;
|
|
app_env.context[conidx].isFeatureExchanged = false;
|
|
app_env.context[conidx].connInterval = 0;
|
|
l2cm_buffer_reset(conidx);
|
|
|
|
// Go to the ready state
|
|
ke_state_set(TASK_APP, APPM_READY);
|
|
|
|
app_env.conn_cnt--;
|
|
|
|
#if (BLE_VOICEPATH)
|
|
app_voicepath_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
#if (BLE_DATAPATH_SERVER)
|
|
app_datapath_server_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
#if (BLE_OTA)
|
|
app_ota_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
#if (BLE_APP_TOTA)
|
|
app_tota_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
#if (BLE_APP_GFPS)
|
|
app_gfps_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
#if (BLE_AI_VOICE)
|
|
app_ai_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
#if (BLE_APP_TILE)
|
|
app_tile_disconnected_evt_handler(conidx);
|
|
#endif
|
|
|
|
app_ble_disconnected_evt_handler(conidx);
|
|
|
|
app_ble_reset_conn_param_mode(conidx);
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static int 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) {
|
|
LOG_I("prf_task_id %d is added.", param->prf_task_id);
|
|
|
|
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] 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 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) {
|
|
// 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_GAPC): {
|
|
#if (BLE_APP_SEC)
|
|
if ((msgid >= GAPC_BOND_CMD) && (msgid <= GAPC_SECURITY_IND)) {
|
|
// Call the Security Module
|
|
msg_pol = appm_get_handler(&app_sec_table_handler, msgid, param, src_id);
|
|
}
|
|
#endif //(BLE_APP_SEC)
|
|
// else drop the message
|
|
} break;
|
|
|
|
case (TASK_ID_GATTC): {
|
|
// Service Changed - Drop
|
|
} break;
|
|
|
|
#if (BLE_APP_HT)
|
|
case (TASK_ID_HTPT): {
|
|
// Call the Health Thermometer Module
|
|
msg_pol = appm_get_handler(&app_ht_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_HT)
|
|
|
|
#if (BLE_APP_DIS)
|
|
case (TASK_ID_DISS): {
|
|
// Call the Device Information Module
|
|
msg_pol = appm_get_handler(&app_dis_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_DIS)
|
|
|
|
#if (BLE_APP_HID)
|
|
case (TASK_ID_HOGPD): {
|
|
// Call the HID Module
|
|
msg_pol = appm_get_handler(&app_hid_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_HID)
|
|
|
|
#if (BLE_APP_BATT)
|
|
case (TASK_ID_BASS): {
|
|
// Call the Battery Module
|
|
msg_pol = appm_get_handler(&app_batt_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_BATT)
|
|
|
|
#if defined(BLE_APP_AM0)
|
|
case (TASK_ID_AM0): {
|
|
// Call the Audio Mode 0 Module
|
|
msg_pol = appm_get_handler(&am0_app_table_handler, msgid, param, src_id);
|
|
} break;
|
|
case (TASK_ID_AM0_HAS): {
|
|
// Call the Audio Mode 0 Module
|
|
msg_pol =
|
|
appm_get_handler(&am0_app_has_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif // defined(BLE_APP_AM0)
|
|
|
|
#if (BLE_APP_HR)
|
|
case (TASK_ID_HRPS): {
|
|
// Call the HRPS Module
|
|
msg_pol = appm_get_handler(&app_hrps_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif
|
|
|
|
#if (BLE_APP_VOICEPATH)
|
|
case (TASK_ID_VOICEPATH): {
|
|
// Call the Voice Path Module
|
|
msg_pol = appm_get_handler(app_voicepath_ble_get_msg_handler_table(), msgid,
|
|
param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_VOICEPATH)
|
|
|
|
#if (BLE_APP_DATAPATH_SERVER)
|
|
case (TASK_ID_DATAPATHPS): {
|
|
// Call the Data Path Module
|
|
msg_pol = appm_get_handler(&app_datapath_server_table_handler, msgid, param,
|
|
src_id);
|
|
} break;
|
|
#endif //(BLE_APP_DATAPATH_SERVER)
|
|
#if (BLE_APP_TILE)
|
|
case (TASK_ID_TILE): {
|
|
// Call the TILE Module
|
|
msg_pol = appm_get_handler(&app_tile_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif
|
|
|
|
#if (BLE_APP_AI_VOICE)
|
|
case (TASK_ID_AI): {
|
|
// Call the AI Voice
|
|
msg_pol = appm_get_handler(app_ai_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_AI_VOICE)
|
|
|
|
#if (BLE_APP_OTA)
|
|
case (TASK_ID_OTA): {
|
|
// Call the OTA
|
|
msg_pol = appm_get_handler(&app_ota_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_OTA)
|
|
|
|
#if (BLE_APP_TOTA)
|
|
case (TASK_ID_TOTA): {
|
|
// Call the TOTA
|
|
msg_pol = appm_get_handler(&app_tota_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_TOTA)
|
|
|
|
#if (BLE_APP_ANCC)
|
|
case (TASK_ID_ANCC): {
|
|
// Call the ANCC
|
|
msg_pol = appm_get_handler(&app_ancc_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_ANCC)
|
|
|
|
#if (BLE_APP_AMS)
|
|
case (TASK_ID_AMSC): {
|
|
// Call the AMS
|
|
msg_pol = appm_get_handler(&app_amsc_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif //(BLE_APP_AMS)
|
|
#if (BLE_APP_GFPS)
|
|
case (TASK_ID_GFPSP): {
|
|
msg_pol = appm_get_handler(&app_gfps_table_handler, msgid, param, src_id);
|
|
} break;
|
|
#endif
|
|
|
|
default: {
|
|
#if (BLE_APP_HT)
|
|
if (msgid == APP_HT_MEAS_INTV_TIMER) {
|
|
msg_pol = appm_get_handler(&app_ht_table_handler, msgid, param, src_id);
|
|
}
|
|
#endif //(BLE_APP_HT)
|
|
|
|
#if (BLE_APP_HID)
|
|
if (msgid == APP_HID_MOUSE_TIMEOUT_TIMER) {
|
|
msg_pol = appm_get_handler(&app_hid_table_handler, msgid, param, src_id);
|
|
}
|
|
#endif //(BLE_APP_HID)
|
|
} break;
|
|
}
|
|
|
|
return (msg_pol);
|
|
}
|
|
|
|
static int gapm_adv_report_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapm_adv_report_ind *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
app_adv_reported_scanned(param);
|
|
return KE_MSG_CONSUMED;
|
|
}
|
|
|
|
static int gapm_addr_solved_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapm_addr_solved_ind *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
/// Indicate that resolvable random address has been solved
|
|
appm_random_ble_addr_solved(true, param->irk.key);
|
|
return KE_MSG_CONSUMED;
|
|
}
|
|
|
|
__STATIC int gattc_mtu_changed_ind_handler(
|
|
ke_msg_id_t const msgid, struct gattc_mtu_changed_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);
|
|
|
|
LOG_I("MTU has been negotiated as %d conidx %d", param->mtu, conidx);
|
|
|
|
#if (BLE_APP_DATAPATH_SERVER)
|
|
app_datapath_server_mtu_exchanged_handler(conidx, param->mtu);
|
|
#endif
|
|
|
|
#if (BLE_VOICEPATH)
|
|
app_voicepath_mtu_exchanged_handler(conidx, param->mtu);
|
|
#endif
|
|
|
|
#if (BLE_OTA)
|
|
app_ota_mtu_exchanged_handler(conidx, param->mtu);
|
|
#endif
|
|
|
|
#if (BLE_APP_TOTA)
|
|
app_tota_mtu_exchanged_handler(conidx, param->mtu);
|
|
#endif
|
|
|
|
#if (BLE_AI_VOICE)
|
|
app_ai_mtu_exchanged_handler(conidx, param->mtu);
|
|
#endif
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
#define APP_CONN_PARAM_INTERVEL_MAX (30)
|
|
__STATIC int gapc_conn_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) {
|
|
bool accept = true;
|
|
ble_evnet_t event;
|
|
|
|
LOG_I("Receive the conn param update request: min %d max %d latency %d "
|
|
"timeout %d",
|
|
param->intv_min, param->intv_max, param->latency, param->time_out);
|
|
|
|
struct gapc_param_update_cfm *cfm = KE_MSG_ALLOC(
|
|
GAPC_PARAM_UPDATE_CFM, src_id, dest_id, gapc_param_update_cfm);
|
|
|
|
event.evt_type = BLE_CONN_PARAM_UPDATE_REQ_EVENT;
|
|
event.p.conn_param_update_req_handled.intv_min = param->intv_min;
|
|
event.p.conn_param_update_req_handled.intv_max = param->intv_max;
|
|
event.p.conn_param_update_req_handled.latency = param->latency;
|
|
event.p.conn_param_update_req_handled.time_out = param->time_out;
|
|
|
|
app_ble_core_global_handle(&event, &accept);
|
|
LOG_I("%s ret %d ", __func__, accept);
|
|
|
|
cfm->accept = accept;
|
|
|
|
#ifdef GFPS_ENABLED
|
|
// if fastpair doesn't have the requirement of finishing
|
|
// pairing in a really short period, just comment out this
|
|
// code block to avoid audio glitch if this event happens during music
|
|
// playback and interval is smaller than 15ms
|
|
if (param->intv_min < (uint16_t)(15 / 1.25)) {
|
|
LOG_I("accept");
|
|
cfm->accept = true;
|
|
fp_update_ble_connect_param_start(KE_IDX_GET(src_id));
|
|
} else {
|
|
fp_update_ble_connect_param_stop(KE_IDX_GET(src_id));
|
|
}
|
|
#endif
|
|
|
|
ke_msg_send(cfm);
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static int gapc_conn_param_updated_handler(ke_msg_id_t const msgid,
|
|
struct gapc_param_updated_ind *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
uint8_t conidx = KE_IDX_GET(src_id);
|
|
LOG_I("Conidx %d conn parameter is updated as interval %d timeout %d", conidx,
|
|
param->con_interval, param->sup_to);
|
|
|
|
APP_BLE_NEGOTIATED_CONN_PARAM_T connParam;
|
|
connParam.con_interval = param->con_interval;
|
|
connParam.sup_to = param->sup_to;
|
|
connParam.con_latency = param->con_latency;
|
|
app_ble_save_negotiated_conn_param(conidx, &connParam);
|
|
|
|
#if (BLE_VOICEPATH)
|
|
app_voicepath_ble_conn_parameter_updated(conidx, param->con_interval,
|
|
param->con_latency);
|
|
#endif
|
|
#if BLE_APP_TILE
|
|
app_tile_ble_conn_parameter_updated(conidx, param);
|
|
#endif
|
|
|
|
app_env.context[conidx].connInterval = param->con_interval;
|
|
|
|
if (param->con_interval >= 32) {
|
|
if (app_ble_is_parameter_mode_enabled(conidx, BLE_CONN_PARAM_MODE_OTA)) {
|
|
app_ble_parameter_mode_clear(conidx, BLE_CONN_PARAM_MODE_OTA);
|
|
app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_OTA_SLOWER, true);
|
|
} else if (app_ble_is_parameter_mode_enabled(
|
|
conidx, BLE_CONN_PARAM_MODE_AI_STREAM_ON)) {
|
|
app_ble_parameter_mode_clear(conidx, BLE_CONN_PARAM_MODE_AI_STREAM_ON);
|
|
app_ble_update_conn_param_mode(BLE_CONN_PARAM_MODE_AI_STREAM_ON, true);
|
|
}
|
|
}
|
|
|
|
return (KE_MSG_CONSUMED);
|
|
}
|
|
|
|
static int gapm_dev_addr_ind_handler(ke_msg_id_t const msgid,
|
|
struct gapm_dev_bdaddr_ind *param,
|
|
ke_task_id_t const dest_id,
|
|
ke_task_id_t const src_id) {
|
|
ble_evnet_t event;
|
|
|
|
// Indicate that a new random BD address set in lower layers
|
|
LOG_I("New dev addr:");
|
|
DUMP8("%02x ", param->addr.addr.addr, 6);
|
|
|
|
#ifdef GFPS_ENABLED
|
|
app_fp_msg_send_updated_ble_addr();
|
|
app_gfps_update_random_salt();
|
|
#endif
|
|
|
|
event.evt_type = BLE_SET_RANDOM_BD_ADDR_EVENT;
|
|
event.p.set_random_bd_addr_handled.new_bdaddr = param->addr.addr.addr;
|
|
app_ble_core_global_handle(&event, NULL);
|
|
|
|
return KE_MSG_CONSUMED;
|
|
}
|
|
|
|
/*
|
|
* GLOBAL VARIABLES DEFINITION
|
|
****************************************************************************************
|
|
*/
|
|
/* Default State handlers definition. */
|
|
KE_MSG_HANDLER_TAB(appm){
|
|
// Note: first message is latest message checked by kernel so default is put
|
|
// on top.
|
|
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)appm_msg_handler},
|
|
|
|
{APP_ADV_TIMEOUT_TIMER, (ke_msg_func_t)app_adv_timeout_handler},
|
|
|
|
{GAPM_DEVICE_READY_IND, (ke_msg_func_t)gapm_device_ready_ind_handler},
|
|
{GAPM_CMP_EVT, (ke_msg_func_t)gapm_cmp_evt_handler},
|
|
{GAPC_GET_DEV_INFO_REQ_IND,
|
|
(ke_msg_func_t)gapc_get_dev_info_req_ind_handler},
|
|
{GAPC_SET_DEV_INFO_REQ_IND,
|
|
(ke_msg_func_t)gapc_set_dev_info_req_ind_handler},
|
|
{GAPC_CONNECTION_REQ_IND, (ke_msg_func_t)gapc_connection_req_ind_handler},
|
|
{GAPC_CMP_EVT, (ke_msg_func_t)gapc_cmp_evt_handler},
|
|
{GAPC_DISCONNECT_IND, (ke_msg_func_t)gapc_disconnect_ind_handler},
|
|
{GAPM_PROFILE_ADDED_IND, (ke_msg_func_t)gapm_profile_added_ind_handler},
|
|
{GATTC_MTU_CHANGED_IND, (ke_msg_func_t)gattc_mtu_changed_ind_handler},
|
|
{GAPC_PARAM_UPDATE_REQ_IND,
|
|
(ke_msg_func_t)gapc_conn_param_update_req_ind_handler},
|
|
{GAPC_PARAM_UPDATED_IND, (ke_msg_func_t)gapc_conn_param_updated_handler},
|
|
{GAPM_ADV_REPORT_IND, (ke_msg_func_t)gapm_adv_report_ind_handler},
|
|
{GAPC_PEER_FEATURES_IND, (ke_msg_func_t)gapc_peer_features_ind_handler},
|
|
{GAPM_ADDR_SOLVED_IND, (ke_msg_func_t)gapm_addr_solved_ind_handler},
|
|
{GAPM_DEV_BDADDR_IND, (ke_msg_func_t)gapm_dev_addr_ind_handler},
|
|
};
|
|
|
|
/* Defines the place holder for the states of all the task instances. */
|
|
ke_state_t appm_state[APP_IDX_MAX];
|
|
|
|
const struct ke_task_desc TASK_DESC_APP = {appm_msg_handler_tab, appm_state,
|
|
APP_IDX_MAX,
|
|
ARRAY_LEN(appm_msg_handler_tab)};
|
|
|
|
#endif //(BLE_APP_PRESENT)
|
|
|
|
/// @} APPTASK
|