From 8b530b18e9956399463fb90ef674076777f19313 Mon Sep 17 00:00:00 2001 From: Anupam Roy Date: Sat, 23 Jul 2016 15:49:30 +0530 Subject: [PATCH] [Adapt:HAL] Implement handler for incoming Authorization req Change-Id: I3dedf7d3d69baeec4a0a4c9e1983188d017f8826 Signed-off-by: Anupam Roy --- bt-oal/bluez_hal/hardware/bluetooth.h | 38 ++++++++++++ bt-oal/bluez_hal/inc/bt-hal-msg.h | 6 ++ bt-oal/bluez_hal/inc/bt-hal-utils.h | 20 ++++++- bt-oal/bluez_hal/src/bt-hal-agent.c | 103 +++++++++++++++++++++++++++++++- bt-oal/bluez_hal/src/bt-hal-bluetooth.c | 32 ++++++++++ bt-oal/bluez_hal/src/bt-hal-gap-agent.c | 68 ++++++++++++++++++++- bt-oal/bluez_hal/src/bt-hal-utils.c | 44 ++++++++++++++ 7 files changed, 308 insertions(+), 3 deletions(-) diff --git a/bt-oal/bluez_hal/hardware/bluetooth.h b/bt-oal/bluez_hal/hardware/bluetooth.h index ae6d446..7c5acf2 100755 --- a/bt-oal/bluez_hal/hardware/bluetooth.h +++ b/bt-oal/bluez_hal/hardware/bluetooth.h @@ -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); diff --git a/bt-oal/bluez_hal/inc/bt-hal-msg.h b/bt-oal/bluez_hal/inc/bt-hal-msg.h index 36b8f50..5c3bf26 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-msg.h +++ b/bt-oal/bluez_hal/inc/bt-hal-msg.h @@ -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 diff --git a/bt-oal/bluez_hal/inc/bt-hal-utils.h b/bt-oal/bluez_hal/inc/bt-hal-utils.h index 5356f18..cb7fa02 100644 --- a/bt-oal/bluez_hal/inc/bt-hal-utils.h +++ b/bt-oal/bluez_hal/inc/bt-hal-utils.h @@ -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_ diff --git a/bt-oal/bluez_hal/src/bt-hal-agent.c b/bt-oal/bluez_hal/src/bt-hal-agent.c index 34ad1e5..2a4e8e5 100644 --- a/bt-oal/bluez_hal/src/bt-hal-agent.c +++ b/bt-oal/bluez_hal/src/bt-hal-agent.c @@ -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, diff --git a/bt-oal/bluez_hal/src/bt-hal-bluetooth.c b/bt-oal/bluez_hal/src/bt-hal-bluetooth.c index 9334c0c..0b5244c 100644 --- a/bt-oal/bluez_hal/src/bt-hal-bluetooth.c +++ b/bt-oal/bluez_hal/src/bt-hal-bluetooth.c @@ -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; diff --git a/bt-oal/bluez_hal/src/bt-hal-gap-agent.c b/bt-oal/bluez_hal/src/bt-hal-gap-agent.c index 5cc8676..8be5874 100644 --- a/bt-oal/bluez_hal/src/bt-hal-gap-agent.c +++ b/bt-oal/bluez_hal/src/bt-hal-gap-agent.c @@ -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) { diff --git a/bt-oal/bluez_hal/src/bt-hal-utils.c b/bt-oal/bluez_hal/src/bt-hal-utils.c index 2dea6f8..d96efab 100644 --- a/bt-oal/bluez_hal/src/bt-hal-utils.c +++ b/bt-oal/bluez_hal/src/bt-hal-utils.c @@ -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; +} -- 2.7.4