Add PTS certification logic 80/276480/2 accepted/tizen/6.5/unified/20220620.131708 submit/tizen_6.5/20220617.070028
authorDohyun Pyun <dh79.pyun@samsung.com>
Fri, 17 Jun 2022 06:24:07 +0000 (15:24 +0900)
committerDohyun Pyun <dh79.pyun@samsung.com>
Fri, 17 Jun 2022 06:26:31 +0000 (15:26 +0900)
GATT/SR/GAW/BV-06-C
GATT/SR/GAW/BV-10-C

Change-Id: I37e37a23f132674e9d5d82b08c914bccb87d0d77
Signed-off-by: Dohyun Pyun <dh79.pyun@samsung.com>
src/gatt-database.c
src/shared/att-types.h
src/shared/gatt-server.c

index 91d6378..d95db9f 100644 (file)
 #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"
@@ -86,6 +111,9 @@ struct btd_gatt_database {
        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 {
@@ -841,6 +869,88 @@ static void gap_rpa_res_support_read_cb(struct gatt_db_attribute *attrib,
 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)
@@ -961,6 +1071,13 @@ static void database_add_record(struct btd_gatt_database *database,
        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)
@@ -991,6 +1108,17 @@ 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,
@@ -1207,6 +1335,21 @@ done:
 #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,
@@ -1494,6 +1637,518 @@ static void register_core_services(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);
 
@@ -3149,6 +3804,38 @@ static void stop_notify_setup(DBusMessageIter *iter, void *user_data)
 }
 #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;
index 48d2985..78d9e4a 100755 (executable)
@@ -154,6 +154,11 @@ struct bt_att_pdu_error_rsp {
 #define BT_ATT_PERM_SECURE             (BT_ATT_PERM_READ_SECURE | \
                                        BT_ATT_PERM_WRITE_SECURE)
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+#define BT_ATT_PERM_TRANSPORT_BREDR    0x0100
+#define BT_ATT_PERM_TRANSPORT_LE       0x0200
+#endif
+
 /* GATT Characteristic Properties Bitfield values */
 #define BT_GATT_CHRC_PROP_BROADCAST                    0x01
 #define BT_GATT_CHRC_PROP_READ                         0x02
index d27c8dd..84de564 100644 (file)
@@ -1643,6 +1643,25 @@ static void exec_write_cb(struct bt_att_chan *chan, uint8_t opcode,
                return;
        }
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+               /* GATT/SR/GAW/BV-10-C
+                * skip this flow for certification
+               */
+               if (!TIZEN_FEATURE_BLUEZ_STACK_CERTIFICATION) {
+                       /* If there is more than one prep request, we are in reliable session */
+                       if (queue_length(server->prep_queue) > 1) {
+                               struct prep_write_data *prep_data;
+
+                               prep_data = queue_find(server->prep_queue,
+                                                       find_no_reliable_characteristic, NULL);
+                               if (prep_data) {
+                                       ecode = BT_ATT_ERROR_REQUEST_NOT_SUPPORTED;
+                                       ehandle = prep_data->handle;
+                                       goto error;
+                               }
+                       }
+               }
+#else
        /* If there is more than one prep request, we are in reliable session */
        if (queue_length(server->prep_queue) > 1) {
                struct prep_write_data *prep_data;
@@ -1655,6 +1674,7 @@ static void exec_write_cb(struct bt_att_chan *chan, uint8_t opcode,
                        goto error;
                }
        }
+#endif
 
        data = new0(struct exec_data, 1);
        data->chan = chan;