Port proximity profiles to new GATT arch 43/96543/1 accepted/tizen/3.0/common/20161114.143329 accepted/tizen/3.0/ivi/20161110.071351 accepted/tizen/3.0/mobile/20161110.071305 accepted/tizen/3.0/tv/20161110.071324 accepted/tizen/3.0/wearable/20161110.071339 submit/tizen_3.0/20161110.000333 submit/tizen_3.0_common/20161114.081136
authorGowtham Anandha Babu <gowtham.ab@samsung.com>
Thu, 27 Oct 2016 12:20:38 +0000 (17:50 +0530)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 9 Nov 2016 09:02:14 +0000 (18:02 +0900)
1) Ported to new GATT architecure
2) Added RegisterProximty and UnregisterProximity DBus methods
   on org.bluez.ProximityReporter1 interface.
3) Since TxPower in not implemented in BlueZ, commented for now.

Change-Id: I749de3345639dfeab05384df950ea6918376092a
Signed-off-by: Gowtham Anandha Babu <gowtham.ab@samsung.com>
profiles/proximity/immalert.c
profiles/proximity/linkloss.c
profiles/proximity/reporter.c
profiles/proximity/reporter.h

index 26a0ac9..3448625 100644 (file)
 #include "src/attio.h"
 #include "src/dbus-common.h"
 
+#ifdef __TIZEN_PATCH__
+#include "src/shared/queue.h"
+#include "src/shared/gatt-db.h"
+#include "src/shared/att.h"
+ #include "btio/btio.h"
+#include "src/gatt-database.h"
+#endif
+
 #include "reporter.h"
 #include "immalert.h"
 
 struct imm_alert_adapter {
        struct btd_adapter *adapter;
+#ifdef __TIZEN_PATCH__
+       struct gatt_db_attribute *imservice;
+#endif
        GSList *connected_devices;
 };
 
@@ -66,6 +77,32 @@ struct connected_device {
 
 static GSList *imm_alert_adapters;
 
+#ifdef __TIZEN_PATCH__
+static bool get_dest_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type)
+{
+       GIOChannel *io = NULL;
+       GError *gerr = NULL;
+
+       io = g_io_channel_unix_new(bt_att_get_fd(att));
+       if (!io)
+               return false;
+
+       bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, dst,
+                                       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;
+       }
+
+       g_io_channel_unref(io);
+       return true;
+}
+#endif
+
 static int imdevice_cmp(gconstpointer a, gconstpointer b)
 {
        const struct connected_device *condev = a;
@@ -180,6 +217,124 @@ static void imm_alert_disc_cb(gpointer user_data)
        imm_alert_remove_condev(condev);
 }
 
+#ifdef __TIZEN_PATCH__
+static void imm_alert_alert_lvl_write(struct gatt_db_attribute *attrib,
+                                       unsigned int id, uint16_t offset,
+                                       const uint8_t *value, size_t len,
+                                       uint8_t opcode, struct bt_att *att,
+                                       void *user_data)
+{
+       struct imm_alert_adapter *ia = user_data;
+       struct connected_device *condev = NULL;
+       uint8_t ecode = 0;
+       bdaddr_t bdaddr;
+       uint8_t bdaddr_type;
+       struct btd_device *device = NULL;
+
+       if (!value || len == 0) {
+               ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
+               goto done;
+       }
+
+       if (offset != 0) {
+               ecode = BT_ATT_ERROR_INVALID_OFFSET;
+               goto done;
+       }
+
+       if (!get_dest_info(att, &bdaddr, &bdaddr_type)) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto done;
+       }
+
+       device = btd_adapter_get_device(ia->adapter, &bdaddr, bdaddr_type);
+       if (!device) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto done;
+       }
+
+       /* Write value should be anyone of 0x00, 0x01, 0x02 */
+       if (value[0] > 0x02) {
+               ecode = 0x80;
+                goto done;
+        }
+
+       /* condev might remain NULL here if nothing is found */
+       condev = find_connected_device(ia, device);
+
+       /* Register a disconnect cb if the alert level is non-zero */
+       if (value[0] != NO_ALERT && !condev) {
+               condev = g_new0(struct connected_device, 1);
+               condev->device = btd_device_ref(device);
+               condev->adapter = ia;
+               condev->callback_id = btd_device_add_attio_callback(device,
+                                       NULL, imm_alert_disc_cb, condev);
+               ia->connected_devices = g_slist_append(ia->connected_devices,
+                                                               condev);
+               DBG("added connected dev %p", device);
+       }
+
+       if (condev) {
+               if (value[0] != NO_ALERT) {
+                       condev->alert_level = value[0];
+                       imm_alert_emit_alert_signal(condev, value[0]);
+               } else {
+                       imm_alert_emit_alert_signal(condev, value[0]);
+                       imm_alert_disc_cb(condev);
+               }
+       }
+
+       DBG("alert level set to %d by device %p", value[0], device);
+       gatt_db_attribute_write_result(attrib, id, ecode);
+       return;
+
+done:
+       error("Set immediate alert level for dev %p", device);
+       /* remove alerts by erroneous devices */
+       imm_alert_disc_cb(condev);
+       gatt_db_attribute_write_result(attrib, id, ecode);
+}
+
+void imm_alert_register(struct btd_adapter *adapter)
+{
+       bt_uuid_t uuid;
+       struct imm_alert_adapter *imadapter;
+       struct gatt_db_attribute *service, *charc;
+       struct gatt_db *db;
+
+       imadapter = g_new0(struct imm_alert_adapter, 1);
+       imadapter->adapter = adapter;
+
+       imm_alert_adapters = g_slist_append(imm_alert_adapters, imadapter);
+       db = (struct gatt_db *) btd_gatt_database_get_db(btd_adapter_get_database(adapter));
+
+       /* Immediate Alert Service */
+       bt_uuid16_create(&uuid, IMMEDIATE_ALERT_SVC_UUID);
+       service = gatt_db_add_service(db, &uuid, true, 3);
+       if (!service)
+               goto err;
+
+       imadapter->imservice = service;
+
+        /*
+         * Alert Level characteristic.
+         */
+        bt_uuid16_create(&uuid, ALERT_LEVEL_CHR_UUID);
+        charc = gatt_db_service_add_characteristic(service, &uuid, BT_ATT_PERM_WRITE,
+                                               BT_GATT_CHRC_PROP_WRITE,
+                                                NULL,
+                                               imm_alert_alert_lvl_write, imadapter);
+       if (!charc)
+               goto err;
+
+       gatt_db_service_set_active(service, true);
+
+       DBG("Immediate Alert service added");
+       return;
+err:
+       DBG("Error adding Immediate Alert service");
+       imm_alert_unregister(adapter);
+}
+#else
 static uint8_t imm_alert_alert_lvl_write(struct attribute *a,
                                struct btd_device *device, gpointer user_data)
 {
@@ -268,6 +423,7 @@ void imm_alert_register(struct btd_adapter *adapter)
 
        DBG("Immediate Alert service added");
 }
+#endif
 
 static void remove_condev_list_item(gpointer data, gpointer user_data)
 {
@@ -279,6 +435,9 @@ static void remove_condev_list_item(gpointer data, gpointer user_data)
 void imm_alert_unregister(struct btd_adapter *adapter)
 {
        struct imm_alert_adapter *imadapter;
+#ifdef __TIZEN_PATCH__
+       struct gatt_db *db;
+#endif
 
        imadapter = find_imm_alert_adapter(adapter);
        if (!imadapter)
@@ -286,6 +445,13 @@ void imm_alert_unregister(struct btd_adapter *adapter)
 
        g_slist_foreach(imadapter->connected_devices, remove_condev_list_item,
                                                                        NULL);
+#ifdef __TIZEN_PATCH__
+       /* Remove registered service */
+       if (imadapter->imservice) {
+               db = (struct gatt_db *) btd_gatt_database_get_db(btd_adapter_get_database(adapter));
+               gatt_db_remove_service(db, imadapter->imservice);
+       }
+#endif
 
        imm_alert_adapters = g_slist_remove(imm_alert_adapters, imadapter);
        g_free(imadapter);
index 2f1ab13..da22f3d 100644 (file)
 #include "src/attio.h"
 #include "src/dbus-common.h"
 
+#ifdef __TIZEN_PATCH__
+#include "src/shared/queue.h"
+#include "src/shared/gatt-db.h"
+#include "src/shared/att.h"
+#include "btio/btio.h"
+#include "src/gatt-database.h"
+#endif
+
 #include "reporter.h"
 #include "linkloss.h"
 
 struct link_loss_adapter {
        struct btd_adapter *adapter;
+#ifdef __TIZEN_PATCH__
+       struct gatt_db_attribute *llservice;
+#else
        uint16_t alert_lvl_value_handle;
+#endif
        GSList *connected_devices;
 };
 
@@ -69,6 +81,32 @@ struct connected_device {
 
 static GSList *link_loss_adapters;
 
+#ifdef __TIZEN_PATCH__
+static bool get_dest_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type)
+{
+       GIOChannel *io = NULL;
+       GError *gerr = NULL;
+
+       io = g_io_channel_unix_new(bt_att_get_fd(att));
+       if (!io)
+               return false;
+
+       bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, dst,
+                                       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;
+       }
+
+       g_io_channel_unref(io);
+       return true;
+}
+#endif
+
 static int lldevice_cmp(gconstpointer a, gconstpointer b)
 {
        const struct connected_device *llcondev = a;
@@ -147,7 +185,54 @@ static void link_loss_emit_alert_signal(struct connected_device *condev)
        g_dbus_emit_property_changed(btd_get_dbus_connection(), path,
                        PROXIMITY_REPORTER_INTERFACE, "LinkLossAlertLevel");
 }
+#ifdef __TIZEN_PATCH__
+static void link_loss_alert_lvl_read(struct gatt_db_attribute *attrib,
+                                       unsigned int id, uint16_t offset,
+                                       uint8_t opcode, struct bt_att *att,
+                                       void *user_data)
+{
+       struct link_loss_adapter *la = user_data;
+       struct connected_device *condev;
+       uint8_t value;
+       uint8_t ecode = 0;
+       bdaddr_t bdaddr;
+       uint8_t bdaddr_type;
+       struct btd_device *device;
+
+       value = NO_ALERT;
+
+       if (offset != 0) {
+               ecode = BT_ATT_ERROR_INVALID_OFFSET;
+               goto out;
+       }
+
+       if (!get_dest_info(att, &bdaddr, &bdaddr_type)) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto out;
+       }
+
+       device = btd_adapter_get_device(la->adapter, &bdaddr, bdaddr_type);
+       if (!device) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto out;
+       }
+
+       condev = find_connected_device(la, device);
+       if (!condev) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto out;
+       }
 
+       if (condev->alert_level)
+               value = condev->alert_level;
+       else
+               DBG("Alert Level is NULL");
+
+       DBG("Alert Level %d", value);
+out:
+       gatt_db_attribute_read_result(attrib, id, ecode, &value, sizeof(value));
+}
+#else
 static uint8_t link_loss_alert_lvl_read(struct attribute *a,
                                struct btd_device *device, gpointer user_data)
 {
@@ -173,6 +258,7 @@ out:
 
        return 0;
 }
+#endif
 
 /* condev can be NULL */
 static void link_loss_remove_condev(struct connected_device *condev)
@@ -224,6 +310,85 @@ static void link_loss_local_disc(struct btd_device *device,
        DBG("alert level zeroed for locally disconnecting dev %p", device);
 }
 
+#ifdef __TIZEN_PATCH__
+static void link_loss_alert_lvl_write(struct gatt_db_attribute *attrib,
+                                       unsigned int id, uint16_t offset,
+                                       const uint8_t *value, size_t len,
+                                       uint8_t opcode, struct bt_att *att,
+                                       void *user_data)
+{
+       struct link_loss_adapter *la = user_data;
+       struct connected_device *condev = NULL;
+        uint8_t ecode = 0;
+       bdaddr_t bdaddr;
+       uint8_t bdaddr_type;
+       struct btd_device *device = NULL;
+
+       if (!value || len == 0) {
+               ecode = BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN;
+               goto done;
+       }
+
+       if (offset != 0) {
+               ecode = BT_ATT_ERROR_INVALID_OFFSET;
+               goto done;
+       }
+
+       if (!get_dest_info(att, &bdaddr, &bdaddr_type)) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto done;
+       }
+
+       device = btd_adapter_get_device(la->adapter, &bdaddr, bdaddr_type);
+       if (!device) {
+               ecode = BT_ATT_ERROR_UNLIKELY;
+               goto done;
+       }
+
+       /* Write value should be anyone of 0x00, 0x01, 0x02 */
+       if (value[0] > 0x02) {
+               ecode = 0x80;
+               goto done;
+       }
+
+       /* condev might remain NULL here if nothing is found */
+       condev = find_connected_device(la, device);
+
+       /* Register a disconnect cb if the alert level is non-zero */
+       if (value[0] != NO_ALERT && !condev) {
+               condev = g_new0(struct connected_device, 1);
+               condev->device = btd_device_ref(device);
+               condev->adapter = la;
+               condev->callback_id = btd_device_add_attio_callback(device,
+                                       NULL, link_loss_disc_cb, condev);
+               condev->local_disc_id = device_add_disconnect_watch(device,
+                                       link_loss_local_disc, condev, NULL);
+
+               la->connected_devices = g_slist_append(la->connected_devices,
+                                                               condev);
+       }
+
+       if (condev) {
+               if (value[0] != NO_ALERT) {
+                       condev->alert_level = value[0];
+                       link_loss_emit_alert_signal(condev);
+               } else {
+                       link_loss_emit_alert_signal(condev);
+                       link_loss_remove_condev(condev);
+                       condev = NULL;
+               }
+       }
+
+       DBG("alert level set to %d by device %p", value[0], device);
+        gatt_db_attribute_write_result(attrib, id, ecode);
+       return;
+done:
+       DBG("Set link loss alert level for dev %p", device);
+       /* reset alert level on erroneous devices */
+       link_loss_remove_condev(condev);
+        gatt_db_attribute_write_result(attrib, id, ecode);
+}
+#else
 static uint8_t link_loss_alert_lvl_write(struct attribute *a,
                                struct btd_device *device, gpointer user_data)
 {
@@ -278,10 +443,16 @@ set_error:
        link_loss_remove_condev(condev);
        return ATT_ECODE_IO;
 }
+#endif
 
 void link_loss_register(struct btd_adapter *adapter)
 {
+#ifdef __TIZEN_PATCH__
+       struct gatt_db_attribute *service, *charc;
+       struct gatt_db *db;
+#else
        gboolean svc_added;
+#endif
        bt_uuid_t uuid;
        struct link_loss_adapter *lladapter;
 
@@ -291,7 +462,32 @@ void link_loss_register(struct btd_adapter *adapter)
        lladapter->adapter = adapter;
 
        link_loss_adapters = g_slist_append(link_loss_adapters, lladapter);
+#ifdef __TIZEN_PATCH__
+       db = (struct gatt_db *) btd_gatt_database_get_db(btd_adapter_get_database(adapter));
+
+       /*
+        * Link Loss Service
+        */
+       service = gatt_db_add_service(db, &uuid, true, 3);
+       if (!service)
+               goto err;
 
+       lladapter->llservice = service;
+
+       /*
+        * Alert Level characteristic.
+        */
+       bt_uuid16_create(&uuid, ALERT_LEVEL_CHR_UUID);
+       charc = 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,
+                                               link_loss_alert_lvl_read,
+                                               link_loss_alert_lvl_write, lladapter);
+
+       if (!charc)
+               goto err;
+
+       gatt_db_service_set_active(service, true);
+#else
        /* Link Loss Service */
        svc_added = gatt_service_add(adapter,
                        GATT_PRIM_SVC_UUID, &uuid,
@@ -309,7 +505,7 @@ void link_loss_register(struct btd_adapter *adapter)
 
        if (!svc_added)
                goto err;
-
+#endif
        DBG("Link Loss service added");
        return;
 
@@ -328,12 +524,23 @@ static void remove_condev_list_item(gpointer data, gpointer user_data)
 void link_loss_unregister(struct btd_adapter *adapter)
 {
        struct link_loss_adapter *lladapter;
+#ifdef __TIZEN_PATCH__
+       struct gatt_db *db;
+#endif
+
        lladapter = find_link_loss_adapter(adapter);
        if (!lladapter)
                return;
 
        g_slist_foreach(lladapter->connected_devices, remove_condev_list_item,
                        NULL);
+#ifdef __TIZEN_PATCH__
+       /* Remove registered service */
+       if (lladapter->llservice) {
+               db = (struct gatt_db *) btd_gatt_database_get_db(btd_adapter_get_database(adapter));
+               gatt_db_remove_service(db, lladapter->llservice);
+       }
+#endif
 
        link_loss_adapters = g_slist_remove(link_loss_adapters, lladapter);
        g_free(lladapter);
index 366d96b..3a88354 100644 (file)
 #include "attrib/att-database.h"
 #include "src/attrib-server.h"
 
+#ifdef __TIZEN_PATCH__
+#include "src/error.h"
+#endif
+
 #include "reporter.h"
 #include "linkloss.h"
 #include "immalert.h"
@@ -99,6 +103,7 @@ const char *get_alert_level_string(uint8_t level)
        return "unknown";
 }
 
+#ifndef __TIZEN_PATCH__
 static void register_tx_power(struct btd_adapter *adapter)
 {
        uint16_t start_handle, h;
@@ -142,6 +147,7 @@ static void register_tx_power(struct btd_adapter *adapter)
 
        g_assert(h - start_handle == svc_size);
 }
+#endif
 
 static gboolean property_get_link_loss_level(const GDBusPropertyTable *property,
                                        DBusMessageIter *iter, void *data)
@@ -222,6 +228,53 @@ int reporter_device_probe(struct btd_service *service)
        return 0;
 }
 
+#ifdef __TIZEN_PATCH__
+static DBusMessage *register_proximity(DBusConnection *conn, DBusMessage *msg,
+                                                               void *user_data)
+{
+       struct btd_adapter *adapter = user_data;
+
+       if(adapter == NULL) {
+               DBG("Adapter is NULL");
+               return btd_error_invalid_args(msg);
+       }
+
+       link_loss_register(adapter);
+       imm_alert_register(adapter);
+
+       /* TODO: TX Power service implementation
+        * is incomplete in BlueZ.
+        */
+       //register_tx_power(adapter);
+
+       return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_proximity(DBusConnection *conn, DBusMessage *msg,
+                                                               void *user_data)
+{
+       struct btd_adapter *adapter = user_data;
+
+       if(adapter == NULL) {
+               DBG("Adapter is NULL");
+               return btd_error_invalid_args(msg);
+       }
+
+       link_loss_unregister(adapter);
+       imm_alert_unregister(adapter);
+
+       return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable reporter_adapter_methods[] = {
+       { GDBUS_METHOD("RegisterProximity", NULL, NULL,
+                                               register_proximity) },
+       { GDBUS_METHOD("UnregisterProximity", NULL, NULL,
+                                               unregister_proximity) },
+       { }
+};
+#endif
+
 void reporter_device_remove(struct btd_service *service)
 {
        struct btd_device *device = btd_service_get_device(service);
@@ -241,11 +294,18 @@ int reporter_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter)
 
        radapter = g_new0(struct reporter_adapter, 1);
        radapter->adapter = adapter;
+#ifdef __TIZEN_PATCH__
+       const char *path = adapter_get_path(adapter);
 
+       g_dbus_register_interface(btd_get_dbus_connection(), path,
+                                       PROXIMITY_REPORTER_INTERFACE,
+                                       reporter_adapter_methods,
+                                       NULL, NULL, adapter, NULL);
+#else
        link_loss_register(adapter);
        register_tx_power(adapter);
        imm_alert_register(adapter);
-
+#endif
        reporter_adapters = g_slist_prepend(reporter_adapters, radapter);
        DBG("Proximity Reporter for adapter %p", adapter);
 
index a8e1aac..ed2c4dc 100644 (file)
@@ -43,4 +43,4 @@ int reporter_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter);
 void reporter_adapter_remove(struct btd_profile *p,
                                                struct btd_adapter *adapter);
 
-const char *get_alert_level_string(uint8_t level);
+const char *get_alert_level_string(uint8_t level);
\ No newline at end of file