@@ -1044,6 +1044,7 @@ service_add_ccc(struct gatt_db_attribute *service,
struct btd_gatt_database *database,
btd_gatt_database_ccc_write_t write_callback,
void *user_data,
+ uint32_t parent_permissions,
btd_gatt_database_destroy_t destroy)
{
struct gatt_db_attribute *ccc;
@@ -1052,9 +1053,23 @@ service_add_ccc(struct gatt_db_attribute *service,
ccc_cb = new0(struct ccc_cb_data, 1);
+ /*
+ * Provide a way for the permissions on a characteristic to dictate
+ * the permissions on the CCC
+ */
+ uint32_t permissions = BT_ATT_PERM_READ | BT_ATT_PERM_WRITE;
+
+ if (parent_permissions & BT_ATT_PERM_ASYNCHRONOUS_ENCRYPT)
+ permissions |= BT_ATT_PERM_WRITE_ENCRYPT;
+
+ if (parent_permissions & BT_ATT_PERM_ASYNCHRONOUS_AUTHEN)
+ permissions |= BT_ATT_PERM_WRITE_AUTHEN;
+
+ if (parent_permissions & BT_ATT_PERM_ASYNCHRONOUS_SECURE)
+ permissions |= BT_ATT_PERM_WRITE_SECURE;
+
bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
- ccc = gatt_db_service_add_descriptor(service, &uuid,
- BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ ccc = gatt_db_service_add_descriptor(service, &uuid, permissions,
gatt_ccc_read_cb, gatt_ccc_write_cb, database);
if (!ccc) {
error("Failed to create CCC entry in database");
@@ -1211,7 +1226,7 @@ static void populate_gatt_service(struct btd_gatt_database *database)
NULL, NULL, database);
database->svc_chngd_ccc = service_add_ccc(service, database, NULL, NULL,
- NULL);
+ 0, NULL);
bt_uuid16_create(&uuid, GATT_CHARAC_CLI_FEAT);
database->cli_feat = gatt_db_service_add_characteristic(service,
@@ -1674,6 +1689,13 @@ static bool parse_chrc_flags(DBusMessageIter *array, uint8_t *props,
*perm |= BT_ATT_PERM_WRITE | BT_ATT_PERM_WRITE_SECURE;
} else if (!strcmp("authorize", flag)) {
*req_prep_authorization = true;
+ } else if (!strcmp("encrypt-asynchronous", flag)) {
+ *perm |= BT_ATT_PERM_ASYNCHRONOUS_ENCRYPT;
+ } else if (!strcmp(
+ "encrypt-authenticated-asynchronous", flag)) {
+ *perm |= BT_ATT_PERM_ASYNCHRONOUS_AUTHEN;
+ } else if (!strcmp("secure-asynchronous", flag)) {
+ *perm |= BT_ATT_PERM_ASYNCHRONOUS_SECURE;
} else {
error("Invalid characteristic flag: %s", flag);
return false;
@@ -2773,7 +2795,7 @@ static bool database_add_ccc(struct external_service *service,
return true;
chrc->ccc = service_add_ccc(service->attrib, service->app->database,
- ccc_write_cb, chrc, NULL);
+ ccc_write_cb, chrc, chrc->perm, NULL);
if (!chrc->ccc) {
error("Failed to create CCC entry for characteristic");
return false;
@@ -137,6 +137,10 @@ struct bt_att_pdu_error_rsp {
BT_ATT_PERM_WRITE_AUTHEN | \
BT_ATT_PERM_WRITE_ENCRYPT | \
BT_ATT_PERM_WRITE_SECURE)
+/* Permissions to be applied to the CCC */
+#define BT_ATT_PERM_ASYNCHRONOUS_ENCRYPT 0x0400
+#define BT_ATT_PERM_ASYNCHRONOUS_AUTHEN 0x0800
+#define BT_ATT_PERM_ASYNCHRONOUS_SECURE 0x1000
/* GATT Characteristic Properties Bitfield values */
#define BT_GATT_CHRC_PROP_BROADCAST 0x01