Skip to content

Commit

Permalink
Apps/bttester: add support for sending Multiple Handle Notifications
Browse files Browse the repository at this point in the history
Sending Multiple Handle notifications is triggered by writing multiple
values, at once, to GATT database. New values are set and notification
is sent for each connection.
  • Loading branch information
KKopyscinski committed Oct 16, 2023
1 parent 44c0f98 commit 5209243
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 2 deletions.
6 changes: 6 additions & 0 deletions apps/bttester/src/btp/btp_gatt.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,12 @@ struct btp_gatt_change_database_cmd {
uint8_t visibility;
} __packed;

#define BTP_GATT_SET_MULT_VALUE 0x20
struct btp_gatt_set_mult_val_cmd {
uint16_t count;
uint8_t data[0];
} __packed;

/* GATT events */
#define BTP_GATT_EV_NOTIFICATION 0x80
struct btp_gatt_notification_ev {
Expand Down
84 changes: 83 additions & 1 deletion apps/bttester/src/btp_gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#define PTS_DSC_WRITE 0x000a
#define PTS_DSC_READ_WRITE 0x000b
#define PTS_CHR_NOTIFY 0x0025
#define PTS_CHR_NOTIFY_ALT 0x0026
#define PTS_LONG_CHR_READ_WRITE 0x0015
#define PTS_LONG_CHR_READ_WRITE_ALT 0x0016
#define PTS_LONG_DSC_READ_WRITE 0x001b
Expand All @@ -90,6 +91,11 @@ struct find_attr_data {
uint16_t handle;
};

struct notify_mult_cb_data {
uint16_t tuple_cnt;
uint16_t handles[0];
};

static int
gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt,
Expand Down Expand Up @@ -230,7 +236,17 @@ static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
.uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY),
.access_cb = gatt_svr_read_write_test,
.val_handle = &notify_handle,
.flags = BLE_GATT_CHR_F_NOTIFY |
.flags = BLE_GATT_CHR_F_READ |
BLE_GATT_CHR_F_WRITE |
BLE_GATT_CHR_F_NOTIFY |
BLE_GATT_CHR_F_INDICATE,
}, {
.uuid = PTS_UUID_DECLARE(PTS_CHR_NOTIFY_ALT),
.access_cb = gatt_svr_read_write_test,
.val_handle = &notify_handle,
.flags = BLE_GATT_CHR_F_READ |
BLE_GATT_CHR_F_WRITE |
BLE_GATT_CHR_F_NOTIFY |
BLE_GATT_CHR_F_INDICATE,
}, {
0, /* No more characteristics in this service. */
Expand Down Expand Up @@ -322,6 +338,8 @@ gatt_svr_read_write_test(uint16_t conn_handle, uint16_t attr_handle,
switch (uuid16) {
case PTS_CHR_READ_WRITE:
case PTS_CHR_READ_WRITE_ALT:
case PTS_CHR_NOTIFY:
case PTS_CHR_NOTIFY_ALT:
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
rc = gatt_svr_chr_write(conn_handle, attr_handle,
ctxt->om, 0,
Expand Down Expand Up @@ -1836,6 +1854,65 @@ get_attr_val(const void *cmd, uint16_t cmd_len,
return status;
}

int
notify_multiple(uint16_t conn_handle, void *arg)
{
struct notify_mult_cb_data *notify_data =
(struct notify_mult_cb_data *) arg;
int rc;

SYS_LOG_DBG("")

rc = ble_gatts_notify_multiple(conn_handle,
notify_data->tuple_cnt,
notify_data->handles);

return rc;
}

static uint8_t
set_mult(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct btp_gatt_set_mult_val_cmd *cp = cmd;
struct ble_gatt_notif tuples[16];
int i;
int rc = 0;
int data_idx = 0;
uint16_t data_len;
struct notify_mult_cb_data cb_data;

for (i = 0; i < cp->count; i++) {
tuples[i].handle = get_le16(cp->data + data_idx);
data_idx += 2;
tuples[i].value = ble_hs_mbuf_att_pkt();
if (tuples[i].value == NULL) {
rc = ENOMEM;
goto done;
}

data_len = get_le16(cp->data + data_idx);
data_idx += 2;

os_mbuf_append(tuples[i].value, cp->data + data_idx, data_len);
data_idx += data_len;
}

for (i = 0; i < cp->count; i++) {
ble_att_svr_write_local(tuples[i].handle, tuples[i].value);
cb_data.handles[i] = tuples[i].handle;
}

cb_data.tuple_cnt = cp->count;
ble_gap_conn_foreach_handle(notify_multiple, (void *)&cb_data);
done:
if (rc != 0) {
return BTP_STATUS_FAILED;
}

return BTP_STATUS_SUCCESS;
}

static uint8_t
change_database(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
Expand Down Expand Up @@ -2018,6 +2095,11 @@ static const struct btp_handler handlers[] = {
.expect_len = sizeof(struct btp_gatt_get_attribute_value_cmd),
.func = get_attr_val,
},
{
.opcode = BTP_GATT_SET_MULT_VALUE,
.expect_len = BTP_HANDLER_LENGTH_VARIABLE,
.func = set_mult,
},
};

int
Expand Down
2 changes: 1 addition & 1 deletion apps/bttester/src/btp_gatt_cl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,7 @@ read_var_cb(uint16_t conn_handle,
SYS_LOG_DBG("status=%d", error->status);

if (ble_gap_conn_find(conn_handle, &conn)) {
return BTP_STATUS_FAILED;
return BTP_STATUS_FAILED;
}

memcpy(attrs, attr, sizeof(struct ble_gatt_attr) * num_attrs);
Expand Down
2 changes: 2 additions & 0 deletions apps/bttester/syscfg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,5 @@ syscfg.vals:

BLE_MESH_ADV_BUF_COUNT: 20
BLE_MESH_TX_SEG_MAX: 6

BLE_EATT_CHAN_NUM: 2

0 comments on commit 5209243

Please sign in to comment.