void bootloader_util_settings_get(const bootloader_settings_t ** pp_bootloader_settings) { static bootloader_settings_t s_converted_boot_settings; // Depending on the configuration / version the compiler used the enums used in bootloader // settings might have different padding (half word / word padded). // Half word padding would be, bc = Bank Code enum, crc (half word), xx = byte padding: // bc0 xx crc crc - bc1 xx xx xx - rest of data // Word padding would be, bc = Bank Code enum, crc (half word), xx = byte padding: // bc0 xx xx xx - crc crc xx xx - bc1 xx xx xx - rest of data // To ensure full compability when updating from older bootloader to new, the padding must // be checked and conversion must be done accordingly. // In case of empty flash, 0xFFFFFFFF it is unimportant how settings are loaded. uint32_t pad_test = *((uint32_t *)&m_boot_settings[SIZE_TEST_INDEX]) & 0xFFFFFF00; if (pad_test == ZERO) { // Bank code enum is word sized, thus it is safe to cast without conversion. // Read only pointer to bootloader settings in flash. bootloader_settings_t const * const p_bootloader_settings = (bootloader_settings_t *)&m_boot_settings[0]; *pp_bootloader_settings = p_bootloader_settings; } else { // Bank code enum is half word sized, thus crc is following the bank code in same word. uint32_t index = 0; s_converted_boot_settings.bank_0 = (bootloader_bank_code_t)((uint16_t)(m_boot_settings[index]) & 0xFFFF); index += sizeof(uint16_t); s_converted_boot_settings.bank_0_crc = uint16_decode(&m_boot_settings[index]); index += sizeof(uint16_t); s_converted_boot_settings.bank_1 = (bootloader_bank_code_t)((uint16_t)(m_boot_settings[index]) & 0xFFFF); // Rest of settings are word sized values and thus will be aligned to next word. index += sizeof(uint32_t); s_converted_boot_settings.bank_0_size = uint32_decode(&m_boot_settings[index]);; index += sizeof(uint32_t); s_converted_boot_settings.sd_image_size = uint32_decode(&m_boot_settings[index]);; index += sizeof(uint32_t); s_converted_boot_settings.bl_image_size = uint32_decode(&m_boot_settings[index]);; index += sizeof(uint32_t); s_converted_boot_settings.app_image_size = uint32_decode(&m_boot_settings[index]);; index += sizeof(uint32_t); s_converted_boot_settings.sd_image_start = uint32_decode(&m_boot_settings[index]);; *pp_bootloader_settings = &s_converted_boot_settings; } }
/**@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 BLE stack. */ static void start_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) { uint32_t err_code; // Verify that the data is exactly four bytes (one word) long. if (p_evt->evt.ble_dfu_pkt_write.len != 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. uint32_t image_size = uint32_decode(p_evt->evt.ble_dfu_pkt_write.p_data); err_code = dfu_image_size_set(image_size); // 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_START_PROCEDURE); err_code = ble_dfu_response_send(p_dfu, BLE_DFU_START_PROCEDURE, resp_val); APP_ERROR_CHECK(err_code); } }
/**@brief Decode an incoming control point write. * * @param[in] rcvd_val received write value * @param[in] len value length * @param[out] decoded_ctrlpt decoded control point structure */ static uint32_t sc_ctrlpt_decode(uint8_t const * p_rcvd_val, uint8_t len, ble_sc_ctrlpt_val_t * p_write_val) { int pos = 0; if (len < BLE_SC_CTRLPT_MIN_LEN) { return NRF_ERROR_INVALID_PARAM; } p_write_val->opcode = (ble_scpt_operator_t) p_rcvd_val[pos++]; switch (p_write_val->opcode) { case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS: break; case BLE_SCPT_START_AUTOMATIC_CALIBRATION: break; case BLE_SCPT_UPDATE_SENSOR_LOCATION: p_write_val->location = (ble_sensor_location_t)p_rcvd_val[pos]; break; case BLE_SCPT_SET_CUMULATIVE_VALUE: p_write_val->cumulative_value = uint32_decode(&(p_rcvd_val[pos])); break; default: return NRF_ERROR_INVALID_PARAM; } return NRF_SUCCESS; }
/**@brief Callback handler to receive data on UDP port. * * @param[in] p_socket Socket identifier. * @param[in] p_ip_header IPv6 header containing source and destination addresses. * @param[in] p_udp_header UDP header identifying local and remote endpoints. * @param[in] process_result Result of data reception, there could be possible errors like * invalid checksum etc. * @param[in] iot_pbuffer_t Packet buffer containing the received data packet. * * @retval NRF_SUCCESS Indicates received data was handled successfully, else an error * code indicating reason for failure. */ uint32_t rx_udp_port_app_handler(const udp6_socket_t * p_socket, const ipv6_header_t * p_ip_header, const udp6_header_t * p_udp_header, uint32_t process_result, iot_pbuffer_t * p_rx_packet) { // APPL_LOG("[APPL]: Got UDP6 data on socket 0x%08lx\r\n", p_socket->socket_id); APP_ERROR_CHECK(process_result); // Print PORTs // APPL_LOG("[APPL]: UDP Destination port: %lx\r\n", HTONS(p_udp_header->destport)); // APPL_LOG("[APPL]: UDP Source port: %lx\r\n", HTONS(p_udp_header->srcport)); uint32_t rx_sequence_num = uint32_decode(&p_rx_packet->p_payload[0]); uint32_t ind_buff = 0; uint32_t err_code = get_packet_buffer_index(&ind_buff, &rx_sequence_num); if (err_code == NRF_ERROR_NOT_FOUND) { // Received packet sequence number is not found amongst expected packets. return NRF_SUCCESS; } if (0 == memcmp(p_rx_packet->p_payload, &m_packet_buffer[ind_buff][0], TEST_PACKET_PAYLOAD_LEN)) { // If received packet is as expected, free slot in buffer. memset(&m_packet_buffer[ind_buff][0], 0x00, TEST_PACKET_PAYLOAD_LEN); } return NRF_SUCCESS; }
/** * @brief Class specific OUT request data callback. * * @param status Endpoint status. * @param p_context Context of transfer (set by @ref app_usbd_core_setup_data_handler_set). * * @return Standard error code. */ static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) { if (status != NRF_USBD_EP_OK) { return NRF_ERROR_INTERNAL; } app_usbd_cdc_acm_t const * p_cdc_acm = p_context; app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); switch (p_cdc_acm_ctx->request.type) { case APP_USBD_CDC_REQ_SET_LINE_CODING: { memcpy(&p_cdc_acm_ctx->line_coding, &p_cdc_acm_ctx->request.payload.line_coding, sizeof(app_usbd_cdc_line_coding_t)); NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, " "format: %u, parity: %u", uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate), p_cdc_acm_ctx->line_coding.bDataBits, p_cdc_acm_ctx->line_coding.bCharFormat, p_cdc_acm_ctx->line_coding.bParityType); break; } default: return NRF_ERROR_NOT_SUPPORTED; } return NRF_SUCCESS; }
uint32_t ser_ble_cmd_rsp_result_code_dec(uint8_t const * const p_buf, uint32_t * const p_pos, uint32_t packet_len, uint8_t op_code, uint32_t * const p_result_code) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_pos); SER_ASSERT_NOT_NULL(p_result_code); if (packet_len < SER_CMD_RSP_HEADER_SIZE) { return NRF_ERROR_DATA_SIZE; } if (p_buf[(*p_pos)] != op_code) { return NRF_ERROR_INVALID_DATA; } *p_result_code = uint32_decode(&(p_buf[(*p_pos) + SER_CMD_RSP_STATUS_CODE_POS])); *p_pos += SER_CMD_RSP_HEADER_SIZE; return NRF_SUCCESS; }
static ble_ancs_c_parse_state_t notif_uid_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) { p_ancs->evt.notif_uid = uint32_decode(&p_data_src[*index]); *index += sizeof(uint32_t); return ATTR_ID; }
void ant_common_page_81_decode(uint8_t const * p_page_buffer, volatile ant_common_page81_data_t * p_page_data) { ant_common_page81_data_layout_t const * p_incoming_data = (ant_common_page81_data_layout_t *)p_page_buffer; p_page_data->sw_revision_minor = p_incoming_data->sw_revision_minor; p_page_data->sw_revision_major = p_incoming_data->sw_revision_major; p_page_data->serial_number = uint32_decode(p_incoming_data->serial_number); page81_data_log(p_page_data); }
/**@brief Function for receiving and validating notifications received from the Notification Provider. * * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. * @param[in] p_ble_evt Bluetooth stack event. * @param[in] p_data_src Pointer to data that was received from the Notification Provider. * @param[in] hvx_len Length of the data that was received by the Notification Provider. */ static void parse_notif(const ble_ancs_c_t * p_ancs, ble_ancs_c_evt_t * p_ancs_evt, const uint8_t * p_data_src, const uint16_t hvx_data_len) { uint32_t err_code; if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH) { m_ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; p_ancs->evt_handler(&m_ancs_evt); } /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ p_ancs_evt->notif.evt_id = (ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX]; p_ancs_evt->notif.evt_flags.silent = (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01; p_ancs_evt->notif.evt_flags.important = (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01; p_ancs_evt->notif.evt_flags.pre_existing = (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01; p_ancs_evt->notif.evt_flags.positive_action = (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01; p_ancs_evt->notif.evt_flags.negative_action = (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01; p_ancs_evt->notif.category_id = (ble_ancs_c_category_id_values_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX]; p_ancs_evt->notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX]; p_ancs_evt->notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]); /*lint -restore*/ err_code = ble_ancs_verify_notification_format(&m_ancs_evt.notif); if (err_code == NRF_SUCCESS) { m_ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF; } else { m_ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; } p_ancs->evt_handler(&m_ancs_evt); }
/**@brief Function for getting the index number of a stored packet or the index number of an empty * slot in the buffer. * * @details Returns the index number of a stored packet with the provided packet sequence number. * Use with INVALID_PACKET_SEQ_NUMBER as input to get the index number of the first * empty slot in the buffer. * * @param[out] p_index_number Index number of the first packet with matching sequence * number. * @param[in] pkt_seq_num Packet sequence number. * * @retval NRF_SUCCESS Matching slot found in the buffer. * @retval NRF_ERROR_NOT_FOUND No match found in the buffer. */ static uint32_t get_packet_buffer_index(uint32_t * p_index_number, uint32_t * pkt_seq_num) { uint32_t i; for (i = 0; i < PACKET_BUFFER_LEN; i++) { uint32_t rx_sequence_num = uint32_decode(&m_packet_buffer[i][0]); if (rx_sequence_num == *pkt_seq_num) { *p_index_number = i; return NRF_SUCCESS; } } *p_index_number = 0; return NRF_ERROR_NOT_FOUND; }
uint32_t uint32_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * p_field) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_index); SER_ASSERT_NOT_NULL(p_field); uint32_t * p_uint32 = (uint32_t *)p_field; SER_ASSERT_LENGTH_LEQ(4, ((int32_t)buf_len - *p_index)); *p_uint32 = uint32_decode(&p_buf[*p_index]); *p_index += 4; return NRF_SUCCESS; }
/**@brief Function for parsing command id and notification id. * Used in the @ref parse_get_notif_attrs_response state machine. * * @details UID and command ID will be received only once at the beginning of the first * GATTC notification of a new attribute request for a given iOS notification. * * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. * @param[in] p_data_src Pointer to data that was received from the Notification Provider. * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. * * @return The next parse state. */ static ble_ancs_c_parse_state_t command_id_and_notif_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) { ble_ancs_c_command_id_values_t command_id; command_id = (ble_ancs_c_command_id_values_t) p_data_src[(*index)++]; if (command_id != BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES) { NRF_LOG_INFO("Invalid Command ID"); return DONE; } p_ancs->evt.attr.notif_uid = uint32_decode(&p_data_src[*index]); *index += sizeof(uint32_t); return ATTR_ID; }
/**@brief Callback handler to receive data on UDP port. * * @param[in] p_socket Socket identifier. * @param[in] p_ip_header IPv6 header containing source and destination addresses. * @param[in] p_udp_header UDP header identifying local and remote endpoints. * @param[in] process_result Result of data reception, there could be possible errors like * invalid checksum etc. * @param[in] iot_pbuffer_t Packet buffer containing the received data packet. * * @retval NRF_SUCCESS Indicates received data was handled successfully, else an error * code indicating reason for failure. */ uint32_t rx_udp_port_app_handler(const udp6_socket_t * p_socket, const ipv6_header_t * p_ip_header, const udp6_header_t * p_udp_header, uint32_t process_result, iot_pbuffer_t * p_rx_packet) { // APPL_LOG("[APPL]: Got UDP6 data on socket 0x%08lx\r\n", p_socket->socket_id); // APPL_LOG("[APPL]: Source IPv6 Address: "); // APPL_ADDR(p_ip_header->srcaddr); APP_ERROR_CHECK(process_result); // Print PORTs // APPL_LOG("[APPL]: UDP Destination port: %lx\r\n", HTONS(p_udp_header->destport)); // APPL_LOG("[APPL]: UDP Source port: %lx\r\n", HTONS(p_udp_header->srcport)); // UDP packet received from the Client node. APPL_LOG("[APPL]: Received UDP packet sequence number: %ld\r\n", \ uint32_decode(&p_rx_packet->p_payload[0])); iot_pbuffer_alloc_param_t pbuff_param; iot_pbuffer_t * p_tx_buffer; pbuff_param.flags = PBUFFER_FLAG_DEFAULT; pbuff_param.type = UDP6_PACKET_TYPE; pbuff_param.length = p_rx_packet->length; // Allocate packet buffer. uint32_t err_code = iot_pbuffer_allocate(&pbuff_param, &p_tx_buffer); APP_ERROR_CHECK(err_code); memcpy(p_tx_buffer->p_payload, p_rx_packet->p_payload, p_rx_packet->length); // Send back the received packet payload without any modification. err_code = udp6_socket_sendto(&m_udp_socket, &p_ip_header->srcaddr, HTONS(UDP_PORT), p_tx_buffer); APP_ERROR_CHECK(err_code); m_display_state = LEDS_TX_UDP_PACKET; m_udp_tx_occured = true; return NRF_SUCCESS; }
void ble_rpc_cmd_rsp_pkt_received(uint8_t * packet, uint16_t packet_length) { uint32_t index = 0; g_cmd_response_buf = packet; if (g_cmd_response_buf[index++] != BLE_RPC_PKT_RESP) { // Received a packet that is not of interest to the command encoder. return; } g_cmd_response.op_code = g_cmd_response_buf[index++]; if (packet_length >= RPC_BLE_CMD_RESP_PKT_MIN_SIZE) { g_cmd_response.err_code = uint32_decode(&g_cmd_response_buf[index++]); } else { g_cmd_response.err_code = NRF_ERROR_INTERNAL; } }
/**@brief Function for parsing received notification attribute response data. * * @details The data that comes from the Notification Provider can be much longer than what * would fit in a single GATTC notification. Therefore, function relies on static * variables and a state-oriented switch case. * UID and command ID will be received only once at the beginning of the first * GATTC notification of a new attribute request for a given iOS notification. * After this, we can loop several ID > LENGTH > DATA > ID > LENGTH > DATA until we have * received all attributes we wanted as a Notification Consumer. The Notification Provider * can also simply stop sending attributes. * * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. * @param[in] p_data_src Pointer to data that was received from the Notification Provider. * @param[in] hvx_len Length of the data that was received from the Notification Provider. */ static void parse_get_notif_attrs_response(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, const uint16_t hvx_data_len) { static uint8_t * p_data_dest; static uint16_t current_attr_index; static ble_ancs_c_evt_t evt; ble_ancs_c_command_id_values_t command_id; uint32_t index; evt.ancs_attr_list = m_ancs_attr_list; for (index = 0; index < hvx_data_len;) { switch (m_parse_state) { case COMMAND_ID_AND_NOTIF_UID: command_id = (ble_ancs_c_command_id_values_t) p_data_src[index++]; if(command_id != BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES) { LOG("[ANCS]: Invalid Command ID"); m_parse_state = DONE; } evt.attr.notif_uid = uint32_decode(&p_data_src[index]); index += sizeof(uint32_t); m_parse_state = ATTR_ID; if (evt.attr.notif_uid != m_ancs_evt.notif.notif_uid) { LOG("UID mismatch: Notification UID %x , Attribute UID %x\n\r", evt.notif.notif_uid, evt.attr.notif_uid); m_parse_state = DONE; } break; case ATTR_ID: if (m_expected_number_of_attrs == 0) { LOG("[ANCS]: All requested attributes received\n\r"); m_parse_state = DONE; index++; } else { evt.attr.attr_id = (ble_ancs_c_notif_attr_id_values_t) p_data_src[index++]; p_data_dest = m_ancs_attr_list[evt.attr.attr_id].p_attr_data; if (m_ancs_attr_list[evt.attr.attr_id].get == true) { m_parse_state = ATTR_LEN1; } m_expected_number_of_attrs--; LOG("Attribute ID %i \n\r", evt.attr.attr_id); } break; case ATTR_LEN1: evt.attr.attr_len = p_data_src[index++]; m_parse_state = ATTR_LEN2; break; case ATTR_LEN2: evt.attr.attr_len |= (p_data_src[index++] << 8); current_attr_index = 0; if (evt.attr.attr_len != 0) { m_parse_state = ATTR_DATA; } else { evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE; p_ancs->evt_handler(&evt); m_parse_state = ATTR_ID; } LOG("Attribute LEN %i \n\r", evt.attr.attr_len); break; case ATTR_DATA: // We have not reached the end of the attribute, nor our max allocated internal size. // Proceed with copying data over to our buffer. if ( (current_attr_index < m_ancs_attr_list[evt.attr.attr_id].attr_len) && (current_attr_index < evt.attr.attr_len)) { p_data_dest[current_attr_index++] = p_data_src[index++]; } // We have reached the end of the attribute, or our max allocated internal size. // Stop copying data over to our buffer. NUL-terminate at the current index. if ( (current_attr_index == evt.attr.attr_len) || (current_attr_index == m_ancs_attr_list[evt.attr.attr_id].attr_len)) { p_data_dest[current_attr_index] = '\0'; // If our max buffer size is smaller than the remaining attribute data, we must // increase index to skip the data until the start of the next attribute. if (current_attr_index < evt.attr.attr_len) { index += (evt.attr.attr_len - current_attr_index); } m_parse_state = ATTR_ID; LOG("Attribute finished!\n\r"); evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE; p_ancs->evt_handler(&evt); } break; case DONE: index = hvx_data_len; break; default: // Default case will never trigger intentionally. Go to the DONE state to minimize the consequences. m_parse_state = DONE; break; } } }
/**@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); } }
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 decoding a ITU Sensor Service Configuration. * * @param[in] p_iss ITU Sensor Service structure * @param[out] p_encoded_buffer Buffer where the encoded data will be written. * * @return Size of encoded data. */ static void its_conf_decode(iss_t * p_iss,uint16_t data_length, uint8_t * data) { if(data_length > 0){ //p_iss->gatt_db_needs_cleaning = true; uint8_t data_bits = data[0]; //if(BIT_VALUE(data_bits,ITS_MEAS_FLAG_OVERRIDE_BIT_PLACEMENT)){ //OVERRIDE.. Client wants to set new values if(data_length > 1){ uint8_t i = 1; //Check if Seq. nr. is set if(BIT_VALUE(data_bits,ITS_MEAS_FLAG_SPACE_TIME_BIT_PLACEMENT)){ p_iss->coord = data[i]; i++; p_iss->curr_seq_nr = uint16_decode(&data[i]); i += 2; } //Check if Unit is set if(BIT_VALUE(data_bits,ITS_MEAS_FLAG_UNIT_BIT_PLACEMENT)){ p_iss->unit = uint16_decode(&data[i]); i += 2; } //Check if Type is set if(BIT_VALUE(data_bits,ITS_MEAS_FLAG_TYPE_MAKE_BIT_PLACEMENT)){ p_iss->type = data[i]; i++; p_iss->make = data[i]; i++; } //Check if ID is set if(BIT_VALUE(data_bits,ITS_MEAS_FLAG_ID_BIT_PLACEMENT)){ p_iss->ID = uint16_decode(&data[i]); i += 2; } //Check if Sampling freq. is set if(BIT_VALUE(data_bits,ITS_MEAS_FLAG_SAMP_FREQ_BIT_PLACEMENT)){ p_iss->samp_freq_in_m_sec = uint32_decode(&data[i]); p_iss->p_update_samp_freq(); } } /*}else{ //set presentation // SET Space + Time p_iss->space_time_present = BIT_VALUE(data_bits,ITS_MEAS_FLAG_SPACE_TIME_BIT_PLACEMENT); //SET Unit p_iss->unit_present = BIT_VALUE(data_bits,ITS_MEAS_FLAG_UNIT_BIT_PLACEMENT); //SET Type p_iss->type_make_present = BIT_VALUE(data_bits,ITS_MEAS_FLAG_TYPE_MAKE_BIT_PLACEMENT); //SET ID p_iss->ID_present = BIT_VALUE(data_bits,ITS_MEAS_FLAG_ID_BIT_PLACEMENT); //SET Sampling freq. p_iss->samp_freq_present = BIT_VALUE(data_bits,ITS_MEAS_FLAG_SAMP_FREQ_BIT_PLACEMENT); } uint16_t data_len = MAX_HTM_LEN; uint8_t data_buf[MAX_HTM_LEN]; memset(data_buf, 0, sizeof(data_buf)); data_len = its_conf_encode(p_iss, data_buf); sd_ble_gatts_value_set(p_iss->meas_conf_handles.value_handle, 0, &data_len, data_buf);*/ } }
/**@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); }
void ble_agsensor_process_request(uint8_t data_len, uint8_t * p_data, uint16_t op_code, bool read_start, bool app_request, bool write) { APPL_LOG("ble_agsensor_process_request opcode %d \r\n", (int)op_code); if (isConfigSendWaiting == true && write == false && app_request == false) { APPL_LOG("ble_agsensor_process_request 1 \r\n"); return; } // APPL_LOG("ble_agsensor_process_request 2 \r\n"); uint8_t sensor_depth; uint32_t tempData32 = 0; uint16_t tempData16 = 0; // Asked for stop sending the Data for specific opcode if (app_request == true && read_start == false && opcode_inRead == op_code && write == false){ // Set to date time as they count as the ping message opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; APPL_LOG("ble_agsensor_process_request 2 \r\n"); return; } hvx_p_config_len = 0; (hvx_p_config_len) += uint16_encode(op_code, &hvx_encoded_buffer[hvx_p_config_len]); switch (op_code) { case BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME: if (write && data_len >=4 && p_data != NULL) { tempData32 = (((uint32_t)((uint8_t *)p_data)[0]) << 0) | (((uint32_t)((uint8_t *)p_data)[1]) << 8) | (((uint32_t)((uint8_t *)p_data)[2]) << 16) | (((uint32_t)((uint8_t *)p_data)[3]) << 24 ); setOffsetTime(tempData32); APPL_LOG("Date time offset update \r\n"); return; } else { // APPL_LOG("Date time msg created \r\n"); datetimeReadEnable = read_start; tempData32 = getTimeInSec(); // tempData32 = SwapByte4(tempData32); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); } break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_BATTERY_LEVEL: // read only batteryLevelReadEnable = read_start; break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_LONGITUDE_LATITUDE: break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_BONDED_DONGLE_RSSI: // read only bondedDongleRssiReadEnable = read_start; break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_BONDED_DONGLE_MAC_ADDRESS: // read only break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_TIME_SYNC_OFFSET: break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_UPDATE_RATE: break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_DATUM: break; /*Mosture */ case BLE_AGSENSOR_CONFIGURATION_OPCODE_MOSTURE_AIRWATER: if (write && data_len >= 5 && p_data != NULL) { APPL_LOG("Moisture sensor AirWater write request\r\n"); sensor_depth = p_data[0]; // Write the Air value in the config tempData16 = uint16_decode(&p_data[1]); cfgWriteConfig(&moisture_air[sensor_depth], &tempData16, sizeof(tempData16)); // Write the Water value in the config tempData16 = uint16_decode(&p_data[3]); cfgWriteConfig(&moisture_water[sensor_depth], &tempData16, sizeof(tempData16)); // Need to create response msg so application get the response to update the UI. ble_agsensor_create_temp_msg(op_code, p_data, data_len); return; } else { if(read_start) { msg_sensor_depth = MAX_SENSOR_COUNT; APPL_LOG("moisture sensor air Water read request\r\n"); // Job is done so need to return msg will be created on the ACK call back return; } else { msg_sensor_depth--; if (msg_sensor_depth == 0) { opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; } } // Add the sensor count in the sending msg hvx_encoded_buffer[hvx_p_config_len] = msg_sensor_depth; hvx_p_config_len ++; // Add the Air value in the sending msg cfgReadConfig(&moisture_air[msg_sensor_depth], &tempData16, sizeof(tempData16)); (hvx_p_config_len) += uint16_encode(tempData16, &hvx_encoded_buffer[hvx_p_config_len]); // Add the Water value in the sending msg cfgReadConfig(&moisture_water[msg_sensor_depth], &tempData16, sizeof(tempData16)); (hvx_p_config_len) += uint16_encode(tempData16, &hvx_encoded_buffer[hvx_p_config_len]); // If app have requested specific data which is not read start then need to create the temp msg if(app_request == true) { ble_agsensor_create_temp_msg(0, &hvx_encoded_buffer, hvx_p_config_len); } APPL_LOG("moisture sensor Air Water data created %d\r\n", msg_sensor_depth); } break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_MOSTURE_ABCD: if (write && data_len >=17 && p_data != NULL) { APPL_LOG("Moisture sensor ABCD write request\r\n"); sensor_depth = p_data[0]; // Write the A value in the config tempData32 = uint32_decode(&p_data[1]); cfgWriteConfig(&moisture_A[sensor_depth], &tempData32, sizeof(tempData32)); // Write the B value in the config tempData32 = uint32_decode(&p_data[5]); cfgWriteConfig(&moisture_B[sensor_depth], &tempData32, sizeof(tempData32)); // Write the B value in the config tempData32 = uint32_decode(&p_data[9]); cfgWriteConfig(&moisture_C[sensor_depth], &tempData32, sizeof(tempData32)); // Write the B value in the config tempData32 = uint32_decode(&p_data[13]); cfgWriteConfig(&moisture_D[sensor_depth], &tempData32, sizeof(tempData32)); // Need to create response msg so application get the response to update the UI. ble_agsensor_create_temp_msg(op_code, p_data, data_len); return; } else { if(read_start) { msg_sensor_depth = MAX_SENSOR_COUNT; APPL_LOG("moisture sensor ABCD read request\r\n"); // Job is done so need to return msg will be created on the ACK call back return; } else { msg_sensor_depth--; if (msg_sensor_depth == 0) { opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; } } // Add the sensor count in the sending msg hvx_encoded_buffer[hvx_p_config_len] = msg_sensor_depth; hvx_p_config_len ++; // Add the A value in the sending msg cfgReadConfig(&moisture_A[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // Add the B value in the sending msg cfgReadConfig(&moisture_B[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // Add the C value in the sending msg cfgReadConfig(&moisture_C[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // Add the D value in the sending msg cfgReadConfig(&moisture_D[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // If app have requested specific data which is not read start then need to create the temp msg if(app_request == true) { ble_agsensor_create_temp_msg(0, &hvx_encoded_buffer, hvx_p_config_len); } APPL_LOG("moisture sensor ABCD data created %d\r\n", msg_sensor_depth); } break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_TEMPERATURE_AB: if (write && data_len >=9 && p_data != NULL) { APPL_LOG("temperature sensor AB write request\r\n"); sensor_depth = p_data[0]; // Write the A value in the config tempData32 = uint32_decode(&p_data[1]); cfgWriteConfig(&temperature_A[sensor_depth], &tempData32, sizeof(tempData32)); // Write the B value in the config tempData32 = uint32_decode(&p_data[5]); cfgWriteConfig(&temperature_B[sensor_depth], &tempData32, sizeof(tempData32)); // Need to create response msg so application get the response to update the UI. ble_agsensor_create_temp_msg(op_code, p_data, data_len); return; } else { if(read_start) { msg_sensor_depth = MAX_SENSOR_COUNT; APPL_LOG("temperature sensor AB read request\r\n"); // Job is done so need to return msg will be created on the ACK call back return; } else { msg_sensor_depth--; if (msg_sensor_depth == 0) { opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; } } // Add the sensor count in the sending msg hvx_encoded_buffer[hvx_p_config_len] = msg_sensor_depth; hvx_p_config_len ++; // Add the A value in the sending msg cfgReadConfig(&temperature_A[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // Add the B value in the sending msg cfgReadConfig(&temperature_B[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // If app have requested specific data which is not read start then need to create the temp msg if(app_request == true) { ble_agsensor_create_temp_msg(0, &hvx_encoded_buffer, hvx_p_config_len); } APPL_LOG("temperature sensor AB data created %d\r\n", msg_sensor_depth); } break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_SALINITY_AIRWATER: if (write && data_len >=5 && p_data != NULL) { APPL_LOG("Salinity sensor AirWater write request\r\n"); sensor_depth = p_data[0]; // Write the Air value in the config tempData16 = uint16_decode(&p_data[1]); cfgWriteConfig(&salinity_air[sensor_depth], &tempData16, sizeof(tempData16)); // Write the Water value in the config tempData16 = uint16_decode(&p_data[3]); cfgWriteConfig(&salinity_water[sensor_depth], &tempData16, sizeof(tempData16)); // Need to create response msg so application get the response to update the UI. ble_agsensor_create_temp_msg(op_code, p_data, data_len); return; } else { if(read_start) { msg_sensor_depth = MAX_SENSOR_COUNT; APPL_LOG("Salinity sensor AirWater read request\r\n"); // Job is done so need to return msg will be created on the ACK call back return; } else { msg_sensor_depth--; if (msg_sensor_depth == 0) { opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; } } // Add the sensor count in the sending msg hvx_encoded_buffer[hvx_p_config_len] = msg_sensor_depth; hvx_p_config_len ++; // Add the Air value in the sending msg cfgReadConfig(&salinity_air[msg_sensor_depth], &tempData16, sizeof(tempData16)); (hvx_p_config_len) += uint16_encode(tempData16, &hvx_encoded_buffer[hvx_p_config_len]); // Add the Water value in the sending msg cfgReadConfig(&salinity_water[msg_sensor_depth], &tempData16, sizeof(tempData16)); (hvx_p_config_len) += uint16_encode(tempData16, &hvx_encoded_buffer[hvx_p_config_len]); // If app have requested specific data which is not read start then need to create the temp msg if(app_request == true) { ble_agsensor_create_temp_msg(0, &hvx_encoded_buffer, hvx_p_config_len); } APPL_LOG("Salinity sensor AirWater data created %d\r\n", msg_sensor_depth); } break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_SALINITY_D: if (write && data_len >=5 && p_data != NULL) { APPL_LOG("Salinity sensor D write request\r\n"); sensor_depth = p_data[0]; // Write the D value in the config tempData32 = uint32_decode(&p_data[1]); cfgWriteConfig(&salinity_D[sensor_depth], &tempData32, sizeof(tempData32)); // Need to create response msg so application get the response to update the UI. ble_agsensor_create_temp_msg(op_code, p_data, data_len); return; } else { if(read_start) { msg_sensor_depth = MAX_SENSOR_COUNT; APPL_LOG("Salinity sensor D read request\r\n"); // Job is done so need to return msg will be created on the ACK call back return; } else { msg_sensor_depth--; if (msg_sensor_depth == 0) { opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; } } // Add the sensor count in the sending msg hvx_encoded_buffer[hvx_p_config_len] = msg_sensor_depth; hvx_p_config_len ++; // Add the D value in the sending msg cfgReadConfig(&salinity_D[msg_sensor_depth], &tempData32, sizeof(tempData32)); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); // If app have requested specific data which is not read start then need to create the temp msg if(app_request == true) { ble_agsensor_create_temp_msg(0, &hvx_encoded_buffer, hvx_p_config_len); } APPL_LOG("Salinity sensor D data created %d\r\n", msg_sensor_depth); } break; case BLE_AGSENSOR_CONFIGURATION_OPCODE_START_MEASUREMENT: isMeasuringSensor = true; sentek_sensor_measurement_type_set(SENSOR_MEASUREMENT_CONTINUOUS); APPL_LOG("Start Measurement\r\n"); return; case BLE_AGSENSOR_CONFIGURATION_OPCODE_STOP_MEASUREMENT: isMeasuringSensor = false; sentek_sensor_measurement_type_set(SENSOR_MEASUREMENT_NONE); APPL_LOG("Stop doing Measurement\r\n"); return; case BLE_AGSENSOR_CONFIGURATION_OPCODE_AIR_NORMALIZE: sentek_sensor_measurement_type_set(SENSOR_MEASUREMENT_AIR_NORMALIZATION); airNormalizationInProgress = true; APPL_LOG("Air Normalization Request\r\n"); return; case BLE_AGSENSOR_CONFIGURATION_OPCODE_WATER_NORMALIZE: sentek_sensor_measurement_type_set(SENSOR_MEASUREMENT_WATER_NORMALIZATION); waterNormalizationInProgress = true; APPL_LOG("Water Normalization Request\r\n"); return; default: APPL_LOG("Default msg created %d\r\n", (int)op_code); datetimeReadEnable = read_start; opcode_inRead = BLE_AGSENSOR_CONFIGURATION_OPCODE_DATETIME; tempData32 = getTimeInSec(); // tempData32 = SwapByte4(tempData32); (hvx_p_config_len) += uint32_encode(tempData32, &hvx_encoded_buffer[hvx_p_config_len]); break; } if (isConnected == true && configIndicationEnable == true) { isConfigSendWaiting = true; return; } // APPL_LOG("read_request 6 \r\n"); return; }