Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions nimble/host/include/host/ble_gatt.h
Original file line number Diff line number Diff line change
Expand Up @@ -692,9 +692,6 @@ int ble_gatts_notify_custom(uint16_t conn_handle, uint16_t att_handle,
* handle-value pair fits into PDU, or only one characteristic remains in the
* list, regular characteristic notification is sent.
*
* If GATT client doesn't support receiving multiple handle notifications,
* this will use GATT notification for each characteristic, separately.
*
* If value of characteristic is not specified it will be read from local
* GATT database.
*
Expand Down Expand Up @@ -733,9 +730,6 @@ int ble_gatts_notify(uint16_t conn_handle, uint16_t chr_val_handle);
* handle-value pair fits into PDU, or only one characteristic remains in the
* list, regular characteristic notification is sent.
*
* If GATT client doesn't support receiving multiple handle notifications,
* this will use GATT notification for each characteristic, separately.
*
* @param conn_handle The connection over which to execute the
* procedure.
* @param num_handles The number of entries in the "chr_val_handles"
Expand Down
3 changes: 3 additions & 0 deletions nimble/host/src/ble_att_clt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,9 @@ ble_att_clt_tx_notify_mult(uint16_t conn_handle, struct os_mbuf *txom)
ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY);
}

return rc;

err:
os_mbuf_free_chain(txom);
return rc;
}
130 changes: 50 additions & 80 deletions nimble/host/src/ble_gattc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4424,85 +4424,78 @@ ble_gatts_notify_multiple_custom(uint16_t conn_handle,
#endif

int rc;
size_t i = 0;
uint16_t cur_chr_cnt = 0;
/* mtu = MTU - 1 octet (OP code) */
uint16_t mtu = ble_att_mtu(conn_handle) - 1;
size_t i;
struct os_mbuf *txom;
struct ble_hs_conn *conn;
uint16_t le16;
uint8_t supported;
uint16_t total = 1; /* opcode */

txom = ble_hs_mbuf_att_pkt();
if (txom == NULL) {
return BLE_HS_ENOMEM;
/* validate handles sanity */
for (i = 0; i < chr_count; i++) {
if (tuples->handle == 0) {
rc = BLE_HS_EINVAL;
goto err;
}
}

conn = ble_hs_conn_find(conn_handle);
if (conn == NULL) {
return BLE_HS_ENOTCONN;
if (chr_count < 2) {
rc = BLE_HS_EINVAL;
goto err;
}

rc = ble_gatts_peer_cl_sup_feat_get(conn_handle, &supported, sizeof(supported));
if (rc) {
goto err;
}

if ((supported & 0x04) == 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe supported features bit offsets should be globally available, to get rid of magic numbers

https://github.com/apache/mynewt-nimble/blob/master/nimble/host/services/gatt/src/ble_svc_gatt.c#L31-L37

rc = BLE_HS_EREJECT;
goto err;
}

/* Read missing values */
for (i = 0; i < chr_count; i++) {
if (tuples->handle == 0) {
rc = BLE_HS_EINVAL;
goto done;
}
if (tuples[i].value == NULL) {
rc = ble_att_svr_read_local(tuples[i].handle, &tuples[i].value);
if (rc != 0) {
goto done;
goto err;
}
}
}

/* If peer does not support fall back to multiple single value
* Notifications */
if ((conn->bhc_gatt_svr.peer_cl_sup_feat[0] & 0x04) == 0) {
for (i = 0; i < chr_count; i++) {
rc = ble_att_clt_tx_notify(conn_handle, tuples[chr_count].handle,
tuples[chr_count].value);
if (rc != 0) {
goto done;
}
}
/* check if this fits into MTU */
for (i = 0; i < chr_count; i++) {
total += sizeof(uint16_t); /* handle */
total += sizeof(uint16_t); /* length */
total += os_mbuf_len(tuples[i].value);
}

for (i = 0; i < chr_count; i++) {
if (txom->om_len + tuples[i].value->om_len > mtu && cur_chr_cnt < 2) {
rc = ble_att_clt_tx_notify(conn_handle, tuples[i].handle,
tuples[i].value);
if (rc != 0) {
goto done;
}
continue;
} else if (txom->om_len + tuples[i].value->om_len > mtu) {
rc = ble_att_clt_tx_notify_mult(conn_handle, txom);
if (rc != 0) {
goto done;
}
cur_chr_cnt = 0;
/* buffer was consumed, allocate new one */
txom = ble_hs_mbuf_att_pkt();
if (txom == NULL) {
return BLE_HS_ENOMEM;
}
}
if (total > ble_att_mtu(conn_handle)) {
rc = BLE_HS_EMSGSIZE;
goto err;
}

os_mbuf_append(txom, &tuples[i].handle, sizeof(uint16_t));
os_mbuf_append(txom, &tuples[i].value->om_len,
sizeof(uint16_t));
txom = ble_hs_mbuf_att_pkt();
if (txom == NULL) {
rc = BLE_HS_ENOMEM;
goto err;
}

for (i = 0; i < chr_count; i++) {
le16 = htole16(tuples[i].handle);
os_mbuf_append(txom, &le16, sizeof(uint16_t));
le16 = htole16(tuples[i].value->om_len);
os_mbuf_append(txom, &le16, sizeof(uint16_t));
os_mbuf_concat(txom, tuples[i].value);
cur_chr_cnt++;
}

if (cur_chr_cnt == 1) {
rc = ble_att_clt_tx_notify(conn_handle, tuples[chr_count].handle,
tuples[chr_count].value);
} else {
rc = ble_att_clt_tx_notify_mult(conn_handle, txom);
return ble_att_clt_tx_notify_mult(conn_handle, txom);

err:
for (i = 0; i < chr_count; i++) {
os_mbuf_free_chain(tuples[i].value);
}

done:
return rc;
}

Expand All @@ -4514,38 +4507,15 @@ ble_gatts_notify_multiple(uint16_t conn_handle,
#if !MYNEWT_VAL(BLE_GATT_NOTIFY_MULTIPLE)
return BLE_HS_ENOTSUP;
#endif
int rc;
size_t i;
struct ble_gatt_notif tuples[num_handles];
struct ble_hs_conn *conn;

BLE_HS_LOG_DEBUG("conn_handle %d\n", conn_handle);
conn = ble_hs_conn_find(conn_handle);
if (conn == NULL) {
return BLE_HS_ENOTCONN;
}

/** Skip sending to client that doesn't support this feature */
BLE_HS_LOG_DEBUG("ble_gatts_notify_multiple: peer_cl_sup_feat %d\n",
conn->bhc_gatt_svr.peer_cl_sup_feat[0]);
if ((conn->bhc_gatt_svr.peer_cl_sup_feat[0] & 0x04) == 0) {
for (i = 0; i < num_handles; i++) {
rc = ble_gatts_notify(conn_handle, chr_val_handles[i]);
if (rc != 0) {
return rc;
}
}
return 0;
}

for (i = 0; i < num_handles; i++) {
tuples[i].handle = chr_val_handles[i];
tuples[i].value = NULL;
BLE_HS_LOG(DEBUG, "handle 0x%02x\n", tuples[i].handle);
}

rc = ble_gatts_notify_multiple_custom(conn_handle, num_handles, tuples);
return rc;
return ble_gatts_notify_multiple_custom(conn_handle, num_handles, tuples);
}

/*****************************************************************************
Expand Down
Loading