/*Includes ----------------------------------------------*/ #include "tool.h" #include "nrf_delay.h" #include "system.h" #include "ble_comm.h" #include "bsp_time.h" #include "hal_led.h" #include "hal_charge.h" #include "hal_ble_common.h" #include "hal_ble_client.h" #include "hal_ble_host.h" #include "app_flash.h" #include "app_wireless_pair.h" #include "app_detectIsHost.h" /*Private macro ------------------------------------------------------------------------------------------------------------------------------------*/ #define APP_WIRELESS_PAIR_FSMTABLE_LEN 8 //状态表长度 #define APP_WIRELESS_PAIR_RSSI_THRESHOLD -18 //rssi阈值 #define APP_WIRELESS_PAIR_RSSI_BUFF_LEN 15 //rssi缓冲区长度 /*Struction ------------------------------------------------------------------------------------------------------------------------------------*/ //定义状态表的数据类型 typedef struct _app_wireless_pair_fsmtable_s { App_Wireless_Pair_Event_e event; //事件 App_Wireless_Pair_State_e CurState; //当前状态 int (*eventActFun)(); //函数指针 App_Wireless_Pair_State_e NextState; //下一个状态 }App_Wireless_Pair_fsmtable_s; //定义状态机类型 typedef struct _app_wireless_pair_fsm_s { App_Wireless_Pair_State_e curState; //当前状态 App_Wireless_Pair_fsmtable_s FsmTable[APP_WIRELESS_PAIR_FSMTABLE_LEN]; //状态表 App_Wireless_Pair_Set_Scan_Cb set_scan_cb; //设置扫描回调 App_Wireless_Pair_Set_Adv_Cb set_adv_cb; //设置广播回调 uint8_t peer_addr[6]; //对端MAC地址 bool is_busy; //是否忙碌 uint8_t led_display_count; //亮灯次数 uint8_t led_switch; //灯的开关 char already_scan_or_adv_mac_buf[16]; //已经在扫描或广播的mac地址 int rssi_buf[APP_WIRELESS_PAIR_RSSI_BUFF_LEN]; //rssi缓冲区 }App_Wireless_Pair_Fsm_s; /*Local Variable ------------------------------------------------------------------------------------------------------------------------------------*/ static App_Wireless_Pair_Fsm_s ob_app_wireless_pair_fsm; /*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/ static void app_wireless_pair_slow_clear_rssi_buff_process(void); static int app_wireless_pair_set_scan_adv_on(void) { int ret = 0; int adv_stop = -1; //若是右鞋则进入主动扫描状态 //若是左鞋则设置扫描回应为MAC地址状态 if(mFlash.isHost) { if(slave_isconnect() == 0) { //已连接状态下,不能调用停止广播 adv_stop = wireless_pair_advertising_stop(); if(ob_app_wireless_pair_fsm.set_adv_cb != NULL && adv_stop == 0 && slave_isconnect() == 0)ret += ob_app_wireless_pair_fsm.set_adv_cb(0x01); else ret = -1; } nrf_ble_scan_stop(); host_disconnect(); //已连接状态下,不能调用停止扫描 if(host_isconnect() == 0) { if(ob_app_wireless_pair_fsm.set_scan_cb != NULL)ret += ob_app_wireless_pair_fsm.set_scan_cb(0x00); else ret = -1; } else { ret = -1; } } else { if(host_isconnect() == 0) { //已连接状态下,不能调用停止扫描 nrf_ble_scan_stop(); if(ob_app_wireless_pair_fsm.set_scan_cb != NULL)ret += ob_app_wireless_pair_fsm.set_scan_cb(0x01); else ret = -1; } slave_disconnect(); //已连接状态下,不能调用停止广播 if(slave_isconnect() == 0)adv_stop = wireless_pair_advertising_stop(); if(adv_stop == 0 && slave_isconnect() == 0) { if(ob_app_wireless_pair_fsm.set_adv_cb != NULL)ret += ob_app_wireless_pair_fsm.set_adv_cb(0x00); else ret = -1; } else { ret = -1; } } if(ret == 0)Process_Start(100,"app_wireless_pair_slow_clear_rssi_buff_process",app_wireless_pair_slow_clear_rssi_buff_process); return ret; } static int app_wireless_pair_set_scan_adv_off(void) { int ret = 0; char buf[16]; int adv_stop = -1; //若是右鞋则进入被动扫描状态 //若是左鞋则设置扫描回应为空数据状态 if(mFlash.isHost) { if(slave_isconnect() == 0) { //已连接状态下,不能调用停止广播 adv_stop = wireless_pair_advertising_stop(); if(ob_app_wireless_pair_fsm.set_adv_cb != NULL && adv_stop == 0 && slave_isconnect() == 0)ret += ob_app_wireless_pair_fsm.set_adv_cb(0x00); else ret = -1; } nrf_ble_scan_stop(); host_disconnect(); //已连接状态下,不能调用停止扫描 if(host_isconnect() == 0) { if(ob_app_wireless_pair_fsm.set_scan_cb != NULL) { sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]); host_set_scan_name(buf,strlen(buf)); ret += ob_app_wireless_pair_fsm.set_scan_cb(0x00); } else ret = -1; } else { ret = -1; } } else { if(host_isconnect() == 0) { //已连接状态下,不能调用停止扫描 //调用停止扫描,因为右鞋不需要,反而会干扰传输速度 nrf_ble_scan_stop(); } slave_disconnect(); //已连接状态下,不能调用停止广播 if(slave_isconnect() == 0)adv_stop = wireless_pair_advertising_stop(); if(adv_stop == 0 && slave_isconnect() == 0) { if(ob_app_wireless_pair_fsm.set_adv_cb != NULL) { if(mFlash.mClient.isConfig == 'C') { sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.mClient.macAddr[0],mFlash.mClient.macAddr[1],mFlash.mClient.macAddr[2],mFlash.macHost[3],mFlash.macHost[4],mFlash.macHost[5]); } else { ble_gap_addr_t m_addr; uint32_t err_code; //获取自身mac地址 err_code = sd_ble_gap_addr_get(&m_addr); APP_ERROR_CHECK(err_code); for(int i=0;i<6;i++)mFlash.macHost[i] = m_addr.addr[5-i]; sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.macHost[3],mFlash.macHost[4],mFlash.macHost[5]); } slave_set_adv_name(buf,strlen(buf)); slave_adv_init(); ret += ob_app_wireless_pair_fsm.set_adv_cb(0x00); } else ret = -1; } else { ret = -1; } } if(ret == 0) { ob_app_wireless_pair_fsm.led_switch = 1; memset(&ob_app_wireless_pair_fsm.peer_addr,0xFF,sizeof(ob_app_wireless_pair_fsm.peer_addr)); for(int i=0;i ob_app_wireless_pair_fsm.rssi_buf[i])?rssi_max:ob_app_wireless_pair_fsm.rssi_buf[i]; // SEGGER_RTT_printf(0,"rssi:%d,%d,st:%d,curState:%d,active:%d,host:%d,slave:%d,mFlash.isHost:%d,led:%d,mac: ",rssi_max,rssi,NRF_RTC0->COUNTER, \ // ob_app_wireless_pair_fsm.curState,wireless_pair_scan_get_active(),\ // host_isconnect(),slave_isconnect(),mFlash.isHost,ob_app_wireless_pair_fsm.led_switch); if(mFlash.isHost) { extern char Target_scan[TARFET_LEN_MAX]; // for(int i=0; i<6; i++)SEGGER_RTT_printf(0,"0x%x ",Target_scan[5-i]); } else { int len; char name[16]; slave_get_advname_len(&len); slave_get_advname(name,len); // for(int i=0; i<6; i++)SEGGER_RTT_printf(0,"0x%x ",name[5-i]); } // if(rssi >= APP_WIRELESS_PAIR_RSSI_THRESHOLD) // { // SEGGER_RTT_printf(0," rssi_mac : ");for(int i=0; i<6; i++)SEGGER_RTT_printf(0,"0x%x ",addr[5-i]);SEGGER_RTT_printf(0,"\r\n"); // } // else // SEGGER_RTT_printf(0,"\r\n"); if(memcmp(addr,null_addr,6) != 0 && rssi >=APP_WIRELESS_PAIR_RSSI_THRESHOLD) { for(int i=0; i<6; i++)ob_app_wireless_pair_fsm.peer_addr[i] = addr[5-i];//这里是确保该rssi对应的mac ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); } else if(rssi_max < APP_WIRELESS_PAIR_RSSI_THRESHOLD) { if(mFlash.isHost && host_isconnect() == 1) { ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); } else if(!mFlash.isHost && slave_isconnect() == 1) { ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); } else ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_DOES_NOT_MEETS_REQUIREMENTS); } else { if(memcmp(addr,null_addr,6) != 0) { ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); } else { if(mFlash.isHost && host_isconnect() == 1) { ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); } else if(!mFlash.isHost && slave_isconnect() == 1) { ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); } else ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_DOES_NOT_MEETS_REQUIREMENTS); } } // if(rssi_max >= APP_WIRELESS_PAIR_RSSI_THRESHOLD) // { // if(memcmp(addr,null_addr,6) != 0) // { // ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); // } // else // { // if(!mFlash.isHost && slave_isconnect() == 1) // { // ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); // } // else ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_DOES_NOT_MEETS_REQUIREMENTS); // } // } // else // { // if(mFlash.isHost && host_isconnect() == 1) // { // ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); // } // else if(!mFlash.isHost && slave_isconnect() == 1) // { // ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_MEETS_REQUIREMENTS); // } // else ret = app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_RSSI_DOES_NOT_MEETS_REQUIREMENTS); // } } return ret; } static void app_wireless_pair_slow_clear_rssi_buff_process(void) { uint8_t addr[6]; memset(addr,0x00,6); app_wireless_pair_enter_in_process(APP_WIRELESS_PAIR_RSSI_THRESHOLD*2,addr); } static void display_led_process(void) { ob_app_wireless_pair_fsm.led_display_count++; if (ob_app_wireless_pair_fsm.led_display_count % 2 == 0) { LED_Start(LED_PAIR, COLOR_BLACK); } else { LED_Start(LED_PAIR, COLOR_BLUE); } if (ob_app_wireless_pair_fsm.led_display_count > 20) { ob_app_wireless_pair_fsm.led_display_count = 0; LED_Stop(LED_PAIR); Process_SetHoldOn(display_led_process, 0); Process_Stop(display_led_process); } } static void app_wireless_pair_start_display_led(void) { ob_app_wireless_pair_fsm.led_display_count = 0; Process_Start(500, "display_led_process", display_led_process); Process_SetHoldOn(display_led_process, 1); } static void app_wireless_pair_stop_display_led(void) { ob_app_wireless_pair_fsm.led_display_count = 0; LED_Stop(LED_PAIR); Process_SetHoldOn(display_led_process, 0); Process_Stop(display_led_process); } static void app_wireless_pair_in_process(void) { int ret = 0; uint8_t *connect_addr; uint8_t peer_addr[6]; //对端mac地址 ble_gap_addr_t m_addr; //自身mac地址 char buf[16]; uint32_t err_code; int adv_stop = -1; uint8_t null_addr[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; if(!get_LR_readly()) { return; } if(ob_app_wireless_pair_fsm.curState == APP_WIRELESS_PAIR_STATE_PAIRING_IN_PROGRESS) { ob_app_wireless_pair_fsm.is_busy = true; //获取已连接的对端mac地址 connect_addr = wireless_pair_get_connect_macaddr(); //获取自身mac地址 err_code = sd_ble_gap_addr_get(&m_addr); APP_ERROR_CHECK(err_code); //获取对端的mac地址 for(int i=0;i<6;i++)peer_addr[i]=ob_app_wireless_pair_fsm.peer_addr[i]; if(mFlash.isHost) //左鞋处理逻辑 { //判断是否处于连接且连接的mac地址为配对地址 if(host_isconnect() == 1 && memcmp(peer_addr,connect_addr,6) == 0) { //判断是否配对过,若已配对过,直接进入配对结束阶段。若无配对过,则记录MAC地址,清除步数,进入配对结束。 if(memcmp(peer_addr,mFlash.mClient.macAddr,6) != 0) { //配置左鞋广播名字,已连接状态下,不能调用停止广播 if(slave_isconnect() == 0)adv_stop = wireless_pair_advertising_stop(); if(adv_stop == 0 && slave_isconnect() == 0) { sprintf(buf,"SH_%02X%02X",m_addr.addr[4], m_addr.addr[5]); slave_set_adv_name(buf,strlen(buf)); slave_adv_init(); ret = ob_app_wireless_pair_fsm.set_adv_cb(0x01); if(ret == 0) { for(int i = 0; i < 6; i++) { mFlash.mClient.macAddr[i] = peer_addr[i]; mFlash.macHost[i] = m_addr.addr[5-i]; mBackup.macAddr_L[i] = mFlash.macHost[i]; //主机地址 mBackup.macAddr_R[i] = mFlash.mClient.macAddr[i]; //从机地址 } mFlash.mClient.isConfig ='C'; mBackup.hardVersion = mFlash.mClient.hardVersion; mBackup.sotfVersion = mFlash.mClient.sotfVersion; mBackup.isConfig = mFlash.mClient.isConfig; if(Flash_SaveBackup() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_Pair, "pair save backup fail");} if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_Pair, "pair clear step fail");} memset(&mFlash.mStep, 0, sizeof(FlashStep_t)); if(Flash_SaveInfomation() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_Pair, "Flash_SaveInfomation fail");} app_wireless_pair_start_led();//如果连接上没靠近,要在这里加才会开线程。 app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_PAIR_DONE); } } } else { app_wireless_pair_start_led();//如果连接上没靠近,要在这里加才会开线程。 app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_PAIR_DONE); } if(ob_app_wireless_pair_fsm.curState == APP_WIRELESS_PAIR_STATE_END_OF_PAIRING && host_get_rssi() >= APP_WIRELESS_PAIR_RSSI_THRESHOLD) { if(slave_isconnect() == 0)adv_stop = wireless_pair_advertising_stop(); if(adv_stop == 0 && slave_isconnect() == 0) { ob_app_wireless_pair_fsm.set_adv_cb(0x00); } } } else { //若不是,断开连接,设置扫描为新的配对地址 sprintf(buf,"%02X%02X%02X%02X%02X%02X",m_addr.addr[5],m_addr.addr[4],m_addr.addr[3],peer_addr[3],peer_addr[4],peer_addr[5]); if(memcmp(ob_app_wireless_pair_fsm.already_scan_or_adv_mac_buf,buf,strlen(buf)) != 0 && memcmp(peer_addr,null_addr,6) != 0) { // SEGGER_RTT_printf(0,"scan_or_adv_mac_buf: %s\r\n",ob_app_wireless_pair_fsm.already_scan_or_adv_mac_buf); // SEGGER_RTT_printf(0,"buf: %s\r\n",buf); if(slave_isconnect() == 0) { //已连接状态下,不能调用停止广播 adv_stop = wireless_pair_advertising_stop(); if(adv_stop == 0 && slave_isconnect() == 0)ret += ob_app_wireless_pair_fsm.set_adv_cb(0x01); } nrf_ble_scan_stop(); host_disconnect(); //已连接状态下,不能调用停止扫描 if(host_isconnect() == 0) { host_set_scan_name(buf,strlen(buf)); ret += ob_app_wireless_pair_fsm.set_scan_cb(0x02); if(ret == 0){memcpy(ob_app_wireless_pair_fsm.already_scan_or_adv_mac_buf,buf,strlen(buf));} } } } } else //右鞋处理逻辑 { //判断是否处于连接且连接的mac地址为配对地址 if(slave_isconnect() == 1 && memcmp(peer_addr,connect_addr,6) == 0) { //判断是否配对过,若已配对过,直接进入配对结束阶段。若无配对过,则记录MAC地址,清除步数,进入配对结束。 if(memcmp(peer_addr,mFlash.mClient.macAddr,6) != 0) { for(int i = 0; i < 6; i++) { mFlash.mClient.macAddr[i] = peer_addr[i]; mFlash.macHost[i] = m_addr.addr[5-i]; mBackup.macAddr_L[i] = mFlash.macHost[i]; //主机地址 mBackup.macAddr_R[i] = mFlash.mClient.macAddr[i]; //从机地址 } mFlash.mClient.isConfig ='C'; mBackup.hardVersion = mFlash.mClient.hardVersion; mBackup.sotfVersion = mFlash.mClient.sotfVersion; mBackup.isConfig = mFlash.mClient.isConfig; if(Flash_SaveBackup() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_Pair, "pair save backup fail");} if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_Pair, "pair clear step fail");} memset(&mFlash.mStep, 0, sizeof(FlashStep_t)); if(Flash_SaveInfomation() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_Pair, "Flash_SaveInfomation fail");} } app_wireless_pair_start_led();//如果连接上没靠近,要在这里加才会开线程。 app_wireless_pair_EventHandle(APP_WIRELESS_PAIR_EVENT_PAIR_DONE); if(ob_app_wireless_pair_fsm.curState == APP_WIRELESS_PAIR_STATE_END_OF_PAIRING && slave_get_rssi() >= APP_WIRELESS_PAIR_RSSI_THRESHOLD) { if(host_isconnect() == 0)nrf_ble_scan_stop(); } } else { //若不是,断开连接,设置广播为新的配对地址 sprintf(buf,"%02X%02X%02X%02X%02X%02X",peer_addr[0],peer_addr[1],peer_addr[2],m_addr.addr[2],m_addr.addr[1],m_addr.addr[0]); if(memcmp(ob_app_wireless_pair_fsm.already_scan_or_adv_mac_buf,buf,strlen(buf)) != 0 && memcmp(peer_addr,null_addr,6) != 0) { if(host_isconnect() == 0) { //已连接状态下,不能调用停止扫描 nrf_ble_scan_stop(); ret += ob_app_wireless_pair_fsm.set_scan_cb(0x01); } slave_disconnect(); //已连接状态下,不能调用停止广播 if(slave_isconnect() == 0)adv_stop = wireless_pair_advertising_stop(); if(adv_stop == 0 && slave_isconnect() == 0) { DEBUG_LOG("pair : advName(%d):%s\n",strlen(buf),buf); slave_set_adv_name(buf,strlen(buf)); slave_adv_init(); ret += ob_app_wireless_pair_fsm.set_adv_cb(0x02); if(ret == 0){memcpy(ob_app_wireless_pair_fsm.already_scan_or_adv_mac_buf,buf,strlen(buf));} } } } } ob_app_wireless_pair_fsm.is_busy = false; } } /*API ------------------------------------------------------------------------------------------------------------------------------------*/ /** @brief 初始化无线配对应用 @param 无 @return 错误代码 - [out] -1失败,0成功 */ int app_wireless_pair_Init(void) { //初始化结构体 // memset(&ob_app_wireless_pair_fsm,0,sizeof(App_Wireless_Pair_Fsm_s)); //不能meset初始化,因为回调函数会被清除。 ob_app_wireless_pair_fsm.curState = APP_WIRELESS_PAIR_STATE_PAIRING_STANDBY; ob_app_wireless_pair_fsm.is_busy = false; ob_app_wireless_pair_fsm.led_switch = 1; memset(&ob_app_wireless_pair_fsm.peer_addr,0xFF,sizeof(ob_app_wireless_pair_fsm.peer_addr)); for(int i=0;i