Bluetooth Low Energy based Firmware Over The Air with Mbed. Mbed part is a external processor of the IoT devices and communicate with a Bluetooth module. The Bluetooth module have to support BLE and implement BLE FOTA profile designed by ours. BLE FOTA profile specification is available from our GIT hub wiki(https://github.com/sevencore/BLEFOTA).
Dependencies: mbed
Fork of mbed_fota by
BleMsgHandler.cpp
00001 /** 00002 * @file BleMsgHandler.cpp 00003 * @brief Ble message handler ( Ble message is communication mathod between Mbed and DA14583 ) 00004 * Copyright 2015 SEVENCORE Co., Ltd. 00005 * 00006 * @author HyeongJun Kim 00007 * @version 1.0.0 00008 * @date 2015-08-19 00009 */ 00010 00011 #include "BleMsgHandler.h" 00012 #include "dialog_fota_config.h" 00013 #include "diss_task.h" 00014 #include "fota_server_task.h" 00015 #include "app_task.h" 00016 00017 /** 00018 **************************************************************************************** 00019 * @addtogroup ext_fota module 00020 * @brief Ble message Handler Class Mathod Definition. 00021 * 00022 * @{ 00023 **************************************************************************************** 00024 */ 00025 00026 extern "C" void mbed_reset(); 00027 00028 namespace sevencore_fota{ 00029 00030 /** 00031 **************************************************************************************** 00032 * @brief Ble message Handler Constructor. 00033 * @param[in] mbed serial class reference to device. 00034 * @detail Create SerialManager instance and Create inner MsgQueue 00035 **************************************************************************************** 00036 */ 00037 BleMsgHandler::BleMsgHandler(Serial *_device) 00038 { 00039 print_flag = 0; 00040 device = _device; 00041 SerialM = new SerialManager(_device); 00042 MsgQ = new MsgQueue(512); 00043 memset(recv_msg,0,512); 00044 } 00045 /** 00046 **************************************************************************************** 00047 * @brief Ble message Handler Constructor. 00048 * @param[in] mbed serial class reference to device. 00049 * @param[in] mbed serial class reference to hostpc. 00050 * @detail Create SerialManager instance and Create inner MsgQueue 00051 **************************************************************************************** 00052 */ 00053 BleMsgHandler::BleMsgHandler(Serial *_device, Serial *_hostpc) 00054 { 00055 print_flag = 1; 00056 device = _device; 00057 hostpc = _hostpc; 00058 SerialM = new SerialManager(_device,_hostpc); 00059 MsgQ = new MsgQueue(512); 00060 memset(recv_msg,0,512); 00061 } 00062 /** 00063 **************************************************************************************** 00064 * @brief Ble message Handler Destructor. 00065 **************************************************************************************** 00066 */ 00067 BleMsgHandler::~BleMsgHandler(void) 00068 { 00069 free(SerialM); 00070 free(MsgQ); 00071 } 00072 /** 00073 **************************************************************************************** 00074 * @brief Ble message handler Start title print function. 00075 **************************************************************************************** 00076 */ 00077 void BleMsgHandler::PrintTitle(void) 00078 { 00079 if( print_flag == 1 ) 00080 hostpc->printf("\nSevencore Fota : BleMsg Handler Start\n"); 00081 //SerialM->ReceiveToSerialTest(); 00082 } 00083 /** 00084 **************************************************************************************** 00085 * @brief Create ble message. 00086 * @param[in] 16byte ble message type. @ref structure 'ble_hdr' member 'bType' 00087 * @param[in] 16byte ble dest task id(number). @ref structure 'ble_hdr' member 'bDstid' 00088 * @param[in] 16byte ble source task id(number). @ref structure 'ble_hdr' member 'bSrcid' 00089 * @param[in] 16byte ble message data length. @ref structure 'ble_hdr' member 'bLength' 00090 * @param[in] input data pointer. 00091 * @param[in] message alloc output pointer. 00092 **************************************************************************************** 00093 */ 00094 void BleMsgHandler::BleMsgAlloc( unsigned short id, 00095 unsigned short dest_id, 00096 unsigned short src_id, 00097 unsigned short data_len, 00098 void *pdata, 00099 uint8_t *msg ) 00100 { 00101 memset(msg,0,sizeof(msg)); 00102 msg[0] = 0x05; 00103 memcpy(&msg[1],&id,sizeof(unsigned short)); 00104 memcpy(&msg[1+1*sizeof(unsigned short)],&dest_id,sizeof(unsigned short)); 00105 memcpy(&msg[1+2*sizeof(unsigned short)],&src_id,sizeof(unsigned short)); 00106 memcpy(&msg[1+3*sizeof(unsigned short)],&data_len,sizeof(unsigned short)); 00107 memcpy(&msg[1+4*sizeof(unsigned short)],pdata,data_len); 00108 } 00109 /** 00110 **************************************************************************************** 00111 * @brief Send ble message to device. 00112 * @param[in] sending message pointer 00113 * @param[in] message size. 00114 **************************************************************************************** 00115 */ 00116 int BleMsgHandler::BleSendMsg(uint8_t *msg, unsigned short size) 00117 { 00118 return SerialM->SendToSerial(msg,size); 00119 } 00120 /** 00121 **************************************************************************************** 00122 * @brief Receive ble message from device. 00123 * @detail Received message insert inner MsgQueue 00124 **************************************************************************************** 00125 */ 00126 void BleMsgHandler::BleReceiveMsg(void) 00127 { 00128 int receive_size = -1;//default 00129 while(receive_size == -1) 00130 { 00131 receive_size = SerialM->ReceiveToSerial(recv_msg); 00132 } 00133 00134 uint8_t *msg; 00135 msg = new uint8_t[receive_size]; 00136 memcpy(msg,recv_msg,receive_size); 00137 memset(recv_msg,0,512); 00138 MsgQ->EnQueue(msg); 00139 } 00140 /** 00141 **************************************************************************************** 00142 * @brief Get message from MsgQueue and Execute corresponding function. 00143 * @detail After get message, extract message type. Each message type connect corresponding function 00144 **************************************************************************************** 00145 */ 00146 void BleMsgHandler::BleMsgHandle(void) 00147 { 00148 uint8_t *msg; 00149 ble_hdr msg_hdr; 00150 unsigned short paramPos = 1 + sizeof(msg_hdr); 00151 00152 if( print_flag == 1) 00153 hostpc->printf("Ble-message Handle Function!\n"); 00154 00155 msg = (uint8_t*)MsgQ->DeQueue(); 00156 memcpy(&msg_hdr, &msg[1], sizeof(msg_hdr)); 00157 00158 if( print_flag == 1 ) 00159 hostpc->printf(" handle msg : id(%d), dst(%d), src(%d), len(%d) !\n", 00160 msg_hdr.bType, msg_hdr.bDstid, msg_hdr.bSrcid, msg_hdr.bLength); 00161 00162 if (msg_hdr.bDstid != TASK_GTL){ 00163 if( print_flag == 1) 00164 hostpc->printf("Dstid not TASK_GTL!\n"); 00165 return; 00166 } 00167 00168 switch( msg_hdr.bType ) 00169 { 00170 case GAPM_CMP_EVT: 00171 if( print_flag == 1) 00172 hostpc->printf("==> GAPM_CMP_EVT!!\n"); 00173 HandleGapmCmpEvt(msg_hdr.bType,(struct gapm_cmp_evt *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid); 00174 break; 00175 case GAPM_DEVICE_READY_IND: 00176 if( print_flag == 1) 00177 hostpc->printf("==> GAPM_DEVICE_READY_IND!!\n"); 00178 gapm_device_ready_ind_handler(msg_hdr.bType,(struct gap_ready_evt *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid,this); 00179 break; 00180 case GAPM_ADV_REPORT_IND: 00181 if( print_flag == 1) 00182 hostpc->printf("==> GAPM_ADV_REPORT_IND!!\n"); 00183 gapm_adv_report_ind_handler(msg_hdr.bType,(struct gapm_adv_report_ind *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid); 00184 break; 00185 case GAPC_CMP_EVT: 00186 if( print_flag == 1) 00187 hostpc->printf("==> GAPC_CMP_EVT!!\n"); 00188 HandleGapcCmpEvt(msg_hdr.bType,(struct gapc_cmp_evt *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid); 00189 break; 00190 case GAPC_CONNECTION_REQ_IND: 00191 if( print_flag == 1) 00192 hostpc->printf("==> GAPC_CONNECTION_REQ_IND!!\n"); 00193 gapc_connection_req_ind_handler(msg_hdr.bType,(struct gapc_connection_req_ind *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid,this); 00194 break; 00195 case GAPC_DISCONNECT_IND: 00196 if( print_flag == 1) 00197 hostpc->printf("==> GAPC_DISCONNECT_IND!!\n"); 00198 gapc_disconnect_ind_handler(msg_hdr.bType,(struct gapc_disconnect_ind *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid,this); 00199 break; 00200 case DISS_CREATE_DB_CFM: 00201 if( print_flag == 1) 00202 hostpc->printf("==> DISS_CREATE_DB_CFM!!\n"); 00203 diss_create_db_cfm_handler(msg_hdr.bType,(struct diss_create_db_cfm *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid,this); 00204 break; 00205 case DISS_DISABLE_IND: 00206 if( print_flag == 1) 00207 hostpc->printf("==> DISS_DISABLE_IND!!\n"); 00208 break; 00209 case DISS_ERROR_IND: 00210 if ( print_flag == 1) 00211 hostpc->printf("Rcved DISS_ERROR_IND Msg\n"); 00212 break; 00213 case FOTA_SERVER_CREATE_DB_CFM: 00214 if( print_flag == 1) 00215 hostpc->printf("==> FOTA_SERVER_CREATE_DB_CFM!!\n"); 00216 fota_server_create_db_cfm_handler(msg_hdr.bType,(struct fota_server_create_db_cfm *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid,this); 00217 break; 00218 case FOTA_SERVER_DISABLE_IND: 00219 if( print_flag == 1) 00220 hostpc->printf("==> FOTA_SERVER_DISABLE_IND!!\n"); 00221 break; 00222 case FOTA_SERVER_ERROR_IND: 00223 if ( print_flag == 1) 00224 hostpc->printf("Rcved FOTA_SERVER_ERROR_IND Msg\n"); 00225 fota_server_data_flash_ind_handler(msg_hdr.bType,(struct fota_server_data_flash_ind *)&msg[paramPos],msg_hdr.bDstid,msg_hdr.bSrcid,this); 00226 break; 00227 default: 00228 if( print_flag == 1) 00229 hostpc->printf("message Type Not Defined ! \n"); 00230 break; 00231 } 00232 }//gapc_disconnect_ind_handler(GAPC_DISCONNECT_IND),(GAPC_CONNECTION_REQ_IND)gapc_connection_req_ind_handler 00233 /** 00234 **************************************************************************************** 00235 * @brief GAPM Command Event Handler. 00236 * @detail After get GAPM command, extract operation. Each operation connect corresponding function 00237 **************************************************************************************** 00238 */ 00239 void BleMsgHandler::HandleGapmCmpEvt(unsigned short msgid, 00240 struct gapm_cmp_evt *param, 00241 unsigned short dest_id, 00242 unsigned short src_id) 00243 { 00244 if (param->status == CO_ERROR_NO_ERROR) 00245 { 00246 switch(param->operation) 00247 { 00248 case GAPM_NO_OP:// No operation. 00249 break; 00250 case GAPM_RESET:// Reset BLE subsystem: LL and HL. 00251 if( print_flag == 1) 00252 hostpc->printf("GAPM_RESET!! Start...\n"); 00253 gapm_reset_completion_handler (msgid, (struct gapm_cmp_evt *)param, dest_id, src_id,this); 00254 break; 00255 case GAPM_CANCEL:// Cancel currently executed operation. 00256 if( print_flag == 1) 00257 hostpc->printf("GAPM_CANCEL\n"); 00258 break; 00259 case GAPM_SET_DEV_CONFIG:// Set device configuration 00260 if( print_flag == 1) 00261 hostpc->printf("Adverting Start...\n"); 00262 gapm_set_dev_config_completion_handler(msgid, (struct gapm_cmp_evt *)param, dest_id, src_id,this); 00263 break; 00264 case GAPM_SET_DEV_NAME: // Set device name 00265 if( print_flag == 1) 00266 hostpc->printf("GAPM_SET_DEV_NAME\n"); 00267 break; 00268 case GAPM_SET_CHANNEL_MAP:// Set device channel map 00269 if( print_flag == 1) 00270 hostpc->printf("GAPM_SET_CHANNEL_MAP\n"); 00271 break; 00272 case GAPM_GET_DEV_NAME:// Get Local device name 00273 if( print_flag == 1) 00274 hostpc->printf("GAPM_GET_DEV_NAME\n"); 00275 break; 00276 case GAPM_GET_DEV_VERSION:// Get Local device version 00277 if( print_flag == 1) 00278 hostpc->printf("GAPM_GET_DEV_VERSION\n"); 00279 break; 00280 case GAPM_GET_DEV_BDADDR:// Get Local device BD Address 00281 if( print_flag == 1) 00282 hostpc->printf("GAPM_GET_DEV_BDADDR\n"); 00283 break; 00284 case GAPM_GET_WLIST_SIZE:// Get White List Size. 00285 if( print_flag == 1) 00286 hostpc->printf("GAPM_GET_WLIST_SIZE\n"); 00287 break; 00288 case GAPM_ADD_DEV_IN_WLIST:// Add devices in white list. 00289 if( print_flag == 1) 00290 hostpc->printf("GAPM_ADD_DEV_IN_WLIST\n"); 00291 break; 00292 case GAPM_RMV_DEV_FRM_WLIST:// Remove devices form white list. 00293 if( print_flag == 1) 00294 hostpc->printf("GAPM_RMV_DEV_FRM_WLIST\n"); 00295 break; 00296 case GAPM_CLEAR_WLIST:// Clear all devices from white list. 00297 if( print_flag == 1) 00298 hostpc->printf("GAPM_CLEAR_WLIST\n"); 00299 break; 00300 case GAPM_ADV_NON_CONN:// Start non connectable advertising 00301 case GAPM_ADV_UNDIRECT:// Start undirected connectable advertising 00302 case GAPM_ADV_DIRECT:// Start directed connectable advertising 00303 if( print_flag == 1) 00304 hostpc->printf("GAPM_ADV_~\n"); 00305 break; 00306 case GAPM_SCAN_ACTIVE:// Start active scan operation 00307 case GAPM_SCAN_PASSIVE: // Start passive scan operation 00308 if( print_flag == 1) 00309 hostpc->printf("GAPM_SCAN_~\n"); 00310 break; 00311 case GAPM_CONNECTION_DIRECT:// Direct connection operation 00312 //break; 00313 case GAPM_CONNECTION_AUTO:// Automatic connection operation 00314 //break; 00315 case GAPM_CONNECTION_SELECTIVE:// Selective connection operation 00316 //break; 00317 case GAPM_CONNECTION_NAME_REQUEST:// Name Request operation (requires to start a direct connection) 00318 if( print_flag == 1) 00319 hostpc->printf("GAPM_CONNECT_~\n"); 00320 break; 00321 case GAPM_RESOLV_ADDR:// Resolve device address 00322 if( print_flag == 1) 00323 hostpc->printf("GAPM_RESOLV_ADDR\n"); 00324 break; 00325 case GAPM_GEN_RAND_ADDR:// Generate a random address 00326 if( print_flag == 1) 00327 hostpc->printf("GAPM_GEN_RAND_ADDR\n"); 00328 break; 00329 case GAPM_USE_ENC_BLOCK:// Use the controller's AES-128 block 00330 if( print_flag == 1) 00331 hostpc->printf("GAPM_USE_ENC_BLOCK\n"); 00332 break; 00333 case GAPM_GEN_RAND_NB:// Generate a 8-byte random number 00334 if( print_flag == 1) 00335 hostpc->printf("GAPM_GEN_RAND_NB\n"); 00336 break; 00337 case GAPM_DBG_GET_MEM_INFO:// Get memory usage 00338 if( print_flag == 1) 00339 hostpc->printf("GAPM_GAPM_DBG_GET_MEM_INFO\n"); 00340 break; 00341 case GAPM_PLF_RESET:// Perform a platform reset 00342 if( print_flag == 1) 00343 hostpc->printf("GAPM_PLF_RESET\n"); 00344 break; 00345 case GAPM_GET_DEV_ADV_TX_POWER:// Get device advertising power level 00346 if( print_flag == 1) 00347 hostpc->printf("GAPM_GET_DEV_ADV_TX_POWER\n"); 00348 break; 00349 default: 00350 if( print_flag == 1) 00351 hostpc->printf("??????????????????????????\n"); 00352 break; 00353 } 00354 }else{ 00355 if( print_flag == 1) 00356 hostpc->printf("?status ERROR?\n"); 00357 } 00358 } 00359 /** 00360 **************************************************************************************** 00361 * @brief GAPC Command Event Handler. 00362 * @detail After get GAPC command, extract operation. Each operation connect corresponding function 00363 **************************************************************************************** 00364 */ 00365 void BleMsgHandler::HandleGapcCmpEvt(unsigned short msgid, 00366 struct gapc_cmp_evt *param, 00367 unsigned short dest_id, 00368 unsigned short src_id) 00369 { 00370 switch(param->operation) 00371 { 00372 case GAPC_NO_OP: // No operation 00373 break; 00374 case GAPC_DISCONNECT: // Disconnect link 00375 break; 00376 case GAPC_GET_PEER_NAME: // Retrieve name of peer device 00377 break; 00378 case GAPC_GET_PEER_VERSION: // Retrieve peer device version info. 00379 break; 00380 case GAPC_GET_PEER_FEATURES: // Retrieve peer device features. 00381 break; 00382 case GAPC_GET_CON_RSSI: // Retrieve connection RSSI. 00383 break; 00384 case GAPC_GET_PRIVACY: // Retrieve Privacy Info. 00385 break; 00386 case GAPC_GET_RECON_ADDR: // Retrieve Reconnection Address Value. 00387 break; 00388 case GAPC_SET_PRIVACY: // Set Privacy flag. 00389 break; 00390 case GAPC_SET_RECON_ADDR: // Set Reconnection Address Value. 00391 break; 00392 case GAPC_UPDATE_PARAMS: // Perform update of connection parameters. 00393 break; 00394 case GAPC_BOND: // Start bonding procedure. 00395 break; 00396 case GAPC_ENCRYPT: // Start encryption procedure. 00397 break; 00398 case GAPC_SECURITY_REQ: // Start security request procedure 00399 break; 00400 case GAPC_GET_CON_CHANNEL_MAP: // Retrieve Connection Channel MAP. 00401 break; 00402 } 00403 } 00404 /** 00405 **************************************************************************************** 00406 * @brief Debugging message output to hostpc. 00407 * @param[in] output char array pointer 00408 **************************************************************************************** 00409 */ 00410 void BleMsgHandler::HostPcPrint(char *str) 00411 { 00412 if(print_flag == 1) 00413 hostpc->printf("%s",str); 00414 } 00415 /** 00416 **************************************************************************************** 00417 * @brief Receive test method 00418 **************************************************************************************** 00419 */ 00420 void BleMsgHandler::ReceiveToSerialTest(void) 00421 { 00422 SerialM->ReceiveToSerialTest(); 00423 } 00424 /** 00425 **************************************************************************************** 00426 * @brief Receive and Store Da14583 flash data. 00427 * @param[in] mbed binary file size 00428 * @param[in] mbed binary version string 00429 **************************************************************************************** 00430 */ 00431 void BleMsgHandler::FirmwareDataReceive(unsigned short code_size, char *version) 00432 { 00433 unsigned short stored_data_cnt = 0; 00434 char path[20]="/local/"; 00435 char databuf[FIRMWARE_DATA_FRAGMENT_SIZE]="/local/"; 00436 if(print_flag == 1) 00437 hostpc->printf("\n!!File name = %s!! code_size = %d\n",version,code_size); 00438 strcat(databuf, version); 00439 strcat(databuf, ".BIN"); 00440 hostpc->printf("\n!!name = %s!\n",databuf); 00441 00442 00443 DIR *d = opendir("/local/"); 00444 struct dirent *p; 00445 while ((p = readdir(d)) != NULL) 00446 { 00447 hostpc->printf("%s,%d\n", p->d_name,strcmp(strchr(p->d_name,'.')+1,"BIN")); 00448 if( strcmp(strchr(p->d_name,'.')+1,"BIN") == 0 ){ 00449 strcat(path,p->d_name); 00450 hostpc->printf("%s\n",path); 00451 remove(path); 00452 strcpy(path,"/local/"); 00453 } 00454 } 00455 closedir(d); 00456 00457 fp = fopen(databuf, "w"); 00458 00459 SerialM->DataReceive((uint8_t*)databuf,2); 00460 if(databuf[0] == 0x80 && databuf[1] == 0x46 ){ 00461 if(print_flag == 1) 00462 hostpc->printf("\n!!Firmware Data Transmition Start!!\n"); 00463 }else{ 00464 if(print_flag == 1) 00465 hostpc->printf("\n!!Firmware Data Transmition ERROR!!\n"); 00466 } 00467 00468 memset(databuf,0,FIRMWARE_DATA_FRAGMENT_SIZE); 00469 00470 while( stored_data_cnt < code_size ) 00471 { 00472 if( code_size - stored_data_cnt >= FIRMWARE_DATA_FRAGMENT_SIZE ){ 00473 SerialM->DataReceive((uint8_t*)databuf,FIRMWARE_DATA_FRAGMENT_SIZE); 00474 fwrite(databuf, 1, FIRMWARE_DATA_FRAGMENT_SIZE, fp); 00475 stored_data_cnt += FIRMWARE_DATA_FRAGMENT_SIZE; 00476 }else{ 00477 SerialM->DataReceive((uint8_t*)databuf, code_size - stored_data_cnt); 00478 fwrite(databuf, 1, code_size - stored_data_cnt, fp); 00479 stored_data_cnt = code_size ; 00480 } 00481 memset(databuf,0,FIRMWARE_DATA_FRAGMENT_SIZE); 00482 } 00483 00484 SerialM->DataReceive((uint8_t*)databuf,2); 00485 if(databuf[0] == 0x80 && databuf[1] == 0x46 ){ 00486 if(print_flag == 1) 00487 hostpc->printf("\n!!Firmware Data Transmition END!!\n"); 00488 }else{ 00489 if(print_flag == 1) 00490 hostpc->printf("\n!!Firmware Data Transmition END ERROR!!\n"); 00491 } 00492 fclose(fp); 00493 wait(5); 00494 if(print_flag == 1) 00495 hostpc->printf("\n!!RESET MBED!!\n"); 00496 mbed_reset(); 00497 } 00498 00499 00500 00501 00502 }//namespace 00503 /// @} ext_fota module
Generated on Tue Jul 12 2022 16:20:47 by 1.7.2