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 KIM HyoengJun

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BleMsgHandler.cpp Source File

BleMsgHandler.cpp

Go to the documentation of this file.
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