Skip to content

Commit 5241ce0

Browse files
committed
bluetooth: services: ras: rreq: Add feature read functionality
Add functionality so the RAS RREQ can read the supported features of the RAS RRSP. Signed-off-by: Sean Madigan <[email protected]>
1 parent 7279874 commit 5241ce0

File tree

2 files changed

+131
-0
lines changed
  • include/bluetooth/services
  • subsys/bluetooth/services/ras/rreq

2 files changed

+131
-0
lines changed

include/bluetooth/services/ras.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,20 @@ typedef void (*bt_ras_rreq_rd_overwritten_cb_t)(struct bt_conn *conn, uint16_t r
347347
typedef void (*bt_ras_rreq_ranging_data_get_complete_t)(struct bt_conn *conn,
348348
uint16_t ranging_counter, int err);
349349

350+
/** @brief RAS features read callback.
351+
*
352+
* @param[in] conn Connection Object.
353+
* @param[in] feature_bits Bit 0 set if Real-time Ranging Data supported
354+
* Bit 1 set if Retrieve Lost Ranging Data Segments supported
355+
* Bit 2 set if Abort Operation supported
356+
* Bit 3 set if Filter Ranging Data supported
357+
* All other bits are RFU.
358+
* @param[in] err Error code, 0 if the features were read successfully. Otherwise a
359+
* negative error code.
360+
*/
361+
typedef void (*bt_ras_rreq_features_read_cb_t)(struct bt_conn *conn, uint32_t feature_bits,
362+
int err);
363+
350364
/** @brief Allocate a RREQ context and assign GATT handles. Takes a reference to the connection.
351365
*
352366
* @note RREQ context will be freed automatically on disconnect.
@@ -486,6 +500,19 @@ int bt_ras_rreq_rd_overwritten_subscribe(struct bt_conn *conn, bt_ras_rreq_rd_ov
486500
*/
487501
int bt_ras_rreq_rd_overwritten_unsubscribe(struct bt_conn *conn);
488502

503+
/** @brief Read supported RAS features from peer.
504+
*
505+
* @note Calling from BT RX thread may return an error as bt_gatt_read will not block if
506+
* there are no available TX buffers.
507+
*
508+
* @param[in] conn Connection Object, which already has associated RREQ context.
509+
* @param[in] cb Features read callback.
510+
*
511+
* @retval 0 If the operation was successful.
512+
* Otherwise, a negative error code is returned.
513+
*/
514+
int bt_ras_rreq_read_features(struct bt_conn *conn, bt_ras_rreq_features_read_cb_t cb);
515+
489516
/** @brief Provide step header for each step back to the user.
490517
*
491518
* @param[in] subevent_header Subevent header data.

subsys/bluetooth/services/ras/rreq/ras_rreq.c

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,18 @@ struct bt_ras_rd_overwritten {
5050
bt_ras_rreq_rd_overwritten_cb_t cb;
5151
};
5252

53+
struct bt_ras_features_read {
54+
struct bt_gatt_read_params read_params;
55+
bt_ras_rreq_features_read_cb_t cb;
56+
};
57+
5358
static struct bt_ras_rreq {
5459
struct bt_conn *conn;
5560
struct bt_ras_rreq_cp cp;
5661
struct bt_ras_on_demand_rd on_demand_rd;
5762
struct bt_ras_rd_ready rd_ready;
5863
struct bt_ras_rd_overwritten rd_overwritten;
64+
struct bt_ras_features_read features_read;
5965
} rreq_pool[CONFIG_BT_RAS_RREQ_MAX_ACTIVE_CONN];
6066

6167
static struct bt_ras_rreq *ras_rreq_find(struct bt_conn *conn)
@@ -481,6 +487,69 @@ static int ras_cp_subscribe_params_populate(struct bt_gatt_dm *dm, struct bt_ras
481487
return 0;
482488
}
483489

490+
static uint8_t feature_read_cb(struct bt_conn *conn, uint8_t err,
491+
struct bt_gatt_read_params *params, const void *data,
492+
uint16_t length)
493+
{
494+
struct bt_ras_rreq *rreq = ras_rreq_find(conn);
495+
496+
if (rreq == NULL) {
497+
return BT_GATT_ITER_STOP;
498+
}
499+
500+
if (!rreq->features_read.cb) {
501+
LOG_ERR("No read callback present");
502+
return BT_GATT_ITER_STOP;
503+
}
504+
505+
if (err) {
506+
LOG_ERR("Read value error: %d", err);
507+
rreq->features_read.cb(conn, 0, err);
508+
return BT_GATT_ITER_STOP;
509+
}
510+
511+
if (!data || length != sizeof(uint32_t)) {
512+
rreq->features_read.cb(conn, 0, -EMSGSIZE);
513+
return BT_GATT_ITER_STOP;
514+
}
515+
516+
struct net_buf_simple feature_buf;
517+
518+
net_buf_simple_init_with_data(&feature_buf, (uint8_t *)data, length);
519+
uint16_t feature_bits = net_buf_simple_pull_le32(&feature_buf);
520+
521+
rreq->features_read.cb(conn, feature_bits, err);
522+
523+
rreq->features_read.cb = NULL;
524+
525+
return BT_GATT_ITER_STOP;
526+
}
527+
528+
static int ras_read_features_params_populate(struct bt_gatt_dm *dm, struct bt_ras_rreq *rreq)
529+
{
530+
const struct bt_gatt_dm_attr *gatt_chrc;
531+
const struct bt_gatt_dm_attr *gatt_desc;
532+
533+
/* RAS Features (Mandatory) */
534+
gatt_chrc = bt_gatt_dm_char_by_uuid(dm, BT_UUID_RAS_FEATURES);
535+
if (!gatt_chrc) {
536+
LOG_WRN("Could not locate mandatory RAS Features characteristic");
537+
return -EINVAL;
538+
}
539+
540+
gatt_desc = bt_gatt_dm_desc_by_uuid(dm, gatt_chrc, BT_UUID_RAS_FEATURES);
541+
if (!gatt_desc) {
542+
LOG_WRN("Could not locate mandatory RAS Features descriptor");
543+
return -EINVAL;
544+
}
545+
rreq->features_read.read_params.single.handle = gatt_desc->handle;
546+
rreq->features_read.read_params.func = feature_read_cb;
547+
rreq->features_read.read_params.handle_count = 1;
548+
rreq->features_read.read_params.single.offset = 0;
549+
550+
return 0;
551+
}
552+
484553
int bt_ras_rreq_cp_subscribe(struct bt_conn *conn)
485554
{
486555
int err;
@@ -824,6 +893,41 @@ int bt_ras_rreq_alloc_and_assign_handles(struct bt_gatt_dm *dm, struct bt_conn *
824893
return err;
825894
}
826895

896+
err = ras_read_features_params_populate(dm, rreq);
897+
if (err) {
898+
bt_ras_rreq_free(conn);
899+
return err;
900+
}
901+
902+
return 0;
903+
}
904+
905+
int bt_ras_rreq_read_features(struct bt_conn *conn, bt_ras_rreq_features_read_cb_t cb)
906+
{
907+
int err;
908+
909+
if (cb == NULL || conn == NULL) {
910+
return -EINVAL;
911+
}
912+
913+
struct bt_ras_rreq *rreq = ras_rreq_find(conn);
914+
915+
if (rreq == NULL) {
916+
return -EINVAL;
917+
}
918+
919+
if (rreq->features_read.cb) {
920+
return -EBUSY;
921+
}
922+
923+
rreq->features_read.cb = cb;
924+
925+
err = bt_gatt_read(conn, &rreq->features_read.read_params);
926+
if (err) {
927+
rreq->features_read.cb = NULL;
928+
return err;
929+
}
930+
827931
return 0;
828932
}
829933

0 commit comments

Comments
 (0)