Skip to content

Commit 0b27c37

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 7044510 commit 0b27c37

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
@@ -160,6 +160,9 @@ int ble_gattc_init(void);
160160
#define BLE_GATTS_INC_SVC_LEN_NO_UUID 4
161161
#define BLE_GATTS_INC_SVC_LEN_UUID 6
162162

163+
#define BLE_GATTS_CEP_F_RELIABLE_WRITE 0x0001
164+
#define BLE_GATTS_CEP_F_AUX_WRITE 0x0002
165+
163166
/**
164167
* Contains counts of resources required by the GATT server. The contents of
165168
* this struct are generally used to populate a configuration struct before
@@ -184,6 +187,12 @@ struct ble_gatt_resources {
184187
*/
185188
uint16_t cccds;
186189

190+
/**
191+
* Number of characteristic extended properties descriptors. Each of
192+
* these also contributes to the total descriptor count.
193+
*/
194+
uint16_t ceps;
195+
187196
/** Total number of ATT attributes. */
188197
uint16_t attrs;
189198
};

nimble/host/src/ble_gatts.c

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

4648
static const struct ble_gatt_svc_def **ble_gatts_svc_defs;
4749
static int ble_gatts_num_svc_defs;
@@ -161,6 +163,22 @@ ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
161163
return flags;
162164
}
163165

166+
static uint16_t
167+
ble_gatts_chr_ext_prop_allowed(const struct ble_gatt_chr_def *chr)
168+
{
169+
uint16_t flags;
170+
171+
flags = 0;
172+
if (chr->flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
173+
flags |= BLE_GATTS_CEP_F_RELIABLE_WRITE;
174+
}
175+
if (chr->flags & BLE_GATT_CHR_F_AUX_WRITE) {
176+
flags |= BLE_GATTS_CEP_F_AUX_WRITE;
177+
}
178+
179+
return flags;
180+
}
181+
164182
static uint8_t
165183
ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
166184
{
@@ -811,6 +829,66 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
811829
return 0;
812830
}
813831

832+
static int
833+
ble_gatts_cep_access_cb(uint16_t conn_handle, uint16_t attr_handle,
834+
struct ble_gatt_access_ctxt *ctxt, void *arg)
835+
{
836+
uint16_t prop = POINTER_TO_UINT(arg);
837+
838+
if (ctxt->op != BLE_GATT_ACCESS_OP_READ_DSC) {
839+
return BLE_ATT_ERR_WRITE_NOT_PERMITTED;
840+
}
841+
842+
os_mbuf_append(ctxt->om, &prop, sizeof(prop));
843+
844+
return 0;
845+
}
846+
847+
static int
848+
ble_gatts_cep_access(uint16_t conn_handle, uint16_t attr_handle,
849+
uint8_t att_op, uint16_t offset, struct os_mbuf **om,
850+
void *arg)
851+
{
852+
struct ble_gatt_access_ctxt gatt_ctxt;
853+
int rc;
854+
855+
gatt_ctxt.op = ble_gatts_dsc_op(att_op);
856+
857+
ble_gatts_dsc_inc_stat(gatt_ctxt.op);
858+
rc = ble_gatts_val_access(conn_handle, attr_handle, offset, &gatt_ctxt,
859+
om, ble_gatts_cep_access_cb, arg);
860+
861+
return rc;
862+
}
863+
864+
static int
865+
ble_gatts_register_cep_dsc(uint16_t *att_handle, ble_gatt_chr_flags flags)
866+
{
867+
struct ble_gatt_cep_dsc cep;
868+
int rc;
869+
870+
cep.properties = 0x0000;
871+
if (flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
872+
cep.properties |= BLE_GATTS_CEP_F_RELIABLE_WRITE;
873+
}
874+
if (flags & BLE_GATT_CHR_F_AUX_WRITE) {
875+
/* TODO: Implement Characteristic User Description
876+
* (Core specification 6.0, vol 3, part G, section 3.3.3.2)*/
877+
cep.properties |= BLE_GATTS_CEP_F_AUX_WRITE;
878+
}
879+
880+
rc = ble_att_svr_register(uuid_cep, BLE_ATT_F_READ, 0,
881+
att_handle, ble_gatts_cep_access,
882+
UINT_TO_POINTER(cep.properties));
883+
if (rc != 0) {
884+
return rc;
885+
}
886+
887+
STATS_INC(ble_gatts_stats, dscs);
888+
889+
return 0;
890+
}
891+
814892
static int
815893
ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
816894
const struct ble_gatt_chr_def *chr,
@@ -821,6 +899,7 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
821899
uint16_t def_handle;
822900
uint16_t val_handle;
823901
uint16_t dsc_handle;
902+
uint16_t cep_handle;
824903
uint8_t att_flags;
825904
int rc;
826905

@@ -877,6 +956,14 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
877956
BLE_HS_DBG_ASSERT(dsc_handle == def_handle + 2);
878957
}
879958

959+
if (ble_gatts_chr_ext_prop_allowed(chr) != 0) {
960+
rc = ble_gatts_register_cep_dsc(&cep_handle, chr->flags);
961+
if (rc != 0) {
962+
return rc;
963+
}
964+
BLE_HS_DBG_ASSERT(cep_handle == def_handle + 3);
965+
}
966+
880967
/* Register each descriptor. */
881968
if (chr->descriptors != NULL) {
882969
for (dsc = chr->descriptors; dsc->uuid != NULL; dsc++) {
@@ -2188,6 +2275,21 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
21882275
res->attrs++;
21892276
}
21902277

2278+
/* If the characteristic permits reliable writes or auxiliary
2279+
* writes, it has an Extended Properties descriptor.
2280+
*/
2281+
if (chr->flags & BLE_GATT_CHR_F_AUX_WRITE ||
2282+
chr->flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
2283+
2284+
/* Each CEP requires:
2285+
* o 1 descriptor
2286+
* o 1 attribute
2287+
*/
2288+
res->dscs++;
2289+
res->ceps++;
2290+
res->attrs++;
2291+
}
2292+
21912293
if (chr->descriptors != NULL) {
21922294
for (d = 0; chr->descriptors[d].uuid != NULL; d++) {
21932295
if (!ble_gatts_dsc_is_sane(chr->descriptors + d)) {

0 commit comments

Comments
 (0)