[Adapt:HAL] Implement handler for incoming Authorization req 25/81725/1
authorAnupam Roy <anupam.r@samsung.com>
Sat, 23 Jul 2016 10:19:30 +0000 (15:49 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Thu, 28 Jul 2016 06:00:05 +0000 (11:30 +0530)
Change-Id: I3dedf7d3d69baeec4a0a4c9e1983188d017f8826
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
bt-oal/bluez_hal/hardware/bluetooth.h
bt-oal/bluez_hal/inc/bt-hal-msg.h
bt-oal/bluez_hal/inc/bt-hal-utils.h
bt-oal/bluez_hal/src/bt-hal-agent.c
bt-oal/bluez_hal/src/bt-hal-bluetooth.c
bt-oal/bluez_hal/src/bt-hal-gap-agent.c
bt-oal/bluez_hal/src/bt-hal-utils.c

index ae6d446..7c5acf2 100755 (executable)
@@ -354,6 +354,39 @@ typedef enum {
     BT_SSP_VARIANT_PASSKEY_NOTIFICATION
 } bt_ssp_variant_t;
 
+/** Bluetooth Profile Service IDs */
+typedef enum {
+    BT_RES_SERVICE_ID,              /* Reserved */
+    BT_SPP_SERVICE_ID,              /* Serial port profile. */
+    BT_DUN_SERVICE_ID,              /* Dial-up networking profile. */
+    BT_A2DP_SRC_SERVICE_ID,         /* A2DP Source profile. */
+    BT_LAP_SERVICE_ID,              /* LAN access profile. */
+    BT_HSP_SERVICE_ID,              /* Headset profile. */
+    BT_HFP_SERVICE_ID,              /* Hands-free profile. */
+    BT_OPP_SERVICE_ID,              /* Object push  */
+    BT_FTP_SERVICE_ID,              /* File transfer */
+    BT_AVRCP_CT_SERVICE_ID,         /* AVRC Controller Terminal */
+    BT_ICP_SERVICE_ID,              /* Intercom Terminal */
+    BT_SYNC_SERVICE_ID,             /* Synchronization */
+    BT_BPP_SERVICE_ID,              /* Basic printing profile */
+    BT_BIP_SERVICE_ID,              /* Basic Imaging profile */
+    BT_PANU_SERVICE_ID,             /* PAN User */
+    BT_NAP_SERVICE_ID,              /* PAN Network access point */
+    BT_GN_SERVICE_ID,               /* PAN Group Ad-hoc networks */
+    BT_SAP_SERVICE_ID,              /* SIM Access profile */
+    BT_A2DP_SERVICE_ID,             /* A2DP Sink */
+    BT_AVRCP_SERVICE_ID,            /* A/V remote control */
+    BT_HID_SERVICE_ID,              /* HID */
+    BT_VDP_SERVICE_ID,              /* Video distribution */
+    BT_PBAP_SERVICE_ID,             /* PhoneBook Access Server*/
+    BT_HSP_HS_SERVICE_ID,           /* HFP HS role */
+    BT_HFP_HS_SERVICE_ID,           /* HSP HS role */
+    BT_MAP_SERVICE_ID,              /* Message Access Profile */
+    BT_MN_SERVICE_ID,               /* Message Notification Service */
+    BT_HDP_SERVICE_ID,              /* Health Device Profile */
+    BT_PCE_SERVICE_ID               /* PhoneBook Access Client*/
+} bt_service_id_t;
+
 #define BT_MAX_NUM_UUIDS 32
 
 /** Bluetooth Interface callbacks */
@@ -444,6 +477,10 @@ typedef void (*le_test_mode_callback)(bt_status_t status, uint16_t num_packets);
  * Status-Provides the status of the read_energy_info API call */
 typedef void (*energy_info_callback)(bt_activity_energy_info *energy_info);
 
+/* Service level Authorization request callback */
+typedef void (*authorize_request_callback) (bt_bdaddr_t *remote_bd_addr, bt_service_id_t service_d);
+
+
 /** TODO: Add callbacks for Link Up/Down and other generic
   *  notifications/callbacks */
 
@@ -464,6 +501,7 @@ typedef struct {
     dut_mode_recv_callback dut_mode_recv_cb;
     le_test_mode_callback le_test_mode_cb;
     energy_info_callback energy_info_cb;
+    authorize_request_callback authorize_request_cb;
 } bt_callbacks_t;
 
 typedef void (*alarm_cb)(void *data);
index 36b8f50..5c3bf26 100644 (file)
@@ -156,6 +156,12 @@ struct hal_ev_bond_state_changed {
         uint8_t state;
 } __attribute__((packed));
 
+#define HAL_EV_AUTHORIZE_REQUEST        0x89
+struct hal_ev_authorize_request {
+       uint8_t  bdaddr[6];
+       uint32_t service_id;
+} __attribute__((packed));
+
 #define HAL_ACL_STATE_CONNECTED         0x00
 #define HAL_ACL_STATE_DISCONNECTED      0x01
 
index 5356f18..cb7fa02 100644 (file)
@@ -31,6 +31,24 @@ static const char BT_BASE_UUID[] = {
        0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb
 };
 
+/** BT Profile Service UUID's */
+#define BT_HAL_HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
+#define BT_HAL_AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_AVRCP_REMOTE_UUID "0000110e-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
+#define BT_HAL_SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
+#define BT_HAL_SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
+
 const char *bt_uuid_t2str(const uint8_t *uuid, char *buf);
 const char *btuuid2str(const uint8_t *uuid);
 const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf);
@@ -52,5 +70,5 @@ int int2str_findstr(const char *str, const struct int2str m[]);
 const char *enum_defines(void *v, int i);
 const char *enum_strings(void *v, int i);
 const char *enum_one_string(void *v, int i);
-
+bt_service_id_t _bt_convert_uuid_string_to_service_id(const char *uuid);
 #endif //_BT_HAL_UTILS_H_
index 34ad1e5..2a4e8e5 100644 (file)
@@ -46,6 +46,7 @@
 #include "bt-hal-log.h"
 #include "bt-hal-msg.h"
 #include "bt-hal-internal.h"
+#include "bt-hal-utils.h"
 #include "bt-hal-event-receiver.h"
 #include "bt-hal-dbus-common-utils.h"
 
@@ -85,9 +86,12 @@ static gboolean __bt_hal_display_request(GapAgentPrivate *agent, GDBusProxy *dev
 static gboolean __bt_hal_passkey_request(GapAgentPrivate *agent, GDBusProxy *device);
 static gboolean __bt_hal_confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
                guint passkey);
+static gboolean __bt_hal_authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
+                                                        const char *uuid);
 static GVariant *__bt_hal_service_getall(GDBusProxy *device, const char *interface);
 static void __bt_hal_agent_release_memory(void);
 static inline void stack_trim(void);
+static void __bt_hal_send_authorize_request_event(const gchar *address, const char *uuid);
 
 #ifdef TIZEN_SYSPOPUP_SUPPORTED
 static gboolean __bt_hal_device_is_hid_keyboard(unsigned int dev_class);
@@ -120,7 +124,7 @@ void* _bt_hal_create_agent(const char *path, gboolean adapter)
        func_cb.display_func = __bt_hal_display_request;
        func_cb.passkey_func = __bt_hal_passkey_request;
        func_cb.confirm_func = __bt_hal_confirm_request;
-       func_cb.authorize_func = NULL;
+       func_cb.authorize_func = __bt_hal_authorize_request;
        func_cb.pairing_cancel_func = NULL;
        func_cb.authorization_cancel_func = NULL;
 
@@ -206,6 +210,25 @@ void* _bt_hal_get_adapter_agent(void)
        return adapter_agent;
 }
 
+static void __bt_hal_send_authorize_request_event(const gchar *address, const char *uuid)
+{
+       struct hal_ev_authorize_request ev;
+       memset(&ev, 0, sizeof(ev));
+
+       DBG("Remote Device address [%s]", address);
+
+       _bt_convert_addr_string_to_type(ev.bdaddr, address);
+       ev.service_id = _bt_convert_uuid_string_to_service_id(uuid);
+
+       handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
+       if (event_cb) {
+               DBG("Sending AUTHORIZE REQUEST");
+               event_cb(HAL_EV_AUTHORIZE_REQUEST, (void*)&ev, sizeof(ev));
+       }
+
+       DBG("-");
+}
+
 /* Legacy Pairing */
 static void __bt_hal_send_pin_request_event(const gchar *address, const gchar *name,
                uint32_t cod)
@@ -552,6 +575,84 @@ done:
        return TRUE;
 }
 
+static gboolean __bt_hal_authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
+                                                        const char *uuid)
+{
+       const gchar *address;
+       const gchar *name;
+       gboolean trust;
+       gboolean paired;
+       GVariant *reply = NULL;
+       GVariant *reply_temp = NULL;
+       GVariant *tmp_value;
+
+       DBG("Authorize Request from Bluez STack: UUID [%s]", uuid);
+
+       reply_temp = __bt_hal_service_getall(device, BT_HAL_DEVICE_INTERFACE);
+       if (reply_temp == NULL) {
+               /* TODO Reject Authorization request */
+               goto done;
+       }
+
+       g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
+
+       tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
+       g_variant_get(tmp_value, "s", &address);
+       G_VARIANT_UNREF(tmp_value);
+       if (!address) {
+               /* TODO Reject Authorization request */
+               goto done;
+       }
+
+       tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
+       g_variant_get(tmp_value, "s", &name);
+       G_VARIANT_UNREF(tmp_value);
+       if (!name)
+               name = address;
+
+       tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
+       g_variant_get(tmp_value, "b", &trust);
+       G_VARIANT_UNREF(tmp_value);
+
+       tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
+       g_variant_get(tmp_value, "b", &paired);
+       G_VARIANT_UNREF(tmp_value);
+       if ((paired == FALSE) && (trust == FALSE)) {
+               ERR("No paired & No trusted device");
+               /* TODO Reject Authorization request */
+               goto done;
+       }
+
+       INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
+
+       if (trust) {
+               INFO("Trusted device, so authorize\n");
+               /* TODO Accept Authorization request */
+               goto done;
+       }
+
+       /*
+        * TODO: Handling for authorization request for different profiles will be
+        * implemented while profiles support is added. For now send all the request
+        * to bt-service or, launch bt-syspopup.
+        */
+#ifdef TIZEN_SYSPOPUP_SUPPORTED
+       DBG("Launch Syspopup: AUTHORIZE_REQUEST");
+       _bt_hal_launch_system_popup(BT_AGENT_EVENT_AUTHORIZE_REQUEST,
+                       name, NULL, NULL, _gap_agent_get_path(agent));
+#else
+       __bt_hal_send_authorize_request_event(address, uuid);
+#endif
+
+done:
+       g_variant_unref(reply);
+       g_variant_unref(reply_temp);
+       __bt_hal_agent_release_memory();
+
+       DBG("-");
+       return TRUE;
+}
+
 #ifdef TIZEN_SYSPOPUP_SUPPORTED
 int _bt_hal_launch_system_popup(bt_hal_agent_event_type_t event_type,
                const char *device_name,
index 9334c0c..0b5244c 100644 (file)
@@ -599,6 +599,34 @@ static void __bt_hal_handle_device_acl_state_changed_event(void *buf, uint16_t l
         DBG("-");
 }
 
+static void __bt_hal_handle_authorize_request_event(void *buf, uint16_t len)
+{
+       struct hal_ev_authorize_request *ev = (struct hal_ev_authorize_request *)buf;
+       bt_bdaddr_t bd_addr;
+
+       DBG("+");
+
+       memcpy(bd_addr.address, ev->bdaddr, 6);
+
+       /* BD address*/
+       DBG("[0x%x]", bd_addr.address[0]);
+       DBG("[0x%x]", bd_addr.address[1]);
+       DBG("[0x%x]", bd_addr.address[2]);
+       DBG("[0x%x]", bd_addr.address[3]);
+       DBG("[0x%x]", bd_addr.address[4]);
+       DBG("[0x%x]", bd_addr.address[5]);
+
+       DBG("Service Id: [%u]", ev->service_id);
+
+       if (!bt_hal_cbacks->authorize_request_cb) {
+               ERR("HAL User authorize_request_cb is not set!!");
+               return;
+       }
+
+       bt_hal_cbacks->authorize_request_cb(&bd_addr, ev->service_id);
+       DBG("-");
+}
+
 static void __bt_hal_handle_ssp_request_event(void *buf, uint16_t len)
 {
        struct hal_ev_ssp_request *ev = (struct hal_ev_ssp_request *)buf;
@@ -702,6 +730,10 @@ static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
                        DBG("Event: HAL_EV_PIN_REQUEST");
                        __bt_hal_handle_pin_request_event(buf, len);
                        break;
+               case HAL_EV_AUTHORIZE_REQUEST:
+                       DBG("Event: HAL_EV_AUTHORIZE_REQUEST");
+                       __bt_hal_handle_authorize_request_event(buf, len);
+                       break;
                default:
                        DBG("Event Currently not handled!!");
                        break;
index 5cc8676..8be5874 100644 (file)
@@ -661,7 +661,73 @@ static void __bt_gap_agent_method(GDBusConnection *connection,
                g_object_unref(device);
                return;
        } else if (g_strcmp0(method_name, "AuthorizeService") == 0) {
-               /* TODO */
+               GapAgentPrivate *priv = user_data;
+               char *sender = (char *)g_dbus_method_invocation_get_sender(invocation);
+               GDBusProxy *device;
+               GDBusConnection *conn;
+               char *addr;
+               char *path;
+               char *uuid;
+
+               if (sender == NULL)
+                       return;
+
+               g_variant_get(parameters, "(&o&s)", &path, &uuid);
+               DBG("Request authorization :sender %s priv->busname %s "
+                               "Device Path :%s UUID: %s",
+                               sender, priv->busname, path, uuid);
+
+               /* Need to check
+                  if (g_strcmp0(sender, agent->busname) != 0)
+                  return;
+                */
+
+               if (!priv->cb.authorize_func)
+                       return;
+
+               conn = _bt_get_system_gconn();
+               if (conn == NULL)
+                       return;
+
+               device = g_dbus_proxy_new_sync(conn,
+                               G_DBUS_PROXY_FLAGS_NONE, NULL,
+                               BT_HAL_BLUEZ_NAME, path,
+                               BT_HAL_PROPERTIES_INTERFACE, NULL, &err);
+
+               if (!device) {
+                       ERR("Fail to make device proxy");
+
+                       g_dbus_method_invocation_return_error(invocation,
+                                       GAP_AGENT_ERROR, GAP_AGENT_ERROR_REJECT,
+                                       "No proxy for device");
+
+                       if (err) {
+                               ERR("Unable to create proxy: %s", err->message);
+                               g_clear_error(&err);
+                       }
+
+                       return;
+               }
+
+               priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
+               priv->reply_context = invocation;
+
+               addr = strstr(path, "dev_");
+               if (addr != NULL) {
+                       char *pos = NULL;
+                       addr += 4;
+                       g_strlcpy(priv->authorize_addr, addr,
+                                       sizeof(priv->authorize_addr));
+
+                       while ((pos = strchr(priv->authorize_addr, '_')) != NULL) {
+                               *pos = ':';
+                       }
+               }
+
+               priv->cb.authorize_func(priv, device, uuid);
+
+               g_object_unref(device);
+               return;
        } else if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
                g_dbus_method_invocation_return_value(invocation, NULL);
        } else if (g_strcmp0(method_name, "ConfirmModeChange") == 0) {
index 2dea6f8..d96efab 100644 (file)
@@ -363,3 +363,47 @@ const char *btproperty2str(const bt_property_t *property)
 
        return buf;
 }
+
+bt_service_id_t _bt_convert_uuid_string_to_service_id(const char *uuid)
+{
+        bt_service_id_t service_id = BT_RES_SERVICE_ID;
+
+        DBG("+");
+
+        if (!strcasecmp(uuid, BT_HAL_HFP_AUDIO_GATEWAY_UUID))
+                service_id = BT_HFP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_HSP_AUDIO_GATEWAY_UUID))
+                service_id = BT_HSP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_A2DP_UUID))
+                service_id = BT_A2DP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_AVRCP_TARGET_UUID))
+                service_id = BT_AVRCP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_AVRCP_REMOTE_UUID))
+                service_id = BT_AVRCP_CT_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_OPP_UUID))
+                service_id = BT_OPP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_FTP_UUID))
+                service_id = BT_FTP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_SPP_UUID))
+                service_id = BT_SPP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_PBAP_UUID))
+                service_id = BT_PBAP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_MAP_UUID))
+                service_id = BT_MAP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_NAP_UUID))
+                service_id = BT_NAP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_GN_UUID))
+                service_id = BT_GN_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_HID_UUID))
+                service_id = BT_HID_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_SAP_UUID_OLD))
+                service_id = BT_SAP_SERVICE_ID;
+        else if (!strcasecmp(uuid, BT_HAL_SAP_UUID_NEW))
+                service_id = BT_SAP_SERVICE_ID;
+        else
+                ERR("Unknwon Service uuid, return BT_RES_SERVICE_ID");
+
+        DBG("service_id = [%d]", service_id);
+        DBG("-");
+        return service_id;
+}