uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); ble_gap_addr_t addr; ble_gap_addr_t * p_addr = &addr; ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; ble_gap_addr_t addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; ble_gap_irk_t irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; for (uint8_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; ++i) { pp_addr_tab[i] = &addr_tab[i]; } for (uint8_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; ++i) { pp_irk_tab[i] = &irk_tab[i]; } ble_gap_whitelist_t whitelist; whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; whitelist.pp_addrs = pp_addr_tab; whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; whitelist.pp_irks = pp_irk_tab; ble_gap_scan_params_t scan_params; scan_params.p_whitelist = &whitelist; ble_gap_scan_params_t * p_scan_params = &scan_params; ble_gap_conn_params_t conn_params; ble_gap_conn_params_t * p_conn_params = &conn_params; uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr, &p_scan_params, &p_conn_params); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params); err_code = ble_gap_connect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
uint32_t ant_coex_config_set_req_enc(uint8_t channel, ANT_BUFFER_PTR const * const p_coex_config, ANT_BUFFER_PTR const * const p_adv_coex_config, uint8_t * const p_buf, uint32_t * const p_buf_len) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); uint8_t svc_number = SVC_ANT_COEX_CONFIG_SET; uint32_t err_code = NRF_SUCCESS; uint32_t buf_len = *p_buf_len; uint32_t index = 0; err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = uint8_t_enc(&channel, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); // Encode coex config buffer size uint8_t coex_config_buffer_size = p_coex_config -> ucBufferSize; err_code = uint8_t_enc(&coex_config_buffer_size, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); // Encode coex config buffer err_code = uint8_vector_enc(p_coex_config -> pucBuffer, coex_config_buffer_size, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); // Encode advanced coex config buffer size uint8_t adv_coex_config_buffer_size = p_adv_coex_config -> ucBufferSize; err_code = uint8_t_enc(&adv_coex_config_buffer_size, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); // Encode advanced coex config buffer err_code = uint8_vector_enc(p_adv_coex_config -> pucBuffer, adv_coex_config_buffer_size, p_buf, buf_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); *p_buf_len = index; return err_code; }
uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, uint16_t packet_len, ble_version_t * * const pp_version) { SER_REQ_DEC_BEGIN(SD_BLE_VERSION_GET); SER_ASSERT_NOT_NULL(pp_version); SER_ASSERT_NOT_NULL(*pp_version); SER_PULL_COND(pp_version, NULL); SER_REQ_DEC_END; }
uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, uint16_t packet_len, uint32_t * const p_opt_id, ble_opt_t **const pp_opt ) { uint32_t index = 0; uint32_t err_code; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_opt_id); SER_ASSERT_NOT_NULL(pp_opt); SER_ASSERT_NOT_NULL(*pp_opt); SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); index++; err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT(((*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || (*p_opt_id == BLE_GAP_OPT_PASSKEY) || (*p_opt_id == BLE_GAP_OPT_PRIVACY)), NRF_ERROR_INVALID_PARAM); if (p_buf[index++] == SER_FIELD_NOT_PRESENT) { *pp_opt = NULL; } else { switch(*p_opt_id) { case BLE_GAP_OPT_LOCAL_CONN_LATENCY: err_code = ble_gap_opt_local_conn_latency_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap.local_conn_latency)); break; case BLE_GAP_OPT_PASSKEY: err_code = ble_gap_opt_passkey_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap.passkey)); break; case BLE_GAP_OPT_PRIVACY: err_code = ble_gap_opt_privacy_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap.privacy)); break; } } SER_ASSERT_LENGTH_EQ(index, packet_len); return err_code; }
uint32_t ble_gap_evt_lesc_dhkey_request_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; uint32_t err_code = NRF_SUCCESS; uint32_t conn_index; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); // [minimal packet is: 'conn_handle' + 'p_pk_peer' SER_FIELD_NOT_PRESENT + // 'oobd_req'] SER_ASSERT_LENGTH_LEQ(sizeof(uint16_t) + sizeof(uint8_t) + sizeof(uint8_t), packet_len); uint32_t event_len = offsetof (ble_gap_evt_t, params) + sizeof(uint8_t) + sizeof(uint8_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_len = event_len; err_code = uint16_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); SER_ASSERT(err_code == NRF_SUCCESS, err_code); // keyset is an extension of standard event data - used to synchronize keys at application err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer = m_app_keys_table[conn_index].keyset.keys_peer.p_pk; err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_dec); SER_ASSERT(err_code == NRF_SUCCESS, err_code); uint8_t data; err_code = uint8_t_dec(p_buf, packet_len, &index, &data); SER_ASSERT(err_code == NRF_SUCCESS, err_code); p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req = data & 0x01; SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return err_code; }
uint32_t ble_gap_evt_sec_info_request_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; uint32_t event_len; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(2 + 1 + 6 + 2 + 1, packet_len); event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_sec_info_request_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_GAP_EVT_SEC_INFO_REQUEST; p_event->header.evt_len = event_len; uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); ble_gap_evt_sec_info_request_t * p_sec_info_request = &(p_event->evt.gap_evt.params.sec_info_request); p_sec_info_request->peer_addr.addr_type = p_buf[index++]; p_sec_info_request->peer_addr.addr[0] = p_buf[index++]; p_sec_info_request->peer_addr.addr[1] = p_buf[index++]; p_sec_info_request->peer_addr.addr[2] = p_buf[index++]; p_sec_info_request->peer_addr.addr[3] = p_buf[index++]; p_sec_info_request->peer_addr.addr[4] = p_buf[index++]; p_sec_info_request->peer_addr.addr[5] = p_buf[index++]; uint16_dec(p_buf, packet_len, &index, &p_sec_info_request->div); p_sec_info_request->enc_info = (p_buf[index] >> 0) & 0x1; p_sec_info_request->id_info = (p_buf[index] >> 1) & 0x1; p_sec_info_request->sign_info = (p_buf[index] >> 2) & 0x1; index++; SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return NRF_SUCCESS; }
uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; ble_gap_addr_t * p_addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; ble_gap_addr_t addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; ble_gap_irk_t * p_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; ble_gap_irk_t irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; ble_gap_addr_t peer_addr; ble_gap_whitelist_t whitelist; ble_gap_adv_params_t adv_params; ble_gap_adv_params_t * p_adv_params; uint32_t i = 0; for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) { p_addresses[i] = &(addresses[i]); } for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) { p_irks[i] = &(irks[i]); } whitelist.pp_addrs = &p_addresses[0]; whitelist.pp_irks = &p_irks[0]; adv_params.p_peer_addr = &peer_addr; adv_params.p_whitelist = &whitelist; p_adv_params = &adv_params; err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_adv_start(p_adv_params); err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; uint32_t sec_tab_index = 0; uint16_t * p_conn_handle; uint8_t sec_status; ble_gap_sec_params_t sec_params; ble_gap_sec_params_t * p_sec_params = &sec_params; // Allocate global security context for soft device err_code = conn_ble_gap_sec_context_create(&sec_tab_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); p_conn_handle = &(m_conn_keys_table[sec_tab_index].conn_handle); // Set up global structure for command decoder ble_gap_sec_keyset_t * p_sec_keyset = &(m_conn_keys_table[sec_tab_index].keyset); p_sec_keyset->keys_periph.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_periph); p_sec_keyset->keys_periph.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_periph); p_sec_keyset->keys_periph.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_periph); p_sec_keyset->keys_central.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_central); p_sec_keyset->keys_central.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_central); p_sec_keyset->keys_central.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_central); err_code = ble_gap_sec_params_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &sec_status, &p_sec_params, &p_sec_keyset); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_sec_params_reply(*p_conn_handle, sec_status, p_sec_params, p_sec_keyset); err_code = ble_gap_sec_params_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sec_keyset); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
uint32_t ble_gap_evt_sec_params_request_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; uint32_t event_len; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(7, packet_len); event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_sec_params_request_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_GAP_EVT_SEC_PARAMS_REQUEST; p_event->header.evt_len = event_len; uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); ble_gap_evt_sec_params_request_t * p_sec_params_request = &(p_event->evt.gap_evt.params.sec_params_request); uint16_dec(p_buf, packet_len, &index, &p_sec_params_request->peer_params.timeout); p_sec_params_request->peer_params.bond = (p_buf[index] >> 0) & 0x1; p_sec_params_request->peer_params.mitm = (p_buf[index] >> 1) & 0x1; p_sec_params_request->peer_params.io_caps = (p_buf[index] >> 2) & 0x7; p_sec_params_request->peer_params.oob = (p_buf[index] >> 5) & 0x1; index++; p_sec_params_request->peer_params.min_key_size = p_buf[index++]; p_sec_params_request->peer_params.max_key_size = p_buf[index++]; 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 ble_gap_evt_auth_status_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; uint32_t err_code = NRF_SUCCESS; uint32_t conn_index; 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); uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.auth_status)) + sizeof (ble_gap_evt_adv_report_t) - sizeof (ble_evt_hdr_t); if (p_event == NULL) { *p_event_len = event_len; return NRF_SUCCESS; } p_event->header.evt_id = BLE_GAP_EVT_AUTH_STATUS; p_event->header.evt_len = event_len; err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = ble_gap_evt_auth_status_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.auth_status)); SER_ASSERT(err_code == NRF_SUCCESS, err_code); // keyset is an extension of standard event data - used to synchronize keys at application err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = ble_gap_sec_keyset_t_dec(p_buf, packet_len, &index, &(m_app_keys_table[conn_index].keyset)); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, packet_len); *p_event_len = event_len; return err_code; }
uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t opt_id = 0xFFFFFFFF; uint16_t act_latency; uint8_t passkey[BLE_GAP_PASSKEY_LEN]; ble_gap_irk_t irk = {{0}}; /* Pre-decode type of ble_opt_t union */ err_code = ble_opt_id_pre_dec(p_rx_buf, rx_buf_len, &opt_id); SER_ASSERT(err_code == NRF_SUCCESS, err_code); ble_opt_t opt; ble_opt_t *p_opt = &opt; /* Initialaize appropriate pointers inside opt union based on opt_id */ switch(opt_id) { case BLE_GAP_OPT_LOCAL_CONN_LATENCY: opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; break; case BLE_GAP_OPT_PASSKEY: opt.gap_opt.passkey.p_passkey = passkey; break; case BLE_GAP_OPT_PRIVACY: opt.gap_opt.privacy.p_irk = &irk; break; } uint32_t sd_err_code; err_code = ble_opt_set_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_opt_set(opt_id, p_opt); err_code = ble_opt_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
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_user_mem_reply_req_dec(uint8_t const * const p_buf, uint32_t packet_len, uint16_t * const p_conn_handle, ble_user_mem_block_t * * const pp_mem_block) { SER_REQ_DEC_BEGIN(SD_BLE_USER_MEM_REPLY); SER_ASSERT_NOT_NULL(p_conn_handle); SER_ASSERT_NOT_NULL(pp_mem_block); SER_ASSERT_NOT_NULL(*pp_mem_block); SER_PULL_uint16(p_conn_handle); SER_PULL_COND(pp_mem_block, ble_user_mem_block_t_dec); SER_REQ_DEC_END; }
uint32_t ble_enable_req_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_enable_params_t * * const pp_ble_enable_params) { uint32_t index = SER_CMD_DATA_POS; uint32_t err_code; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(pp_ble_enable_params); SER_ASSERT_NOT_NULL(*pp_ble_enable_params); err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_ble_enable_params, ble_enable_params_t_dec); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, packet_len); return err_code; }
uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint16_t * const p_conn_handle, uint32_t * const p_result_code) { uint32_t index = 0; uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, SD_BLE_GATTS_SERVICE_ADD, p_result_code); if (decode_result != NRF_SUCCESS) { return decode_result; } if (*p_result_code != NRF_SUCCESS) { SER_ASSERT_LENGTH_EQ(index, packet_len); return NRF_SUCCESS; } SER_ASSERT_NOT_NULL(p_conn_handle); SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); uint16_dec(p_buf, packet_len, &index, p_conn_handle); SER_ASSERT_LENGTH_EQ(index, packet_len); return decode_result; }
uint32_t uint8_vector_enc(uint8_t const * const p_data, uint16_t const dlen, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index) { SER_ASSERT_NOT_NULL(p_data); SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_index); SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index)); memcpy(&p_buf[*p_index], p_data, dlen); *p_index += dlen; return NRF_SUCCESS; }
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 ser_conn_dtm_command_process(uint8_t * p_command, uint16_t command_len) { SER_ASSERT_NOT_NULL(p_command); uint32_t err_code = NRF_SUCCESS; uint8_t * p_tx_buf = NULL; uint32_t tx_buf_len = 0; /* Allocate a memory buffer from HAL Transport layer for transmitting the Command Response. * Loop until a buffer is available. */ do { err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); if (err_code == NRF_ERROR_NO_MEM) { ser_conn_on_no_mem_handler(); } } while (NRF_ERROR_NO_MEM == err_code); if (err_code == NRF_SUCCESS) { p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_DTM_RESP; tx_buf_len -= SER_PKT_TYPE_SIZE; err_code = ble_dtm_init_req_dec(p_command, command_len, &m_comm_params); if (NRF_SUCCESS == err_code) { err_code = ble_dtm_init_rsp_enc(NRF_SUCCESS, &p_tx_buf[SER_PKT_TYPE_SIZE], &tx_buf_len); if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } tx_buf_len += SER_PKT_TYPE_SIZE; /* Set a flag that device is ready to enter DTM mode. */ m_is_ready_to_enter_dtm = true; err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len); if (err_code != NRF_SUCCESS) { err_code = NRF_ERROR_INTERNAL; } /* TX buffer is going to be freed automatically in the HAL Transport layer. */ } else { err_code = NRF_ERROR_INTERNAL; } } return err_code; }
uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, uint16_t packet_len, ble_uuid128_t * * const pp_uuid, uint8_t * * const pp_uuid_type) { SER_REQ_DEC_BEGIN(SD_BLE_UUID_VS_ADD); SER_ASSERT_NOT_NULL(pp_uuid); SER_ASSERT_NOT_NULL(pp_uuid_type); SER_ASSERT_NOT_NULL(*pp_uuid); SER_ASSERT_NOT_NULL(*pp_uuid_type); SER_PULL_COND(pp_uuid, ble_uuid128_t_dec); SER_PULL_COND(pp_uuid_type, NULL); SER_REQ_DEC_END; }
uint32_t ant_coex_config_get_req_dec(uint8_t const * const p_buf, uint16_t packet_len, uint8_t * const p_channel) { uint32_t index = SER_CMD_DATA_POS; uint32_t err_code; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_channel); err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, packet_len); return err_code; }
uint32_t uint32_t_enc(void const * const p_field, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_field); SER_ASSERT_NOT_NULL(p_index); uint32_t * p_uint32 = (uint32_t *)p_field; SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); *p_index += uint32_encode(*p_uint32, &p_buf[*p_index]); return NRF_SUCCESS; }
uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, uint32_t packet_len, int8_t * p_tx_power) { SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_tx_power); uint32_t err_code = NRF_SUCCESS; uint32_t index = SER_CMD_DATA_POS; err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power); SER_ASSERT(err_code == NRF_SUCCESS, err_code); SER_ASSERT_LENGTH_EQ(index, packet_len); return NRF_SUCCESS; }
uint32_t ble_gattc_evt_rel_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; uint32_t event_len = 0; uint16_t include_count = 0; uint32_t error_code = NRF_SUCCESS; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(8, packet_len); include_count = uint16_decode(&p_buf[BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION]); event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes)) - sizeof (ble_evt_hdr_t) + (include_count * sizeof (ble_gattc_include_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_REL_DISC_RSP; error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); error_code = ble_gattc_evt_rel_disc_rsp_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.rel_disc_rsp)); SER_ASSERT(error_code == NRF_SUCCESS, error_code); SER_ASSERT_LENGTH_EQ(index, packet_len); return error_code; }
uint32_t ble_gattc_evt_char_vals_read_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; uint32_t event_len = 0; uint32_t error_code = NRF_SUCCESS; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_event_len); SER_ASSERT_LENGTH_LEQ(10, packet_len); event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.char_vals_read_rsp.values)) - sizeof (ble_evt_hdr_t) + uint16_decode(&p_buf[BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION]); if (p_event == NULL) { *p_event_len = event_len; return NRF_SUCCESS; } else { SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); *p_event_len = event_len; } p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; 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)); //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP error_code = ble_gattc_evt_char_vals_read_rsp_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.char_vals_read_rsp)); SER_ASSERT_LENGTH_EQ(index, packet_len); return error_code; }
uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; #if NRF_SD_BLE_API_VERSION > 5 uint8_t conn_cfg_tag; uint8_t adv_handle; err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &adv_handle, &conn_cfg_tag); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_adv_start(adv_handle, conn_cfg_tag); #else ble_gap_addr_t peer_addr; ble_gap_adv_params_t adv_params; ble_gap_adv_params_t * p_adv_params; adv_params.p_peer_addr = &peer_addr; p_adv_params = &adv_params; #if NRF_SD_BLE_API_VERSION >= 4 uint8_t conn_cfg_tag; err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params, &conn_cfg_tag); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_adv_start(p_adv_params, conn_cfg_tag); #else err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_adv_start(p_adv_params); #endif #endif err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; ble_gap_scan_params_t scan_params; ble_gap_scan_params_t * p_scan_params = &scan_params; #if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5 ble_data_t adv_report_buffer; ble_data_t * p_adv_report_buffer = &adv_report_buffer; mp_scan_data = conn_ble_gap_ble_data_buf_alloc(SCAN_BUFFER_ID); adv_report_buffer.p_data = mp_scan_data; adv_report_buffer.len = SER_MAX_ADV_DATA; err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params, &p_adv_report_buffer); SER_ASSERT(err_code == NRF_SUCCESS, err_code); if (p_adv_report_buffer) { conn_ble_gap_scan_data_set(p_adv_report_buffer->p_data); } sd_err_code = sd_ble_gap_scan_start(p_scan_params, p_adv_report_buffer); if (sd_err_code != NRF_SUCCESS) { conn_ble_gap_scan_data_unset(true); } err_code = ble_gap_scan_start_rsp_enc(sd_err_code, p_adv_report_buffer, p_tx_buf, p_tx_buf_len); #else err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_scan_start(p_scan_params); err_code = ble_gap_scan_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); #endif SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
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; }
uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, uint8_t * const p_buf, uint32_t * const p_buf_len) { uint32_t index = 0; uint32_t err_code = NRF_SUCCESS; SER_ASSERT_NOT_NULL(p_buf); SER_ASSERT_NOT_NULL(p_buf_len); uint32_t total_len = *p_buf_len; SER_ASSERT_LENGTH_LEQ(index + 2, total_len); p_buf[index++] = SD_BLE_GAP_ADV_START; p_buf[index++] = (p_adv_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; if (p_adv_params != NULL) { err_code = uint8_t_enc(&(p_adv_params->type), p_buf, total_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = cond_field_enc(p_adv_params->p_peer_addr, p_buf, total_len, &index, ble_gap_addr_enc); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = uint8_t_enc(&(p_adv_params->fp), p_buf, total_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = cond_field_enc(p_adv_params->p_whitelist, p_buf, total_len, &index, ble_gap_whitelist_t_enc); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = uint16_t_enc(&(p_adv_params->interval), p_buf, total_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = uint16_t_enc(&(p_adv_params->timeout), p_buf, total_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); err_code = ble_gap_adv_ch_mask_t_enc(&(p_adv_params->channel_mask), p_buf, total_len, &index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); } *p_buf_len = index; return err_code; }
uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, uint32_t buf_len, uint8_t * * pp_name, uint16_t * * pp_name_len) { uint32_t index = 0; SER_ASSERT_NOT_NULL(pp_name_len); SER_ASSERT_NOT_NULL(*pp_name_len); SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); index++; if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) { return NRF_ERROR_INVALID_PARAM; } if (p_buf[index++] == SER_FIELD_PRESENT) { SER_ASSERT_LENGTH_LEQ(index + 2, buf_len); **pp_name_len = uint16_decode(&p_buf[index]); index += sizeof (uint16_t); } else { *pp_name_len = NULL; } SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) { return NRF_ERROR_INVALID_PARAM; } if (p_buf[index] == SER_FIELD_NOT_PRESENT) { *pp_name = NULL; } return NRF_SUCCESS; }