1.目的
识别什么是主动扫描 什么是被动扫描
2.分析
3.平台:
协议栈版本:DA1458x_SDK
编译软件:keil 4.72
硬件平台:开发板
例子:DA1458x_SDK5.0.3\DA1458x_SDK5.0.3\DA1458x_SDK\5.0.3\projects\target_apps\ble_examples\prox_reporter\Keil_4
4.步骤
先看主函数
int main_func(void)
{
sleep_mode_t sleep_mode;
bool flag = 0;
//global initialise
system_init(); //系统初始化函数
/*
************************************************************************************
* Platform initialization
************************************************************************************
*/
// start_custom_task();
//app_proxr_alert_start(100);
while(1) {
app_batt_set_level(0x55);
do {
// schedule all pending events
schedule_while_ble_on();
}
while ((app_asynch_proc())); //grant control to the application, try to go to power down //if the application returns GOTO_SLEEP
//((STREAMDATA_QUEUE)&& stream_queue_more_data())); //grant control to the streamer, try to go to power down
//if the application returns GOTO_SLEEP
//wait for interrupt and go to sleep if this is allowed
if (((!BLE_APP_PRESENT) && (check_gtl_state())) ||
(BLE_APP_PRESENT))
{ //Disable the interrupts
GLOBAL_INT_STOP();
app_asynch_sleep_proc();
// get the allowed sleep mode
// time from rwip_power_down() to WFI() must be kept as short as possible!!
sleep_mode = rwip_power_down();
if ((sleep_mode == mode_ext_sleep) || (sleep_mode == mode_deep_sleep)) {
//power down the radio and whatever is allowed
arch_goto_sleep(sleep_mode);
//wait for an interrupt to resume operation
WFI();
//resume operation
arch_resume_from_sleep();
}
else if (sleep_mode == mode_idle)
{
if (((!BLE_APP_PRESENT) && check_gtl_state()) ||
(BLE_APP_PRESENT))
//wait for an interrupt to resume operation
WFI();
}
// restore interrupts
GLOBAL_INT_START();
}
if (USE_WDOG)
wdg_reload(WATCHDOG_DEFAULT_PERIOD);
}
}
****************************************************************************************
* @brief Global System Init
* @return void
****************************************************************************************
*/
void system_init(void)
{
sys_startup_flag = true;
/*
************************************************************************************
* Platform initialization
************************************************************************************
*/
//initialise the Watchdog unit
wdg_init(0);
//confirm XTAL 16 MHz calibration
xtal16_calibration_check ();
//set the system clocks
set_system_clocks();
//Initiliaze the GPIOs
GPIO_init();
// Initialize NVDS module
nvds_init((uint8_t *)NVDS_FLASH_ADDRESS, NVDS_FLASH_SIZE);
// Check and read BD address
nvds_read_bdaddr();
//Peripherals initilization
periph_init();
// Initialize random process
srand(1);
//Trim the radio from the otp
iq_trim_from_otp();
/*
************************************************************************************
* BLE initialization
************************************************************************************
*/ init_pwr_and_clk_ble();
// Initialize BLE stack
rwip_clear_interrupts ();
// Initialize rw
rwip_init(error);
//Patch llm task
patch_llm_task();
//Patch gtl task if (BLE_GTL_PATCH)
patch_gtl_task();
//Patch llc task
if (BLE_MEM_LEAK_PATCH)
patch_llc_task();
//Enable the BLE core
SetBits32(BLE_RWBTLECNTL_REG, RWBLE_EN, 1);
// Initialise random number generator seed using random bits acquired from TRNG
if (USE_TRNG)
init_rand_seed_from_trng();
//send a message to the host if an error occured
if (BLE_HCIC_ITF)
hcic_reset_message();
rcx20_calibrate ();
arch_disable_sleep();
/*
************************************************************************************
* Application initializations
************************************************************************************
*/
// Initialise APP
#if (BLE_APP_PRESENT)
app_init(); // Initialize APP
#endif
if (user_app_main_loop_callbacks.app_on_init !=NULL)
user_app_main_loop_callbacks.app_on_init();
//Initialise lld_sleep
lld_sleep_init_func();
/*
************************************************************************************
* XTAL16M trimming settings
************************************************************************************
*/
//set trim and bias of xtal16
xtal16__trim_init();
// Enable the TX_EN/RX_EN interrupts, depending on the RF mode of operation (PLL-LUT and MGC_KMODALPHA combinations)
enable_rf_diag_irq(RF_DIAG_IRQ_MODE_RXTX);
/*
************************************************************************************
* Watchdog
************************************************************************************
*/
if(USE_WDOG)
{
wdg_reload(WATCHDOG_DEFAULT_PERIOD);
wdg_resume ();
}
#ifndef __DA14581__
# if (BLE_CONNECTION_MAX_USER > 4)
cs_table[0] = cs_table[0];
# endif
#else //DA14581
# if (BLE_CONNECTION_MAX_USER > 1)
cs_table[0] = cs_table[0];
# endif
#endif //__DA14581__
}
void app_init(void)
{
// Reset the environment
memset(&app_env[0], 0, sizeof(app_env));
bool security_default_val = true;
uint8_t length = NVDS_LEN_SECURITY_ENABLE;
// Get the security enable from the storage
if (nvds_get(NVDS_TAG_SECURITY_ENABLE, &length, (uint8_t *)&security_default_val) != NVDS_OK)
{
// Set true by default (several profiles requires security)
security_default_val = true;
}
for (uint8_t i = 0; i< APP_EASY_MAX_ACTIVE_CONNECTION; i++)
{
// Set true by default (several profiles requires security)
app_env[i].sec_en = true;
}
// Create APP task
ke_task_create(TASK_APP, &TASK_DESC_APP); //创建任务
// Initialize Task state
ke_state_set(TASK_APP, APP_DISABLED);
}
/// Application Task Descriptor
static const struct ke_task_desc TASK_DESC_APP = {NULL,
&app_default_handler,
app_state,
APP_STATE_MAX,
APP_IDX_MAX};
/* Default State handlers definition. */
const struct ke_msg_handler app_default_state[] =
{
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_entry_point_handler},
};
/* Specifies the message handlers that are common to all states. */
const struct ke_state_handler app_default_handler = KE_STATE_HANDLER(app_default_state);
const process_event_func_t app_process_handlers[] = {
#if (!EXCLUDE_DLG_GAP)
(process_event_func_t) app_gap_process_handler,
#endif
#if (!EXCLUDE_DLG_TIMER)
(process_event_func_t) app_timer_api_process_handler,
#endif
#if (!EXCLUDE_DLG_MSG)
(process_event_func_t) app_msg_utils_api_process_handler,
#endif
#if ((BLE_APP_SEC) && (!EXCLUDE_DLG_SEC))
(process_event_func_t) app_sec_process_handler,
#endif
#if ((BLE_DIS_SERVER) && (!EXCLUDE_DLG_DISS))
(process_event_func_t) app_dis_process_handler,
#endif
#if ((BLE_PROX_REPORTER) && (!EXCLUDE_DLG_PROXR))
(process_event_func_t) app_proxr_process_handler,
#endif
#if ((BLE_BAS_SERVER) && (!EXCLUDE_DLG_BASS))
(process_event_func_t) app_bass_process_handler,
#endif
#if (((BLE_FINDME_TARGET)&& (!EXCLUDE_DLG_FINDT)) || ((BLE_FINDME_LOCATOR)&& (!EXCLUDE_FINDL)))
(process_event_func_t) app_findme_process_handler,
#endif //BLE_FINDME_LOCATOR
#if ((BLE_SPOTA_RECEIVER) && (!EXCLUDE_DLG_SPOTAR))
(process_event_func_t) app_spota_process_handler,
#endif
//#if ((BLE_CUSTOM1_SERVER) && (!EXCLUDE_DLG_CUSTS1))
// (process_event_func_t) app_custs1_process_handler,
//#endif (process_event_func_t) app_custs1_process_handler,
};
int app_entry_point_handler (ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id){
int i=0;
enum ke_msg_status_tag process_msg_handling_result;
while (i
/*
* FUNCTION DEFINITIONS
****************************************************************************************
*/
static const struct ke_msg_handler app_gap_process_handlers[]=
{
{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_CMP_EVT, (ke_msg_func_t)gapc_cmp_evt_handler}, {GAPC_CONNECTION_REQ_IND, (ke_msg_func_t)gapc_connection_req_ind_handler},
{GAPC_DISCONNECT_IND, (ke_msg_func_t)gapc_disconnect_ind_handler},
{APP_MODULE_INIT_CMP_EVT, (ke_msg_func_t)app_module_init_cmp_evt_handler},
{GAPM_ADV_REPORT_IND, (ke_msg_func_t)gapm_adv_report_ind_handler},
};
enum process_event_response app_gap_process_handler (ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id,
enum ke_msg_status_tag *msg_ret)
{
return (app_std_process_event(msgid, param,src_id,dest_id,msg_ret, app_gap_process_handlers,
sizeof(app_gap_process_handlers)/sizeof(struct ke_msg_handler)));
}
enum process_event_response app_std_process_event (
ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const src_id,
ke_task_id_t const dest_id,
enum ke_msg_status_tag *msg_ret,
const struct ke_msg_handler *handlers,
const int handler_num)
{
ke_msg_func_t func = NULL;
func = handler_search(msgid, handlers, handler_num );
if (func != NULL)
{
(*msg_ret) = (enum ke_msg_status_tag) func(msgid, param, dest_id, src_id);
return (PR_EVENT_HANDLED);
}
else
return (PR_EVENT_UNHANDLED);
};
这样注册了 可以用
void ke_timer_set(ke_msg_id_t const timer_id, ke_task_id_t const task, uint32_t delay);;来启动对应的事件
void ke_timer_clear(ke_msg_id_t const timerid, ke_task_id_t const task);//来停止事件
//还不知道怎么注册蓝牙服务的、、、
2在user_callback_config.h里面
.再看 user_app_callbacks 结构体,里面是对应蓝牙协议栈对应的回调函数,比如。
蓝牙开始广播 则:回调default_app_on_db_init_complete函数
蓝牙连上了回调:default_app_on_connection
蓝牙断开回调:default_app_on_disconnect等等
但是.但是 但是 还知道在哪里注册这些东西的。
static const struct app_callbacks user_app_callbacks = {
.app_on_connection = default_app_on_connection,
.app_on_disconnect = default_app_on_disconnect,
.app_on_update_params_rejected = NULL,
.app_on_update_params_complete = NULL,
.app_on_set_dev_config_complete = default_app_on_set_dev_config_complete,
.app_on_adv_undirect_complete = app_advertise_complete,
.app_on_adv_direct_complete = NULL,
.app_on_db_init_complete = default_app_on_db_init_complete,
.app_on_scanning_completed = NULL,
.app_on_adv_report_ind = NULL, .app_on_pairing_request = default_app_on_pairing_request,
.app_on_tk_exch_nomitm = default_app_on_tk_exch_nomitm,
.app_on_irk_exch = NULL,
.app_on_csrk_exch = default_app_on_csrk_exch,
.app_on_ltk_exch = default_app_on_ltk_exch,
.app_on_pairing_succeded = NULL,
.app_on_encrypt_ind = NULL,
.app_on_mitm_passcode_req = NULL,
.app_on_encrypt_req_ind = default_app_on_encrypt_req_ind,
};
void default_app_on_db_init_complete( void )
{
EXECUTE_DEFAULT_OPERATION_VOID(default_operation_adv);
return;
}
然后如下
/**
****************************************************************************************
* @brief Structure containing the operations used by the default handlers.
* @return void
****************************************************************************************
*/
struct default_app_operations {
void (*default_operation_adv)(void);
};
再看default_operation_adv的地址,最终调用default_advertise_operation函数
// Default Handler Operations
static const struct default_app_operations user_default_app_operations = {
.default_operation_adv = default_advertise_operation,
};
/**
****************************************************************************************
* @brief The advertise operation used by the rest of default handlers.
* @return None.
****************************************************************************************
*/
void default_advertise_operation(void)
{
if (user_default_hnd_conf.adv_scenario==DEF_ADV_FOREVER)
app_easy_gap_undirected_advertise_start();
else if (user_default_hnd_conf.adv_scenario==DEF_ADV_WITH_TIMEOUT)
app_easy_gap_undirected_advertise_with_timeout_start(user_default_hnd_conf.advertise_period,NULL);
}
void app_easy_gap_undirected_advertise_start(void)
{
struct gapm_start_advertise_cmd* cmd;
cmd = app_easy_gap_undirected_advertise_start_create_msg();
// Send the message
app_advertise_start_msg_send(cmd);
adv_cmd=NULL ;
// We are now connectable
ke_state_set(TASK_APP, APP_CONNECTABLE);
}
3.看下蓝牙连上的时候的回调
void default_app_on_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param)
{
if (app_env[connection_idx].conidx != GAP_INVALID_CONIDX)
{
if (user_default_hnd_conf.adv_scenario==DEF_ADV_WITH_TIMEOUT)
app_easy_gap_advertise_with_timeout_stop( );
default_advertise_stop_operation();
app_prf_enable (param->conhdl);
if ((user_default_hnd_conf.security_request_scenario==DEF_SEC_REQ_ON_CONNECT) && (BLE_APP_SEC))
{
app_easy_security_request(connection_idx);
}
}
else
{
// No connection has been establish, restart advertising
EXECUTE_DEFAULT_OPERATION_VOID(default_operation_adv);
}
return;
}
void app_prf_enable (uint16_t conhdl)
{
uint8_t i=0;
while( user_prf_funcs[i].task_id != TASK_NONE )
{
if( user_prf_funcs[i].enable_func != NULL )
{
user_prf_funcs[i++].enable_func(conhdl);
}
else i++;
}
i=0;
/*--------------------------------------------------------------
* ENABLE REQUIRED PROFILES
*-------------------------------------------------------------*/
while( prf_funcs[i].task_id != TASK_NONE )
{
if(( prf_funcs[i].enable_func != NULL ) && (!app_task_in_user_app(prf_funcs[i].task_id)))
{
prf_funcs[i++].enable_func(conhdl);
}
else i++;
}
i=0;
#if BLE_CUSTOM_SERVER while( cust_prf_funcs[i].task_id != TASK_NONE )
{
if( cust_prf_funcs[i].enable_func != NULL )
{
cust_prf_funcs[i++].enable_func(conhdl);
}
else i++;
}
#endif
}
这里主要是注册服务的初始化事件 ,看prf_funcs[]数组 如下
const struct prf_func_callbacks prf_funcs[] =
{
#if BLE_PROX_REPORTER
{TASK_PROXR, app_proxr_create_db, app_proxr_enable},
#endif
#if BLE_BAS_SERVER
{TASK_BASS, app_bass_create_db, app_bass_enable},
#endif
#if BLE_FINDME_TARGET {TASK_FINDT, NULL, app_findt_enable},
#endif
#if BLE_FINDME_LOCATOR
{TASK_FINDL, NULL, app_findl_enable},
#endif
#if BLE_DIS_SERVER
{TASK_DISS, app_diss_create_db, app_diss_enable},
#endif
#if BLE_SPOTA_RECEIVER
{TASK_SPOTAR, app_spotar_create_db, app_spotar_enable},
#endif
{TASK_NONE, NULL, NULL}, // DO NOT MOVE. Mast always be last
};
以BLE_BAS_SERVER服务来分析。连上蓝牙就启动app_bass_enable启动电池采集事件。。