I need to build a simple BLE dc motor control with a potentiometer to provide the rotational position of the motor.
Anyways, my first step is understanding the Nordic libraries. I opened up the Zephyr peripheral sample and have a few questions.
Here is a code excerpt.
/* Vendor Primary Service Declaration */
BT_GATT_SERVICE_DEFINE(vnd_svc,
BT_GATT_PRIMARY_SERVICE(&vnd_uuid),
BT_GATT_CHARACTERISTIC(&vnd_enc_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_READ_ENCRYPT |
BT_GATT_PERM_WRITE_ENCRYPT,
read_vnd, write_vnd, vnd_value),
BT_GATT_CCC(vnd_ccc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
BT_GATT_CHARACTERISTIC(&vnd_auth_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
BT_GATT_PERM_READ_AUTHEN |
BT_GATT_PERM_WRITE_AUTHEN,
read_vnd, write_vnd, vnd_value),
BT_GATT_CHARACTERISTIC(&vnd_long_uuid.uuid, BT_GATT_CHRC_READ |
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_EXT_PROP,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE |
BT_GATT_PERM_PREPARE_WRITE,
read_long_vnd, write_long_vnd, &vnd_long_value),
BT_GATT_CEP(&vnd_long_cep),
BT_GATT_CHARACTERISTIC(&vnd_signed_uuid.uuid, BT_GATT_CHRC_READ |
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_AUTH,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
read_signed, write_signed, &signed_value),
BT_GATT_CHARACTERISTIC(&vnd_write_cmd_uuid.uuid,
BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_WRITE, NULL,
write_without_rsp_vnd, &vnd_value),
);
static ssize_t read_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, u16_t len, u16_t offset)
{
const char *value = attr->user_data;
return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
strlen(value));
}
static ssize_t write_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, u16_t len, u16_t offset,
u8_t flags)
{
u8_t *value = attr->user_data;
if (offset + len > sizeof(vnd_value)) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}
memcpy(value + offset, buf, len);
return len;
}
Question #1
The code defines various custom characteristics for a custom service. I assume this is just giving an example of what is possible and that those UUID's can be set to any value. Or do vnd_enc and vnd_auth have some specific meaning?
Question #2
Right now reading and writing to those custom attributes are set to callback functions such as read_vnd above. I see the value to read and return to the client is set from the attr->user_data. However, no value is being read when I try to read that characteristic via the LightBlue app.
What is it's value? When you read a characteristic you do not pass in any arguments so I am confused about this.
Question #3
In the write_vnd function I assume the attr->user_data is the value the client wants to write to this characteristic, but I could be wrong. However, I don't understand why the code
is writing to buf. What is the purpose of it?