Skip to content

Commit 23bf060

Browse files
nimble/host: add support for Characteristic Extended Properties descriptor
Add support for Characteristic Extended Properties descriptor. For each characteristic that has reliable/auxiliary write flags set an instance of Extended Properties descriptor will be registred.
1 parent 344e83d commit 23bf060

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

nimble/host/include/host/ble_gatt.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ struct ble_hs_cfg;
6565
/** GATT Client Characteristic Configuration descriptor 16-bit UUID. */
6666
#define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902
6767

68+
/** GATT Client Characteristic Configuration descriptor 16-bit UUID. */
69+
#define BLE_GATT_DSC_EXT_PROP_UUID16 0x2900
70+
6871
/** @} */
6972

7073
/**
@@ -246,6 +249,11 @@ struct ble_gatt_dsc {
246249
ble_uuid_any_t uuid;
247250
};
248251

252+
/** Represents a Characteristic Extended Properties descriptor */
253+
struct ble_gatt_cep_dsc {
254+
/** Characteristic Extended properties **/
255+
uint16_t properties;
256+
};
249257

250258
/** Represents a handle-value tuple for multiple handle notifications. */
251259
struct ble_gatt_notif {

nimble/host/src/ble_gatt_priv.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ int ble_gattc_init(void);
187187
#define BLE_GATTS_INC_SVC_LEN_NO_UUID 4
188188
#define BLE_GATTS_INC_SVC_LEN_UUID 6
189189

190+
#define BLE_GATTS_CEP_F_RELIABLE_WRITE 0x0001
191+
#define BLE_GATTS_CEP_F_AUX_WRITE 0x0002
192+
190193
/**
191194
* Contains counts of resources required by the GATT server. The contents of
192195
* this struct are generally used to populate a configuration struct before
@@ -211,6 +214,12 @@ struct ble_gatt_resources {
211214
*/
212215
uint16_t cccds;
213216

217+
/**
218+
* Number of characteristic extended properties descriptors. Each of
219+
* these also contributes to the total descriptor count.
220+
*/
221+
uint16_t ceps;
222+
214223
/** Total number of ATT attributes. */
215224
uint16_t attrs;
216225
};

nimble/host/src/ble_gatts.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ static const ble_uuid_t *uuid_chr =
4343
BLE_UUID16_DECLARE(BLE_ATT_UUID_CHARACTERISTIC);
4444
static const ble_uuid_t *uuid_ccc =
4545
BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16);
46+
static const ble_uuid_t *uuid_cep =
47+
BLE_UUID16_DECLARE(BLE_GATT_DSC_EXT_PROP_UUID16);
4648

4749
static const struct ble_gatt_svc_def **ble_gatts_svc_defs;
4850
static int ble_gatts_num_svc_defs;
@@ -170,6 +172,22 @@ ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
170172
return flags;
171173
}
172174

175+
static uint16_t
176+
ble_gatts_chr_ext_prop_allowed(const struct ble_gatt_chr_def *chr)
177+
{
178+
uint16_t flags;
179+
180+
flags = 0;
181+
if (chr->flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
182+
flags |= BLE_GATTS_CEP_F_RELIABLE_WRITE;
183+
}
184+
if (chr->flags & BLE_GATT_CHR_F_AUX_WRITE) {
185+
flags |= BLE_GATTS_CEP_F_AUX_WRITE;
186+
}
187+
188+
return flags;
189+
}
190+
173191
static uint8_t
174192
ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
175193
{
@@ -820,6 +838,66 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
820838
return 0;
821839
}
822840

841+
static int
842+
ble_gatts_cep_access_cb(uint16_t conn_handle, uint16_t attr_handle,
843+
struct ble_gatt_access_ctxt *ctxt, void *arg)
844+
{
845+
uint16_t prop = POINTER_TO_UINT(arg);
846+
847+
if (ctxt->op != BLE_GATT_ACCESS_OP_READ_DSC) {
848+
return BLE_ATT_ERR_WRITE_NOT_PERMITTED;
849+
}
850+
851+
os_mbuf_append(ctxt->om, &prop, sizeof(prop));
852+
853+
return 0;
854+
}
855+
856+
static int
857+
ble_gatts_cep_access(uint16_t conn_handle, uint16_t attr_handle,
858+
uint8_t att_op, uint16_t offset, struct os_mbuf **om,
859+
void *arg)
860+
{
861+
struct ble_gatt_access_ctxt gatt_ctxt;
862+
int rc;
863+
864+
gatt_ctxt.op = ble_gatts_dsc_op(att_op);
865+
866+
ble_gatts_dsc_inc_stat(gatt_ctxt.op);
867+
rc = ble_gatts_val_access(conn_handle, attr_handle, offset, &gatt_ctxt,
868+
om, ble_gatts_cep_access_cb, arg);
869+
870+
return rc;
871+
}
872+
873+
static int
874+
ble_gatts_register_cep_dsc(uint16_t *att_handle, ble_gatt_chr_flags flags)
875+
{
876+
struct ble_gatt_cep_dsc cep;
877+
int rc;
878+
879+
cep.properties = 0x0000;
880+
if (flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
881+
cep.properties |= BLE_GATTS_CEP_F_RELIABLE_WRITE;
882+
}
883+
if (flags & BLE_GATT_CHR_F_AUX_WRITE) {
884+
/* TODO: Implement Characteristic User Description
885+
* (Core specification 6.0, vol 3, part G, section 3.3.3.2)*/
886+
cep.properties |= BLE_GATTS_CEP_F_AUX_WRITE;
887+
}
888+
889+
rc = ble_att_svr_register(uuid_cep, BLE_ATT_F_READ, 0,
890+
att_handle, ble_gatts_cep_access,
891+
UINT_TO_POINTER(cep.properties));
892+
if (rc != 0) {
893+
return rc;
894+
}
895+
896+
STATS_INC(ble_gatts_stats, dscs);
897+
898+
return 0;
899+
}
900+
823901
static int
824902
ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
825903
const struct ble_gatt_chr_def *chr,
@@ -830,6 +908,7 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
830908
uint16_t def_handle;
831909
uint16_t val_handle;
832910
uint16_t dsc_handle;
911+
uint16_t cep_handle;
833912
uint8_t att_flags;
834913
int rc;
835914

@@ -886,6 +965,14 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
886965
BLE_HS_DBG_ASSERT(dsc_handle == def_handle + 2);
887966
}
888967

968+
if (ble_gatts_chr_ext_prop_allowed(chr) != 0) {
969+
rc = ble_gatts_register_cep_dsc(&cep_handle, chr->flags);
970+
if (rc != 0) {
971+
return rc;
972+
}
973+
BLE_HS_DBG_ASSERT(cep_handle == def_handle + 3);
974+
}
975+
889976
/* Register each descriptor. */
890977
if (chr->descriptors != NULL) {
891978
for (dsc = chr->descriptors; dsc->uuid != NULL; dsc++) {
@@ -2222,6 +2309,21 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
22222309
res->attrs++;
22232310
}
22242311

2312+
/* If the characteristic permits reliable writes or auxiliary
2313+
* writes, it has an Extended Properties descriptor.
2314+
*/
2315+
if (chr->flags & BLE_GATT_CHR_F_AUX_WRITE ||
2316+
chr->flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
2317+
2318+
/* Each CEP requires:
2319+
* o 1 descriptor
2320+
* o 1 attribute
2321+
*/
2322+
res->dscs++;
2323+
res->ceps++;
2324+
res->attrs++;
2325+
}
2326+
22252327
if (chr->descriptors != NULL) {
22262328
for (d = 0; chr->descriptors[d].uuid != NULL; d++) {
22272329
if (!ble_gatts_dsc_is_sane(chr->descriptors + d)) {

0 commit comments

Comments
 (0)