Exemplo n.º 1
0
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 STOP_DATA_PACKET:
                            (void)dfu_image_validate();
                            (void)dfu_image_activate();

                            // Break the loop by returning.
                            return;

                        case INIT_PACKET:
                            // Validate init packet.
                            // We expect to receive the init packet in two rounds of 512 bytes.
                            // If that fails, we abort, and boot the application.
                            // @note: Current release doesn't handle an init packet.

                            break;

                        default:
                            // No implementation needed.
                            break;
                    }

                    // Free the processed element.
                    retval = data_queue_element_free(index);
                    APP_ERROR_CHECK(retval);                    
                }
            }
        }
}
Exemplo n.º 2
0
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);
                }
            }
        }
}
Exemplo n.º 3
0
/**@brief     Function for processing application 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 app_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    uint32_t err_code;

    if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0)
    {
        // Data length is not a multiple of 4 (word size).
        err_code = ble_dfu_response_send(p_dfu,
                                         BLE_DFU_RECEIVE_APP_PROCEDURE,
                                         BLE_DFU_RESP_VAL_NOT_SUPPORTED);
        APP_ERROR_CHECK(err_code);
        return;
    }

    uint32_t length = p_evt->evt.ble_dfu_pkt_write.len;
    
    err_code = hci_mem_pool_rx_produce(length, (void**) &mp_rx_buffer);
    if (err_code != NRF_SUCCESS)
    {
        dfu_error_notify(p_dfu, err_code);
        return;
    }
    
    uint8_t * p_data_packet = p_evt->evt.ble_dfu_pkt_write.p_data;
    memcpy(mp_rx_buffer, p_data_packet, length);

    err_code = hci_mem_pool_rx_data_size_set(length);
    if (err_code != NRF_SUCCESS)
    {
        dfu_error_notify(p_dfu, err_code);
        return;
    }

    err_code = hci_mem_pool_rx_extract(&mp_rx_buffer, &length);
    if (err_code != NRF_SUCCESS)
    {
        dfu_error_notify(p_dfu, err_code);
        return;
    }

    dfu_update_packet_t dfu_pkt;

    dfu_pkt.packet_type                      = DATA_PACKET;
    dfu_pkt.params.data_packet.packet_length = length / sizeof(uint32_t);
    dfu_pkt.params.data_packet.p_data_packet = (uint32_t*)mp_rx_buffer;
    
    err_code = dfu_data_pkt_handle(&dfu_pkt);

    if (err_code == NRF_SUCCESS)
    {
        // All the expected firmware data has been received and processed successfully.

        m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len;

        // Notify the DFU Controller about the success about the procedure.
        err_code = ble_dfu_response_send(p_dfu,
                                         BLE_DFU_RECEIVE_APP_PROCEDURE,
                                         BLE_DFU_RESP_VAL_SUCCESS);
        APP_ERROR_CHECK(err_code);
    }
    else if (err_code == NRF_ERROR_INVALID_LENGTH)
    {
        // Firmware data packet was handled successfully. And more firmware data is expected.
        m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len;

        // Check if a packet receipt notification is needed to be sent.
        if (m_pkt_rcpt_notif_enabled)
        {
            // Decrement the counter for the number firmware packets needed for sending the
            // next packet receipt notification.
            m_pkt_notif_target_cnt--;

            if (m_pkt_notif_target_cnt == 0)
            {
                err_code = ble_dfu_pkts_rcpt_notify(p_dfu, m_num_of_firmware_bytes_rcvd);
                APP_ERROR_CHECK(err_code);

                // Reset the counter for the number of firmware packets.
                m_pkt_notif_target_cnt = m_pkt_notif_target;
            }
        }
    }
    else
    {
        uint32_t hci_error = hci_mem_pool_rx_consume(mp_rx_buffer);
        if (hci_error != NRF_SUCCESS)
        {
            dfu_error_notify(p_dfu, hci_error);
        }
        
        dfu_error_notify(p_dfu, err_code);
    }
}
Exemplo n.º 4
0
/**@brief Function for processing ANTFS upload data event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_upload_data_handle(const antfs_event_return_t * p_event)
{
    static uint8_t *        p_rxd_data;
    static uint32_t         rxd_data_size;
    uint32_t                err_code = NRF_SUCCESS;
    ota_image_header_t *    p_ota_image_header;

     // Allocate a memory pool for upload buffering.
    if (m_data_buffered == 0)
    {
        // Check which pool is empty.
        if (m_mem_pool_1.size == 0)
        {
            mp_buffering_handle = &m_mem_pool_1;
        }
        else if (m_mem_pool_2.size == 0)
        {
            mp_buffering_handle = &m_mem_pool_2;
        }
        else
        {
            // something is wrong.
            dfu_error_notify(err_code, 6);
        }
        mp_rx_buffer = &mp_buffering_handle->a_mem_pool[0];
    }

    if ((p_event->bytes + m_data_buffered) < ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)
    {
        // Copy over the buffer the rx'd 8 byte data
        memcpy(mp_rx_buffer + m_data_buffered, p_event->data, p_event->bytes);
        // Advance buffered count
        m_data_buffered += p_event->bytes;
        // Advance current over all data count.
    }
    else
    {
        // something is wrong.
        dfu_error_notify(err_code, 7);
    }

    if ((m_data_buffered >= ANTFS_UPLOAD_DATA_BUFFER_MIN_SIZE) ||
            ((m_pending_offset + m_data_buffered) >= m_current_file_size))
    {
        /* If any of the pool is still pending process and we are running out of space
        * The ANTFS_UPLOAD_DATA_BUFFER_MIN_SIZE should be enough delay to get the previous buffer be processed, including flashing*/
        if (((m_mem_pool_1.size != 0) || (m_mem_pool_2.size != 0)) && ((m_pending_offset + m_data_buffered) < m_current_file_size))
        {
            if (m_data_buffered < ANTFS_UPLOAD_DATA_BUFFER_MAX_SIZE)
            {   // We can wait for a bit.
                return;
            }
            else
            {
                // Something is wrong. the device is not flashing.
                upload_data_response_fail_reset();
                return;
            }
        }

        mp_buffering_handle->size   = m_data_buffered;          // Set the size and consider this pool closed and ready for processing.
        m_data_buffered             = 0;                        // Reset buffered data count

        // Decide what to do with the data in the buffer.
        switch (m_current_file_index)
        {
            case ANTFS_FILE_INDEX_UPDATE_STACK:
            case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER:
            case ANTFS_FILE_INDEX_UPDATE_APPLICATION:
            case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER:

                // Not in the right state
                if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY)
                {
                    // Throw it away.
                    mp_buffering_handle->size   = 0;
                    mp_buffering_handle         = NULL;

                    upload_data_response_fail_reset();
                    return;
                }

                p_rxd_data      = mp_buffering_handle->a_mem_pool;
                rxd_data_size   = mp_buffering_handle->size;

                // pre calculate pending offset
                m_pending_offset  = m_pending_offset + rxd_data_size;

                /***********
                 * Header Section
                 */
                if (!m_ota_image_header_parsed)
                {
                    // Parse the Header
                    if (antfs_ota_image_header_parsing(&p_rxd_data, &rxd_data_size))
                    {
                        m_ota_image_header_parsed = true;
                        p_ota_image_header = antfs_ota_image_header_get();
                    }
                    else
                    {
                        return;                                         // Get more
                    }

                    if ((p_ota_image_header == NULL)                                                        ||  // Make sure it is a valid header
                        (p_ota_image_header->architecture_identifier != OTA_IMAGE_ARCH_IDENTIFIER_ST_BL_AP) ||  // Make sure it is SD BL and AP arch
                        (p_ota_image_header->image_format != OTA_IMAGE_IMAGE_FORMAT_BINARY))                    // Make sure it is in Binary format
                    {
                        // Invalid header, fail now.
                        upload_data_response_fail_reset();
                        return;
                    }

                    // Fill in DFU parameters
                    m_dfu_pkt.params.start_packet.dfu_update_mode   = m_update_mode;
                    m_dfu_pkt.params.start_packet.sd_image_size     = p_ota_image_header->wireless_stack_size;
                    m_dfu_pkt.params.start_packet.bl_image_size     = p_ota_image_header->bootloader_size;
                    m_dfu_pkt.params.start_packet.app_image_size    = p_ota_image_header->application_size;
                    m_dfu_pkt.params.start_packet.info_bytes_size   = OTA_IMAGE_CRC_SIZE_MAX;

                    err_code = dfu_start_pkt_handle(&m_dfu_pkt);        // reinitializing dfu pkt
                    if (err_code)
                    {
                        upload_data_response_fail_reset();
                        return;
                    }

                    m_image_data_max    = p_ota_image_header->wireless_stack_size   +
                                          p_ota_image_header->bootloader_size       +
                                          p_ota_image_header->application_size      +
                                          OTA_IMAGE_CRC_SIZE_MAX;
                    m_header_crc_seed   = antfs_ota_image_header_crc_get();
                    m_current_crc       = m_header_crc_seed;
                    m_current_offset    = p_ota_image_header->header_size;
                }

                /***********
                 * Image Section
                 */
                if (!m_image_data_complete)
                {
                    m_upload_swap_space_prepared = false;

                    m_dfu_pkt.params.data_packet.p_data_packet  = (uint32_t*) p_rxd_data;
                    m_dfu_pkt.params.data_packet.packet_length  = rxd_data_size / sizeof(uint32_t);

                    // store flushed information for flash write verification.
                    mp_buffering_handle->size                   = rxd_data_size;
                    mp_buffering_handle->crc                    = crc_crc16_update(0, p_rxd_data, rxd_data_size);

                    // Pass the image to dfu.
                    m_dfu_pkt.packet_type        = DATA_PACKET;
                    err_code = dfu_data_pkt_handle(&m_dfu_pkt);
                    if (err_code == NRF_SUCCESS)
                    {
                        // All the expected firmware image has been received and processed successfully.
                        m_image_data_complete = true;
                    }
                    else if (err_code == NRF_ERROR_INVALID_LENGTH)
                    {
                        // The image is still partially completed. We need more.
                        //do nothing;
                    }
                    // Unmanaged return code. Something is wrong need to abort.
                    else
                    {
                        //TODO Need to figure out what to do on unmanaged returns. Maybe reset
                        dfu_error_notify(err_code, 9);
                    }
                }

                m_antfs_dfu_state = ANTFS_DFU_STATE_READY;

                break;

            default:
                mp_buffering_handle->size = 0;
                break;
        }
    }
}
Exemplo n.º 5
0
/**@brief     Function for processing application 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 app_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    uint32_t err_code;

    if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0)
    {
        // Data length is not a multiple of 4 (word size).

        err_code = ble_dfu_response_send(p_dfu,
                                         BLE_DFU_RECEIVE_APP_PROCEDURE,
                                         BLE_DFU_RESP_VAL_NOT_SUPPORTED);
        APP_ERROR_CHECK(err_code);
        return;
    }

    dfu_update_packet_t dfu_pkt;

    dfu_pkt.packet_type   = DATA_PACKET;
    dfu_pkt.packet_length = p_evt->evt.ble_dfu_pkt_write.len / sizeof(uint32_t);
    dfu_pkt.p_data_packet = (uint32_t *)p_evt->evt.ble_dfu_pkt_write.p_data;

    err_code = dfu_data_pkt_handle(&dfu_pkt);

    if (err_code == NRF_SUCCESS)
    {
        // All the expected firmware data has been received and processed successfully.

        m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len;

        // Notify the DFU Controller about the success about the procedure.
        err_code = ble_dfu_response_send(p_dfu,
                                         BLE_DFU_RECEIVE_APP_PROCEDURE,
                                         BLE_DFU_RESP_VAL_SUCCESS);
        APP_ERROR_CHECK(err_code);
    }
    else if (err_code == NRF_ERROR_INVALID_LENGTH)
    {
        // Firmware data packet was handled successfully. And more firmware data is expected.
        m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len;

        // Check if a packet receipt notification is needed to be sent.
        if (m_pkt_rcpt_notif_enabled)
        {
            // Decrement the counter for the number firmware packets needed for sending the
            // next packet receipt notification.
            m_pkt_notif_target_cnt--;

            if (m_pkt_notif_target_cnt == 0)
            {
                err_code = ble_dfu_pkts_rcpt_notify(p_dfu, m_num_of_firmware_bytes_rcvd);
                APP_ERROR_CHECK(err_code);

                // Reset the counter for the number of firmware packets.
                m_pkt_notif_target_cnt = m_pkt_notif_target;
            }
        }
    }
    else
    {
        // An error has occurred. Notify the DFU Controller about this error condition.
        // Translate the err_code returned to DFU Response Value.
        ble_dfu_resp_val_t resp_val;

        resp_val = nrf_error_to_dfu_resp_val(err_code, BLE_DFU_RECEIVE_APP_PROCEDURE);

        err_code = ble_dfu_response_send(p_dfu,
                                         BLE_DFU_RECEIVE_APP_PROCEDURE,
                                         resp_val);
        APP_ERROR_CHECK(err_code);
    }
}