GATT-Server:Support Service Change Indication on reconnect. 69/76469/1
authorh.sandeep <h.sandeep@samsung.com>
Fri, 24 Jun 2016 04:51:25 +0000 (10:21 +0530)
committerh.sandeep <h.sandeep@samsung.com>
Fri, 24 Jun 2016 04:57:55 +0000 (10:27 +0530)
This patch handles sending service changed indication
to client device after reconnection, if the client
had already registered for service changed indication.

Change-Id: If0fa76d05ddc4b668f71c5b1080966e5f5b6e35c
Signed-off-by: h.sandeep <h.sandeep@samsung.com>
src/device.c
src/device.h
src/gatt-database.c
src/shared/att.c
src/shared/att.h

index 2b3c25f..50baf24 100644 (file)
@@ -515,6 +515,9 @@ static gboolean store_device_info_cb(gpointer user_data)
        char class[9];
        char **uuids = NULL;
        gsize length = 0;
+#ifdef __TIZEN_PATCH__
+       gboolean svc_change_regd = false;
+#endif
 
        device->store_id = 0;
 
@@ -641,6 +644,12 @@ static gboolean store_device_info_cb(gpointer user_data)
                g_key_file_remove_group(key_file, "DeviceID", NULL);
        }
 
+#ifdef __TIZEN_PATCH__
+       svc_change_regd = bt_att_get_svc_changed_indication_registered(device->att);
+       g_key_file_set_boolean(key_file, "Att", "SvcChangeRegd",
+                                               svc_change_regd);
+#endif
+
        if (device->local_csrk)
                store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
 
@@ -4235,6 +4244,7 @@ static void load_info(struct btd_device *device, const char *local,
        int source, vendor, product, version;
        char **techno, **t;
 #ifdef __TIZEN_PATCH__
+       gboolean svc_change_regd;
        char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
 #endif
        /* Load device name from storage info file, if that fails fall back to
@@ -4402,6 +4412,15 @@ next:
                btd_device_set_pnpid(device, source, vendor, product, version);
        }
 
+#ifdef __TIZEN_PATCH__
+       /* Load Service changed Registered flag */
+       svc_change_regd = g_key_file_get_boolean(key_file, "Att",
+                                               "SvcChangeRegd", NULL);
+
+       bt_att_set_svc_changed_indication_registered(device->att,
+                                               svc_change_regd);
+#endif
+
        if (store_needed)
                store_device_info(device);
 }
@@ -6521,6 +6540,33 @@ static bool remote_counter(uint32_t *sign_cnt, void *user_data)
        return true;
 }
 
+#ifdef __TIZEN_PATCH__
+static bool load_svc_change_indication_status(struct btd_device *device, const char *local,
+                               const char *peer)
+{
+       char filename[PATH_MAX];
+       GKeyFile *key_file;
+       gboolean svc_change_regd = false;
+       snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
+
+       key_file = g_key_file_new();
+       if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
+               goto failed;
+
+       /* Load Service changed Registered flag */
+       svc_change_regd = g_key_file_get_boolean(key_file, "Att",
+                                               "SvcChangeRegd", NULL);
+       bt_att_set_svc_changed_indication_registered(device->att,
+                                               svc_change_regd);
+
+
+failed:
+       g_key_file_free(key_file);
+
+       return svc_change_regd;
+}
+#endif
+
 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
 {
        GError *gerr = NULL;
@@ -6612,6 +6658,11 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
         */
        adapter_connect_list_remove(dev->adapter, dev);
 
+#ifdef __TIZEN_PATCH__
+       /* load the service changed indication status on connection */
+       load_svc_change_indication_status(dev, srcaddr, dstaddr);
+#endif
+
        return true;
 }
 
@@ -8452,4 +8503,15 @@ void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
 {
        dev->legacy_pairing = legacy_pairing;
 }
+
+void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value)
+{
+       bt_att_set_svc_changed_indication_registered(dev->att, value);
+       store_device_info(dev);
+}
+
+bool btd_device_get_svc_changed_indication(struct btd_device *dev)
+{
+       return bt_att_get_svc_changed_indication_registered(dev->att);
+}
 #endif
index e5f6385..cf247ba 100644 (file)
@@ -219,6 +219,8 @@ gboolean device_is_profile_blocked(struct btd_device *device,
                const char *uuid);
 void btd_device_disconnect(struct btd_device *dev);
 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing);
+void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value);
+bool btd_device_get_svc_changed_indication(struct btd_device *dev);
 #ifdef TIZEN_WEARABLE
 void device_change_pkt_type(gpointer data, gpointer user_data);
 #endif /* TIZEN_WEARABLE */
index c038694..989f286 100644 (file)
@@ -167,6 +167,10 @@ struct device_info {
        uint8_t bdaddr_type;
 };
 
+#ifdef __TIZEN_PATCH__
+static void conf_cb(void *user_data);
+#endif
+
 static void ccc_cb_free(void *data)
 {
        struct ccc_cb_data *ccc_cb = data;
@@ -221,6 +225,31 @@ find_device_state(struct btd_gatt_database *database, bdaddr_t *bdaddr,
 }
 
 #ifdef __TIZEN_PATCH__
+static void send_service_changed_indication_on_reconnect(
+                                       struct btd_device *device,
+                                       struct bt_gatt_server *server)
+{
+       struct btd_gatt_database *database;
+       uint16_t start_handle = 0X0001, end_handle = 0xFFFF;
+       uint8_t value[4];
+       uint16_t svc_chngd_handle;
+       DBG("");
+
+       database = btd_adapter_get_database(device_get_adapter(device));
+
+       if (!database)
+               return;
+
+       svc_chngd_handle = gatt_db_attribute_get_handle(database->svc_chngd_ccc);
+
+       put_le16(start_handle, value);
+       put_le16(end_handle, value + 2);
+
+       bt_gatt_server_send_indication(server, svc_chngd_handle,
+                               value, sizeof(value), conf_cb,
+                               NULL, NULL);
+}
+
 static bool dev_addr_match(const void *a, const void *b)
 {
        const struct device_state *dev_state = a;
@@ -529,6 +558,13 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
                return;
 
        device_attach_att(device, io);
+
+#ifdef __TIZEN_PATCH__
+       if (btd_device_get_svc_changed_indication(device)) {
+               send_service_changed_indication_on_reconnect(device,
+                                       btd_device_get_gatt_server(device));
+       }
+#endif
 }
 
 #ifdef __TIZEN_PATCH__
@@ -895,6 +931,23 @@ static void gatt_ccc_write_cb(struct gatt_db_attribute *attrib,
 
 done:
        gatt_db_attribute_write_result(attrib, id, ecode);
+#ifdef __TIZEN_PATCH__
+       if (!ecode) {
+               uint16_t svc_chngd_handle = gatt_db_attribute_get_handle(database->svc_chngd_ccc);
+               if (handle == svc_chngd_handle) {
+                       if (ccc->value[0] != 0) {
+                               struct btd_device *device = NULL;
+                               device = btd_adapter_get_device(
+                                                       database->adapter,
+                                                       &bdaddr, bdaddr_type);
+
+                               if (!device)
+                                       return;
+                               btd_device_set_svc_changed_indication(device, true);
+                       }
+               }
+       }
+#endif
 }
 
 static struct gatt_db_attribute *
index e5cd223..187e685 100644 (file)
@@ -67,6 +67,10 @@ struct bt_att {
 
        bool in_req;                    /* There's a pending incoming request */
 
+#ifdef __TIZEN_PATCH__
+       bool service_change_indication; /* Service changed indication status */
+#endif
+
        uint8_t *buf;
        uint16_t mtu;
 
@@ -1467,3 +1471,23 @@ bool bt_att_has_crypto(struct bt_att *att)
 
        return att->crypto ? true : false;
 }
+
+#ifdef __TIZEN_PATCH__
+bool bt_att_set_svc_changed_indication_registered(struct bt_att *att, bool value)
+{
+       if (!att)
+               return false;
+
+       att->service_change_indication = value;
+
+       return true;
+}
+
+bool bt_att_get_svc_changed_indication_registered(struct bt_att *att)
+{
+       if (!att)
+               return false;
+
+       return att->service_change_indication;
+}
+#endif
index 2a7f87e..727d48d 100644 (file)
@@ -91,3 +91,7 @@ bool bt_att_set_local_key(struct bt_att *att, uint8_t sign_key[16],
 bool bt_att_set_remote_key(struct bt_att *att, uint8_t sign_key[16],
                        bt_att_counter_func_t func, void *user_data);
 bool bt_att_has_crypto(struct bt_att *att);
+#ifdef __TIZEN_PATCH__
+bool bt_att_set_svc_changed_indication_registered(struct bt_att *att, bool value);
+bool bt_att_get_svc_changed_indication_registered(struct bt_att *att);
+#endif
\ No newline at end of file