예제 #1
0
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;
}
예제 #7
0
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;
}
예제 #9
0
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;
}
예제 #13
0
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;
}
예제 #18
0
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;
}
예제 #23
0
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;
}
예제 #24
0
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;
}
예제 #27
0
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;
}
예제 #29
0
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;
}
예제 #30
0
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;
}