X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=bt-service%2Fbt-service-agent.c;h=d231908bcbba156b10d988f13cd41d599dd7fdbb;hb=39ba85ec55b2de81bb872bacb035f6731e56086e;hp=48929308f4d10d8873e2d1f02a208514ad6e13ad;hpb=ade592e99b54c9156e258b1d890ee28ec1465ba8;p=platform%2Fcore%2Fconnectivity%2Fbluetooth-frwk.git diff --git a/bt-service/bt-service-agent.c b/bt-service/bt-service-agent.c index 4892930..d231908 100644 --- a/bt-service/bt-service-agent.c +++ b/bt-service/bt-service-agent.c @@ -1,13 +1,11 @@ /* - * bluetooth-frwk - * - * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,8 +20,13 @@ #include #include #include +#include #include +#include + +#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE #include +#endif #include "bt-internal-types.h" #include "bt-service-common.h" @@ -35,18 +38,15 @@ #include "bt-service-device.h" #include "bt-service-audio.h" -#if defined(LIBNOTIFY_SUPPORT) -#include "bt-popup.h" -#elif defined(LIBNOTIFICATION_SUPPORT) -#include "bt-service-agent-notification.h" -#else -#include +#ifdef TIZEN_DPM_ENABLE +#include "bt-service-dpm.h" #endif #define BT_APP_AUTHENTICATION_TIMEOUT 35 #define BT_APP_AUTHORIZATION_TIMEOUT 15 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb" +#define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb" #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB" #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb" #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb" @@ -58,16 +58,31 @@ #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb" #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb" +#define HID_DEVICE_UUID "00001124-0000-1000-8000-00805f9b43bf" +#define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00" +#define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a" +#define IOTIVITY_UUID "12341234-1C25-481F-9DFB-59193D238280" #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent" -#define BT_AGENT_INTERFACE "org.bluez.Agent" + +#define BT_AGENT_INTERFACE "org.bluez.Agent1" + #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize" #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize" -#define BT_PIN_MAX_LENGTH 16 #define BT_PASSKEY_MAX_LENGTH 4 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200 +#define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3 +#define BT_PAN_MAX_CONNECTION 4 + +extern guint nap_connected_device_count; + +static char *passkey_watcher = NULL; + +#define G_VARIANT_UNREF(variant) \ + g_variant_unref(variant); \ + variant = NULL static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address, const gchar *name); @@ -82,43 +97,37 @@ static void __bt_agent_release_memory(void) /* Release Stack Memory*/ stack_trim(); } - -static int __syspopup_launch(gpointer user_data) -{ - int ret; - bundle *b = (bundle *) user_data; -#if defined(LIBNOTIFY_SUPPORT) - ret = notify_launch(b); -#elif defined(LIBNOTIFICATION_SUPPORT) - ret = notification_launch(b); -#else - ret = syspopup_launch("bt-syspopup", b); -#endif - return ret; -} - static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data) { int ret; - bundle *b = (bundle *) user_data; + static int retry_count; + bundle *b = (bundle *)user_data; + retv_if(user_data == NULL, FALSE); - if (NULL == b) { - BT_DBG("There is some problem with the user data..popup can not be created\n"); - return FALSE; - } - ret = __syspopup_launch(b); + ++retry_count; - if (0 > ret) - BT_DBG("Sorry Can not launch popup\n"); - else - BT_DBG("Hurray Popup launched \n"); + ret = syspopup_launch("bt-syspopup", b); + if (ret < 0) { + BT_ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..", + ret, retry_count); + if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) { + BT_ERR("Sorry!! Max retry %d reached", retry_count); + bundle_free(b); + retry_count = 0; + return FALSE; + } + } else { + BT_DBG("Hurray!! Finally Popup launched"); + retry_count = 0; + bundle_free(b); + } - bundle_free(b); - return FALSE; + return (ret < 0) ? TRUE : FALSE; } -static int __launch_system_popup(bt_agent_event_type_t event_type, +int _bt_launch_system_popup(bt_agent_event_type_t event_type, const char *device_name, + const unsigned char *auth_info, char *passkey, const char *filename, const char *agent_path) @@ -127,13 +136,14 @@ static int __launch_system_popup(bt_agent_event_type_t event_type, bundle *b; char event_str[BT_MAX_EVENT_STR_LENGTH + 1]; - BT_DBG("_bt_agent_launch_system_popup +"); - b = bundle_create(); - if (!b) + if (!b) { + BT_ERR("Launching system popup failed"); return -1; + } bundle_add(b, "device-name", device_name); + bundle_add(b, "auth-info", (const char *)auth_info); bundle_add(b, "passkey", passkey); bundle_add(b, "file", filename); bundle_add(b, "agent-path", agent_path); @@ -192,7 +202,12 @@ static int __launch_system_popup(bt_agent_event_type_t event_type, g_strlcpy(event_str, "message-request", sizeof(event_str)); break; + case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE: + g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str)); + break; + default: + BT_ERR("Invalid event type"); bundle_free(b); return -1; @@ -200,65 +215,112 @@ static int __launch_system_popup(bt_agent_event_type_t event_type, bundle_add(b, "event-type", event_str); - ret = __syspopup_launch(b); + ret = syspopup_launch("bt-syspopup", b); if (0 > ret) { - BT_DBG("Popup launch failed...retry %d\n", ret); + BT_ERR("Popup launch failed...retry %d", ret); + g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS, - (GSourceFunc) __bt_agent_system_popup_timer_cb, - b); + (GSourceFunc)__bt_agent_system_popup_timer_cb, b); } else { bundle_free(b); } - BT_DBG("_bt_agent_launch_system_popup -%d", ret); + BT_INFO("_bt_agent_launch_system_popup"); return 0; } -static gboolean __pincode_request(GapAgent *agent, DBusGProxy *device) +static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface) { - uint32_t device_class; - GHashTable *hash = NULL; - GValue *value; - const gchar *address; - const gchar *name; GError *error = NULL; + GVariant *reply; + + reply = g_dbus_proxy_call_sync(device, + "GetAll", g_variant_new("(s)", interface), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &error); + if (reply == NULL) { + ERR("GetAll dBUS-RPC failed"); + if (error) { + ERR("D-Bus API failure: errCode[%x], message[%s]", + error->code, error->message); + g_clear_error(&error); + } + return NULL; + } + + return reply; +} + +static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device) +{ + uint32_t device_class; + gchar *address = NULL; + unsigned char auth_info[5] = {0, }; + gchar *name = NULL; + GVariant *reply = NULL; + GVariant *reply_temp = NULL; + GVariant *tmp_value; + char pin_code[BLUETOOTH_PIN_CODE_MAX_LENGTH + 1]; + + BT_DBG("+"); + +#ifdef TIZEN_DPM_ENABLE + if (_bt_dpm_get_bluetooth_pairing_state() == DPM_RESTRICTED) { + BT_ERR("Not allow to pair the device"); + gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL); + __bt_agent_release_memory(); + return TRUE; + } +#endif - BT_DBG("+\n"); + reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE); - dbus_g_proxy_call(device, "GetProperties", &error, - G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", - G_TYPE_STRING, G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - BT_DBG("error in GetBasicProperties [%s]\n", error->message); - g_error_free(error); + if (reply_temp == NULL) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", - NULL); + NULL); goto done; } - value = g_hash_table_lookup(hash, "Class"); - device_class = value ? g_value_get_uint(value) : 0; + g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/ + + tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32); + g_variant_get(tmp_value, "u", &device_class); + G_VARIANT_UNREF(tmp_value); - value = g_hash_table_lookup(hash, "Address"); - address = value ? g_value_get_string(value) : NULL; + 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) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Name"); - name = value ? g_value_get_string(value) : NULL; - if (!name) - name = address; + tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING); + g_variant_get(tmp_value, "s", &name); + G_VARIANT_UNREF(tmp_value); + if (!name) { + BT_DBG("Replacing the name with address"); + name = g_strdup(address); + } else { + BT_INFO("Name = %s, Address = %s, Class = 0x%x", name, address, device_class); + if (name[0] == '\0') { + g_free(name); + BT_DBG("Name[0]=NULL, Replacing the name with address"); + name = g_strdup(address); + } + } - if (__bt_agent_is_auto_response(device_class, address, name)) { - /* Use Fixed PIN "0000" for basic pairing*/ + __bt_get_auth_info(reply, (char *)auth_info); + if (_bt_is_device_creating() == TRUE && + _bt_is_bonding_device_address(address) == TRUE && + __bt_agent_is_auto_response(device_class, address, name)) { + BT_DBG("0000 Auto Pair"); + /* Use Fixed PIN "0000" for basic pairing */ _bt_set_autopair_status_in_bonding_info(TRUE); gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000", NULL); } else if (__bt_agent_is_hid_keyboard(device_class)) { + BT_DBG("HID Keyboard"); char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 }; if (__bt_agent_generate_passkey(str_passkey, @@ -271,191 +333,229 @@ static gboolean __pincode_request(GapAgent *agent, DBusGProxy *device) gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, str_passkey, NULL); - __launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, - name, str_passkey, NULL, + _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, + name, auth_info, str_passkey, NULL, _gap_agent_get_path(agent)); + } else if (_bt_get_device_pin_code(address, pin_code) + == BLUETOOTH_ERROR_NONE) { + BT_DBG("Use stored PIN code(%s)", pin_code); + gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, pin_code, + NULL); + goto done; } else { - __launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL, - NULL, _gap_agent_get_path(agent)); + BT_DBG("Show Pin entry"); + _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, auth_info, + NULL, NULL, _gap_agent_get_path(agent)); } done: - g_hash_table_destroy(hash); + g_variant_unref(reply); + g_variant_unref(reply_temp); + g_free(address); + g_free(name); __bt_agent_release_memory(); - - BT_DBG("-\n"); + BT_DBG("-"); return TRUE; } -static gboolean __passkey_request(GapAgent *agent, DBusGProxy *device) +static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device) { - uint32_t device_class; - GHashTable *hash = NULL; - GValue *value; - const gchar *address; - const gchar *name; - GError *error = NULL; + gchar *address = NULL; + gchar *name = NULL; + unsigned char auth_info[5] = {0, }; + GVariant *reply = NULL; + GVariant *reply_temp = NULL; + GVariant *tmp_value; + BT_DBG("+"); + +#ifdef TIZEN_DPM_ENABLE + if (_bt_dpm_get_bluetooth_pairing_state() == DPM_RESTRICTED) { + BT_ERR("Not allow to pair the device"); + gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL); + __bt_agent_release_memory(); + return TRUE; + } +#endif - BT_DBG("+\n"); + reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE); - dbus_g_proxy_call(device, "GetProperties", &error, - G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", - G_TYPE_STRING, G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - BT_DBG("error in GetBasicProperties [%s]\n", error->message); - g_error_free(error); + if (reply_temp == NULL) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Class"); - device_class = value ? g_value_get_uint(value) : 0; + g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/ - value = g_hash_table_lookup(hash, "Address"); - address = value ? g_value_get_string(value) : NULL; + 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) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Name"); - name = value ? g_value_get_string(value) : NULL; + tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING); + g_variant_get(tmp_value, "s", &name); + G_VARIANT_UNREF(tmp_value); if (!name) - name = address; + name = g_strdup(address); - __launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL, - _gap_agent_get_path(agent)); + __bt_get_auth_info(reply, (char *)auth_info); + + _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, auth_info, + NULL, NULL, _gap_agent_get_path(agent)); done: + g_variant_unref(reply); + g_variant_unref(reply_temp); + g_free(address); + g_free(name); __bt_agent_release_memory(); - g_hash_table_destroy(hash); - BT_DBG("-\n"); + BT_DBG("-"); return TRUE; } -static gboolean __display_request(GapAgent *agent, DBusGProxy *device, +static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device, guint passkey) { - GHashTable *hash = NULL; - GValue *value; - const gchar *address; - const gchar *name; - GError *error = NULL; + gchar *address = NULL; + gchar *name = NULL; + unsigned char auth_info[5] = {0, }; char *str_passkey; + GVariant *reply = NULL; + GVariant *reply_temp = NULL; + GVariant *tmp_value = NULL; - BT_DBG("+\n"); + BT_DBG("+"); - dbus_g_proxy_call(device, "GetProperties", &error, - G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, - G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - BT_DBG("error in GetBasicProperties [%s]\n", error->message); - g_error_free(error); + reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE); + if (reply_temp == NULL) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Address"); - address = value ? g_value_get_string(value) : NULL; + 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) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Name"); - name = value ? g_value_get_string(value) : NULL; + tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING); + g_variant_get(tmp_value, "s", &name); + G_VARIANT_UNREF(tmp_value); if (!name) - name = address; + name = g_strdup(address); - str_passkey = g_strdup_printf("%d", passkey); + __bt_get_auth_info(reply, (char *)auth_info); - __launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name, - str_passkey, NULL, + str_passkey = g_strdup_printf("%06d", passkey); + + if (passkey_watcher) { + GVariant *param = NULL; + + BT_INFO("Send passkey to %s", passkey_watcher); + + param = g_variant_new("(ss)", address, str_passkey); + + _bt_send_event_to_dest(passkey_watcher, BT_ADAPTER_EVENT, + BLUETOOTH_EVENT_PASSKEY_NOTIFICATION, param); + } else { + _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name, + auth_info, str_passkey, NULL, _gap_agent_get_path(agent)); + } g_free(str_passkey); done: + g_variant_unref(reply); + g_variant_unref(reply_temp); + g_free(address); + g_free(name); __bt_agent_release_memory(); - g_hash_table_destroy(hash); - BT_DBG("-\n"); + BT_DBG("-"); return TRUE; } -static gboolean __confirm_request(GapAgent *agent, DBusGProxy *device, +static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device, guint passkey) { - uint32_t device_class; - GHashTable *hash = NULL; - GValue *value; - const gchar *address; - const gchar *name; - GError *error = NULL; + gchar *address = NULL; + gchar *name = NULL; + unsigned char auth_info[5] = {0, }; char str_passkey[7]; - - BT_DBG("+ passkey[%.6d]\n", passkey); + GVariant *reply_temp = NULL; + GVariant *reply = NULL; + GVariant *tmp_value; + BT_DBG("+ passkey[%.6d]", passkey); + +#ifdef TIZEN_DPM_ENABLE + if (_bt_dpm_get_bluetooth_pairing_state() == DPM_RESTRICTED) { + BT_ERR("Not allow to pair the device"); + gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL); + __bt_agent_release_memory(); + return TRUE; + } +#endif snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey); - dbus_g_proxy_call(device, "GetProperties", &error, - G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, - G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - BT_DBG("error in GetBasicProperties [%s]\n", error->message); - g_error_free(error); + reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE); + + if (reply_temp == NULL) { + BT_ERR("Device doesn't exist"); gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Class"); - device_class = value ? g_value_get_uint(value) : 0; + g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/ - value = g_hash_table_lookup(hash, "Address"); - address = value ? g_value_get_string(value) : NULL; + 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) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Name"); - name = value ? g_value_get_string(value) : NULL; + tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING); + g_variant_get(tmp_value, "s", &name); + G_VARIANT_UNREF(tmp_value); if (!name) - name = address; + name = g_strdup(address); + __bt_get_auth_info(reply, (char *)auth_info); - __launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name, - str_passkey, NULL, + BT_DBG("LAUNCH SYSPOPUP"); + _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name, + auth_info, str_passkey, NULL, _gap_agent_get_path(agent)); done: + g_variant_unref(reply); + g_variant_unref(reply_temp); + g_free(address); + g_free(name); __bt_agent_release_memory(); - g_hash_table_destroy(hash); - - BT_DBG("-\n"); + BT_DBG("-"); return TRUE; } -static gboolean __pairing_cancel_request(GapAgent *agent, const char *address) +static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address) { BT_DBG("On Going Pairing is cancelled by remote\n"); - gap_agent_reply_pin_code(agent, GAP_AGENT_CANCEL, "", NULL); - -#ifndef LIBNOTIFY_SUPPORT syspopup_destroy_all(); -#endif __bt_agent_release_memory(); @@ -468,25 +568,24 @@ static gboolean __a2dp_authorize_request_check(void) return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL); } -static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device, +static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device, const char *uuid) { - GHashTable *hash = NULL; - GValue *value; - const gchar *address; - const gchar *name; - bool enabled; + gchar *address = NULL; + gchar *name = NULL; + unsigned char auth_info[5] = {0, }; gboolean trust; - gboolean paired; + GVariant *reply = NULL; + GVariant *reply_temp = NULL; + GVariant *tmp_value; +#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE + bool enabled; tethering_h tethering = NULL; - GError *error = NULL; - int ret; +#endif int result = BLUETOOTH_ERROR_NONE; int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST; - BT_DBG("+\n"); - - BT_DBG("+\n"); + BT_DBG("+"); /* Check if already Media connection exsist */ if (!strcasecmp(uuid, A2DP_UUID)) { @@ -495,7 +594,7 @@ static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device, ret = __a2dp_authorize_request_check(); if (ret) { - BT_DBG("Already one A2DP device connected \n"); + BT_ERR("Already one A2DP device connected \n"); gap_agent_reply_authorize(agent, GAP_AGENT_REJECT, NULL); goto done; @@ -504,9 +603,16 @@ static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device, /* Check completed */ if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) || + !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) || + !strcasecmp(uuid, HFP_HS_UUID) || + !strcasecmp(uuid, HSP_HS_UUID) || !strcasecmp(uuid, A2DP_UUID) || - !strcasecmp(uuid, HID_UUID) || - !strcasecmp(uuid, AVRCP_TARGET_UUID)) { + !strcasecmp(uuid, HID_UUID) || + !strcasecmp(uuid, HID_DEVICE_UUID) || + !strcasecmp(uuid, SAP_UUID_OLD) || + !strcasecmp(uuid, SAP_UUID_NEW) || + !strcasecmp(uuid, IOTIVITY_UUID) || + !strcasecmp(uuid, AVRCP_TARGET_UUID)) { BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid); gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL); @@ -519,6 +625,13 @@ static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device, !strcasecmp(uuid, BNEP_UUID)) { BT_DBG("Network connection request: %s", uuid); +#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE + if (nap_connected_device_count >= + BT_PAN_MAX_CONNECTION) { + BT_ERR("Max connection exceeded"); + goto fail; + } + int ret; ret = tethering_create(&tethering); if (ret != TETHERING_ERROR_NONE) { @@ -530,94 +643,80 @@ static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device, ret = tethering_destroy(tethering); - if (ret != TETHERING_ERROR_NONE) { + if (ret != TETHERING_ERROR_NONE) BT_ERR("Fail to create tethering: %d", ret); - } if (enabled != true) { BT_ERR("BT tethering is not enabled"); goto fail; } +#endif gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL); goto done; +#ifdef TIZEN_FEATURE_NETWORK_TETHERING_ENABLE fail: gap_agent_reply_authorize(agent, GAP_AGENT_REJECT, NULL); goto done; +#endif } - - dbus_g_proxy_call(device, "GetProperties", &error, G_TYPE_INVALID, - dbus_g_type_get_map("GHashTable", G_TYPE_STRING, - G_TYPE_VALUE), - &hash, G_TYPE_INVALID); - if (error) { - BT_DBG("error in GetBasicProperties [%s]\n", error->message); - g_error_free(error); + reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE); + if (reply_temp == NULL) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Address"); - address = value ? g_value_get_string(value) : NULL; + 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) { gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL); goto done; } - value = g_hash_table_lookup(hash, "Alias"); - name = value ? g_value_get_string(value) : NULL; + 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; + name = g_strdup(address); - value = g_hash_table_lookup(hash, "Trusted"); - trust = value ? g_value_get_boolean(value) : 0; + tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN); + g_variant_get(tmp_value, "b", &trust); + G_VARIANT_UNREF(tmp_value); - value = g_hash_table_lookup(hash, "Paired"); - paired = value ? g_value_get_boolean(value) : 0; - if ((paired == FALSE) && (trust == FALSE)) { - BT_DBG("No paired & No trusted device"); - gap_agent_reply_authorize(agent, - GAP_AGENT_REJECT, NULL); - goto done; - } + __bt_get_auth_info(reply, (char *)auth_info); - BT_DBG("Authorization request for device [%s] Service:[%s]\n", address, - uuid); + BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid); if (strcasecmp(uuid, OPP_UUID) == 0 && _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER, NULL) == TRUE) { _bt_send_event(BT_OPP_SERVER_EVENT, - BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE, - DBUS_TYPE_INT32, &result, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID); + BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE, + g_variant_new("(iss)", result, address, name)); goto done; } if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER, (char *)uuid) == TRUE) { - bt_rfcomm_server_info_t *server_info; - - server_info = _bt_rfcomm_get_server_info_using_uuid((char *)uuid); - retv_if(server_info == NULL, TRUE); - retv_if(server_info->server_type != BT_CUSTOM_SERVER, TRUE); - - _bt_send_event(BT_RFCOMM_SERVER_EVENT, - BLUETOOTH_EVENT_RFCOMM_AUTHORIZE, - DBUS_TYPE_INT32, &result, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INT16, &server_info->control_fd, - DBUS_TYPE_INVALID); + bt_agent_osp_server_t *osp_serv; + osp_serv = _gap_agent_get_osp_server(agent, + BT_RFCOMM_SERVER, (char *)uuid); + + if (osp_serv) { + _bt_send_event(BT_RFCOMM_SERVER_EVENT, + BLUETOOTH_EVENT_RFCOMM_AUTHORIZE, + g_variant_new("(issssn)", result, address, uuid, + name, osp_serv->path, osp_serv->fd)); + } goto done; } @@ -630,33 +729,37 @@ fail: request_type = BT_AGENT_EVENT_MAP_REQUEST; if (trust) { - BT_DBG("Trusted device, so authorize\n"); + BT_INFO("Trusted device, so authorize\n"); gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL); } else { - __launch_system_popup(request_type, name, NULL, NULL, + _bt_launch_system_popup(request_type, name, auth_info, NULL, NULL, _gap_agent_get_path(agent)); } done: - __bt_agent_release_memory(); - g_hash_table_destroy(hash); + if (reply) + g_variant_unref(reply); - BT_DBG("-\n"); + if (reply_temp) + g_variant_unref(reply_temp); + + g_free(name); + g_free(address); + __bt_agent_release_memory(); + BT_DBG("-"); return TRUE; } -static gboolean __authorization_cancel_request(GapAgent *agent, +static gboolean __authorization_cancel_request(GapAgentPrivate *agent, const char *address) { BT_DBG("On Going Authorization is cancelled by remote\n"); gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL); -#ifndef LIBNOTIFY_SUPPORT syspopup_destroy_all(); -#endif __bt_agent_release_memory(); @@ -668,16 +771,16 @@ void _bt_destroy_agent(void *agent) if (!agent) return; - _gap_agent_reset_dbus(agent); + _gap_agent_reset_dbus((GapAgentPrivate *)agent); - g_object_unref(agent); + g_free(agent); } void* _bt_create_agent(const char *path, gboolean adapter) { GAP_AGENT_FUNC_CB func_cb; - DBusGProxy *adapter_proxy; - GapAgent* agent; + GDBusProxy *adapter_proxy; + GapAgentPrivate *agent; adapter_proxy = _bt_get_adapter_proxy(); if (!adapter_proxy) @@ -691,33 +794,36 @@ void* _bt_create_agent(const char *path, gboolean adapter) func_cb.pairing_cancel_func = __pairing_cancel_request; func_cb.authorization_cancel_func = __authorization_cancel_request; - agent = _gap_agent_new(); + /* Allocate memory*/ + agent = g_new0(GapAgentPrivate, 1); _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy); if (adapter) { if (!_gap_agent_register(agent)) { _bt_destroy_agent(agent); - return NULL; + agent = NULL; } } return agent; } -gboolean _bt_agent_register_osp_server(const gint type, const char *uuid) +gboolean _bt_agent_register_osp_server(const gint type, + const char *uuid, char *path, int fd) { void *agent = _bt_get_adapter_agent(); if (!agent) return FALSE; - return _gap_agent_register_osp_server(agent, type, uuid); + return _gap_agent_register_osp_server(agent, type, uuid, path, fd); } gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid) { void *agent = _bt_get_adapter_agent(); + if (!agent) return FALSE; @@ -737,11 +843,39 @@ gboolean _bt_agent_reply_authorize(gboolean accept) return gap_agent_reply_authorize(agent, accept_val, NULL); } -gboolean _bt_agent_is_canceled(void *agent) +gboolean _bt_agent_is_canceled(void) { + void *agent = _bt_get_adapter_agent(); + if (!agent) + return FALSE; + return _gap_agent_is_canceled(agent); } +void _bt_agent_set_canceled(gboolean value) +{ + void *agent = _bt_get_adapter_agent(); + if (!agent) + return; + + return _gap_agent_set_canceled(agent, value); +} + +int _bt_agent_reply_cancellation(void) +{ + void *agent = _bt_get_adapter_agent(); + + if (!agent) + return BLUETOOTH_ERROR_INTERNAL; + + if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) { + BT_ERR("Fail to reply agent"); + return BLUETOOTH_ERROR_INTERNAL; + } + + return BLUETOOTH_ERROR_NONE; +} + static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class) { switch ((dev_class & 0x1f00) >> 8) { @@ -807,12 +941,12 @@ static gboolean __bt_agent_is_device_blacklist(const char *address, long size; size_t result; - BT_DBG("+ \n"); + BT_DBG("+"); fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r"); if (fp == NULL) { - BT_DBG("fopen failed \n"); + BT_ERR("Unable to open blacklist file"); return FALSE; } @@ -830,18 +964,18 @@ static gboolean __bt_agent_is_device_blacklist(const char *address, result = fread((char *)buffer, 1, size, fp); fclose(fp); if (result != size) { - BT_DBG("Read Error\n"); + BT_ERR("Read Error"); g_free(buffer); return FALSE; } - BT_DBG("Buffer = %s\n", buffer); + BT_DBG("Buffer = %s", buffer); lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0); g_free(buffer); if (lines == NULL) { - BT_DBG("No lines in the file \n"); + BT_ERR("No lines in the file"); return FALSE; } @@ -858,12 +992,16 @@ static gboolean __bt_agent_is_device_blacklist(const char *address, if (__bt_agent_find_device_by_partial_name(lines[i], name)) goto done; + if (g_str_has_prefix(lines[i], "KeyboardAutoPair")) + if (__bt_agent_find_device_by_address_exactname( + lines[i], address)) + goto done; } g_strfreev(lines); - BT_DBG("- \n"); + BT_DBG("-"); return FALSE; done: - BT_DBG("Found the device\n"); + BT_DBG("Found the device"); g_strfreev(lines); return TRUE; } @@ -872,6 +1010,7 @@ static gboolean __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address, const gchar *name) { gboolean is_headset = FALSE; + gboolean is_mouse = FALSE; char lap_address[BT_LOWER_ADDRESS_LENGTH]; BT_DBG("bt_agent_is_headset_class, %d +", dev_class); @@ -901,9 +1040,29 @@ static gboolean __bt_agent_is_auto_response(uint32_t dev_class, break; } break; + case 0x05: + switch (dev_class & 0xff) { + case 0x80: /* 0x80: Pointing device(Mouse) */ + is_mouse = TRUE; + break; + + case 0x40: /* 0x40: input device (BT keyboard) */ + + /* Get the LAP(Lower Address part) */ + g_strlcpy(lap_address, address, sizeof(lap_address)); + + /* Need to Auto pair the blacklisted Keyboard */ + if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) { + BT_DBG("Device is not black listed\n"); + return FALSE; + } else { + BT_ERR("Device is black listed\n"); + return TRUE; + } + } } - if (!is_headset) + if ((!is_headset) && (!is_mouse)) return FALSE; /* Get the LAP(Lower Address part) */ @@ -913,7 +1072,7 @@ static gboolean __bt_agent_is_auto_response(uint32_t dev_class, BT_DBG("Address 3 byte = %s\n", lap_address); if (__bt_agent_is_device_blacklist(lap_address, name)) { - BT_DBG("Device is black listed\n"); + BT_ERR("Device is black listed\n"); return FALSE; } @@ -940,7 +1099,8 @@ static int __bt_agent_generate_passkey(char *passkey, int size) for (i = 0; i < size; i++) { len = read(random_fd, &value, sizeof(value)); - passkey[i] = '0' + (value % 10); + if (len > 0) + passkey[i] = '0' + (value % 10); } close(random_fd); @@ -949,3 +1109,17 @@ static int __bt_agent_generate_passkey(char *passkey, int size) return 0; } + +int _bt_set_passkey_notification(const char *sender, gboolean enable) +{ + BT_INFO("Set passkey notification(sender:%s, %s)", + sender, enable ? "Enable" : "Disable"); + + g_free(passkey_watcher); + if (enable == TRUE) + passkey_watcher = g_strdup(sender); + else + passkey_watcher = NULL; + + return BLUETOOTH_ERROR_NONE; +}