/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice. * * @param[in] p_dfu DFU Service Structure. * @param[in] p_ble_evt Pointer to the event received from BLE stack. */ static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) { if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle) { nrf_dfu_res_code_t res_code; nrf_dfu_req_t dfu_req; nrf_dfu_res_t dfu_res = {{{0}}}; memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); // Set req type dfu_req.req_type = NRF_DFU_OBJECT_OP_WRITE; // Set data and length dfu_req.p_req = p_ble_evt->evt.gatts_evt.params.write.data; dfu_req.req_len = p_ble_evt->evt.gatts_evt.params.write.len; res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); if(res_code != NRF_DFU_RES_CODE_SUCCESS) { NRF_LOG_INFO("Failure to run packet write\r\n"); } // Check if a packet receipt notification is needed to be sent. if (m_pkt_notif_target != 0 && --m_pkt_notif_target_cnt == 0) { (void)response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc); // Reset the counter for the number of firmware packets. m_pkt_notif_target_cnt = m_pkt_notif_target; } } }
static void on_packet_received(serial_dfu_t * p_dfu) { nrf_dfu_req_t dfu_req; nrf_dfu_res_t dfu_res = {{{0}}}; serial_dfu_response_t serial_response; memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); const serial_dfu_op_code_t op_code = (serial_dfu_op_code_t)p_dfu->recv_buffer[0]; const uint16_t packet_payload_len = p_dfu->slip.current_index - 1; uint8_t * p_payload = &p_dfu->recv_buffer[1]; serial_response.op_code = op_code; nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); nrf_gpio_pin_set(AVAILABLE_LED_PIN_NO); switch (op_code) { case SERIAL_DFU_OP_CODE_CREATE_OBJECT: if (packet_payload_len != CREATE_OBJECT_REQUEST_LEN) { serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; break; } NRF_LOG_DEBUG("Received create object\r\n"); // Reset the packet receipt notification on create object p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target; // Get type parameter dfu_req.obj_type = p_payload[0]; // Get length value dfu_req.object_size = uint32_decode(&p_payload[1]); // Set req type dfu_req.req_type = NRF_DFU_OBJECT_OP_CREATE; serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); break; case SERIAL_DFU_OP_CODE_SET_RECEIPT_NOTIF: NRF_LOG_DEBUG("Set receipt notif\r\n"); if (packet_payload_len != SET_RECEIPT_NOTIF_REQUEST_LEN) { serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; break; } p_dfu->pkt_notif_target = uint16_decode(&p_payload[0]); p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target; serial_response.resp_val = NRF_DFU_RES_CODE_SUCCESS; break; case SERIAL_DFU_OP_CODE_CALCULATE_CRC: NRF_LOG_DEBUG("Received calculate CRC\r\n"); dfu_req.req_type = NRF_DFU_OBJECT_OP_CRC; serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); serial_response.crc_response.offset = dfu_res.offset; serial_response.crc_response.crc = dfu_res.crc; break; case SERIAL_DFU_OP_CODE_EXECUTE_OBJECT: NRF_LOG_DEBUG("Received execute object\r\n"); // Set req type dfu_req.req_type = NRF_DFU_OBJECT_OP_EXECUTE; serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); break; case SERIAL_DFU_OP_CODE_SELECT_OBJECT: NRF_LOG_DEBUG("Received select object\r\n"); if (packet_payload_len != SELECT_OBJECT_REQUEST_LEN) { serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; break; } // Set object type to read info about dfu_req.obj_type = p_payload[0]; dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT; serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); serial_response.select_response.max_size = dfu_res.max_size; serial_response.select_response.offset = dfu_res.offset; serial_response.select_response.crc = dfu_res.crc; break; case SERIAL_DFU_OP_CODE_GET_SERIAL_MTU: NRF_LOG_DEBUG("Received get serial mtu\r\n"); serial_response.resp_val = NRF_DFU_RES_CODE_SUCCESS; serial_response.serial_mtu_response.mtu = sizeof(p_dfu->recv_buffer); break; case SERIAL_DFU_OP_CODE_WRITE_OBJECT: // Set req type dfu_req.req_type = NRF_DFU_OBJECT_OP_WRITE; // Set data and length dfu_req.p_req = &p_payload[0]; dfu_req.req_len = packet_payload_len; serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); if(serial_response.resp_val != NRF_DFU_RES_CODE_SUCCESS) { NRF_LOG_ERROR("Failure to run packet write\r\n"); } // Check if a packet receipt notification is needed to be sent. if (p_dfu->pkt_notif_target != 0 && --p_dfu->pkt_notif_target_count == 0) { serial_response.op_code = SERIAL_DFU_OP_CODE_CALCULATE_CRC; serial_response.crc_response.offset = dfu_res.offset; serial_response.crc_response.crc = dfu_res.crc; // Reset the counter for the number of firmware packets. p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target; } break; default: // Unsupported op code. NRF_LOG_WARNING("Received unsupported OP code\r\n"); serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; break; } if (op_code != SERIAL_DFU_OP_CODE_WRITE_OBJECT) { response_send(p_dfu, &serial_response); } }
/**@brief Function for handling a Write event on the Control Point characteristic. * * @param[in] p_dfu DFU Service Structure. * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack. * * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code. */ static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt) { nrf_dfu_res_code_t res_code; nrf_dfu_req_t dfu_req; nrf_dfu_res_t dfu_res = {{{0}}}; memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); switch (p_ble_write_evt->data[0]) { case BLE_DFU_OP_CODE_CREATE_OBJECT: if (p_ble_write_evt->len != PKT_CREATE_PARAM_LEN) { return response_send(p_dfu, BLE_DFU_OP_CODE_CREATE_OBJECT, NRF_DFU_RES_CODE_INVALID_PARAMETER); } NRF_LOG_INFO("Received create object\r\n"); // Reset the packet receipt notification on create object m_pkt_notif_target_cnt = m_pkt_notif_target; // Get type parameter //lint -save -e415 dfu_req.obj_type = p_ble_write_evt->data[1]; //lint -restore // Get length value //lint -save -e416 dfu_req.object_size = uint32_decode(&(p_ble_write_evt->data[2])); //lint -restore // Set req type dfu_req.req_type = NRF_DFU_OBJECT_OP_CREATE; res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); return response_send(p_dfu, BLE_DFU_OP_CODE_CREATE_OBJECT, res_code); case BLE_DFU_OP_CODE_EXECUTE_OBJECT: NRF_LOG_INFO("Received execute object\r\n"); // Set req type dfu_req.req_type = NRF_DFU_OBJECT_OP_EXECUTE; res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); return response_send(p_dfu, BLE_DFU_OP_CODE_EXECUTE_OBJECT, res_code); case BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF: NRF_LOG_INFO("Set receipt notif\r\n"); if (p_ble_write_evt->len != PKT_SET_PRN_PARAM_LEN) { return (response_send(p_dfu, BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, NRF_DFU_RES_CODE_INVALID_PARAMETER)); } //lint -save -e415 m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1])); //lint -restore m_pkt_notif_target_cnt = m_pkt_notif_target; return response_send(p_dfu, BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, NRF_DFU_RES_CODE_SUCCESS); case BLE_DFU_OP_CODE_CALCULATE_CRC: NRF_LOG_INFO("Received calculate CRC\r\n"); dfu_req.req_type = NRF_DFU_OBJECT_OP_CRC; res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); if (res_code == NRF_DFU_RES_CODE_SUCCESS) { return response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc); } else { return response_send(p_dfu, BLE_DFU_OP_CODE_CALCULATE_CRC, res_code); } case BLE_DFU_OP_CODE_SELECT_OBJECT: NRF_LOG_INFO("Received select object\r\n"); if (p_ble_write_evt->len != PKT_READ_OBJECT_INFO_PARAM_LEN) { return response_send(p_dfu, BLE_DFU_OP_CODE_SELECT_OBJECT, NRF_DFU_RES_CODE_INVALID_PARAMETER); } // Set object type to read info about //lint -save -e415 dfu_req.obj_type = p_ble_write_evt->data[1]; //lint -restore dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT; res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); if (res_code == NRF_DFU_RES_CODE_SUCCESS) { return response_select_object_cmd_send(p_dfu, dfu_res.max_size, dfu_res.offset, dfu_res.crc); } else { return response_send(p_dfu, BLE_DFU_OP_CODE_SELECT_OBJECT, res_code); } default: NRF_LOG_INFO("Received unsupported OP code\r\n"); // Unsupported op code. return response_send(p_dfu, p_ble_write_evt->data[0], NRF_DFU_RES_CODE_INVALID_PARAMETER); } }