@@ -39,6 +39,8 @@ static const ble_uuid_t *uuid_chr =
39
39
BLE_UUID16_DECLARE (BLE_ATT_UUID_CHARACTERISTIC );
40
40
static const ble_uuid_t * uuid_ccc =
41
41
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 );
42
44
43
45
static const struct ble_gatt_svc_def * * ble_gatts_svc_defs ;
44
46
static int ble_gatts_num_svc_defs ;
@@ -154,6 +156,22 @@ ble_gatts_chr_clt_cfg_allowed(const struct ble_gatt_chr_def *chr)
154
156
return flags ;
155
157
}
156
158
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
+
157
175
static uint8_t
158
176
ble_gatts_att_flags_from_chr_flags (ble_gatt_chr_flags chr_flags )
159
177
{
@@ -804,6 +822,66 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
804
822
return 0 ;
805
823
}
806
824
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
+
807
885
static int
808
886
ble_gatts_register_chr (const struct ble_gatt_svc_def * svc ,
809
887
const struct ble_gatt_chr_def * chr ,
@@ -814,6 +892,7 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
814
892
uint16_t def_handle ;
815
893
uint16_t val_handle ;
816
894
uint16_t dsc_handle ;
895
+ uint16_t cep_handle ;
817
896
uint8_t att_flags ;
818
897
int rc ;
819
898
@@ -870,6 +949,14 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
870
949
BLE_HS_DBG_ASSERT (dsc_handle == def_handle + 2 );
871
950
}
872
951
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
+
873
960
/* Register each descriptor. */
874
961
if (chr -> descriptors != NULL ) {
875
962
for (dsc = chr -> descriptors ; dsc -> uuid != NULL ; dsc ++ ) {
@@ -2172,6 +2259,21 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
2172
2259
res -> attrs ++ ;
2173
2260
}
2174
2261
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
+
2175
2277
if (chr -> descriptors != NULL ) {
2176
2278
for (d = 0 ; chr -> descriptors [d ].uuid != NULL ; d ++ ) {
2177
2279
if (!ble_gatts_dsc_is_sane (chr -> descriptors + d )) {
0 commit comments