#include "profile.h"
#include "service.h"
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY /* BT Qualification : GATT DB */
+#include "../profile.h"
+#define SERVICS_A 0xA00A
+#define SERVICS_B 0xA00B
+#define SERVICS_C 0xA00C
+#define SERVICS_D 0xA00D
+#define SERVICS_E 0xA00E
+#define SERVICS_F 0xA00F
+#define SERVICS_G 0xA01A
+#define SERVICS_H 0xA01B
+
+#define VALUE_V1 0xB001
+#define VALUE_V2 0xB002
+#define VALUE_V3 0xB003
+#define VALUE_V4 0xB004
+#define VALUE_V5 0xB005
+#define VALUE_V6 0xB006
+#define VALUE_V7 0xB007
+#define VALUE_V8 0xB008
+#define VALUE_V9 0xB009
+#define VALUE_V10 0xB00A
+#define VALUE_V11 0xB00B
+#define VALUE_V12 0xB00C
+#endif
+
#define GATT_MANAGER_IFACE "org.bluez.GattManager1"
#define GATT_PROFILE_IFACE "org.bluez.GattProfile1"
#define GATT_SERVICE_IFACE "org.bluez.GattService1"
struct gatt_db_attribute *eatt;
struct queue *apps;
struct queue *profiles;
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY /* BT Qualification : GATT DB */
+ uint32_t service_sdp_handle;
+#endif
};
struct gatt_app {
done:
gatt_db_attribute_read_result(attrib, id, error, value, len);
}
+
+static bool is_valid_att_le_transport( struct bt_att *att,
+ struct gatt_db_attribute *attr)
+{
+ GIOChannel *io = NULL;
+ GError *gerr = NULL;
+ uint8_t dst_type;
+ uint32_t perm;
+
+ perm = gatt_db_attribute_get_permissions(attr);
+
+ io = g_io_channel_unix_new(bt_att_get_fd(att));
+ if (!io)
+ return false;
+
+ bt_io_get(io, &gerr, BT_IO_OPT_DEST_TYPE, &dst_type,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("gatt: bt_io_get: %s", gerr->message);
+ g_error_free(gerr);
+ g_io_channel_unref(io);
+ return false;
+ }
+
+ if (dst_type == BDADDR_BREDR && perm & BT_ATT_PERM_TRANSPORT_LE)
+ return false;
+ else if (dst_type != BDADDR_BREDR && perm & BT_ATT_PERM_TRANSPORT_BREDR)
+ return false;
+ g_io_channel_unref(io);
+ return true;
+}
+
+static void b1_read_cb(struct gatt_db_attribute *attrib,
+ unsigned int id, uint16_t offset,
+ uint8_t opcode, struct bt_att *att,
+ void *user_data)
+{
+ uint8_t error = 0;
+ size_t len = 0;
+ uint8_t value;
+
+ if (!is_valid_att_le_transport(att, attrib)) {
+ error = BT_OTP_ERROR_WRITE_REQUEST_REJECTED;
+ goto done;
+ }
+
+ len = 1;
+ value = 0x05;
+ if (offset > len) {
+ error = BT_ATT_ERROR_INVALID_OFFSET;
+ goto done;
+ }
+
+done:
+ gatt_db_attribute_read_result(attrib, id, error, &value, len);
+}
+
+static void b2_read_cb(struct gatt_db_attribute *attrib,
+ unsigned int id, uint16_t offset,
+ uint8_t opcode, struct bt_att *att,
+ void *user_data)
+{
+ uint8_t error = 0;
+ size_t len = 0;
+ uint8_t atval[256] = { 0, };
+ const char *handle_15 = "11111222223333344444555556666677777888889999900000aaaaaaaaaabbbbbbbbbbb";
+
+ if (!is_valid_att_le_transport(att, attrib)) {
+ error = BT_OTP_ERROR_WRITE_REQUEST_REJECTED;
+ goto done;
+ }
+
+ len = strlen(handle_15);
+ if (offset > len) {
+ error = BT_ATT_ERROR_INVALID_OFFSET;
+ goto done;
+ }
+ strncpy((char *) atval, handle_15, len);
+
+done:
+ gatt_db_attribute_read_result(attrib, id, error, atval, len);
+}
#endif
static sdp_record_t *record_new(uuid_t *uuid, uint16_t start, uint16_t end)
rec->handle = record->handle;
rec->attr = attr;
queue_push_tail(database->records, rec);
+
+
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ if (TIZEN_FEATURE_BLUEZ_STACK_CERTIFICATION) {
+ database->service_sdp_handle = record->handle;
+ }
+#endif
}
static void populate_gap_service(struct btd_gatt_database *database)
NULL, database);
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ if (TIZEN_FEATURE_BLUEZ_STACK_CERTIFICATION) {
+ /*
+ * Peripheral preferrence connection characteristic.
+ */
+ bt_uuid16_create(&uuid, GATT_CHARAC_PERIPHERAL_PREF_CONN);
+ gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ }
+
/* Central address resolution characteristic */
bt_uuid16_create(&uuid, GATT_CHARAC_CENTRAL_RPA_RESOLUTION);
gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
#endif
}
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY /* BT Qualification : GATT DB */
+static void confirm_write(struct gatt_db_attribute *attr, int err,
+ void *user_data)
+{
+ DBG("## confirm_write()!!! ");
+ DBG("## handle: %d", gatt_db_attribute_get_handle(attr));
+ if (!err)
+ return;
+
+ DBG("Error caching attribute %p - err: %d\n", attr, err);
+}
+
+static uint32_t permissions_from_props(uint8_t props, uint8_t ext_props);
+#endif
+
static struct gatt_db_attribute *
service_add_ccc(struct gatt_db_attribute *service,
struct btd_gatt_database *database,
populate_gap_service(database);
populate_gatt_service(database);
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ if (TIZEN_FEATURE_BLUEZ_STACK_CERTIFICATION) {
+ int len;
+ bt_uuid_t uuid;
+ uint8_t atval[256] = { 0 };
+ struct gatt_db_attribute *service, *tmp;
+ uint32_t permission = BT_ATT_PERM_NONE;
+ uint32_t service_sdp_handle;
+
+ // Value V11 (128-bit UUID) - 0000B00B000000000123456789ABCDEF
+ const uint128_t uint128_value = {
+ .data = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x0B, 0xB0, 0x00, 0x00 } };
+
+ // Service C (128-bit UUID) - 0000A00C000000000123456789ABCDEF
+ const uint128_t uint128_service_c_1_value = {
+ .data = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x0C, 0xA0, 0x00, 0x00 } };
+
+ // Value V9 (128-bit UUID) - 0000B009000000000123456789ABCDEF
+ const uint128_t uint128_value_v9 = {
+ .data = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x09, 0xB0, 0x00, 0x00 } };
+
+ // Descriptor V5D4 (128-bit UUID) - 0000D5D4000000000123456789ABCDEF
+ const uint128_t uint128_descriptor_V5D4_value = {
+ .data = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0xD4, 0xD5, 0x00, 0x00 } };
+
+ // Descriptor V9D2 (128-bit UUID) - 0000D9D2000000000123456789ABCDEF
+ const uint128_t uint128_descriptor_V9D2_value = {
+ .data = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0xD2, 0xD9, 0x00, 0x00 } };
+
+ // Descriptor V9D3 (128-bit UUID) - 0000D9D3000000000123456789ABCDEF
+ const uint128_t uint128_descriptor_V9D3_value = {
+ .data = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0xD3, 0xD9, 0x00, 0x00 } };
+
+ const char *handle_26 = "11111222223333344444555556666677777888889999900000aaaaaaaaaabbbbbbbbbbb1";
+ const char *handle_A4 = "111112222233333444445555555555aaaaaaaaaa1";
+ const char *handle_A6 = "22222333334444455555661";
+ const char *handle_A8 = "333334444455555666667771";
+ const char *handle_AA = "11111222223333344444555556666677777888889991";
+ const char *handle_AC = "222223333344444555556666677777888889999900001";
+ const char *handle_AE = "3333344444555556666677777888889999900000111111";
+
+/**************************************************************************/
+// 1
+ /* Add the Service D */
+ bt_uuid16_create(&uuid, SERVICS_D);
+ service = gatt_db_add_service(database->db, &uuid, false, 5);
+ database_add_record(database, service);
+
+ service_sdp_handle = database->service_sdp_handle;
+
+// 2, 3
+ bt_uuid16_create(&uuid, VALUE_V12);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x0C;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+// 4, 5
+ bt_uuid128_create(&uuid, uint128_value);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x0B;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ gatt_db_service_set_active(service, true);
+ DBG("Service D");
+
+/**************************************************************************/
+// 10
+ /* Add the Service B */
+ bt_uuid16_create(&uuid, SERVICS_B);
+ service = gatt_db_add_service(database->db, &uuid, true, 3);
+ database_add_record(database, service);
+
+// 11, 12
+ bt_uuid16_create(&uuid, VALUE_V6);
+ permission = permissions_from_props(BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_EXT_PROP, BT_GATT_CHRC_EXT_PROP_ENC);
+ DBG("Permissions %d", permission);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, permission,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+
+ if (tmp) {
+ atval[0] = 0x06;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+ gatt_db_service_set_active(service, true);
+ DBG("Service B.3");
+
+/**************************************************************************/
+// 20
+ /* Add the Service A */
+ bt_uuid16_create(&uuid, SERVICS_A);
+ service = gatt_db_add_service(database->db, &uuid, true, 8);
+ database_add_record(database, service);
+
+// 21
+ tmp = gatt_db_get_attribute(database->db, service_sdp_handle);
+ if (tmp) {
+ gatt_db_service_add_included(service, tmp);
+ DBG("Service D Included in Service A");
+ }
+
+// 23, 24
+ bt_uuid16_create(&uuid, VALUE_V1);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_TRANSPORT_LE,
+ BT_GATT_CHRC_PROP_READ,
+ b1_read_cb,
+ NULL, database);
+
+ if (tmp) {
+ atval[0] = 0x01;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ }
+
+// 25, 26
+ bt_uuid16_create(&uuid, VALUE_V2);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_TRANSPORT_BREDR,
+ BT_GATT_CHRC_PROP_READ,
+ b2_read_cb,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_26);
+ strncpy((char *) atval, handle_26, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+// 27, 28
+ bt_uuid16_create(&uuid, VALUE_V3);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_WRITE | BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x01;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ gatt_db_service_set_active(service, true);
+ DBG("Service A");
+
+ /**************************************************************************/
+// 30
+ /* Add the Service B */
+ bt_uuid16_create(&uuid, SERVICS_B);
+ service = gatt_db_add_service(database->db, &uuid, true, 4);
+ database_add_record(database, service);
+
+// 31, 32
+ bt_uuid16_create(&uuid, VALUE_V7);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_WRITE | BT_GATT_CHRC_PROP_NOTIFY,
+ NULL,
+ NULL, database);
+ service_add_ccc(service, database, NULL, tmp, NULL);
+ if (tmp) {
+ atval[0] = 0x07;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ gatt_db_service_set_active(service, true);
+ DBG("Service B.4");
+
+ /**************************************************************************/
+// 60
+ /* Add the Service A */
+ bt_uuid16_create(&uuid, SERVICS_E);
+ service = gatt_db_add_service(database->db, &uuid, true, 3);
+ database_add_record(database, service);
+// 61, 62
+
+ bt_uuid16_create(&uuid, VALUE_V4);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
+ 0x0A,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x04;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ gatt_db_service_set_active(service, true);
+ DBG("Service B.1");
+/**************************************************************************/
+// 70
+ bt_uuid16_create(&uuid, SERVICS_F);
+ service = gatt_db_add_service(database->db, &uuid, true, 7);
+ database_add_record(database, service);
+// 71, 72
+ bt_uuid16_create(&uuid, VALUE_V5);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ_AUTHEN,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x05;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+// 73, 74
+ bt_uuid16_create(&uuid, VALUE_V12);
+ permission = permissions_from_props(BT_GATT_CHRC_PROP_EXT_PROP, BT_GATT_CHRC_EXT_PROP_AUTH);
+ DBG("permission %d", permission);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, permission,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_EXT_PROP,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x0A;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ bt_uuid16_create(&uuid, GATT_CHARAC_EXT_PROPER_UUID);
+ tmp = gatt_db_service_add_descriptor(service, &uuid,
+ BT_ATT_PERM_READ,
+ NULL, NULL, NULL);
+
+ if (tmp) {
+ atval[0] = BT_GATT_CHRC_EXT_PROP_ENC_READ;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+// 75, 76
+ bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID);
+ permission = permissions_from_props(BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_EXT_PROP, BT_GATT_CHRC_EXT_PROP_ENC);
+ DBG("permission %d", permission);
+ gatt_db_service_add_characteristic(service, &uuid, permission,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_EXT_PROP,
+ NULL,
+ NULL, database);
+ bt_uuid128_create(&uuid, uint128_descriptor_V5D4_value);
+ tmp = gatt_db_service_add_descriptor(service, &uuid,
+ BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_26);
+ strncpy((char *) atval, handle_26, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+ gatt_db_service_set_active(service, true);
+ DBG("Service B.2");
+
+/**************************************************************************/
+
+// 80
+ bt_uuid16_create(&uuid, SERVICS_H);
+ service = gatt_db_add_service(database->db, &uuid, true, 3);
+ database_add_record(database, service);
+
+// 81, 82
+ bt_uuid16_create(&uuid, VALUE_V8);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x84;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ gatt_db_service_set_active(service, true);
+ DBG("Service B.5");
+
+/**************************************************************************/
+//90
+ bt_uuid128_create(&uuid, uint128_service_c_1_value);
+ service = gatt_db_add_service(database->db, &uuid, true,6);
+ database_add_record(database, service);
+
+//91
+ tmp = gatt_db_get_attribute(database->db, service_sdp_handle);
+ if (tmp) {
+ gatt_db_service_add_included(service, tmp);
+ DBG("Service D Included in Service C.1");
+ }
+
+// 92
+ bt_uuid128_create(&uuid, uint128_value_v9);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x09;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+// 95, 96
+ bt_uuid128_create(&uuid, uint128_descriptor_V9D2_value);
+ tmp = gatt_db_service_add_descriptor(service, &uuid,
+ BT_ATT_PERM_ENCRYPT | BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_26);
+ strncpy((char *) atval, handle_26, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ bt_uuid128_create(&uuid, uint128_descriptor_V9D3_value);
+ tmp = gatt_db_service_add_descriptor(service, &uuid,
+ BT_ATT_PERM_AUTHEN | BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x33;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ DBG("Service C.1");
+ gatt_db_service_set_active(service, true);
+
+/**************************************************************************/
+// A0
+ bt_uuid16_create(&uuid, SERVICS_G);
+ service = gatt_db_add_service(database->db, &uuid, true, 15);
+ database_add_record(database, service);
+
+// A1, A2
+ bt_uuid16_create(&uuid, VALUE_V10);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ atval[0] = 0x0A;
+ gatt_db_attribute_write(tmp, 0, atval, 1,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+
+// A3, A4
+ bt_uuid16_create(&uuid, VALUE_V2);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ_ENCRYPT,
+ BT_GATT_CHRC_PROP_READ,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_A4);
+ strncpy((char *) atval, handle_A4, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+// A5, A6
+ bt_uuid16_create(&uuid, VALUE_V2);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_A6);
+ strncpy((char *) atval, handle_A6, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+// A7, A8
+ bt_uuid16_create(&uuid, VALUE_V2);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_A8);
+ strncpy((char *) atval, handle_A8, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+// A9, AA
+ bt_uuid16_create(&uuid, VALUE_V2);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_AA);
+ strncpy((char *) atval, handle_AA, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+// AB, AC
+ bt_uuid16_create(&uuid, VALUE_V2);
+ tmp = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_AC);
+ strncpy((char *) atval, handle_AC, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+
+// AD, AE
+ bt_uuid16_create(&uuid, VALUE_V2);
+ gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_READ | BT_ATT_PERM_WRITE,
+ BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_WRITE,
+ NULL,
+ NULL, database);
+ if (tmp) {
+ len = strlen(handle_AE);
+ strncpy((char *) atval, handle_AE, len);
+ gatt_db_attribute_write(tmp, 0, atval, len,
+ BT_ATT_OP_WRITE_REQ,
+ NULL, confirm_write,
+ NULL);
+ tmp = NULL;
+ }
+
+ gatt_db_service_set_active(service, true);
+ DBG("Service C.2");
+ }
+#endif
+
if (main_opts.did_source > 0)
populate_devinfo_service(database);
}
#endif
+static uint32_t permissions_from_props(uint8_t props, uint8_t ext_props)
+{
+ uint32_t perm = 0;
+
+ if (props & BT_GATT_CHRC_PROP_WRITE ||
+ props & BT_GATT_CHRC_PROP_WRITE_WITHOUT_RESP ||
+ ext_props & BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE ||
+ ext_props & BT_GATT_CHRC_EXT_PROP_ENC_WRITE ||
+ ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_WRITE)
+ perm |= BT_ATT_PERM_WRITE;
+
+ if (props & BT_GATT_CHRC_PROP_READ ||
+ ext_props & BT_GATT_CHRC_EXT_PROP_ENC_READ ||
+ ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_READ)
+ perm |= BT_ATT_PERM_READ;
+
+ if (ext_props & BT_GATT_CHRC_EXT_PROP_ENC_READ)
+ perm |= BT_ATT_PERM_READ_ENCRYPT;
+
+ if (ext_props & BT_GATT_CHRC_EXT_PROP_ENC_WRITE)
+ perm |= BT_ATT_PERM_WRITE_ENCRYPT;
+
+ if (ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_READ)
+ perm |= BT_ATT_PERM_READ_AUTHEN;
+
+ if (ext_props & BT_GATT_CHRC_EXT_PROP_AUTH_WRITE)
+ perm |= BT_ATT_PERM_WRITE_AUTHEN;
+
+ return perm;
+}
+
+
static uint8_t ccc_write_cb(struct pending_op *op, void *user_data)
{
struct external_chrc *chrc = user_data;