/**@brief Function for handling the callback events from the dfu module. * Callbacks are expected when \ref dfu_data_pkt_handle has been executed. * * @param[in] packet Packet type for which this callback is related. * @param[in] result Operation result code. NRF_SUCCESS when a queued operation was successful. * @param[in] p_data Pointer to the data to which the operation is related. */ static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data) { switch (packet) { ble_dfu_resp_val_t resp_val; uint32_t err_code; case DATA_PACKET: if (result != NRF_SUCCESS) { // Disconnect from peer. if (IS_CONNECTED()) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); } } else { err_code = hci_mem_pool_rx_consume(p_data); APP_ERROR_CHECK(err_code); // If the callback matches final data packet received then the peer is notified. if (mp_final_packet == p_data) { // Notify the DFU Controller about the success of the procedure. err_code = ble_dfu_response_send(&m_dfu, BLE_DFU_RECEIVE_APP_PROCEDURE, BLE_DFU_RESP_VAL_SUCCESS); APP_ERROR_CHECK(err_code); } } break; case START_PACKET: // Translate the err_code returned by the above function to DFU Response Value. resp_val = nrf_err_code_translate(result, BLE_DFU_START_PROCEDURE); err_code = ble_dfu_response_send(&m_dfu, BLE_DFU_START_PROCEDURE, resp_val); APP_ERROR_CHECK(err_code); break; default: // ignore. break; } }
/**@brief Function for handling the callback events from the dfu module. * Callbacks are expected when \ref dfu_data_pkt_handle has been executed. * * @param[in] packet Packet type for which this callback is related. * @param[in] result Operation result code. NRF_SUCCESS when a queued operation was successful. * @param[in] p_data Pointer to the data to which the operation is related. */ static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data) { switch (packet) { ble_dfu_resp_val_t resp_val; uint32_t err_code; case DATA_PACKET: if (result != NRF_SUCCESS) { // Disconnect from peer. if (IS_CONNECTED()) { err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(err_code); } } else { err_code = hci_mem_pool_rx_consume(p_data); APP_ERROR_CHECK(err_code); } break; case START_PACKET: // Translate the err_code returned by the above function to DFU Response Value. resp_val = nrf_err_code_translate(result, BLE_DFU_START_PROCEDURE); err_code = ble_dfu_response_send(&m_dfu, BLE_DFU_START_PROCEDURE, resp_val); APP_ERROR_CHECK(err_code); break; default: // ignore. break; } }
/**@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); } }
uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer) { return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE)); }