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 ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const * const p_srvc_uuid, uint8_t * const p_buf, uint32_t * p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(index + 5, *p_buf_len); p_buf[index++] = SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER; index += uint16_encode(conn_handle, &p_buf[index]); index += uint16_encode(start_handle, &p_buf[index]); SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); p_buf[index++] = (p_srvc_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; if (p_srvc_uuid != NULL) { SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); index += uint16_encode(p_srvc_uuid->uuid, &p_buf[index]); p_buf[index++] = p_srvc_uuid->type; } *p_buf_len = index; return NRF_SUCCESS; }
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 ble_gattc_characteristics_discover_req_enc( uint16_t conn_handle, ble_gattc_handle_range_t const * const p_handle_range, uint8_t * const p_buf, uint32_t * p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); p_buf[index++] = SD_BLE_GATTC_CHARACTERISTICS_DISCOVER; index += uint16_encode(conn_handle, &p_buf[index]); SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; if (p_handle_range != NULL) { SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); } *p_buf_len = index; return NRF_SUCCESS; }
uint32_t count16_cond_data16_enc(uint16_t const * const p_data, uint16_t const count, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index) { uint32_t i = 0; SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - *p_index)); *p_index += uint16_encode(count, &p_buf[*p_index]); if (p_data) { SER_ASSERT_LENGTH_LEQ((int32_t)(2 * count + 1), ((int32_t)buf_len - *p_index)); p_buf[*p_index] = SER_FIELD_PRESENT; *p_index += 1; //memcpy may fail in case of Endianness difference between application and connectivity processor for (i = 0; i < count; i++) { *p_index += uint16_encode(p_data[i], &p_buf[*p_index]); } } else { SER_ASSERT_LENGTH_LEQ((1), ((int32_t)buf_len - *p_index)); p_buf[*p_index] = SER_FIELD_NOT_PRESENT; *p_index += 1; } return NRF_SUCCESS; }
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_gap_address_set_req_enc(uint8_t addr_cycle_mode, ble_gap_addr_t const * const p_addr, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1, *p_buf_len); p_buf[index++] = SD_BLE_GAP_ADDRESS_SET; p_buf[index++] = addr_cycle_mode; p_buf[index++] = (p_addr == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; if (p_addr != NULL) { SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, *p_buf_len); p_buf[index++] = p_addr->addr_type; memcpy(&p_buf[index], p_addr->addr, BLE_GAP_ADDR_LEN); index += BLE_GAP_ADDR_LEN; } *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, uint32_t event_len, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_event); SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); index += uint16_encode(BLE_GATTC_EVT_DESC_DISC_RSP, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.count, &(p_buf[index])); uint16_t service_count = p_event->evt.gattc_evt.params.desc_disc_rsp.count; SER_ASSERT_LENGTH_LEQ(index + (service_count * 5), *p_buf_len); for (uint16_t i = 0; i < service_count; i++) { index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid, &(p_buf[index])); p_buf[index++] = p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type; } *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, uint32_t event_len, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_event); SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 13, *p_buf_len); index += uint16_encode(BLE_GATTC_EVT_WRITE_RSP, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.handle, &(p_buf[index])); p_buf[index++] = p_event->evt.gattc_evt.params.write_rsp.write_op; index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.offset, &(p_buf[index])); index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.len, &(p_buf[index])); SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.write_rsp.len, *p_buf_len); if (p_event->evt.gattc_evt.params.write_rsp.len > 0) { memcpy(&(p_buf[index]), &(p_event->evt.gattc_evt.params.write_rsp.data[0]), p_event->evt.gattc_evt.params.write_rsp.len); index += p_event->evt.gattc_evt.params.write_rsp.len; } *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_gatts_service_add_req_enc(uint8_t type, ble_uuid_t const * const p_uuid, uint16_t const * const p_conn_handle, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1 + 1, *p_buf_len); p_buf[index++] = SD_BLE_GATTS_SERVICE_ADD; p_buf[index++] = type; p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; if (p_uuid != NULL) { SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); index += uint16_encode(p_uuid->uuid, &p_buf[index]); p_buf[index++] = p_uuid->type; } SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); p_buf[index++] = (p_conn_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, uint8_t const * const p_uuid_le_len, uint8_t const * const p_uuid_le, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); p_buf[index++] = SD_BLE_UUID_ENCODE; p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; if (p_uuid != NULL) { SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); index += uint16_encode(p_uuid->uuid, &p_buf[index]); p_buf[index++] = p_uuid->type; } SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); p_buf[index++] = (p_uuid_le_len == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; p_buf[index++] = (p_uuid_le == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, ble_gap_sec_params_t const * const p_sec_params, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(1 + 2 + 1, *p_buf_len); p_buf[index++] = SD_BLE_GAP_AUTHENTICATE; index += uint16_encode(conn_handle, &p_buf[index]); p_buf[index++] = (p_sec_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; if (p_sec_params != NULL) { SER_ASSERT_LENGTH_LEQ(index + 2 + 1 + 1 + 1, *p_buf_len); index += uint16_encode(p_sec_params->timeout, &p_buf[index]); p_buf[index++] = ((p_sec_params->oob << 5) | (p_sec_params->io_caps << 2) | (p_sec_params->mitm << 1) | (p_sec_params->bond << 0)); p_buf[index++] = p_sec_params->min_key_size; p_buf[index++] = p_sec_params->max_key_size; } *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT(p_hvx_params == NULL || !(p_hvx_params->p_len == NULL && p_hvx_params->p_data != NULL), NRF_ERROR_NULL); SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 1, *p_buf_len); p_buf[index++] = SD_BLE_GATTS_HVX; index += uint16_encode(conn_handle, &p_buf[index]); p_buf[index++] = (p_hvx_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; if (p_hvx_params != NULL) { SER_ASSERT_LENGTH_LEQ(index + 2 + 1 + 2 + 2, *p_buf_len); index += uint16_encode(p_hvx_params->handle, &p_buf[index]); p_buf[index++] = p_hvx_params->type; index += uint16_encode(p_hvx_params->offset, &p_buf[index]); if (p_hvx_params->p_len != NULL) { SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); SER_ERROR_CHECK(*p_hvx_params->p_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); p_buf[index++] = SER_FIELD_PRESENT; index += uint16_encode(*(p_hvx_params->p_len), &p_buf[index]); if (p_hvx_params->p_data != NULL) { SER_ASSERT_LENGTH_LEQ(index + 1 + *(p_hvx_params->p_len), *p_buf_len); p_buf[index++] = SER_FIELD_PRESENT; memcpy(&(p_buf[index]), p_hvx_params->p_data, *(p_hvx_params->p_len)); index += *(p_hvx_params->p_len); } else { p_buf[index++] = SER_FIELD_NOT_PRESENT; } } else { p_buf[index++] = SER_FIELD_NOT_PRESENT; p_buf[index++] = SER_FIELD_NOT_PRESENT; } } *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, uint32_t * const p_struct_len, void * const p_void_write) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_index); SER_ASSERT_NOT_NULL(p_struct_len); uint32_t err_code = NRF_SUCCESS; uint32_t in_struct_len = *p_struct_len; *p_struct_len = offsetof(ble_gatts_evt_write_t, data); uint16_t handle; err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); SER_ASSERT(err_code == NRF_SUCCESS, err_code); uint8_t op; err_code = uint8_t_dec(p_buf, buf_len, p_index, &op); SER_ASSERT(err_code == NRF_SUCCESS, err_code); ble_gatts_attr_context_t context; err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); SER_ASSERT(err_code == NRF_SUCCESS, err_code); uint16_t offset; err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); SER_ASSERT(err_code == NRF_SUCCESS, err_code); uint16_t len; err_code = uint16_t_dec(p_buf, buf_len, p_index, &len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); *p_struct_len += len; if (p_void_write != NULL) { ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *)p_void_write; SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); p_write->handle = handle; p_write->op = op; memcpy(&(p_write->context), &context, sizeof (ble_gatts_attr_context_t)); p_write->offset = offset; p_write->len = len; SER_ASSERT_LENGTH_LEQ(p_write->len, buf_len - *p_index); memcpy(p_write->data, &p_buf[*p_index], p_write->len); } *p_index += len; return err_code; }
uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, uint32_t * const p_struct_size, void * const p_void_struct) { ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; uint32_t err_code = NRF_SUCCESS; uint16_t value_len; uint16_t count; uint32_t i; SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &count); uint16_dec(p_buf, buf_len, p_index, &value_len); uint32_t total_struct_size = *p_struct_size; //calculate the size of the struct *p_struct_size = offsetof(ble_gattc_evt_char_val_by_uuid_read_rsp_t, handle_value[count]); *p_struct_size += value_len * count; if (p_read) { p_read->value_len = value_len; p_read->count = count; ble_gattc_handle_value_t * p_handle_value; uint8_t * p_value; SER_ASSERT_LENGTH_LEQ(*p_struct_size, total_struct_size); p_value = (uint8_t *)&p_read->handle_value[count]; for (i = 0; i < count; i++) { p_handle_value = (ble_gattc_handle_value_t *)&p_read->handle_value[i]; p_handle_value->p_value = p_value; SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); uint16_dec(p_buf, buf_len, p_index, &(p_handle_value->handle)); SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); memcpy(p_handle_value->p_value, &p_buf[*p_index], p_read->value_len); *p_index += p_read->value_len; p_value += value_len; } } else { *p_index += count * (value_len + 2); } return err_code; }
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_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 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_include_add_req_enc(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t * const p_include_handle, uint8_t * const p_buf, uint32_t * const p_buf_len) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(6, *p_buf_len); uint32_t index = 0; uint32_t buf_len = *p_buf_len; uint32_t err_code; uint8_t opCode = SD_BLE_GATTS_INCLUDE_ADD; uint8_t presenceFlag; err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = uint16_t_enc(&inc_srvc_handle, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); presenceFlag = (p_include_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; err_code = uint8_t_enc(&presenceFlag, p_buf, *p_buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); *p_buf_len = index; return err_code; }
uint32_t ble_gattc_char_value_by_uuid_read_req_dec( uint8_t const * const p_buf, uint16_t buf_len, uint16_t * const p_conn_handle, ble_uuid_t * * const pp_uuid, ble_gattc_handle_range_t * * const pp_handle_range) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_conn_handle); SER_ASSERT_NOT_NULL(pp_uuid); SER_ASSERT_NOT_NULL(*pp_uuid); SER_ASSERT_NOT_NULL(pp_handle_range); SER_ASSERT_NOT_NULL(*pp_handle_range); uint32_t index = 0; uint32_t err_code; SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2, buf_len); SER_ASSERT(p_buf[index] == SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, NRF_ERROR_INVALID_DATA); index++; uint16_dec(p_buf, buf_len, &index, p_conn_handle); err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle_range, ble_gattc_handle_range_t_dec); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, buf_len); return err_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 ble_gatts_value_get_req_dec(uint8_t const * const p_buf, uint16_t packet_len, uint16_t * const handle, uint16_t * const offset, uint16_t * * const pp_len, uint8_t * * const pp_data) { uint32_t index = 0; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 6, packet_len); SER_ASSERT(p_buf[index] == SD_BLE_GATTS_VALUE_GET, NRF_ERROR_INVALID_PARAM); index++; uint16_dec(p_buf, packet_len, &index, handle); uint16_dec(p_buf, packet_len, &index, offset); if (p_buf[index++] == SER_FIELD_PRESENT) { uint16_dec(p_buf, packet_len, &index, *pp_len); } else { *pp_len = NULL; } if (p_buf[index++] == SER_FIELD_NOT_PRESENT) { *pp_data = NULL; } return NRF_SUCCESS; }
uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len, uint16_t const * const p_appearance) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); uint32_t total_len = *p_buf_len; uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_GET, return_code, p_buf, p_buf_len); if (err_code != NRF_SUCCESS) { return err_code; } if (return_code != NRF_SUCCESS) { return NRF_SUCCESS; } SER_ASSERT_NOT_NULL(p_appearance); uint32_t index = *p_buf_len; SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), total_len); index += uint16_encode(*p_appearance, &p_buf[index]); *p_buf_len = index; return NRF_SUCCESS; }
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_gatts_attr_md_enc(void const * const p_void_attr_md, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index) { ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; uint32_t err_code = NRF_SUCCESS; err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->read_perm, p_buf, buf_len, p_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->write_perm, p_buf, buf_len, p_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); /* serializer does not support attributes on stack */ if (p_attr_md->vloc != BLE_GATTS_VLOC_STACK) { err_code = NRF_ERROR_INVALID_PARAM; } uint8_t temp8; temp8 = p_attr_md->vlen | (p_attr_md->vloc << 1) | (p_attr_md->rd_auth << 3) | (p_attr_md->wr_auth << 4); SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); p_buf[*p_index] = temp8; *p_index += 1; return err_code; }
uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, uint16_t packet_len, uint16_t * const p_conn_handle, uint16_t * * const pp_handles, uint16_t * const p_handle_count) { SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated SER_ASSERT_NOT_NULL(p_conn_handle); //check if *p_conn_handle exist SER_ASSERT_NOT_NULL(pp_handles); //check if *p_handles exist SER_ASSERT_NOT_NULL(*pp_handles); //check if p_handles exist SER_ASSERT_NOT_NULL(p_handle_count); //check if *p_handle_count exist uint32_t index = SER_CMD_DATA_POS; uint32_t status_code; SER_ASSERT_LENGTH_LEQ(5, packet_len - index); //make sure that payload length is at least 5 bytes uint16_dec(p_buf, packet_len, &index, p_conn_handle); //decode handle table count with optional handle table status_code = count16_cond_data16_dec(p_buf, packet_len, &index, pp_handles, p_handle_count); SER_ASSERT(status_code == NRF_SUCCESS, status_code); SER_ASSERT_LENGTH_EQ(index, packet_len); return status_code; }
uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index) { ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *) p_void_write; uint32_t error_code = NRF_SUCCESS; error_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = uint8_t_enc(&(p_write->op), p_buf, buf_len, p_index); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = ble_gatts_attr_context_t_enc(&(p_write->context), p_buf, buf_len, p_index); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); SER_ASSERT(error_code == NRF_SUCCESS, error_code); uint16_t data_len = p_write->len; error_code = uint16_t_enc(&data_len, p_buf, buf_len, p_index); SER_ASSERT(error_code == NRF_SUCCESS, error_code); SER_ASSERT_LENGTH_LEQ(data_len, buf_len - *p_index); memcpy(&p_buf[*p_index], p_write->data, data_len); *p_index += data_len; return error_code; }
uint32_t ble_version_get_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len, ble_version_t const * const p_version) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); uint32_t total_len = *p_buf_len; uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_VERSION_GET, return_code, p_buf, p_buf_len); if (err_code != NRF_SUCCESS) { return err_code; } if (return_code != NRF_SUCCESS) { return NRF_SUCCESS; } SER_ASSERT_NOT_NULL(p_version); uint32_t index = *p_buf_len; SER_ASSERT_LENGTH_LEQ(index + 5, total_len); p_buf[index++] = p_version->version_number; index += uint16_encode(p_version->company_id, &p_buf[index]); index += uint16_encode(p_version->subversion_number, &p_buf[index]); *p_buf_len = index; return NRF_SUCCESS; }
uint32_t ble_opt_get_req_enc(uint32_t opt_id, ble_opt_t const * const p_opt, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; uint32_t err_code; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); SER_ASSERT_LENGTH_LEQ(1+4+1, *p_buf_len); // [OPCODE][OP_ID][PRESENT] SER_ASSERT(((opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || (opt_id == BLE_GAP_OPT_PASSKEY) || (opt_id == BLE_GAP_OPT_PRIVACY)), NRF_ERROR_INVALID_PARAM); p_buf[index++] = SD_BLE_OPT_GET; err_code = uint32_t_enc(&opt_id, p_buf, *p_buf_len, &index); if (err_code != NRF_SUCCESS) { return err_code; } p_buf[index++] = (p_opt == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; *p_buf_len = index; return NRF_SUCCESS; }