uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, uint32_t packet_len, uint16_t * p_conn_handle, uint8_t * p_sec_status, ble_gap_sec_params_t * * const pp_sec_params) { uint32_t index = SER_CMD_HEADER_SIZE; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_conn_handle); SER_ASSERT_NOT_NULL(p_sec_status); SER_ASSERT_NOT_NULL(pp_sec_params); SER_ASSERT_NOT_NULL(*pp_sec_params); SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, packet_len); uint16_dec(p_buf, packet_len, &index, p_conn_handle); uint8_dec(p_buf, packet_len, &index, p_sec_status); if (p_buf[index] == SER_FIELD_PRESENT) { index++; SER_ASSERT_LENGTH_LEQ(index + 5, packet_len); uint16_dec(p_buf, packet_len, &index, &((*pp_sec_params)->timeout)); (*pp_sec_params)->bond = (p_buf[index] >> 0) & 0x01; (*pp_sec_params)->mitm = (p_buf[index] >> 1) & 0x01; (*pp_sec_params)->io_caps = (p_buf[index] >> 2) & 0x07; (*pp_sec_params)->oob = (p_buf[index] >> 5) & 0x01; index++; uint8_dec(p_buf, packet_len, &index, &(*pp_sec_params)->min_key_size); uint8_dec(p_buf, packet_len, &index, &(*pp_sec_params)->max_key_size); }
uint32_t buf_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, uint8_t * * const pp_data, uint16_t data_len, uint16_t dlen) { uint8_t is_present = 0; SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index)); uint8_dec(p_buf, buf_len, p_index, &is_present); if (is_present == SER_FIELD_PRESENT) { SER_ASSERT_NOT_NULL(pp_data); SER_ASSERT_NOT_NULL(*pp_data); SER_ASSERT_LENGTH_LEQ(dlen, data_len); SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index)); memcpy(*pp_data, &p_buf[*p_index], dlen); *p_index += dlen; } else { if (pp_data) { *pp_data = NULL; } } return NRF_SUCCESS; }
uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, uint8_t * * const pp_data, uint16_t * * const pp_len) { SER_ASSERT_NOT_NULL(pp_len); SER_ASSERT_NOT_NULL(*pp_len); SER_ASSERT_NOT_NULL(pp_data); SER_ASSERT_NOT_NULL(*pp_data); SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - (*p_index))); uint8_t is_present = 0; uint8_dec(p_buf, buf_len, p_index, &is_present); if (!is_present) { *pp_len = NULL; //if length field is not present (*p_index)++; //then data can not be present *pp_data = NULL; return NRF_SUCCESS; } else { return len16data_dec(p_buf, buf_len, p_index, pp_data, *pp_len); } }
uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_struct) { ble_gatts_read_authorize_params_t * p_params = (ble_gatts_read_authorize_params_t *) p_void_struct; uint32_t error_code = NRF_SUCCESS; SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); uint8_t temp_val; SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); uint8_dec(p_buf, buf_len, p_index, &temp_val); p_params->update = temp_val; SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &p_params->offset); error_code = len16data_dec(p_buf, buf_len, p_index, &p_params->p_data, &p_params->len); SER_ASSERT(error_code == NRF_SUCCESS, error_code); return error_code; }
uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_evt_t * const p_event, uint32_t * const p_event_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_evt_tx_complete_t); if (p_event == NULL) { *p_event_len = event_len; return NRF_SUCCESS; } SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); p_event->header.evt_id = BLE_EVT_TX_COMPLETE; p_event->header.evt_len = event_len; uint16_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.conn_handle); uint8_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.params.tx_complete.count); SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return NRF_SUCCESS; }
uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, uint32_t const buf_len, uint8_t * p_uuid_le_len, uint8_t * * const pp_uuid_le, ble_uuid_t * * const pp_uuid) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_uuid_le_len); uint32_t err_code; uint32_t index = 0; uint8_t opcode = SD_BLE_UUID_DECODE; SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - index)); uint8_dec(p_buf, buf_len, &index, &opcode); SER_ASSERT(opcode == SD_BLE_UUID_DECODE, NRF_ERROR_INVALID_DATA); err_code = len8data_dec(p_buf, buf_len, &index, pp_uuid_le, p_uuid_le_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, NULL); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, buf_len); return err_code; }
uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_struct) { ble_gatts_rw_authorize_reply_params_t * p_params = (ble_gatts_rw_authorize_reply_params_t *) p_void_struct; uint32_t error_code = NRF_SUCCESS; SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); uint8_dec(p_buf, buf_len, p_index, &(p_params->type)); if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) { error_code = ble_gatts_read_authorize_params_t_dec(p_buf, buf_len, p_index, &p_params->params.read); SER_ASSERT(error_code == NRF_SUCCESS, error_code); } else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) { error_code = ble_gatts_write_authorize_params_t_dec(p_buf, buf_len, p_index, &p_params->params.write); SER_ASSERT(error_code == NRF_SUCCESS, error_code); } else { return NRF_ERROR_INVALID_PARAM; } return error_code; }
uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_version_t * p_version, uint32_t * const p_result_code) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_result_code); uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, SD_BLE_VERSION_GET, p_result_code); if (status_code != NRF_SUCCESS) { return status_code; } if (*p_result_code != NRF_SUCCESS) { SER_ASSERT_LENGTH_EQ(index, packet_len); return NRF_SUCCESS; } uint8_dec(p_buf, packet_len, &index, &(p_version->version_number)); uint16_dec(p_buf, packet_len, &index, &(p_version->company_id)); uint16_dec(p_buf, packet_len, &index, &p_version->subversion_number); SER_ASSERT_LENGTH_EQ(index, packet_len); return status_code; }
uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_attr_md) { ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; uint32_t err_code = NRF_SUCCESS; uint8_t temp8; err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->read_perm); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->write_perm); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); uint8_dec(p_buf, buf_len, p_index, &temp8); p_attr_md->vlen = temp8; p_attr_md->vloc = temp8 >> 1; p_attr_md->rd_auth = temp8 >> 3; p_attr_md->wr_auth = temp8 >> 4; return err_code; }
uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_char_pf) { ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; SER_ASSERT_LENGTH_LEQ(7, buf_len - *p_index); uint8_dec(p_buf, buf_len, p_index, &p_char_pf->format); uint8_dec(p_buf, buf_len, p_index, (uint8_t *)&p_char_pf->exponent); uint16_dec(p_buf, buf_len, p_index, &p_char_pf->unit); uint8_dec(p_buf, buf_len, p_index, &p_char_pf->name_space); uint16_dec(p_buf, buf_len, p_index, &p_char_pf->desc); return NRF_SUCCESS; }
uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_evt_t * const p_event, uint32_t * const p_event_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); uint16_t tmp_conn_handle; uint16_t tmp_gatt_status; uint16_t tmp_error_handle; uint16_t tmp_service_count; uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); uint16_dec(p_buf, packet_len, &index, &tmp_service_count); uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.desc_disc_rsp) + sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_desc_t); if (p_event == NULL) { *p_event_len = event_len; return NRF_SUCCESS; } SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); p_event->header.evt_id = BLE_GATTC_EVT_DESC_DISC_RSP; p_event->header.evt_len = event_len; p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; p_event->evt.gattc_evt.error_handle = tmp_error_handle; p_event->evt.gattc_evt.params.desc_disc_rsp.count = tmp_service_count; SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 5), packet_len); for (uint16_t i = 0; i < tmp_service_count; i++) { uint16_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle); uint16_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid); uint8_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type); } SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return NRF_SUCCESS; }
uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_uuid) { ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; SER_ASSERT_LENGTH_LEQ(3, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &p_uuid->uuid); uint8_dec(p_buf, buf_len, p_index, &p_uuid->type); return NRF_SUCCESS; }
uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_evt_t * const p_event, uint32_t * const p_event_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(13, packet_len); uint16_t tmp_attr_len = uint16_decode(&(p_buf[11])); uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.write_rsp) + sizeof (ble_gattc_evt_write_rsp_t) - 1 + tmp_attr_len; if (p_event == NULL) { *p_event_len = event_len; return NRF_SUCCESS; } SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); p_event->header.evt_id = BLE_GATTC_EVT_WRITE_RSP; p_event->header.evt_len = event_len; uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.handle)); uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.write_op)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.offset)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.len)); SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); if (tmp_attr_len > 0) { memcpy(&(p_event->evt.gattc_evt.params.write_rsp.data[0]), &(p_buf[index]), tmp_attr_len); index += tmp_attr_len; } SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return NRF_SUCCESS; }
uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_evt_t * const p_event, uint32_t * const p_event_len) { uint32_t index = 0; uint16_t tmp_attr_len; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(11, packet_len); tmp_attr_len = uint16_decode(&(p_buf[9])); uint32_t event_len = offsetof(ble_gattc_evt_t, params.hvx) + offsetof (ble_gattc_evt_hvx_t, data) + tmp_attr_len; if (p_event == NULL) { *p_event_len = event_len; return NRF_SUCCESS; } SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); p_event->header.evt_id = BLE_GATTC_EVT_HVX; p_event->header.evt_len = event_len; uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.handle)); uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.type)); uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.len)); SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); if (tmp_attr_len > 0) { memcpy(&(p_event->evt.gattc_evt.params.hvx.data[0]), &(p_buf[index]), tmp_attr_len); index += tmp_attr_len; } SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return NRF_SUCCESS; }
uint32_t count16_cond_data16_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, uint16_t * * const pp_data, uint16_t * const p_count) { uint16_t count = 0; uint8_t is_present = 0; uint16_t i; SER_ASSERT_NOT_NULL(p_count); SER_ASSERT_NOT_NULL(pp_data); SER_ASSERT_NOT_NULL(*pp_data); SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - (*p_index))); uint16_dec(p_buf, buf_len, p_index, &count); if (count > *p_count) { return NRF_ERROR_DATA_SIZE; } SER_ASSERT_LENGTH_LEQ(count, *p_count); uint8_dec(p_buf, buf_len, p_index, &is_present); if (!is_present) { *pp_data = NULL; return NRF_SUCCESS; } else { for (i = 0; i < count; i++ ) { uint16_dec(p_buf, buf_len, p_index, &((&(**pp_data))[i]) ); } *p_count = i; } return NRF_SUCCESS; }
uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, uint32_t packet_len, uint8_t * const p_addr_cycle_mode, ble_gap_addr_t * * const pp_addr) { uint32_t index = SER_CMD_DATA_POS; uint32_t err_code; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_addr_cycle_mode); SER_ASSERT_NOT_NULL(pp_addr); SER_ASSERT_NOT_NULL(*pp_addr); uint8_dec(p_buf, packet_len, &index, (void *)p_addr_cycle_mode); err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, packet_len); return err_code; }
uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_attr_context) { uint32_t error_code = NRF_SUCCESS; ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->srvc_uuid)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->char_uuid)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->desc_uuid)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &(p_context->srvc_handle)); uint16_dec(p_buf, buf_len, p_index, &(p_context->value_handle)); uint8_dec(p_buf, buf_len, p_index, &(p_context->type)); return error_code; }
uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, uint16_t packet_len, uint16_t * const p_conn_handle, uint16_t * const p_start_handle, ble_uuid_t * * const pp_srvc_uuid) { uint32_t index = SER_CMD_DATA_POS; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_conn_handle); SER_ASSERT_NOT_NULL(p_start_handle); SER_ASSERT_NOT_NULL(pp_srvc_uuid); SER_ASSERT_NOT_NULL(*pp_srvc_uuid); SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 2 + 1, packet_len); uint16_dec(p_buf, packet_len, &index, p_conn_handle); uint16_dec(p_buf, packet_len, &index, p_start_handle); switch (p_buf[index++]) { case SER_FIELD_NOT_PRESENT: *pp_srvc_uuid = NULL; break; case SER_FIELD_PRESENT: SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); uint16_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->uuid); uint8_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->type); break; default: return NRF_ERROR_INVALID_DATA; } SER_ASSERT_LENGTH_EQ(index, packet_len); return NRF_SUCCESS; }
uint32_t cond_field_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * * const pp_field, field_decoder_handler_t fp_field_parser) { uint32_t err_code = NRF_SUCCESS; uint8_t is_present; SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); uint8_dec(p_buf, buf_len, p_index, &is_present); if (is_present == SER_FIELD_PRESENT) { SER_ASSERT_NOT_NULL(pp_field); SER_ASSERT_NOT_NULL(*pp_field); if (fp_field_parser != NULL) { err_code = fp_field_parser(p_buf, buf_len, p_index, *pp_field); } } else if (is_present == SER_FIELD_NOT_PRESENT) { if (pp_field != NULL) { *pp_field = NULL; } } else { err_code = NRF_ERROR_INVALID_DATA; } return err_code; }
uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_hvx_params) { ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; uint32_t err_code = NRF_SUCCESS; SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->handle); uint8_dec(p_buf, buf_len, p_index, &p_hvx_params->type); uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->offset); SER_ASSERT_NOT_NULL(&p_hvx_params->p_len); err_code = cond_len16_cond_data_dec(p_buf, buf_len, p_index, &p_hvx_params->p_data, &p_hvx_params->p_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }