Skip to content

Commit 87aa57f

Browse files
nimble/host: add gatts method for async authorization
ble_gatts_pending_req_auth method can be used to prepare and send response to pending ATT request e.g. when user has to authorize operation on attribute that requires authorization
1 parent 8cbacaa commit 87aa57f

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

nimble/host/include/host/ble_gatt.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,23 @@ int ble_gatts_start(void);
12141214
*/
12151215
int ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat, uint8_t len);
12161216

1217+
/**
1218+
* Prepares and sends a response for pending ATT request.
1219+
*
1220+
* @param conn_handle The connection over which to authorize a
1221+
* pending ATT procedure
1222+
* @param attr_handle The Handle of characteristic to perform att
1223+
* procedure on.
1224+
* @param cid L2CAP channel ID on which request has been
1225+
* received
1226+
*
1227+
* @return 0 on success;
1228+
* BLE_HS_EAUTHOR if no matching attribute is
1229+
* found on pending_attr_list.
1230+
*/
1231+
int ble_gatts_pending_req_auth(uint16_t conn_handle, uint16_t attr_handle,
1232+
uint16_t cid);
1233+
12171234
#ifdef __cplusplus
12181235
}
12191236
#endif

nimble/host/src/ble_gatts.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,129 @@ ble_gatts_find_dsc(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid,
20342034
}
20352035
}
20362036

2037+
int ble_gatts_pending_req_auth(uint16_t conn_handle, uint16_t attr_handle,
2038+
uint16_t cid)
2039+
{
2040+
struct ble_att_prep_write_cmd *prep_req;
2041+
struct ble_att_write_req *write_req;
2042+
struct pending_attr *pend_attr;
2043+
struct pending_attr *attr;
2044+
uint8_t att_err;
2045+
int rc;
2046+
2047+
/* Silence warnings */
2048+
rc = 0;
2049+
att_err = 0;
2050+
pend_attr = NULL;
2051+
2052+
ble_hs_lock();
2053+
SLIST_FOREACH(attr, &pending_attr_list, next) {
2054+
if (attr->conn_handle == conn_handle &&
2055+
attr->cid == cid) {
2056+
pend_attr = attr;
2057+
}
2058+
}
2059+
ble_hs_unlock();
2060+
2061+
if (!pend_attr) {
2062+
/* No matching attribute was found on pending_attr_list */
2063+
return BLE_HS_ENOENT;
2064+
}
2065+
2066+
if (attr_handle != 0) {
2067+
att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
2068+
rc = BLE_HS_EAUTHOR;
2069+
ble_att_svr_tx_rsp(conn_handle, cid, rc, pend_attr->om,
2070+
pend_attr->att_opcode, att_err, attr_handle);
2071+
goto done;
2072+
}
2073+
2074+
switch(pend_attr->att_opcode) {
2075+
case BLE_ATT_OP_READ_REQ:
2076+
rc = ble_att_svr_create_read_rsp(conn_handle,cid, pend_attr->om, rc,
2077+
BLE_ATT_OP_READ_REQ,
2078+
pend_attr->attr_handle,
2079+
pend_attr->offset, &att_err);
2080+
goto done;
2081+
2082+
case BLE_ATT_OP_READ_BLOB_REQ:
2083+
rc = ble_att_svr_create_read_rsp(conn_handle,cid, pend_attr->om, rc,
2084+
BLE_ATT_OP_READ_BLOB_REQ,
2085+
pend_attr->attr_handle,
2086+
pend_attr->offset, &att_err);
2087+
goto done;
2088+
2089+
case BLE_ATT_OP_WRITE_REQ:
2090+
write_req = (struct ble_att_write_req *)(pend_attr)->om->om_data;
2091+
rc = ble_att_svr_create_write_rsp(conn_handle, cid, &pend_attr->om,
2092+
rc, write_req, pend_attr->offset,
2093+
pend_attr->attr_handle, &att_err);
2094+
goto done;
2095+
2096+
case BLE_ATT_OP_READ_MULT_REQ:
2097+
/* iterate through remaining requested handles */
2098+
while ((OS_MBUF_PKTLEN(pend_attr->om) - pend_attr->offset) >= 2) {
2099+
os_mbuf_copydata(pend_attr->om, pend_attr->offset, 2,
2100+
&attr_handle);
2101+
pend_attr->offset += 2;
2102+
rc = ble_att_svr_check_author_perm(conn_handle, attr_handle,
2103+
&att_err,
2104+
BLE_ATT_ACCESS_OP_WRITE, cid);
2105+
if (rc == BLE_HS_EPENDING) {
2106+
return rc;
2107+
}
2108+
if (rc != 0) {
2109+
break;
2110+
}
2111+
}
2112+
2113+
rc = ble_att_svr_create_read_mult_rsp(conn_handle, cid, &pend_attr->om,
2114+
rc, &att_err, &attr_handle);
2115+
goto done;
2116+
2117+
case BLE_ATT_OP_READ_MULT_VAR_REQ:
2118+
/* iterate through remaining requested handles */
2119+
while ((OS_MBUF_PKTLEN(pend_attr->om) - pend_attr->offset) >= 2) {
2120+
os_mbuf_copydata(pend_attr->om, pend_attr->offset, 2,
2121+
&attr_handle);
2122+
pend_attr->offset += 2;
2123+
rc = ble_att_svr_check_author_perm(conn_handle, attr_handle,
2124+
&att_err,
2125+
BLE_ATT_ACCESS_OP_WRITE, cid);
2126+
if (rc == BLE_HS_EPENDING) {
2127+
return rc;
2128+
}
2129+
if (rc != 0) {
2130+
break;
2131+
}
2132+
}
2133+
2134+
rc = ble_att_svr_create_read_mult_var_len_rsp(conn_handle, cid,
2135+
&pend_attr->om, rc,
2136+
&att_err, &attr_handle);
2137+
goto done;
2138+
2139+
case BLE_ATT_OP_PREP_WRITE_REQ:
2140+
prep_req = (struct ble_att_prep_write_cmd *)(pend_attr)->om->om_data;
2141+
rc = ble_att_svr_create_prep_write_rsp(conn_handle, cid,
2142+
&pend_attr->om, prep_req, rc,
2143+
att_err, attr_handle);
2144+
return rc;
2145+
}
2146+
2147+
done:
2148+
ble_hs_lock();
2149+
SLIST_FOREACH(attr, &pending_attr_list, next) {
2150+
if (attr->conn_handle == conn_handle &&
2151+
attr->cid == cid) {
2152+
SLIST_REMOVE(&pending_attr_list, attr, pending_attr, next);
2153+
}
2154+
}
2155+
ble_hs_unlock();
2156+
2157+
return rc;
2158+
}
2159+
20372160
int
20382161
ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs)
20392162
{

0 commit comments

Comments
 (0)