Skip to content

Commit a7f42ba

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 f14e458 commit a7f42ba

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

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

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

nimble/host/src/ble_gatts.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ static const ble_uuid_t *uuid_chr =
3939
BLE_UUID16_DECLARE(BLE_ATT_UUID_CHARACTERISTIC);
4040
static const ble_uuid_t *uuid_ccc =
4141
BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16);
42+
static const ble_uuid_t *uuid_cep =
43+
BLE_UUID16_DECLARE(BLE_GATT_DSC_EXT_PROP_UUID16);
4244

4345
static const struct ble_gatt_svc_def **ble_gatts_svc_defs;
4446
static int ble_gatts_num_svc_defs;
@@ -154,6 +156,22 @@ ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
154156
return flags;
155157
}
156158

159+
static uint16_t
160+
ble_gatts_chr_ext_prop_allowed(const struct ble_gatt_chr_def *chr)
161+
{
162+
uint16_t flags;
163+
164+
flags = 0;
165+
if (chr->flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
166+
flags |= BLE_GATTS_CEP_F_RELIABLE_WRITE;
167+
}
168+
if (chr->flags & BLE_GATT_CHR_F_AUX_WRITE) {
169+
flags |= BLE_GATTS_CEP_F_AUX_WRITE;
170+
}
171+
172+
return flags;
173+
}
174+
157175
static uint8_t
158176
ble_gatts_att_flags_from_chr_flags(ble_gatt_chr_flags chr_flags)
159177
{
@@ -804,6 +822,66 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
804822
return 0;
805823
}
806824

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

@@ -870,6 +949,14 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
870949
BLE_HS_DBG_ASSERT(dsc_handle == def_handle + 2);
871950
}
872951

952+
if (ble_gatts_chr_ext_prop_allowed(chr) != 0) {
953+
rc = ble_gatts_register_cep_dsc(&cep_handle, chr->flags);
954+
if (rc != 0) {
955+
return rc;
956+
}
957+
BLE_HS_DBG_ASSERT(cep_handle == def_handle + 3);
958+
}
959+
873960
/* Register each descriptor. */
874961
if (chr->descriptors != NULL) {
875962
for (dsc = chr->descriptors; dsc->uuid != NULL; dsc++) {
@@ -2172,6 +2259,21 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
21722259
res->attrs++;
21732260
}
21742261

2262+
/* If the characteristic permits reliable writes or auxiliary
2263+
* writes, it has an Extended Properties descriptor.
2264+
*/
2265+
if (chr->flags & BLE_GATT_CHR_F_AUX_WRITE ||
2266+
chr->flags & BLE_GATT_CHR_F_RELIABLE_WRITE) {
2267+
2268+
/* Each CEP requires:
2269+
* o 1 descriptor
2270+
* o 1 attribute
2271+
*/
2272+
res->dscs++;
2273+
res->ceps++;
2274+
res->attrs++;
2275+
}
2276+
21752277
if (chr->descriptors != NULL) {
21762278
for (d = 0; chr->descriptors[d].uuid != NULL; d++) {
21772279
if (!ble_gatts_dsc_is_sane(chr->descriptors + d)) {

0 commit comments

Comments
 (0)