ParserStatus parse_frame(in_cmd_t *cmd, plchar_t *payload, const frame_t frame) { int in_pos = 0; int in_len = strlen(frame); if (frame[in_pos++] != START_CHAR) { return PARSER_INVALID_START; } mk_address_t addr = addr_decode(frame[in_pos++]); if (addr < 1 || addr > 3) { return PARSER_INVALID_ADDRESS; } in_cmd_t _cmd = MERGE_ADDR_CMD(addr, frame[in_pos++]); if (!in_command_exists(_cmd)) { return PARSER_INVALID_COMMAND; } const char *crc_chars = &frame[in_len - 3]; crc_t crc = calc_crc(frame, in_len - 3); if (!crc_ok(crc, crc_chars)) { return PARSER_INVALID_CRC; /* invalid crc */ } (void)mb64_decode(payload, in_len - 6, &frame[in_pos]); *cmd = _cmd; return PARSER_NO_ERROR; }
/**@brief Function for decoding a command packet with RPC_SD_BLE_GAP_ADV_START opcode. * * This function will decode the command, call the BLE Stack API, and also send command response * to the peer through the the transport layer. * * @param[in] p_command The encoded structure that needs to be decoded and passed on * to the BLE Stack API. * @param[in] command_len The length of the encoded command read from transport layer. * * @retval NRF_SUCCESS If the decoding of the command was successful, the SoftDevice * API was called, and the command response was sent to peer, * otherwise an error code. * @retval NRF_ERROR_INVALID_LENGTH If the content length of the packet is not conforming to the * codec specification. */ static uint32_t gap_adv_start_handle(uint8_t * p_command, uint32_t command_len) { ble_gap_adv_params_t adv_params; ble_gap_addr_t directed_peer_address; ble_gap_whitelist_t white_list; uint32_t index = 0; adv_params.type = p_command[index++]; RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); if (p_command[index++] == RPC_BLE_FIELD_PRESENT) { // Peer Address Present. Decode the peer address. index += addr_decode(&directed_peer_address, &(p_command[index])); adv_params.p_peer_addr = &(directed_peer_address); RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); } else { adv_params.p_peer_addr = NULL; } adv_params.fp = p_command[index++]; RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); // Whitelist present. if (p_command[index++] == RPC_BLE_FIELD_PRESENT) { uint8_t decoded_length = 0; uint32_t err_code = whitelist_decode(&white_list, &(p_command[index]), &decoded_length); if (err_code != NRF_SUCCESS) { return ble_rpc_cmd_resp_send(SD_BLE_GAP_ADV_START, err_code); } index = index + decoded_length; RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); adv_params.p_whitelist = &white_list; RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); } else { adv_params.p_whitelist = NULL; } adv_params.interval = uint16_decode(&p_command[index]); index += sizeof(uint16_t); RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); adv_params.timeout = uint16_decode(&p_command[index]); RPC_DECODER_LENGTH_CHECK(command_len, index, SD_BLE_GAP_ADV_START); uint32_t err_code = sd_ble_gap_adv_start(&adv_params); return ble_rpc_cmd_resp_send(SD_BLE_GAP_ADV_START, err_code); }
/**@brief Function for decoding a ble_gap_whitelist_t from an input buffer. * * @param[out] p_wl The pointer to the decode result structure. * @param[in] p_buffer The buffer containing the encoded ble_gap_whitelist_t. * @param[out] p_len Number of bytes decoded. * * @retval NRF_SUCCESS If the decoding of whitelists was successful. * @retval NRF_ERROR_INVALID_LENGTH If the content length of the packet is not conforming to the * codec specification. */ static uint32_t whitelist_decode(ble_gap_whitelist_t * const p_wl, const uint8_t * const p_buffer, uint8_t * p_len) { uint32_t index = 0; uint32_t error_code = NRF_SUCCESS; static ble_gap_addr_t * p_addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; static ble_gap_addr_t addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; static ble_gap_irk_t * p_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; static ble_gap_irk_t irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; p_wl->addr_count = p_buffer[index++]; if (p_wl->addr_count > BLE_GAP_WHITELIST_ADDR_MAX_COUNT) { error_code = NRF_ERROR_INVALID_LENGTH; } else { uint32_t i; for (i = 0; i < p_wl->addr_count; i++) { index += addr_decode(&(addresses[i]), &(p_buffer[index])); p_addresses[i] = &(addresses[i]); } p_wl->irk_count = p_buffer[index++]; if (p_wl->irk_count > BLE_GAP_WHITELIST_IRK_MAX_COUNT) { error_code = NRF_ERROR_INVALID_LENGTH; } else { for (i = 0; i < p_wl->irk_count; i++) { // Reuse the memory used by the buffer because irk is also a byte array like // the buffer. memcpy(irks[i].irk, &(p_buffer[index]), BLE_GAP_SEC_KEY_LEN); index += BLE_GAP_SEC_KEY_LEN; p_irks[i] = &irks[i]; } } p_wl->pp_addrs = (p_wl->addr_count != 0) ? p_addresses : NULL; p_wl->pp_irks = (p_wl->irk_count != 0) ? p_irks : NULL; } *p_len = index; return error_code; }