Skip to content

Commit 6a629f2

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 58944c3 commit 6a629f2

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
@@ -1245,6 +1245,23 @@ int ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_
12451245
int ble_gatts_read_cccd(uint16_t conn_handle, uint16_t chr_val_handle,
12461246
uint8_t *cccd_value);
12471247

1248+
/**
1249+
* Prepares and sends a response for pending ATT request.
1250+
*
1251+
* @param conn_handle The connection over which to authorize a
1252+
* pending ATT procedure
1253+
* @param attr_handle The Handle of characteristic to perform att
1254+
* procedure on.
1255+
* @param cid L2CAP channel ID on which request has been
1256+
* received
1257+
*
1258+
* @return 0 on success;
1259+
* BLE_HS_EAUTHOR if no matching attribute is
1260+
* found on pending_attr_list.
1261+
*/
1262+
int ble_gatts_pending_req_auth(uint16_t conn_handle, uint16_t attr_handle,
1263+
uint16_t cid);
1264+
12481265
#ifdef __cplusplus
12491266
}
12501267
#endif

nimble/host/src/ble_gatts.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,129 @@ ble_gatts_find_dsc(const ble_uuid_t *svc_uuid, const ble_uuid_t *chr_uuid,
20612061
}
20622062
}
20632063

2064+
int ble_gatts_pending_req_auth(uint16_t conn_handle, uint16_t attr_handle,
2065+
uint16_t cid)
2066+
{
2067+
struct ble_att_prep_write_cmd *prep_req;
2068+
struct ble_att_write_req *write_req;
2069+
struct pending_attr *pend_attr;
2070+
struct pending_attr *attr;
2071+
uint8_t att_err;
2072+
int rc;
2073+
2074+
/* Silence warnings */
2075+
rc = 0;
2076+
att_err = 0;
2077+
pend_attr = NULL;
2078+
2079+
ble_hs_lock();
2080+
SLIST_FOREACH(attr, &pending_attr_list, next) {
2081+
if (attr->conn_handle == conn_handle &&
2082+
attr->cid == cid) {
2083+
pend_attr = attr;
2084+
}
2085+
}
2086+
ble_hs_unlock();
2087+
2088+
if (!pend_attr) {
2089+
/* No matching attribute was found on pending_attr_list */
2090+
return BLE_HS_ENOENT;
2091+
}
2092+
2093+
if (attr_handle != 0) {
2094+
att_err = BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
2095+
rc = BLE_HS_EAUTHOR;
2096+
ble_att_svr_tx_rsp(conn_handle, cid, rc, pend_attr->om,
2097+
pend_attr->att_opcode, att_err, attr_handle);
2098+
goto done;
2099+
}
2100+
2101+
switch(pend_attr->att_opcode) {
2102+
case BLE_ATT_OP_READ_REQ:
2103+
rc = ble_att_svr_create_read_rsp(conn_handle,cid, pend_attr->om, rc,
2104+
BLE_ATT_OP_READ_REQ,
2105+
pend_attr->attr_handle,
2106+
pend_attr->offset, &att_err);
2107+
goto done;
2108+
2109+
case BLE_ATT_OP_READ_BLOB_REQ:
2110+
rc = ble_att_svr_create_read_rsp(conn_handle,cid, pend_attr->om, rc,
2111+
BLE_ATT_OP_READ_BLOB_REQ,
2112+
pend_attr->attr_handle,
2113+
pend_attr->offset, &att_err);
2114+
goto done;
2115+
2116+
case BLE_ATT_OP_WRITE_REQ:
2117+
write_req = (struct ble_att_write_req *)(pend_attr)->om->om_data;
2118+
rc = ble_att_svr_create_write_rsp(conn_handle, cid, &pend_attr->om,
2119+
rc, write_req, pend_attr->offset,
2120+
pend_attr->attr_handle, &att_err);
2121+
goto done;
2122+
2123+
case BLE_ATT_OP_READ_MULT_REQ:
2124+
/* iterate through remaining requested handles */
2125+
while ((OS_MBUF_PKTLEN(pend_attr->om) - pend_attr->offset) >= 2) {
2126+
os_mbuf_copydata(pend_attr->om, pend_attr->offset, 2,
2127+
&attr_handle);
2128+
pend_attr->offset += 2;
2129+
rc = ble_att_svr_check_author_perm(conn_handle, attr_handle,
2130+
&att_err,
2131+
BLE_ATT_ACCESS_OP_WRITE, cid);
2132+
if (rc == BLE_HS_EPENDING) {
2133+
return rc;
2134+
}
2135+
if (rc != 0) {
2136+
break;
2137+
}
2138+
}
2139+
2140+
rc = ble_att_svr_create_read_mult_rsp(conn_handle, cid, &pend_attr->om,
2141+
rc, &att_err, &attr_handle);
2142+
goto done;
2143+
2144+
case BLE_ATT_OP_READ_MULT_VAR_REQ:
2145+
/* iterate through remaining requested handles */
2146+
while ((OS_MBUF_PKTLEN(pend_attr->om) - pend_attr->offset) >= 2) {
2147+
os_mbuf_copydata(pend_attr->om, pend_attr->offset, 2,
2148+
&attr_handle);
2149+
pend_attr->offset += 2;
2150+
rc = ble_att_svr_check_author_perm(conn_handle, attr_handle,
2151+
&att_err,
2152+
BLE_ATT_ACCESS_OP_WRITE, cid);
2153+
if (rc == BLE_HS_EPENDING) {
2154+
return rc;
2155+
}
2156+
if (rc != 0) {
2157+
break;
2158+
}
2159+
}
2160+
2161+
rc = ble_att_svr_create_read_mult_var_len_rsp(conn_handle, cid,
2162+
&pend_attr->om, rc,
2163+
&att_err, &attr_handle);
2164+
goto done;
2165+
2166+
case BLE_ATT_OP_PREP_WRITE_REQ:
2167+
prep_req = (struct ble_att_prep_write_cmd *)(pend_attr)->om->om_data;
2168+
rc = ble_att_svr_create_prep_write_rsp(conn_handle, cid,
2169+
&pend_attr->om, prep_req, rc,
2170+
att_err, attr_handle);
2171+
return rc;
2172+
}
2173+
2174+
done:
2175+
ble_hs_lock();
2176+
SLIST_FOREACH(attr, &pending_attr_list, next) {
2177+
if (attr->conn_handle == conn_handle &&
2178+
attr->cid == cid) {
2179+
SLIST_REMOVE(&pending_attr_list, attr, pending_attr, next);
2180+
}
2181+
}
2182+
ble_hs_unlock();
2183+
2184+
return rc;
2185+
}
2186+
20642187
int
20652188
ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs)
20662189
{

0 commit comments

Comments
 (0)