[Adapt:BluezHAL]Handle remote device properties 17/78117/1
authorAtul Rai <a.rai@samsung.com>
Mon, 4 Jul 2016 09:24:50 +0000 (18:24 +0900)
committerAtul Rai <a.rai@samsung.com>
Mon, 4 Jul 2016 09:44:02 +0000 (18:44 +0900)
This patch implements HAL API get_remote_device_properties()
and handles remote device properties events from stack.

Change-Id: I7116e633bad5182b20d660d6c0ca10a221874cfc
Signed-off-by: Atul Rai <a.rai@samsung.com>
bt-oal/bluez_hal/src/bt-hal-bluetooth.c
bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.c
bt-oal/bluez_hal/src/bt-hal-device-dbus-handler.h

index ac4ca98..47f1a2f 100644 (file)
@@ -120,7 +120,12 @@ static int set_adapter_property(const bt_property_t *property)
 
 static int get_remote_device_properties(bt_bdaddr_t *remote_addr)
 {
-       return BT_STATUS_UNSUPPORTED;
+       if (!remote_addr) {
+               ERR("Invalid param");
+               return BT_STATUS_PARM_INVALID;
+       }
+
+       return _bt_hal_dbus_get_remote_device_properties(remote_addr);
 }
 
 static int get_remote_device_property(bt_bdaddr_t *remote_addr,
@@ -505,6 +510,25 @@ static void __bt_hal_handle_device_found_event(void *buf, uint16_t len)
        bt_hal_cbacks->device_found_cb(ev->num_props, props);
 }
 
+static void __bt_hal_handle_remote_device_properties_event(void *buf, uint16_t len)
+{
+       struct hal_ev_remote_device_props *ev = (struct hal_ev_remote_device_props *) buf;
+       bt_bdaddr_t bd_addr;
+       bt_property_t props[ev->num_props];
+
+       DBG("+");
+
+       if (!bt_hal_cbacks->remote_device_properties_cb)
+               return;
+
+       len -= sizeof(*ev);
+       __bt_device_props_to_hal(props, ev->props, ev->num_props, len);
+       memcpy(bd_addr.address, ev->bdaddr, 6);
+       bt_hal_cbacks->remote_device_properties_cb(
+                       ev->status, &bd_addr, ev->num_props, props);
+       DBG("-");
+}
+
 static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
 {
        DBG("+");
@@ -524,6 +548,11 @@ static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
                case HAL_EV_DEVICE_FOUND:
                        DBG("Event: HAL_EV_DEVICE_FOUND");
                        __bt_hal_handle_device_found_event(buf, len);
+                       break;
+               case HAL_EV_REMOTE_DEVICE_PROPS:
+                       DBG("Event: HAL_EV_REMOTE_DEVICE_PROPS");
+                       __bt_hal_handle_remote_device_properties_event(buf, len);
+                       break;
                default:
                        DBG("Event Currently not handled!!");
                        break;
index 2ab3f3f..bfb3639 100644 (file)
@@ -46,6 +46,8 @@
 #include "bt-hal-device-dbus-handler.h"
 #include "bt-hal-event-receiver.h"
 
+static handle_stack_msg event_cb = NULL;
+
 /* Forward Delcaration */
 static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res, gpointer user_data);
 
@@ -66,7 +68,8 @@ int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr)
        memset(&ev, 0, sizeof(ev));
        DBG("+");
 
-       DBG("Transport [%d] Add[0x%x] [0x%x][0x%x][0x%x][0x%x][0x%x]", transport, bd_addr->address[0], bd_addr->address[1],
+       DBG("Transport [%d] Add[0x%x] [0x%x][0x%x][0x%x][0x%x][0x%x]",
+                       transport, bd_addr->address[0], bd_addr->address[1],
                        bd_addr->address[2], bd_addr->address[3],
                        bd_addr->address[4], bd_addr->address[5]);
        conn = _bt_get_system_gconn();
@@ -133,7 +136,8 @@ int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr)
 
        _bt_convert_addr_string_to_type(ev.bdaddr, address);
 
-       handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
+       if (!event_cb)
+               event_cb = _bt_hal_get_stack_message_handler();
        if (event_cb) {
                DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
                event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
@@ -285,7 +289,8 @@ static void __bt_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
 
        _bt_convert_addr_string_to_type(ev.bdaddr, dev_address);
 
-       handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
+       if (!event_cb)
+               event_cb = _bt_hal_get_stack_message_handler();
        if (event_cb) {
                DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
                event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
@@ -321,7 +326,8 @@ static void __bt_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
        _bt_convert_device_path_to_address(device_path, dev_address);
        _bt_convert_addr_string_to_type(ev.bdaddr, dev_address);
 
-       handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
+       if (!event_cb)
+               event_cb = _bt_hal_get_stack_message_handler();
        if (event_cb) {
                DBG("Sending HAL_EV_BOND_STATE_CHANGED event");
                event_cb(HAL_EV_BOND_STATE_CHANGED, (void*)&ev, sizeof(ev));
@@ -329,3 +335,230 @@ static void __bt_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
        g_free(device_path);
        DBG("-");
 }
+
+static gboolean __bt_device_bonded_device_info_cb(gpointer user_data)
+{
+       /* Buffer and propety count management */
+       uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
+       struct hal_ev_remote_device_props *ev = (void*) buf;;
+       size_t size = 0;
+
+       GVariant *result = user_data;
+       GVariantIter *property_iter;
+       GVariantIter *char_value_iter;
+
+       const gchar *address = NULL;
+       const gchar *name = NULL;
+       unsigned int cod = 0;
+       gint rssi = 0;
+       gboolean trust = FALSE;
+       gboolean paired = FALSE;
+       int connected = 0;
+       GByteArray *manufacturer_data = NULL;
+       const gchar *key;
+       GVariant *value;
+       guint8 char_value;
+       unsigned int data_len = 0;
+
+       memset(buf, 0, sizeof(buf));
+       size = sizeof(*ev);
+       ev->num_props = 0;
+       ev->status = BT_STATUS_SUCCESS;
+
+       g_variant_get(result, "(a{sv})", &property_iter);
+       while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
+               if(!g_strcmp0(key, "Address")) {
+                       address = g_variant_get_string(value, NULL);
+                       DBG("Address [%s]", address);
+                       _bt_convert_addr_string_to_type(ev->bdaddr, address);
+               } else if (!g_strcmp0(key, "Alias")) {
+                       name = g_variant_get_string(value, NULL);
+                       DBG("Alias [%s]", name);
+                       size += __bt_insert_hal_properties(buf + size,
+                                       HAL_PROP_DEVICE_FRIENDLY_NAME, strlen(name) + 1, name);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key, "Class")) {
+                       cod = g_variant_get_uint32(value);
+                       DBG("Class [%d]", cod);
+                       size += __bt_insert_hal_properties(buf + size,
+                                       HAL_PROP_DEVICE_CLASS, sizeof(unsigned int), &cod);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key, "Connected")) {
+                       connected = g_variant_get_byte(value);
+                       DBG("Connected [%d]", connected);
+                       size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
+                                       sizeof(unsigned int), &connected);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key,"Paired")) {
+                       paired = g_variant_get_boolean(value);
+                       DBG("Paired [%d]", paired);
+                       size += __bt_insert_hal_properties(buf + size,
+                                       HAL_PROP_DEVICE_PAIRED, sizeof(unsigned int), &paired);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key, "Trusted")) {
+                       trust = g_variant_get_boolean(value);
+                       DBG("Trusted [%d]", trust);
+                       size += __bt_insert_hal_properties(buf + size,
+                                       HAL_PROP_DEVICE_TRUSTED, sizeof(unsigned int), &trust);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key, "Name")) {
+                       name = g_variant_get_string(value, NULL);
+                       DBG("Name [%s]", name);
+                       size += __bt_insert_hal_properties(buf + size,
+                                       HAL_PROP_DEVICE_NAME, strlen(name) + 1, name);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key, "RSSI")) {
+                       rssi = g_variant_get_int16(value);
+                       DBG("RSSI [%d]", rssi);
+                       size += __bt_insert_hal_properties(buf + size,
+                                       HAL_PROP_DEVICE_RSSI, sizeof(unsigned int), &rssi);
+                       ev->num_props++;
+               } else if (!g_strcmp0(key, "UUIDs")) {
+                       char **uuid_value;
+                       int uuid_count = 0;
+                       gsize size1 = 0;
+                       int i =0;
+                       size1 = g_variant_get_size(value);
+                       int num_props_tmp = ev->num_props;
+                       if (size1 > 0) {
+                               uuid_value = (char **)g_variant_get_strv(value, &size1);
+                               for (i = 0; uuid_value[i] != NULL; i++)
+                                       uuid_count++;
+                               /* UUID collection */
+                               uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
+                               for (i = 0; uuid_value[i] != NULL; i++) {
+                                       char *uuid_str = NULL;
+                                       uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
+                                       memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
+                                       uuid_str = g_strdup(uuid_value[i]);
+                                       DBG("UUID string [%s]\n", uuid_str);
+                                       _bt_convert_uuid_string_to_type(uuid, uuid_str);
+                                       memcpy(uuids + i * BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
+                               }
+                               size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
+                                               (BT_HAL_STACK_UUID_SIZE * uuid_count), uuids);
+                               ev->num_props = num_props_tmp + 1;
+                               g_free(uuid_value);
+                       }
+               } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
+                       data_len = g_variant_get_uint16(value);
+                       DBG("ManufacturerDataLen [%d]", data_len);
+               } else if (!g_strcmp0(key, "ManufacturerData")) {
+                       manufacturer_data = g_byte_array_new();
+                       g_variant_get(value, "ay", &char_value_iter);
+                       while(g_variant_iter_loop(char_value_iter, "y",  &char_value)) {
+                               g_byte_array_append(manufacturer_data, &char_value, 1);
+                       }
+
+                       if (manufacturer_data) {
+                               if (manufacturer_data->len > 0) {
+                                       size += __bt_insert_hal_properties(
+                                                       buf + size, HAL_PROP_DEVICE_BLE_ADV_DATA,
+                                                       manufacturer_data->len, manufacturer_data->data);
+                                       ev->num_props++;
+                               }
+                       }
+                       g_byte_array_free(manufacturer_data, FALSE);
+               } else {
+                       ERR("Unhandled Property:[%s]", key);
+               }
+       }
+
+       DBG("trust: %d, paired: %d", trust, paired);
+       if (!event_cb)
+               event_cb = _bt_hal_get_stack_message_handler();
+       if (!event_cb) {
+               ERR("event_cb is NULL");
+               goto done;
+       }
+
+       if ((paired == FALSE) && (trust == FALSE)) {
+               ev->status = BT_STATUS_FAIL;
+               ev->num_props = 0;
+               size = sizeof(*ev);
+               DBG("Send Remote Device properties event to HAL,"
+                               " Num Prop [%d] total size [%d]",ev->num_props, size);
+               event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
+       } else {
+               if (size > 2) {
+                       DBG("Send Remote Device properties event to HAL,"
+                               " Num Prop [%d] total size [%d]",ev->num_props, size);
+                       event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
+               }
+       }
+
+done:
+       g_variant_unref(result);
+       return FALSE;
+}
+
+int _bt_hal_dbus_get_remote_device_properties(bt_bdaddr_t *remote_addr)
+{
+       char *device_path = NULL;
+       char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+       GError *error = NULL;
+       GDBusProxy *device_proxy;
+       GDBusConnection *conn;
+       GVariant *result;
+
+       if(!remote_addr) {
+               ERR("Invalid device address ptr received");
+               return BT_STATUS_PARM_INVALID;
+       }
+
+       _bt_convert_addr_type_to_string(address, remote_addr->address);
+       device_path = _bt_get_device_object_path(address);
+       if (!device_path) {
+               ERR("Device not paired");
+               return BT_STATUS_FAIL;
+       }
+
+       conn = _bt_get_system_gconn();
+       if (!conn) {
+               ERR("_bt_get_system_gconn failed");
+               return BT_STATUS_FAIL;
+       }
+
+       device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+                       NULL,
+                       BT_HAL_BLUEZ_NAME,
+                       device_path,
+                       BT_HAL_PROPERTIES_INTERFACE,
+                       NULL, NULL);
+
+       if (!device_proxy) {
+               ERR("Error creating device_proxy");
+               g_free(device_path);
+               return BT_STATUS_FAIL;
+       }
+
+       result = g_dbus_proxy_call_sync(device_proxy,
+                       "GetAll",
+                       g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1,
+                       NULL,
+                       &error);
+
+       if (!result) {
+               ERR("Error occured in Proxy call");
+               if (error != NULL) {
+                       ERR("Error occured in Proxy call (Error: %s)", error->message);
+                       g_clear_error(&error);
+               }
+               g_object_unref(device_proxy);
+               g_free(device_path);
+               return BT_STATUS_FAIL;
+       }
+
+       g_object_unref(device_proxy);
+       g_free(device_path);
+       /*
+        * As we need to provide async callback to user from HAL, simply schedule a
+        * callback method which will carry actual result
+        */
+       g_idle_add(__bt_device_bonded_device_info_cb, (gpointer)result);
+
+       DBG("-");
+       return BT_STATUS_SUCCESS;
+}
index a619a83..a7841fb 100644 (file)
@@ -40,6 +40,8 @@ int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr);
 
 int _bt_hal_device_remove_bond(const bt_bdaddr_t *bd_addr);
 
+int _bt_hal_dbus_get_remote_device_properties(bt_bdaddr_t *remote_addr);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */