pinebuds/services/ble_app/app_main/app_ble_mode_switch.c

1211 lines
31 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.
*
****************************************************************************/
/*****************************header include********************************/
#include "string.h"
#include "co_math.h" // Common Maths Definition
#include "cmsis_os.h"
#include "ble_app_dbg.h"
#include "stdbool.h"
#include "app_thread.h"
#include "app_utils.h"
#include "apps.h"
#include "app.h"
#include "app_sec.h"
#include "app_ble_include.h"
#include "nvrecord.h"
#include "app_bt_func.h"
#include "hal_timer.h"
#include "app_bt.h"
#include "app_hfp.h"
#include "rwprf_config.h"
#include "nvrecord_ble.h"
#include "app_sec.h"
/************************private macro defination***************************/
#define DEBUG_BLE_STATE_MACHINE true
#if DEBUG_BLE_STATE_MACHINE
#define SET_BLE_STATE(newState) \
do \
{ \
LOG_I("[STATE]%s->%s at line %d", ble_state2str(bleModeEnv.state), ble_state2str(newState), __LINE__); \
bleModeEnv.state = (newState); \
} while (0);
#define SET_BLE_OP(newOp) \
do \
{ \
LOG_I("[OP]%s->%s at line %d", ble_op2str(bleModeEnv.op), ble_op2str(newOp), __LINE__); \
bleModeEnv.op = (newOp); \
} while (0);
#else
#define SET_BLE_STATE(newState) \
do \
{ \
bleModeEnv.state = (newState); \
} while (0);
#define SET_BLE_OP(newOp) \
do \
{ \
bleModeEnv.op = (newOp); \
} while (0);
#endif
extern void bt_drv_reg_op_set_rand_seed(uint32_t seed);
/************************private type defination****************************/
/************************extern function declearation***********************/
extern uint8_t bt_addr[6];
/**********************private function declearation************************/
/*---------------------------------------------------------------------------
* ble_state2str
*---------------------------------------------------------------------------
*
*Synopsis:
* get the string of the ble state
*
* Parameters:
* state - state to get string
*
* Return:
* the string of the BLE state
*/
static char *ble_state2str(uint8_t state);
/*---------------------------------------------------------------------------
* ble_op2str
*---------------------------------------------------------------------------
*
*Synopsis:
* get the string of the ble operation
*
* Parameters:
* op - operation to get string
*
* Return:
* the string of the BLE operation
*/
static char *ble_op2str(uint8_t op);
/*---------------------------------------------------------------------------
* ble_adv_user2str
*---------------------------------------------------------------------------
*
*Synopsis:
* get the string of the ble_adv_user
*
* Parameters:
* op - operation to get string
*
* Return:
* the string of the ble_adv_user
*/
static char *ble_adv_user2str(enum BLE_ADV_USER_E user);
/*---------------------------------------------------------------------------
* ble_adv_config_param
*---------------------------------------------------------------------------
*
*Synopsis:
* configure BLE adv related parameter in @advParam for further use
*
* Parameters:
* advType - advertisment mode, see @ for more info
* advInterval - advertisement interval in MS
*
* Return:
* void
*/
static void ble_adv_config_param(uint8_t advType, uint16_t advInterval);
/*---------------------------------------------------------------------------
* ble_adv_is_allowed
*---------------------------------------------------------------------------
*
*Synopsis:
* check if BLE advertisment is allowed or not
*
* Parameters:
* void
*
* Return:
* true - if advertisement is allowed
* flase - if adverstisement is not allowed
*/
static bool ble_adv_is_allowed(void);
/*---------------------------------------------------------------------------
* ble_start_adv
*---------------------------------------------------------------------------
*
*Synopsis:
* start BLE advertisement
*
* Parameters:
* param - see @BLE_ADV_PARAM_T to get more info
*
* Return:
* void
*/
static void ble_start_adv(void *param);
/*---------------------------------------------------------------------------
* ble_start_adv_failed_cb
*---------------------------------------------------------------------------
*
*Synopsis:
* callback function of start BLE advertisement failed
*
* Parameters:
* void
*
* Return:
* void
*/
static void ble_start_adv_failed_cb(void);
/*---------------------------------------------------------------------------
* ble_start_scan
*---------------------------------------------------------------------------
*
*Synopsis:
* start BLE scan api
*
* Parameters:
* param - see @BLE_SCAN_PARAM_T to get more info
*
* Return:
* void
*/
static void ble_start_scan(void *param);
/*---------------------------------------------------------------------------
* ble_start_connect
*---------------------------------------------------------------------------
*
*Synopsis:
* start BLE connection
*
* Parameters:
* bleBdAddr - address of BLE device to connect
*
* Return:
* void
*/
static void ble_start_connect(uint8_t *bleBdAddr);
/*---------------------------------------------------------------------------
* ble_stop_all_activities
*---------------------------------------------------------------------------
*
*Synopsis:
* stop all BLE pending operations, stop ongoing adv and scan
* NOTE: will not disconnect BLE connections
*
* Parameters:
* void
*
* Return:
* void
*/
static void ble_stop_all_activities(void);
/*---------------------------------------------------------------------------
* ble_execute_pending_op
*---------------------------------------------------------------------------
*
*Synopsis:
* execute pended BLE op
*
* Parameters:
* void
*
* Return:
* void
*/
static void ble_execute_pending_op(void);
/*---------------------------------------------------------------------------
* ble_switch_activities
*---------------------------------------------------------------------------
*
*Synopsis:
* switch BLE activities after last state complete
*
* Parameters:
* void
*
* Return:
* void
*/
static void ble_switch_activities(void);
/************************private variable defination************************/
static BLE_MODE_ENV_T bleModeEnv;
static BLE_ADV_PARAM_T advParam;
static BLE_SCAN_PARAM_T scanParam;
/****************************function defination****************************/
// common used function
#ifdef USE_LOG_I_ID
static inline char *ble_state2str(uint8_t state)
{
return (char *)(uint32_t)state;
}
static inline char *ble_op2str(uint8_t op)
{
return (char *)(uint32_t)op;
}
static inline char *ble_adv_user2str(enum BLE_ADV_USER_E user)
{
return (char *)(uint32_t)user;
}
#else
static char *ble_state2str(uint8_t state)
{
char *str = NULL;
#define CASES(state) \
case state: \
str = "[" #state "]"; \
break
switch (state)
{
CASES(STATE_IDLE);
CASES(ADVERTISING);
CASES(STARTING_ADV);
CASES(STOPPING_ADV);
CASES(SCANNING);
CASES(STARTING_SCAN);
CASES(STOPPING_SCAN);
CASES(CONNECTING);
CASES(STARTING_CONNECT);
CASES(STOPPING_CONNECT);
default:
str = "[INVALID]";
break;
}
return str;
}
static char *ble_op2str(uint8_t op)
{
char *str = NULL;
#define CASEO(op) \
case op: \
str = "[" #op "]"; \
break
switch (op)
{
CASEO(OP_IDLE);
CASEO(START_ADV);
CASEO(START_SCAN);
CASEO(START_CONNECT);
CASEO(STOP_ADV);
CASEO(STOP_SCAN);
CASEO(STOP_CONNECT);
default:
str = "[INVALID]";
break;
}
return str;
}
static char *ble_adv_user2str(enum BLE_ADV_USER_E user)
{
#define CASE_S(s) \
case s: \
return "[" #s "]";
#define CASE_D() \
default: \
return "[INVALID]";
switch (user)
{
CASE_S(USER_STUB)
CASE_S(USER_GFPS)
CASE_S(USER_GSOUND)
CASE_S(USER_AI)
CASE_S(USER_INTERCONNECTION)
CASE_S(USER_TILE)
CASE_S(USER_OTA)
CASE_D()
}
}
#endif
void app_ble_mode_init(void)
{
LOG_I("%s", __func__);
memset(&bleModeEnv, 0, sizeof(bleModeEnv));
SET_BLE_STATE(STATE_IDLE);
SET_BLE_OP(OP_IDLE);
bleModeEnv.bleEnv = &app_env;
}
// ble advertisement used functions
static void ble_adv_config_param(uint8_t advType, uint16_t advInterval)
{
uint8_t avail_space;
memset(&advParam, 0, sizeof(advParam));
advParam.advType = advType;
advParam.advInterval = advInterval;
advParam.withFlag = true;
// connectable adv is not allowed if max connection reaches
if (app_is_arrive_at_max_ble_connections() && (GAPM_ADV_UNDIRECT == advType))
{
LOG_W("will change adv type to none-connectable because max ble connection reaches");
advParam.advType = GAPM_ADV_NON_CONN;
}
for (uint8_t user = 0; user < BLE_ADV_USER_NUM; user++)
{
if (bleModeEnv.bleDataFillFunc[user])
{
bleModeEnv.bleDataFillFunc[user]((void *)&advParam);
// check if the adv/scan_rsp data length is legal
if(advParam.withFlag)
{
ASSERT(BLE_ADV_DATA_WITH_FLAG_LEN >= advParam.advDataLen, "[BLE][ADV]adv data exceed");
}
else
{
ASSERT(BLE_ADV_DATA_WITHOUT_FLAG_LEN >= advParam.advDataLen, "[BLE][ADV]adv data exceed");
}
ASSERT(SCAN_RSP_DATA_LEN >= advParam.scanRspDataLen, "[BLE][ADV]scan response data exceed");
}
}
if(advParam.withFlag)
{
avail_space = BLE_ADV_DATA_WITH_FLAG_LEN - advParam.advDataLen - BLE_ADV_DATA_STRUCT_HEADER_LEN;
}
else
{
avail_space = BLE_ADV_DATA_WITHOUT_FLAG_LEN - advParam.advDataLen - BLE_ADV_DATA_STRUCT_HEADER_LEN;
}
// Check if data can be added to the adv Data
if (avail_space > 2)
{
avail_space = co_min(avail_space, bleModeEnv.bleEnv->dev_name_len);
advParam.advData[advParam.advDataLen++] = avail_space + 1;
// Fill Device Name Flag
advParam.advData[advParam.advDataLen++] =
(avail_space == bleModeEnv.bleEnv->dev_name_len) ? '\x08' : '\x09';
// Copy device name
memcpy(&advParam.advData[advParam.advDataLen], bleModeEnv.bleEnv->dev_name, avail_space);
// Update adv Data Length
advParam.advDataLen += avail_space;
}
}
static bool ble_adv_is_allowed(void)
{
bool allowed_adv = true;
if (!app_is_stack_ready())
{
LOG_I("reason: stack not ready");
allowed_adv = false;
}
if (app_is_power_off_in_progress())
{
LOG_I("reason: in power off mode");
allowed_adv = false;
}
if (bleModeEnv.advSwitch)
{
LOG_I("adv switched off:%d", bleModeEnv.advSwitch);
allowed_adv = false;
}
if (btapp_hfp_is_sco_active())
{
LOG_I("SCO ongoing");
allowed_adv = false;
}
if (false == allowed_adv)
{
app_ble_stop_activities();
}
return allowed_adv;
}
static void ble_start_adv(void *param)
{
switch (bleModeEnv.state)
{
case ADVERTISING:
SET_BLE_STATE(STOPPING_ADV);
SET_BLE_OP(START_ADV);
appm_stop_advertising();
break;
case SCANNING:
SET_BLE_STATE(STOPPING_SCAN);
SET_BLE_OP(START_ADV);
appm_stop_scanning();
break;
case CONNECTING:
SET_BLE_STATE(STOPPING_CONNECT);
SET_BLE_OP(START_ADV);
appm_stop_connecting();
break;
case STARTING_ADV:
case STARTING_SCAN:
case STARTING_CONNECT:
case STOPPING_ADV:
case STOPPING_SCAN:
case STOPPING_CONNECT:
SET_BLE_OP(START_ADV);
break;
case STATE_IDLE:
if (!ble_adv_is_allowed())
{
LOG_I("[ADV] not allowed.");
if (START_ADV == bleModeEnv.op)
{
SET_BLE_OP(OP_IDLE);
}
break;
}
memcpy(&bleModeEnv.advInfo, param, sizeof(bleModeEnv.advInfo));
appm_start_advertising(&bleModeEnv.advInfo);
SET_BLE_STATE(STARTING_ADV);
break;
default:
break;
}
}
static void ble_start_adv_failed_cb(void)
{
if (STARTING_ADV == bleModeEnv.state)
{
SET_BLE_STATE(STATE_IDLE);
}
// start pending op(start adv again)
}
static void ble_start_scan(void *param)
{
switch (bleModeEnv.state)
{
case ADVERTISING:
SET_BLE_STATE(STOPPING_ADV);
SET_BLE_OP(START_SCAN);
appm_stop_advertising();
break;
case SCANNING:
SET_BLE_STATE(STOPPING_SCAN);
SET_BLE_OP(START_SCAN);
appm_stop_scanning();
break;
case CONNECTING:
SET_BLE_STATE(STOPPING_CONNECT);
SET_BLE_OP(START_SCAN);
appm_stop_connecting();
break;
case STARTING_ADV:
case STARTING_SCAN:
case STARTING_CONNECT:
case STOPPING_ADV:
case STOPPING_SCAN:
case STOPPING_CONNECT:
SET_BLE_OP(START_SCAN);
break;
case STATE_IDLE:
SET_BLE_STATE(STARTING_SCAN);
memcpy(&bleModeEnv.scanInfo, param, sizeof(BLE_SCAN_PARAM_T));
appm_start_scanning(bleModeEnv.scanInfo.scanInterval,
bleModeEnv.scanInfo.scanWindow,
bleModeEnv.scanInfo.scanType);
break;
default:
break;
}
}
static void ble_start_connect(uint8_t *bleBdAddr)
{
SET_BLE_OP(START_CONNECT);
if ((CONNECTING != bleModeEnv.state) &&
(STARTING_CONNECT != bleModeEnv.state))
{
switch (bleModeEnv.state)
{
case ADVERTISING:
SET_BLE_STATE(STOPPING_ADV);
appm_stop_advertising();
break;
case SCANNING:
SET_BLE_STATE(STOPPING_SCAN);
appm_stop_scanning();
break;
case STATE_IDLE:
SET_BLE_STATE(STARTING_CONNECT);
struct gap_bdaddr bdAddr;
memcpy(bdAddr.addr.addr, bleBdAddr, BTIF_BD_ADDR_SIZE);
bdAddr.addr_type = 0;
LOG_I("Master paired with mobile dev is scanned, connect it via BLE.");
appm_start_connecting(&bdAddr);
break;
default:
break;
}
}
}
static void ble_stop_all_activities(void)
{
switch (bleModeEnv.state)
{
case ADVERTISING:
SET_BLE_OP(OP_IDLE);
SET_BLE_STATE(STOPPING_ADV);
appm_stop_advertising();
break;
case SCANNING:
SET_BLE_OP(OP_IDLE);
SET_BLE_STATE(STOPPING_SCAN);
appm_stop_scanning();
break;
case CONNECTING:
SET_BLE_OP(OP_IDLE);
SET_BLE_STATE(STOPPING_CONNECT);
appm_stop_connecting();
break;
case STARTING_ADV:
SET_BLE_OP(STOP_ADV);
break;
case STARTING_SCAN:
SET_BLE_OP(STOP_SCAN);
break;
case STARTING_CONNECT:
SET_BLE_OP(STOP_CONNECT);
break;
case STOPPING_ADV:
case STOPPING_SCAN:
case STOPPING_CONNECT:
SET_BLE_OP(OP_IDLE);
break;
default:
break;
}
}
static void ble_execute_pending_op(void)
{
LOG_I("%s", __func__);
uint8_t op = bleModeEnv.op;
SET_BLE_OP(OP_IDLE);
switch (op)
{
case START_ADV:
ble_start_adv(&advParam);
break;
case START_SCAN:
ble_start_scan(&scanParam);
break;
case START_CONNECT:
ble_start_connect(bleModeEnv.bleAddrToConnect);
break;
case STOP_ADV:
case STOP_SCAN:
case STOP_CONNECT:
ble_stop_all_activities();
break;
default:
break;
}
}
static void ble_switch_activities(void)
{
switch (bleModeEnv.state)
{
case STARTING_ADV:
SET_BLE_STATE(ADVERTISING);
break;
case STARTING_SCAN:
SET_BLE_STATE(SCANNING);
break;
case STARTING_CONNECT:
SET_BLE_STATE(CONNECTING);
break;
case STOPPING_ADV:
SET_BLE_STATE(STATE_IDLE);
break;
case STOPPING_SCAN:
SET_BLE_STATE(STATE_IDLE);
break;
case STOPPING_CONNECT:
SET_BLE_STATE(STATE_IDLE);
break;
default:
break;
}
ble_execute_pending_op();
}
// BLE advertisement event callbacks
void app_advertising_started(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_switch_activities);
}
void app_advertising_starting_failed(void)
{
memset(&bleModeEnv.advInfo, 0, sizeof(bleModeEnv.advInfo));
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_start_adv_failed_cb);
}
void app_advertising_stopped(void)
{
memset(&bleModeEnv.advInfo, 0, sizeof(bleModeEnv.advInfo));
app_bt_start_custom_function_in_bt_thread(0,
0,
( uint32_t )ble_switch_activities);
}
// BLE adv data updated event callback
void app_adv_data_updated(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_switch_activities);
}
// BLE scan event callbacks
void app_scanning_started(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_switch_activities);
}
void app_scanning_stopped(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_switch_activities);
}
// BLE connect event callbacks
void app_connecting_started(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_switch_activities);
}
void app_connecting_stopped(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_switch_activities);
}
/**
* @brief : callback function of BLE connect failed
*
*/
static void app_ble_connecting_failed_handler(void)
{
if ((CONNECTING == bleModeEnv.state) ||
(STOPPING_CONNECT == bleModeEnv.state) ||
(STARTING_CONNECT == bleModeEnv.state) )
{
SET_BLE_STATE(STATE_IDLE);
}
}
void app_connecting_failed(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)app_ble_connecting_failed_handler);
}
void app_ble_connected_evt_handler(uint8_t conidx, const uint8_t *pPeerBdAddress)
{
ble_evnet_t event;
if ((ADVERTISING == bleModeEnv.state) ||
(STARTING_ADV == bleModeEnv.state) ||
(CONNECTING == bleModeEnv.state))
{
SET_BLE_STATE(STATE_IDLE);
}
if (START_CONNECT == bleModeEnv.op)
{
SET_BLE_OP(OP_IDLE);
}
event.evt_type = BLE_CONNECT_EVENT;
event.p.connect_handled.conidx = conidx;
event.p.connect_handled.peer_bdaddr = pPeerBdAddress;
app_ble_core_global_handle(&event, NULL);
app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL);
app_stop_fast_connectable_ble_adv_timer();
}
void app_ble_disconnected_evt_handler(uint8_t conidx)
{
ble_evnet_t event;
event.evt_type = BLE_DISCONNECT_EVENT;
event.p.disconnect_handled.conidx = conidx;
app_ble_core_global_handle(&event, NULL);
app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL);
}
// BLE APIs for external use
void app_ble_data_fill_enable(enum BLE_ADV_USER_E user, bool enable)
{
LOG_I("%s user %d%s enable %d", __func__, user, ble_adv_user2str(user), enable);
ASSERT(user < BLE_ADV_USER_NUM, "%s user %d", __func__, user);
if (enable)
{
bleModeEnv.adv_user_enable |= (1 << user);
}
else
{
bleModeEnv.adv_user_enable &= ~(1 << user);
}
}
bool app_ble_get_data_fill_enable(enum BLE_ADV_USER_E user)
{
bool enable = bleModeEnv.adv_user_enable & (1 << user);
LOG_I("%s user %d enable %d", __func__, user, enable);
return enable;
}
/**
* @brief : callback function of BLE scan starting failed
*
*/
static void app_ble_scanning_starting_failed_handler(void)
{
if (STARTING_SCAN == bleModeEnv.state)
{
SET_BLE_STATE(STATE_IDLE);
}
}
void app_scanning_starting_failed(void)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)app_ble_scanning_starting_failed_handler);
}
// BLE APIs for external use
void app_ble_register_data_fill_handle(enum BLE_ADV_USER_E user, BLE_DATA_FILL_FUNC_T func, bool enable)
{
bool needUpdateAdv = false;
if (BLE_ADV_USER_NUM <= user)
{
LOG_W("invalid user");
}
else
{
if (func != bleModeEnv.bleDataFillFunc[user] &&
NULL != func)
{
needUpdateAdv = true;
bleModeEnv.bleDataFillFunc[user] = func;
}
}
bleModeEnv.adv_user_register |= (1 << user);
if (needUpdateAdv)
{
app_ble_data_fill_enable(user, enable);
}
}
void app_ble_system_ready(void)
{
uint32_t generatedSeed = hal_sys_timer_get();
for (uint8_t index = 0; index < sizeof(bt_addr); index++)
{
generatedSeed ^= (((uint32_t)(bt_addr[index])) << (hal_sys_timer_get() & 0xF));
}
bt_drv_reg_op_set_rand_seed(generatedSeed);
#if defined(ENHANCED_STACK)
app_notify_stack_ready(STACK_READY_BLE);
#else
app_notify_stack_ready(STACK_READY_BLE | STACK_READY_BT);
#endif
}
static void ble_adv_refreshing(void *param)
{
BLE_ADV_PARAM_T *pAdvParam = (BLE_ADV_PARAM_T *)param;
// four conditions that we just need to update the ble adv data instead of restarting ble adv
// 1. BLE advertising is on
// 2. No on-going BLE operation
// 3. BLE adv type is the same
// 4. BLE adv interval is the same
if ((ADVERTISING == bleModeEnv.state) && \
(OP_IDLE == bleModeEnv.op) && \
bleModeEnv.advInfo.advType == pAdvParam->advType && \
bleModeEnv.advInfo.advInterval == pAdvParam->advInterval)
{
memcpy(&bleModeEnv.advInfo, param, sizeof(bleModeEnv.advInfo));
SET_BLE_STATE(STARTING_ADV);
appm_update_adv_data(pAdvParam->advData,
pAdvParam->advDataLen,
pAdvParam->scanRspData,
pAdvParam->scanRspDataLen);
}
else
{
// otherwise, restart ble adv
ble_start_adv(param);
}
}
static bool app_ble_start_adv(uint8_t advType, uint16_t advInterval)
{
uint32_t adv_user_enable = bleModeEnv.adv_user_enable;
LOG_I("[ADV]type:%d, interval:%d ca:%p", advType, advInterval, __builtin_return_address(0));
if (!ble_adv_is_allowed())
{
LOG_I("[ADV] not allowed.");
return false;
}
ble_adv_config_param(advType, advInterval);
LOG_I("%s old_user_enable 0x%x new 0x%x", __func__, adv_user_enable, bleModeEnv.adv_user_enable);
if (!bleModeEnv.adv_user_enable)
{
LOG_I("no adv user enable");
LOG_I("[ADV] not allowed.");
app_ble_stop_activities();
return false;
}
// param of adv request is exactly same as current adv
if (ADVERTISING == bleModeEnv.state &&
!memcmp(&bleModeEnv.advInfo, &advParam, sizeof(advParam)))
{
LOG_I("reason: adv param not changed");
LOG_I("[ADV] not allowed.");
return false;
}
LOG_I("[ADV_LEN] %d [DATA]:", advParam.advDataLen);
DUMP8("%02x ", advParam.advData, advParam.advDataLen);
LOG_I("[SCAN_RSP_LEN] %d [DATA]:", advParam.scanRspDataLen);
DUMP8("%02x ", advParam.scanRspData, advParam.scanRspDataLen);
ble_adv_refreshing(&advParam);
return true;
}
void app_ble_start_connectable_adv(uint16_t advInterval)
{
LOG_D("%s", __func__);
app_bt_start_custom_function_in_bt_thread(
(uint32_t)GAPM_ADV_UNDIRECT, (uint32_t)advInterval,
(uint32_t)app_ble_start_adv);
}
void app_ble_refresh_adv_state(uint16_t advInterval)
{
LOG_D("%s", __func__);
app_bt_start_custom_function_in_bt_thread(
(uint32_t)GAPM_ADV_UNDIRECT, (uint32_t)advInterval,
(uint32_t)app_ble_start_adv);
}
void app_ble_start_scan(enum BLE_SCAN_FILTER_POLICY scanFilterPolicy, uint16_t scanWindow, uint16_t scanInterval)
{
scanParam.scanWindow = scanWindow;
scanParam.scanInterval = scanInterval;
scanParam.scanType = scanFilterPolicy; //BLE_SCAN_ALLOW_ADV_WLST
app_bt_start_custom_function_in_bt_thread((uint32_t)(&scanParam),
0,
(uint32_t)ble_start_scan);
}
void app_ble_start_connect(uint8_t *bdAddrToConnect)
{
memcpy(bleModeEnv.bleAddrToConnect, bdAddrToConnect, BTIF_BD_ADDR_SIZE);
app_bt_start_custom_function_in_bt_thread((uint32_t)bleModeEnv.bleAddrToConnect,
0,
(uint32_t)ble_start_connect);
}
bool app_ble_is_connection_on(uint8_t index)
{
return (BLE_CONNECTED ==
bleModeEnv.bleEnv->context[index].connectStatus);
}
bool app_ble_is_any_connection_exist(void)
{
bool ret = false;
for (uint8_t i = 0; i < BLE_CONNECTION_MAX; i++)
{
if (app_ble_is_connection_on(i))
{
ret = true;
}
}
return ret;
}
void app_ble_start_disconnect(uint8_t conIdx)
{
if (BLE_CONNECTED == bleModeEnv.bleEnv->context[conIdx].connectStatus)
{
LOG_I("will disconnect connection:%d", conIdx);
bleModeEnv.bleEnv->context[conIdx].connectStatus = BLE_DISCONNECTING;
app_bt_start_custom_function_in_bt_thread((uint32_t)conIdx,
0,
(uint32_t)appm_disconnect);
}
else
{
LOG_I("will not execute disconnect since state is:%d",
bleModeEnv.bleEnv->context[conIdx].connectStatus);
}
}
void app_ble_disconnect_all(void)
{
for (uint8_t i = 0; i < BLE_CONNECTION_MAX; i++)
{
app_ble_start_disconnect(i);
}
}
void app_ble_stop_activities(void)
{
LOG_I("%s %p", __func__, __builtin_return_address(0));
app_stop_fast_connectable_ble_adv_timer();
if (bleModeEnv.state != OP_IDLE)
{
app_bt_start_custom_function_in_bt_thread(0,
0,
(uint32_t)ble_stop_all_activities);
}
}
void app_ble_force_switch_adv(uint8_t user, bool onOff)
{
ASSERT(user < BLE_SWITCH_USER_NUM, "ble switch user exceed");
if (onOff)
{
bleModeEnv.advSwitch &= ~(1 << user);
app_ble_refresh_adv_state(BLE_ADVERTISING_INTERVAL);
}
else if ((bleModeEnv.advSwitch & (1 << user)) == 0)
{
bleModeEnv.advSwitch |= (1 << user);
app_ble_stop_activities();
// disconnect all of the BLE connections if box is closed
if (BLE_SWITCH_USER_BOX == user)
{
app_ble_disconnect_all();
}
}
LOG_I("%s user %d onoff %d switch 0x%x", __func__, user, onOff, bleModeEnv.advSwitch);
}
bool app_ble_is_in_advertising_state(void)
{
return (ADVERTISING == bleModeEnv.state) ||
(STARTING_ADV == bleModeEnv.state) ||
(STOPPING_ADV == bleModeEnv.state);
}
static uint32_t POSSIBLY_UNUSED ble_get_manufacture_data_ptr(uint8_t *advData,
uint32_t dataLength,
uint8_t *manufactureData)
{
uint8_t followingDataLengthOfSection;
uint8_t rawContentDataLengthOfSection;
uint8_t flag;
while (dataLength > 0)
{
followingDataLengthOfSection = *advData++;
dataLength--;
if (dataLength < followingDataLengthOfSection)
{
return 0; // wrong adv data format
}
if (followingDataLengthOfSection > 0)
{
flag = *advData++;
dataLength--;
rawContentDataLengthOfSection = followingDataLengthOfSection - 1;
if (BLE_ADV_MANU_FLAG == flag)
{
uint32_t lengthToCopy;
if (dataLength < rawContentDataLengthOfSection)
{
lengthToCopy = dataLength;
}
else
{
lengthToCopy = rawContentDataLengthOfSection;
}
memcpy(manufactureData, advData - 2, lengthToCopy + 2);
return lengthToCopy + 2;
}
else
{
advData += rawContentDataLengthOfSection;
dataLength -= rawContentDataLengthOfSection;
}
}
}
return 0;
}
//received adv data
void app_adv_reported_scanned(struct gapm_adv_report_ind *ptInd)
{
/*
LOG_I("Scanned RSSI %d BD addr:", (int8_t)ptInd->report.rssi);
DUMP8("0x%02x ", ptInd->report.adv_addr.addr, BTIF_BD_ADDR_SIZE);
LOG_I("Scanned adv data:");
DUMP8("0x%02x ", ptInd->report.data, ptInd->report.data_len);
*/
ble_adv_data_parse(ptInd->report.adv_addr.addr,
(int8_t)ptInd->report.rssi,
ptInd->report.data,
(unsigned char)ptInd->report.data_len);
}
void app_ibrt_ui_disconnect_ble(void)
{
app_ble_disconnect_all();
}
uint32_t app_ble_get_user_register(void)
{
return bleModeEnv.adv_user_register;
}
enum BLE_STATE_E app_ble_get_current_state(void)
{
return bleModeEnv.state;
}
enum BLE_OP_E app_ble_get_current_operation(void)
{
return bleModeEnv.op;
}
void app_ble_get_runtime_adv_param(uint8_t* pAdvType, uint16_t* pAdvIntervalMs)
{
*pAdvType = advParam.advType;
*pAdvIntervalMs = advParam.advInterval;
}