Skip to content

Commit cacfff5

Browse files
nimble/host: add gatts method for async authorization
This method can be used for asynchronous authorization. It can be used by application to trigger access callback of characteristic and send ATT response, in case where ble_att_svr_rx_foo returns with BLE_HS_EPENDING without triggering att response. Move ble_att_svr_tx_rsp() declaration to ble_att_priv.h
1 parent 72ea3c3 commit cacfff5

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

nimble/host/include/host/ble_gatt.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,24 @@ 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+
* Handles authorization of pending ATT request. If the specified attribute
1219+
* handle is found on pending_attr_list, the operation is performed by calling
1220+
* the registered access callback and ATT response is issued.
1221+
*
1222+
* @param conn_handle The connection over which to authorize a
1223+
* pending ATT procedure
1224+
* @param attr_handle The Handle of characteristic to perform att
1225+
* procedure on.
1226+
* @param authorize Whether to authorize a procedure
1227+
*
1228+
* @return 0 on success;
1229+
* BLE_HS_EAUTHOR if no matching attribute is
1230+
* found on pending_attr_list.
1231+
*/
1232+
int ble_gatts_pending_req_auth(uint16_t conn_handle, uint16_t attr_handle,
1233+
int authorize);
1234+
12171235
#ifdef __cplusplus
12181236
}
12191237
#endif

nimble/host/src/ble_att_priv.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ struct pending_attr {
131131
struct ble_att_svr_entry *entry;
132132
uint16_t offset;
133133
struct os_mbuf *om;
134-
uint16_t opcode;
134+
uint16_t access_opcode;
135+
uint8_t att_opcode;
135136
};
136137

137138
SLIST_HEAD(pending_attr_list_head, pending_attr);
@@ -238,6 +239,12 @@ void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle);
238239
int ble_att_svr_tx_error_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom,
239240
uint8_t req_op, uint16_t handle,
240241
uint8_t error_code);
242+
243+
int ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status,
244+
struct os_mbuf *om, uint8_t att_op,
245+
uint8_t err_status, uint16_t err_handle);
246+
int ble_att_svr_build_write_rsp(struct os_mbuf **rxom,
247+
struct os_mbuf**out_txom, uint8_t *att_err);
241248
/*** $clt */
242249

243250
/** An information-data entry in a find information response. */

nimble/host/src/ble_gatts.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,72 @@ 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+
int authorize)
2039+
{
2040+
struct pending_attr *attr;
2041+
struct pending_attr *rsp_attr;
2042+
ble_att_svr_access_fn *access_cb;
2043+
int rc;
2044+
uint8_t att_err = 0;
2045+
struct os_mbuf *txom;
2046+
2047+
/* Silence warnings */
2048+
rc = 0;
2049+
rsp_attr = NULL;
2050+
txom = NULL;
2051+
2052+
ble_hs_lock();
2053+
SLIST_FOREACH(attr, &pending_attr_list, next) {
2054+
if (attr->conn_handle == conn_handle &&
2055+
attr->entry->ha_handle_id == attr_handle) {
2056+
rsp_attr = attr;
2057+
SLIST_REMOVE(&pending_attr_list, attr, pending_attr, next);
2058+
}
2059+
}
2060+
ble_hs_unlock();
2061+
2062+
if (!rsp_attr) {
2063+
/* No matching attribute was found on pending_attr_list */
2064+
return BLE_HS_ENOENT;
2065+
}
2066+
2067+
/* TODO: handle prepare write requests*/
2068+
2069+
if (rsp_attr->att_opcode == BLE_ATT_OP_WRITE_REQ) {
2070+
/* TODO: check if it failed, figure out req variable */
2071+
rc = ble_att_svr_build_write_rsp(&rsp_attr->om, &txom, &att_err);
2072+
if (rc != 0) {
2073+
goto done;
2074+
}
2075+
}
2076+
2077+
if (authorize) {
2078+
access_cb = rsp_attr->entry->ha_cb;
2079+
rc = access_cb(rsp_attr->conn_handle, rsp_attr->entry->ha_handle_id,
2080+
rsp_attr->access_opcode, rsp_attr->offset,
2081+
&rsp_attr->om, rsp_attr->entry->ha_cb_arg);
2082+
} else {
2083+
rc = BLE_ATT_ERR_INSUFFICIENT_AUTHOR;
2084+
}
2085+
2086+
if (rsp_attr->att_opcode == BLE_ATT_OP_WRITE_REQ) {
2087+
rsp_attr->om = txom;
2088+
}
2089+
2090+
if (rc != 0 ) {
2091+
att_err = rc;
2092+
rc = BLE_HS_EAPP;
2093+
}
2094+
2095+
/* TODO: don't use BLE_L2CAP_CID_ATT, find a way to get cid */
2096+
done:
2097+
ble_att_svr_tx_rsp(conn_handle, BLE_L2CAP_CID_ATT, rc, rsp_attr->om,
2098+
rsp_attr->att_opcode, att_err, attr_handle);
2099+
2100+
return 0;
2101+
}
2102+
20372103
int
20382104
ble_gatts_add_svcs(const struct ble_gatt_svc_def *svcs)
20392105
{

0 commit comments

Comments
 (0)