Пример #1
0
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;
}
Пример #2
0
/**@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);
}
Пример #3
0
/**@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;
}