コード例 #1
0
ファイル: dfu_transport_serial.c プロジェクト: tkadom/TWBLE
static void process_dfu_packet(void * p_event_data, uint16_t event_size)
{
    uint32_t              retval;
    uint32_t              index;
    dfu_update_packet_t * packet;

        while (false == DATA_QUEUE_EMPTY())
        {
            // Fetch the element to be processed.
            for (index = 0; index < MAX_BUFFERS ; index++)
            {
                packet = &m_data_queue.data_packet[index];
                if (INVALID_PACKET != packet->packet_type)
                {

                    switch (DATA_QUEUE_ELEMENT_GET_PTYPE(index))
                    {
                        case DATA_PACKET:
                            (void)dfu_data_pkt_handle(packet);
                            break;

                        case START_PACKET:
                            packet->params.start_packet = 
                                (dfu_start_packet_t*)packet->params.data_packet.p_data_packet;
                            retval = dfu_start_pkt_handle(packet);
                            APP_ERROR_CHECK(retval);
                            break;

                        case INIT_PACKET:
                            (void)dfu_init_pkt_handle(packet);
                            retval = dfu_init_pkt_complete();
                            APP_ERROR_CHECK(retval);
                            break;

                        case STOP_DATA_PACKET:
                            (void)dfu_image_validate();
                            (void)dfu_image_activate();

                            // Break the loop by returning.
                            return;

                        default:
                            // No implementation needed.
                            break;
                    }

                    // Free the processed element.
                    retval = data_queue_element_free(index);
                    APP_ERROR_CHECK(retval);
                }
            }
        }
}
コード例 #2
0
ファイル: dfu_transport_ble.c プロジェクト: 1072258106/duband
/**@brief     Function for processing initialization data written by the peer to the DFU Packet
 *            Characteristic.
 *
 * @param[in] p_dfu DFU Service Structure.
 * @param[in] p_evt Pointer to the event received from the BLE stack.
 */
static void init_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    uint32_t            err_code;
    uint8_t             num_of_padding_bytes = 0;
    dfu_update_packet_t dfu_pkt;

    dfu_pkt.packet_type   = INIT_PACKET;

    dfu_pkt.p_data_packet = (uint32_t *) p_evt->evt.ble_dfu_pkt_write.p_data;

    // The DFU module accepts the dfu_pkt.packet_length to be in 'number of words'. And so if the
    // received data does not have a size which is a multiple of four, it should be padded with
    // zeros and the packet_length should be incremented accordingly before calling
    // dfu_init_pkt_handle.
    if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0)
    {
         // Find out the number of bytes to be padded.
         num_of_padding_bytes = sizeof(uint32_t)
                                -
                                (p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1));

         uint8_t i;
         for (i = 0; i < num_of_padding_bytes; i++)
         {
             dfu_pkt.p_data_packet[p_evt->evt.ble_dfu_pkt_write.len + i] = 0;
         }
    }

    dfu_pkt.packet_length = (p_evt->evt.ble_dfu_pkt_write.len + num_of_padding_bytes)
                            / sizeof(uint32_t);

    err_code = dfu_init_pkt_handle(&dfu_pkt);

    // Translate the err_code returned by the above function to DFU Response Value.
    ble_dfu_resp_val_t resp_val;

    resp_val = nrf_error_to_dfu_resp_val(err_code, BLE_DFU_INIT_PROCEDURE);

    err_code = ble_dfu_response_send(p_dfu, BLE_DFU_INIT_PROCEDURE, resp_val);
    APP_ERROR_CHECK(err_code);
}
コード例 #3
0
/**@brief     Function for processing start data written by the peer to the DFU Packet
 *            Characteristic.
 *
 * @param[in] p_dfu     DFU Service Structure.
 * @param[in] p_evt     Pointer to the event received from the S110 SoftDevice.
 */
static void start_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    uint32_t err_code;
    
    dfu_start_packet_t start_packet   = {.dfu_update_mode = m_update_mode};    
    dfu_update_packet_t update_packet =
    {
        .packet_type         = START_PACKET,
        .params.start_packet = &start_packet
    };
    
    uint32_t length = p_evt->evt.ble_dfu_pkt_write.len;

    // Verify that the data is exactly three * four bytes (three words) long.
    // Or a single word to support backwards compatibility of application image transfer.
    if ((length != (3 * sizeof(uint32_t))) && (length != sizeof(uint32_t)))
    {
        err_code = ble_dfu_response_send(p_dfu,
                                         BLE_DFU_START_PROCEDURE,
                                         BLE_DFU_RESP_VAL_NOT_SUPPORTED);
        APP_ERROR_CHECK(err_code);
    }
    else
    {
        // Extract the size of from the DFU Packet Characteristic.
        uint8_t * length_data = p_evt->evt.ble_dfu_pkt_write.p_data;

        if (length == sizeof(uint32_t))
        {
            // Legacy update.
            start_packet.sd_image_size  = 0;
            start_packet.bl_image_size  = 0;
            start_packet.app_image_size = uint32_decode(length_data);
        }
        else
        {
            start_packet.sd_image_size  = uint32_decode(length_data);
            start_packet.bl_image_size  = uint32_decode(length_data + 4);
            start_packet.app_image_size = uint32_decode(length_data + 8);
        }

        err_code = dfu_start_pkt_handle(&update_packet);
        if (err_code != NRF_SUCCESS)
        {
            // Translate the err_code returned by the above function to DFU Response Value.
            ble_dfu_resp_val_t resp_val;

            resp_val = nrf_err_code_translate(err_code, BLE_DFU_START_PROCEDURE);

            err_code = ble_dfu_response_send(p_dfu, BLE_DFU_START_PROCEDURE, resp_val);
        }

        APP_ERROR_CHECK(err_code);
    }
}


/**@brief     Function for processing initialization data written by the peer to the DFU Packet
 *            Characteristic.
 *
 * @param[in] p_dfu     DFU Service Structure.
 * @param[in] p_evt     Pointer to the event received from the S110 SoftDevice.
 */
static void init_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    uint32_t            err_code;
    dfu_update_packet_t dfu_pkt;
    uint8_t             num_of_padding_bytes = 0;    

    dfu_pkt.packet_type   = INIT_PACKET;

    dfu_pkt.params.data_packet.p_data_packet = (uint32_t *)p_evt->evt.ble_dfu_pkt_write.p_data;

    // The DFU module accepts the dfu_pkt.packet_length to be in 'number of words'. And so if the
    // received data does not have a size which is a multiple of four, it should be padded with
    // zeros and the packet_length should be incremented accordingly before calling
    // dfu_init_pkt_handle.
    if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0)
    {
         // Find out the number of bytes to be padded.
         num_of_padding_bytes = sizeof(uint32_t)
                                -
                                (p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1));

         uint32_t i;
         for (i = 0; i < num_of_padding_bytes; i++)
         {
             dfu_pkt.params.data_packet.p_data_packet[p_evt->evt.ble_dfu_pkt_write.len + i] = 0;
         }
    }

    dfu_pkt.params.data_packet.packet_length = 
        (p_evt->evt.ble_dfu_pkt_write.len + num_of_padding_bytes) / sizeof(uint32_t);

    err_code = dfu_init_pkt_handle(&dfu_pkt);

    // Translate the err_code returned by the above function to DFU Response Value.
    ble_dfu_resp_val_t resp_val;

    resp_val = nrf_err_code_translate(err_code, BLE_DFU_INIT_PROCEDURE);

    err_code = ble_dfu_response_send(p_dfu, BLE_DFU_INIT_PROCEDURE, resp_val);
    APP_ERROR_CHECK(err_code);
}
コード例 #4
0
ファイル: dfu_transport_ant.c プロジェクト: IOIOI/nRF51
/**@brief Function for processing ANTFS upload request data event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_upload_request_handle(const antfs_event_return_t * p_event)
{
    uint32_t    err_code = RESPONSE_MESSAGE_OK;
    uint8_t     new_request = false;

    if ((m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_ERASE) || (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING))
    {
        return;
    }

    /*reset*/
    m_response_info.file_index.data           = p_event->file_index;
    m_response_info.max_burst_block_size.data = 0;
    m_response_info.max_file_size             = 0;
    m_response_info.file_size.data            = 0;
    m_response_info.file_crc                  = 0;

    // Evaluate File Index first
    if (m_current_file_index != p_event->file_index )
    {
        m_current_file_index = p_event->file_index;
        m_current_offset                        = 0;
        m_current_crc                           = 0;
    }

    if (p_event->offset == MAX_ULONG)
    {
        // This is a request to continue upload.
    }
    else if (p_event->offset == 0x00)
    {
        new_request = true;
    }
    else if(p_event->offset != m_current_offset)
    {
        // Something is wrong.
        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
        m_antfs_dfu_state = ANTFS_DFU_STATE_STALL;
    }
    else
    {
        // no implementation.
    }

    switch (m_current_file_index)
    {
#if !defined (S210_V3_STACK)
        case ANTFS_FILE_INDEX_UPDATE_STACK:
        case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER:
        case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER:
#endif // S210_V3_STACK
        case ANTFS_FILE_INDEX_UPDATE_APPLICATION:
        {
            // Current valid file size is the last offset written to the file.
            m_response_info.file_size.data            = m_current_offset;
            // Intentionally report maximum allowed upload file size as max writeable file size + header and crc.
            // Writeable size check will be performed by dfu_start_pkt_handle() after parsing uploaded header
            m_response_info.max_file_size             = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Maximum burst block should be maximum allowable downloadable file size.
            m_response_info.max_burst_block_size.data = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Last valid CRC.
            m_response_info.file_crc                  = m_current_crc;

            // Will only handle upload request while at ANTFS_DFU_STATE_READY
            if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED)
            {
                if (new_request)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                }
                else
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));                 // To handle resume at end of data.
                }
                return;
            }
            else if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY)
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                return;
            }

            // Check File Size if it can still fit. Uploaded file size may be larger than the total writeable space because it includes header
            // and CRC that do not get written to flash. Writeable size check will be performed by dfu_start_pk_handle() after
            // parsing uploaded header
            if ((p_event->offset + p_event->bytes) > (ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX + OTA_IMAGE_CRC_SIZE_MAX))
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_ENOUGH_SPACE, &m_response_info));
                return;
            }

            m_data_buffered         = 0;

            if (new_request)
            {
                m_current_offset    = 0;
                m_current_crc       = 0;
                m_pending_offset    = 0;

                antfs_ota_init();

                // Only supports offset starting at 0;
                if (p_event->offset != 0)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    return;
                }

//                boot_return_set(PARAM_RETURN_BOOT_STATUS_Entered);

                // Store file size,
                m_current_file_size     = p_event->bytes;

                if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK)
                {
                    m_update_mode = DFU_UPDATE_SD;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_BL;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_APPLICATION)
                {
                    m_update_mode = DFU_UPDATE_APP;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_SD;
                    m_update_mode |= DFU_UPDATE_BL;//lint !e655 suppress Lint Warning 655: Bit-wise operations
                }

                m_dfu_pkt.packet_type = INIT_PACKET;

                if ((*ANT_BOOT_APP_SIZE > DFU_IMAGE_MAX_SIZE_BANKED)    ||
                    (*ANT_BOOT_APP_SIZE == 0xFFFFFFFF)                  ||
                    (*ANT_BOOT_APP_SIZE == 0x00000000)                  ||
                    (m_update_mode & DFU_UPDATE_SD))/*lint !e655 suppress Lint Warning 655: Bit-wise operations*/
                {
                    m_dfu_pkt.params.init_packet.total_image_size = DFU_IMAGE_MAX_SIZE_FULL;
                }
                else
                {
                    m_dfu_pkt.params.init_packet.total_image_size = m_current_file_size;
                }

                if (m_upload_swap_space_prepared == true)
                {
                    // Prepare no flash, except the states
                    m_dfu_pkt.params.init_packet.total_image_size = 0;
                }

                err_code = dfu_init_pkt_handle(&m_dfu_pkt);
                if (err_code)
                {
                    if (err_code == NRF_ERROR_INVALID_STATE)
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
                    }
                    else
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    }
                    return;
                }

                m_ota_image_header_parsed   = false;
                m_image_data_complete       = false;
                m_image_data_offset         = 0;

                m_data_buffered             = 0;

                // A flash erase is expected at this time. postpone response if there is.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_ERASE;
                    return;
                }
            }
            else
            {
                // Check if there are still pending writes scheduled in Flash.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                    return;
                }
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
        }
            break;
        default:
            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_EXIST, &m_response_info));
    }
}