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

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.

dialog_fota/app.cpp

Committer:
dudnwjs
Date:
2015-08-24
Revision:
11:1ed93accb3fb
Parent:
9:fcf91f563147

File content as of revision 11:1ed93accb3fb:

/**
 * @file app.cpp
 * @brief Application entry point
 * Copyright 2015 SEVENCORE Co., Ltd.
 *
 * @author HyeongJun Kim 
 * @version 1.0.0  
 * @date 2015-08-17
*/
#include "app.h"
#include "gapm_task.h"
#include "dialog_fota_config.h"
#include "diss_task.h"
#include "fota_server_task.h"

namespace sevencore_fota{
/**
 ****************************************************************************************
 * @addtogroup dialog_fota module
 * @brief Application entry point function definition.
 *
 * @{
 ****************************************************************************************
 */ 
struct app_env_tag app_env;
/**
 ****************************************************************************************
 * @brief Send Reset request to GAPM task.
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_rst_gap(BleMsgHandler *BMH)
{
    struct gapm_reset_cmd gm_cmd;
    gm_cmd.operation = GAPM_RESET;
    
    app_env.state = APP_IDLE;
    app_env.num_of_devices = 0;
    for (int i=0; i < MAX_SCAN_DEVICES; i++)
    {
        app_env.devices[i].free = true;
        app_env.devices[i].adv_addr.addr[0] = '\0';
        app_env.devices[i].data[0] = '\0';
        app_env.devices[i].data_len = 0;
        app_env.devices[i].rssi = 0;
    }
    
    uint8_t *msg;
    unsigned short msg_size = 1+sizeof(ble_hdr) + sizeof(gapm_reset_cmd);
    msg = new uint8_t[msg_size];
    BMH->BleMsgAlloc(GAPM_RESET_CMD, TASK_GAPM, TASK_GTL,
                        sizeof(struct gapm_reset_cmd),&gm_cmd,msg);    
    
    BMH->BleSendMsg(msg,msg_size);

    return;
}
/**
 ****************************************************************************************
 * @brief Send enable request to DISS profile task.
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_diss_db_create(BleMsgHandler* BMH)
{
    uint8_t *msg;
    // Add DIS in the database
    struct diss_create_db_req req;
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(struct diss_create_db_req);
    req.features = (DIS_MANUFACTURER_NAME_CHAR_SUP|DIS_MODEL_NB_STR_CHAR_SUP|DIS_SERIAL_NB_STR_CHAR_SUP);
    
    msg = new uint8_t[msg_size];
    
    BMH->BleMsgAlloc(DISS_CREATE_DB_REQ,TASK_DISS, TASK_GTL,sizeof(struct diss_create_db_req),&req,msg);
    BMH->BleSendMsg(msg,msg_size);
}
/**
 ****************************************************************************************
 * @brief Send enable request to FOTA profile task.
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_fota_server_db_create(BleMsgHandler* BMH)
{
    uint8_t *msg;
    // Add DIS in the database
    struct fota_server_create_db_req req;
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(struct fota_server_create_db_req);
    req.features = 0x01FF;
    
    msg = new uint8_t[msg_size];
    
    BMH->BleMsgAlloc(FOTA_SERVER_CREATE_DB_REQ,TASK_FOTA_SERVER, TASK_GTL,sizeof(struct fota_server_create_db_req),&req,msg);
    BMH->BleSendMsg(msg,msg_size);
}
/**
 ****************************************************************************************
 * @brief Send Start Advertising command to GAPM task.
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_adv_start(BleMsgHandler* BMH)
{
    uint8_t device_name_length;
    uint8_t device_name_avail_space;
    uint8_t device_name_temp_buf[64];
    uint8_t *msg;
    unsigned short msg_size;
    msg_size = 1 + sizeof(ble_hdr) + sizeof(struct gapm_start_advertise_cmd);
    msg = new uint8_t[msg_size];
    
    // Allocate a message for GAP
    struct gapm_start_advertise_cmd cmd;
    cmd.op.code     = GAPM_ADV_UNDIRECT;
    cmd.op.addr_src = GAPM_PUBLIC_ADDR;
    cmd.intv_min    = APP_ADV_INT_MIN;
    cmd.intv_max    = APP_ADV_INT_MAX;
    cmd.channel_map = APP_ADV_CHMAP;
    cmd.info.host.mode = GAP_GEN_DISCOVERABLE;
    cmd.info.host.adv_data_len       = APP_ADV_DATA_MAX_SIZE;
    cmd.info.host.scan_rsp_data_len  = APP_SCAN_RESP_DATA_MAX_SIZE;

    /*-----------------------------------------------------------------------------------
     * Set the Advertising Data and the Scan Response Data
     *---------------------------------------------------------------------------------*/
    

    // Advertising Data
    #if (NVDS_SUPPORT)
    if(nvds_get(NVDS_TAG_APP_BLE_ADV_DATA, &cmd.info.host.adv_data_len,
                &cmd.info.host.adv_data[0]) != NVDS_OK)
    #endif //(NVDS_SUPPORT)
    {
        cmd.info.host.adv_data_len = APP_DFLT_ADV_DATA_LEN;
        memcpy(&cmd.info.host.adv_data[0], APP_DFLT_ADV_DATA, cmd.info.host.adv_data_len);

        //Add list of UUID
        #if (BLE_APP_HT)
        cmd.info.host.adv_data_len += APP_HT_ADV_DATA_UUID_LEN;
        memcpy(&cmd.info.host.adv_data[APP_DFLT_ADV_DATA_LEN], APP_HT_ADV_DATA_UUID, APP_HT_ADV_DATA_UUID_LEN);
        #else
            #if (BLE_APP_NEB)
            cmd.info.host.adv_data_len += APP_NEB_ADV_DATA_UUID_LEN;
            memcpy(&cmd.info.host.adv_data[APP_DFLT_ADV_DATA_LEN], APP_NEB_ADV_DATA_UUID, APP_NEB_ADV_DATA_UUID_LEN);
            #endif //(BLE_APP_NEB)
        #endif //(BLE_APP_HT)
    }

    // Scan Response Data
    #if (NVDS_SUPPORT)
    if(nvds_get(NVDS_TAG_APP_BLE_SCAN_RESP_DATA, &cmd.info.host.scan_rsp_data_len,
                &cmd.info.host.scan_rsp_data[0]) != NVDS_OK)
    #endif //(NVDS_SUPPORT)
    {
        cmd.info.host.scan_rsp_data_len = APP_SCNRSP_DATA_LENGTH;
        memcpy(&cmd.info.host.scan_rsp_data[0], APP_SCNRSP_DATA, cmd.info.host.scan_rsp_data_len);
    }

    // Get remaining space in the Advertising Data - 2 bytes are used for name length/flag
    device_name_avail_space = APP_ADV_DATA_MAX_SIZE - cmd.info.host.adv_data_len - 2;

    // Check if data can be added to the Advertising data
    if (device_name_avail_space > 0)
    {
        // Get the Device Name to add in the Advertising Data (Default one or NVDS one)
        #if (NVDS_SUPPORT)
        device_name_length = NVDS_LEN_DEVICE_NAME;
        if (nvds_get(NVDS_TAG_DEVICE_NAME, &device_name_length, &device_name_temp_buf[0]) != NVDS_OK)
        #endif //(NVDS_SUPPORT)
        {
            // Get default Device Name (No name if not enough space)
            device_name_length = strlen(APP_DFLT_DEVICE_NAME);
            memcpy(&device_name_temp_buf[0], APP_DFLT_DEVICE_NAME, device_name_length);
        }

        if(device_name_length > 0)
        {
            // Check available space
            if( device_name_length > device_name_avail_space)
                device_name_length = device_name_avail_space;

            // Fill Length
            cmd.info.host.adv_data[cmd.info.host.adv_data_len]     = device_name_length + 1;
            // Fill Device Name Flag
            cmd.info.host.adv_data[cmd.info.host.adv_data_len + 1] = '\x09';
            // Copy device name
            memcpy(&cmd.info.host.adv_data[cmd.info.host.adv_data_len + 2], device_name_temp_buf, device_name_length);

            // Update Advertising Data Length
            cmd.info.host.adv_data_len += (device_name_length + 2);
        }
    }
    
    // Send the message
    BMH->BleMsgAlloc(GAPM_START_ADVERTISE_CMD,TASK_GAPM, TASK_GTL,sizeof (struct gapm_start_advertise_cmd),&cmd,msg);
    BMH->BleSendMsg(msg, msg_size);

    return;
}
/**
 ****************************************************************************************
 * @brief Set Bondabe mode.
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_set_mode(BleMsgHandler* BMH)
{
    uint8_t *msg;
    struct gapm_set_dev_config_cmd cmd;
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(struct gapm_set_dev_config_cmd);
    msg = new uint8_t[msg_size];
    
    cmd.operation = GAPM_SET_DEV_CONFIG;
    // Device Role
    cmd.role = GAP_PERIPHERAL_SLV;
    // Device Appearance
    cmd.appearance = 0x0000;
    // Device Appearance write permission requirements for peer device
    cmd.appearance_write_perm = GAPM_WRITE_DISABLE;
    // Device Name write permission requirements for peer device
    cmd.name_write_perm = GAPM_WRITE_DISABLE;
    // Peripheral only: *****************************************************************
    // Maximum trasnimt unit size
    //cmd.max_mtu = 16;
    // Slave preferred Minimum of connection interval
    cmd.con_intv_min = 8;         // 10ms (8*1.25ms)
    // Slave preferred Maximum of connection interval
    cmd.con_intv_max = 16;        // 20ms (16*1.25ms)
    // Slave preferred Connection latency
    cmd.con_latency  = 0;
    // Slave preferred Link supervision timeout
    cmd.superv_to    = 100;
    // Privacy settings bit field
    cmd.flags = 0;
    
    BMH->BleMsgAlloc(GAPM_SET_DEV_CONFIG_CMD, TASK_GAPM, TASK_GTL,sizeof(struct gapm_set_dev_config_cmd ),&cmd, msg);
    BMH->BleSendMsg(msg,msg_size);

    return;
}
/**
 ****************************************************************************************
 * @brief Send enable request to DISS profile task.
 * @param[in] device  Ble device info
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
 void app_dis_enable(ble_dev *device,BleMsgHandler* BMH)
{
    uint8_t *msg;
    // Allocate the message
    struct diss_enable_req req;
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(diss_enable_req);
    // Fill in the parameter structure
    req.conhdl             = device->conhdl;
    req.sec_lvl            = 1;
    req.con_type           = PRF_CON_DISCOVERY;

    msg = new uint8_t[msg_size];
    
    // Send the message
    BMH->BleMsgAlloc(DISS_ENABLE_REQ,TASK_DISS, TASK_GTL, sizeof(struct diss_enable_req),&req,msg);
    BMH->BleSendMsg(msg,msg_size);
}
/**
 ****************************************************************************************
 * @brief Send enable request to FOTA profile task.
 * @param[in] device  Ble device info
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_fota_server_enable(ble_dev *device,BleMsgHandler* BMH)
{
    uint8_t *msg;
    struct fota_server_enable_req req;
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(struct fota_server_enable_req);
    req.conhdl = device->conhdl;
    req.sec_lvl = 1;
    
    msg = new uint8_t[msg_size];

    // Send the message
    BMH->BleMsgAlloc(FOTA_SERVER_ENABLE_REQ, TASK_FOTA_SERVER, TASK_GTL,sizeof(struct fota_server_enable_req),&req,msg);
    BMH->BleSendMsg(msg,msg_size);
}
/**
 ****************************************************************************************
 * @brief Send connection confirmation.
 * param[in] auth  Authentication requirements.
 * @param[in] device  Ble device info
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_connect_confirm(uint8_t auth,ble_dev *device,BleMsgHandler* BMH)
{
    uint8_t *msg;
    // confirm connection
    struct gapc_connection_cfm cfm;
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(gapc_connection_cfm);
    cfm.auth = auth;
    cfm.authorize = GAP_AUTHZ_NOT_SET;
    
    msg = new uint8_t[msg_size];

    // Send the message
    BMH->BleMsgAlloc(GAPC_CONNECTION_CFM, KE_BUILD_ID(TASK_GAPC,device->conidx), TASK_GTL,sizeof (struct gapc_connection_cfm),&cfm,msg);
    BMH->BleSendMsg(msg,msg_size);
}
/**
 ****************************************************************************************
 * @brief Send the GAPC_DISCONNECT_IND message to a task.
 * @param[in] dst     Task id of the destination task.
 * @param[in] conhdl  The conhdl parameter of the GAPC_DISCONNECT_IND message.
 * @param[in] reason  The reason parameter of the GAPC_DISCONNECT_IND message.
 * @param[in] BMH     Ble Message Handler class reference
 * @return void.
 ****************************************************************************************
 */
void app_send_disconnect(uint16_t dst, uint16_t conhdl, uint8_t reason,BleMsgHandler* BMH)
{
    uint8_t *msg;
    struct gapc_disconnect_ind disconnect_ind; 
    unsigned short msg_size = 1 + sizeof(ble_hdr) + sizeof(gapc_disconnect_ind);
    // fill parameters
    disconnect_ind.conhdl   = conhdl;
    disconnect_ind.reason   = reason;
    
    msg = new uint8_t[msg_size];

    // send indication
    BMH->BleMsgAlloc(GAPC_DISCONNECT_IND,dst, TASK_GTL,sizeof(struct gapc_disconnect_ind),&disconnect_ind,msg);
    BMH->BleSendMsg(msg,msg_size);
}

}//namespace

/// @} dialog_fota module