4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
28 #include <stacktrim.h>
30 #if defined(LIBNOTIFY_SUPPORT)
32 #elif defined(LIBNOTIFICATION_SUPPORT)
33 #include "bt-service-agent-notification.h"
35 #include <syspopup_caller.h>
39 #include <bundle_internal.h>
41 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
42 #include <tethering.h>
45 #include "bt-internal-types.h"
46 #include "bt-service-common.h"
47 #include "bt-service-agent.h"
48 #include "bt-service-gap-agent.h"
49 #include "bt-service-adapter.h"
50 #include "bt-service-event.h"
51 #include "bt-service-rfcomm-server.h"
52 #include "bt-service-device.h"
53 #include "bt-service-audio.h"
55 #define BT_APP_AUTHENTICATION_TIMEOUT 35
56 #define BT_APP_AUTHORIZATION_TIMEOUT 15
58 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
59 #define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
60 #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
61 #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
62 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
63 #define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
64 #define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
65 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
66 #define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
67 #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
68 #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
69 #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
70 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
71 #define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
72 #define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
74 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
76 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
78 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
79 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
81 #define BT_PIN_MAX_LENGTH 16
82 #define BT_PASSKEY_MAX_LENGTH 4
84 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
85 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
86 #define BT_PAN_MAX_CONNECTION 4
87 extern guint nap_connected_device_count;
89 #define G_VARIANT_UNREF(variant) \
90 g_variant_unref(variant); \
93 static gboolean syspopup_mode = TRUE;
95 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
97 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
98 static int __bt_agent_generate_passkey(char *passkey, int size);
100 static void __bt_agent_release_memory(void)
102 /* Release Malloc Memory*/
105 /* Release Stack Memory*/
109 static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
112 static int retry_count;
113 bundle *b = (bundle *)user_data;
114 retv_if(user_data == NULL, FALSE);
117 #if defined(LIBNOTIFY_SUPPORT)
118 ret = notify_launch(b);
119 #elif defined(LIBNOTIFICATION_SUPPORT)
120 ret = notification_launch(b);
122 ret = syspopup_launch("bt-syspopup", b);
125 BT_ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..",
127 if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) {
128 BT_ERR("Sorry!! Max retry %d reached", retry_count);
134 BT_DBG("Hurray!! Finally Popup launched");
139 return (ret < 0) ? TRUE : FALSE;
142 #ifdef TIZEN_WEARABLE
143 static void __bt_unbond_cb(GDBusProxy *proxy,
144 GAsyncResult *res, gpointer user_data)
149 value = g_dbus_proxy_call_finish(proxy, res, &err);
151 BT_ERR("Error: Unbond Failed");
153 BT_ERR("errCode[%x], message[%s]\n", err->code, err->message);
158 g_variant_unref(value);
159 BT_INFO("Unbonding is done");
163 static gboolean __bt_unpair_device(void)
169 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
170 if (device_list == NULL) {
171 BT_ERR("g_array_new is failed");
175 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
176 BT_ERR("_bt_get_bonded_devices is failed");
177 g_array_free(device_list, TRUE);
181 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
182 for (i = 0; i < no_of_device; i++) {
183 GDBusProxy *adapter_proxy;
184 bluetooth_device_info_t info;
185 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
186 char *device_path = NULL;
188 info = g_array_index(device_list, bluetooth_device_info_t, i);
189 if (info.device_class.major_class ==
190 BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO)
193 adapter_proxy = _bt_get_adapter_proxy();
194 if (!adapter_proxy) {
195 BT_ERR("adapter_proxy is NULL");
196 g_array_free(device_list, TRUE);
200 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
201 device_path = _bt_get_device_object_path(addr);
202 if (device_path == NULL) {
203 BT_ERR("device_path is NULL");
204 g_array_free(device_list, TRUE);
208 g_dbus_proxy_call(adapter_proxy,
209 "UnpairDevice", g_variant_new("o", device_path),
210 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
211 (GAsyncReadyCallback)__bt_unbond_cb, NULL);
213 BT_INFO("unbonding %s is requested", addr);
215 g_array_free(device_list, TRUE);
219 g_array_free(device_list, TRUE);
223 static void __bt_popup_event_filter(GDBusConnection *connection,
224 const gchar *sender_name,
225 const gchar *object_path,
226 const gchar *interface_name,
227 const gchar *signal_name,
228 GVariant *parameters,
231 BT_DBG("Sender Name[%s] Object Path[%s] Interface[%s] Signal[%s]",
232 sender_name, object_path, interface_name, signal_name);
234 if (g_strcmp0(interface_name, "User.Bluetooth.syspopup") == 0 &&
235 g_strcmp0(signal_name, "ResetResponse") == 0) {
238 g_variant_get(parameters, "(i)", &response);
239 BT_DBG("response = %d", response);
243 int __bt_service_subscribe_popup(GDBusConnection *conn,
246 static guint subs_interface_added_id = 0;
249 return BLUETOOTH_ERROR_INVALID_PARAM;
252 if (subs_interface_added_id == 0) {
253 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
254 NULL, "User.Bluetooth.syspopup", "ResetResponse", NULL, NULL, 0,
255 __bt_popup_event_filter, NULL, NULL);
258 if (subs_interface_added_id > 0) {
259 g_dbus_connection_signal_unsubscribe(conn,
260 subs_interface_added_id);
261 subs_interface_added_id = 0;
264 return BLUETOOTH_ERROR_NONE;
267 static void __bt_register_popup_event_signal(void)
269 GDBusConnection *conn;
273 conn = _bt_get_system_gconn();
277 __bt_service_subscribe_popup(conn, TRUE);
283 static gboolean __is_reset_required(const gchar *address)
286 uint32_t no_of_device;
288 bluetooth_device_info_t info;
289 gboolean is_required = FALSE;
291 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
292 if (device_list == NULL) {
293 BT_ERR("g_array_new is failed");
297 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
298 BT_ERR("_bt_get_bonded_devices is failed");
299 g_array_free(device_list, TRUE);
303 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
304 for (i = 0; i < no_of_device; i++) {
305 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
307 info = g_array_index(device_list, bluetooth_device_info_t, i);
309 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
310 if (g_strcmp0(address, addr) == 0) {
311 BT_DBG("This device is already in paired list");
316 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
321 g_array_free(device_list, TRUE);
327 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
328 const char *device_name,
330 const char *filename,
331 const char *agent_path)
335 char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
339 BT_ERR("Launching system popup failed");
343 bundle_add(b, "device-name", device_name);
344 bundle_add(b, "passkey", passkey);
345 bundle_add(b, "file", filename);
346 bundle_add(b, "agent-path", agent_path);
348 switch (event_type) {
349 case BT_AGENT_EVENT_PIN_REQUEST:
350 g_strlcpy(event_str, "pin-request", sizeof(event_str));
353 case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
354 g_strlcpy(event_str, "passkey-confirm-request",
358 case BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED:
359 g_strlcpy(event_str, "passkey-auto-accepted",
363 case BT_AGENT_EVENT_PASSKEY_REQUEST:
364 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
367 case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
368 g_strlcpy(event_str, "passkey-display-request",
372 case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
373 g_strlcpy(event_str, "authorize-request",
377 case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
378 g_strlcpy(event_str, "confirm-mode-request",
382 case BT_AGENT_EVENT_FILE_RECEIVED:
383 g_strlcpy(event_str, "file-received", sizeof(event_str));
386 case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
387 g_strlcpy(event_str, "keyboard-passkey-request",
391 case BT_AGENT_EVENT_TERMINATE:
392 g_strlcpy(event_str, "terminate", sizeof(event_str));
395 case BT_AGENT_EVENT_EXCHANGE_REQUEST:
396 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
399 case BT_AGENT_EVENT_PBAP_REQUEST:
400 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
403 case BT_AGENT_EVENT_MAP_REQUEST:
404 g_strlcpy(event_str, "message-request", sizeof(event_str));
407 #ifdef TIZEN_WEARABLE
408 case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
409 __bt_register_popup_event_signal();
410 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
414 case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
415 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
419 BT_ERR("Invalid event type");
425 bundle_add(b, "event-type", event_str);
427 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
428 ret = syspopup_launch("bt-syspopup", b);
431 BT_ERR("Popup launch failed...retry %d", ret);
433 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
434 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
439 BT_INFO("_bt_agent_launch_system_popup");
443 static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
445 GError *error = NULL;
448 reply = g_dbus_proxy_call_sync(device,
449 "GetAll", g_variant_new("(s)", interface),
450 G_DBUS_CALL_FLAGS_NONE, -1,
453 ERR("GetAll dBUS-RPC failed");
455 ERR("D-Bus API failure: errCode[%x], message[%s]",
456 error->code, error->message);
457 g_clear_error(&error);
465 static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
467 uint32_t device_class;
468 const gchar *address;
470 GVariant *reply = NULL;
471 GVariant *reply_temp = NULL;
474 int result = BLUETOOTH_ERROR_NONE;
478 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
480 if (reply_temp == NULL) {
481 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
486 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
488 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
489 g_variant_get(tmp_value, "u", &device_class);
490 G_VARIANT_UNREF(tmp_value);
492 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
493 g_variant_get(tmp_value, "s", &address);
494 G_VARIANT_UNREF(tmp_value);
496 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
500 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
501 g_variant_get(tmp_value, "s", &name);
502 G_VARIANT_UNREF(tmp_value);
506 if (_bt_is_device_creating() == TRUE &&
507 _bt_is_bonding_device_address(address) == TRUE &&
508 __bt_agent_is_auto_response(device_class, address, name)) {
509 BT_DBG("0000 Auto Pair");
510 /* Use Fixed PIN "0000" for basic pairing */
511 _bt_set_autopair_status_in_bonding_info(TRUE);
512 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
514 } else if (__bt_agent_is_hid_keyboard(device_class)) {
515 BT_DBG("HID Keyboard");
516 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
518 if (__bt_agent_generate_passkey(str_passkey,
519 BT_PASSKEY_MAX_LENGTH) != 0) {
520 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
525 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
529 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
533 BT_DBG("LAUNCH SYSPOPUP");
534 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
535 name, str_passkey, NULL,
536 _gap_agent_get_path(agent));
538 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
539 param = g_variant_new("(isss)", result, address, name, str_passkey);
540 _bt_send_event(BT_ADAPTER_EVENT,
541 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
545 BT_DBG("Show Pin entry");
548 BT_DBG("LAUNCH SYSPOPUP");
549 _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
550 NULL, _gap_agent_get_path(agent));
552 BT_DBG("Send BLUETOOTH_EVENT_PIN_REQUEST");
553 param = g_variant_new("(iss)", result, address, name);
554 _bt_send_event(BT_ADAPTER_EVENT,
555 BLUETOOTH_EVENT_PIN_REQUEST, param);
560 g_variant_unref(reply);
561 g_variant_unref(reply_temp);
562 __bt_agent_release_memory();
568 static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
570 const gchar *address;
572 GVariant *reply = NULL;
573 GVariant *reply_temp = NULL;
577 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
579 if (reply_temp == NULL) {
580 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
585 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
587 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
588 g_variant_get(tmp_value, "s", &address);
589 G_VARIANT_UNREF(tmp_value);
591 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
595 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
596 g_variant_get(tmp_value, "s", &name);
597 G_VARIANT_UNREF(tmp_value);
602 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
606 BT_DBG("LAUNCH SYSPOPUP");
607 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
608 _gap_agent_get_path(agent));
610 int result = BLUETOOTH_ERROR_NONE;
613 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_REQUEST");
614 param = g_variant_new("(iss)", result, address, name);
615 _bt_send_event(BT_ADAPTER_EVENT,
616 BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
621 g_variant_unref(reply);
622 g_variant_unref(reply_temp);
623 __bt_agent_release_memory();
629 static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
632 const gchar *address;
635 GVariant *reply = NULL;
636 GVariant *reply_temp = NULL;
637 GVariant *tmp_value = NULL;
641 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
642 if (reply_temp == NULL) {
643 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
648 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
650 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
651 g_variant_get(tmp_value, "s", &address);
652 G_VARIANT_UNREF(tmp_value);
654 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
658 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
659 g_variant_get(tmp_value, "s", &name);
660 G_VARIANT_UNREF(tmp_value);
664 str_passkey = g_strdup_printf("%d", passkey);
667 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, str_passkey,
671 BT_DBG("LAUNCH SYSPOPUP");
672 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
674 _gap_agent_get_path(agent));
676 int result = BLUETOOTH_ERROR_NONE;
679 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
680 param = g_variant_new("(isss)", result, address, name, str_passkey);
681 _bt_send_event(BT_ADAPTER_EVENT,
682 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
689 g_variant_unref(reply);
690 g_variant_unref(reply_temp);
691 __bt_agent_release_memory();
697 static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
700 const gchar *address;
703 GVariant *reply_temp = NULL;
704 GVariant *reply = NULL;
706 BT_DBG("+ passkey[%.6d]", passkey);
708 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
710 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
712 if (reply_temp == NULL) {
713 BT_ERR("Device doesn't exist");
714 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
719 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
721 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
722 g_variant_get(tmp_value, "s", &address);
723 G_VARIANT_UNREF(tmp_value);
725 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
729 tmp_value = g_variant_lookup_value (reply, "Name", G_VARIANT_TYPE_STRING);
730 g_variant_get(tmp_value, "s", &name);
731 G_VARIANT_UNREF(tmp_value);
735 #ifdef TIZEN_WEARABLE
736 uint32_t device_class = 0x00;
737 uint32_t major_class;
739 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
740 g_variant_get(tmp_value, "u", &device_class);
741 G_VARIANT_UNREF(tmp_value);
743 major_class = (device_class & 0x1f00) >> 8;
745 if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
746 BT_DBG("Audio device. Launch passkey pop-up");
747 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
748 str_passkey, NULL, _gap_agent_get_path(agent));
752 if (__is_reset_required(address)) {
753 BT_INFO("Launch system reset pop-up");
754 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
755 NULL, NULL, _gap_agent_get_path(agent));
757 BT_INFO("Launch passkey pop-up");
758 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED, name,
759 str_passkey, NULL, _gap_agent_get_path(agent));
761 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
765 BT_DBG("Confirm reply");
766 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
769 BT_DBG("LAUNCH SYSPOPUP");
770 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
772 _gap_agent_get_path(agent));
774 int result = BLUETOOTH_ERROR_NONE;
777 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST");
778 param = g_variant_new("(isss)", result, address, name, str_passkey);
779 _bt_send_event(BT_ADAPTER_EVENT,
780 BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
786 g_variant_unref(reply);
787 g_variant_unref(reply_temp);
788 __bt_agent_release_memory();
794 static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
796 BT_DBG("On Going Pairing is cancelled by remote\n");
798 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
799 syspopup_destroy_all();
802 __bt_agent_release_memory();
807 static gboolean __a2dp_authorize_request_check(void)
809 /* Check for existing Media device to disconnect */
810 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
813 static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
816 const gchar *address;
820 GVariant *reply = NULL;
821 GVariant *reply_temp = NULL;
823 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
825 tethering_h tethering = NULL;
827 int result = BLUETOOTH_ERROR_NONE;
828 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
833 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
838 /* Check if already Media connection exsist */
839 if (!strcasecmp(uuid, A2DP_UUID)) {
840 gboolean ret = FALSE;
842 ret = __a2dp_authorize_request_check();
845 BT_ERR("Already one A2DP device connected \n");
846 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
851 /* Check completed */
853 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
854 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
855 !strcasecmp(uuid, HFP_HS_UUID) ||
856 !strcasecmp(uuid, HSP_HS_UUID) ||
857 !strcasecmp(uuid, A2DP_UUID) ||
858 !strcasecmp(uuid, HID_UUID) ||
859 !strcasecmp(uuid, SAP_UUID_OLD) ||
860 !strcasecmp(uuid, SAP_UUID_NEW) ||
861 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
862 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
863 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
869 if (!strcasecmp(uuid, NAP_UUID) ||
870 !strcasecmp(uuid, GN_UUID) ||
871 !strcasecmp(uuid, BNEP_UUID)) {
873 BT_DBG("Network connection request: %s", uuid);
874 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
875 if (nap_connected_device_count >=
876 BT_PAN_MAX_CONNECTION) {
877 BT_ERR("Max connection exceeded");
881 ret = tethering_create(&tethering);
883 if (ret != TETHERING_ERROR_NONE) {
884 BT_ERR("Fail to create tethering: %d", ret);
888 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
890 ret = tethering_destroy(tethering);
892 if (ret != TETHERING_ERROR_NONE) {
893 BT_ERR("Fail to create tethering: %d", ret);
896 if (enabled != true) {
897 BT_ERR("BT tethering is not enabled");
902 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
905 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
907 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
914 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
915 if (reply_temp == NULL) {
916 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
921 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
923 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
924 g_variant_get(tmp_value, "s", &address);
925 G_VARIANT_UNREF(tmp_value);
927 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
931 tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
932 g_variant_get(tmp_value, "s", &name);
933 G_VARIANT_UNREF(tmp_value);
937 tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
938 g_variant_get(tmp_value, "b", &trust);
939 G_VARIANT_UNREF(tmp_value);
941 tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
942 g_variant_get(tmp_value, "b", &paired);
943 G_VARIANT_UNREF(tmp_value);
944 if ((paired == FALSE) && (trust == FALSE)) {
945 BT_ERR("No paired & No trusted device");
946 gap_agent_reply_authorize(agent,
947 GAP_AGENT_REJECT, NULL);
951 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
953 if (strcasecmp(uuid, OPP_UUID) == 0 &&
954 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
956 _bt_send_event(BT_OPP_SERVER_EVENT,
957 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
958 g_variant_new("(iss)", result, address, name));
963 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
964 (char *)uuid) == TRUE) {
965 bt_agent_osp_server_t *osp_serv;
966 osp_serv = _gap_agent_get_osp_server(agent,
967 BT_RFCOMM_SERVER, (char *)uuid);
970 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
971 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
972 g_variant_new("(issssn)", result, address, uuid,
973 name, osp_serv->path, osp_serv->fd));
979 if (!strcasecmp(uuid, OPP_UUID))
980 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
981 else if (!strcasecmp(uuid, PBAP_UUID))
982 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
983 else if (!strcasecmp(uuid, MAP_UUID))
984 request_type = BT_AGENT_EVENT_MAP_REQUEST;
987 BT_INFO("Trusted device, so authorize\n");
988 gap_agent_reply_authorize(agent,
989 GAP_AGENT_ACCEPT, NULL);
992 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL);
994 _bt_launch_system_popup(request_type, name, NULL, NULL,
995 _gap_agent_get_path(agent));
1000 g_variant_unref(reply);
1001 g_variant_unref(reply_temp);
1002 __bt_agent_release_memory();
1008 static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
1009 const char *address)
1011 BT_DBG("On Going Authorization is cancelled by remote\n");
1013 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
1015 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
1016 syspopup_destroy_all();
1019 __bt_agent_release_memory();
1024 void _bt_destroy_agent(void *agent)
1029 _gap_agent_reset_dbus((GapAgentPrivate *)agent);
1034 void* _bt_create_agent(const char *path, gboolean adapter)
1036 GAP_AGENT_FUNC_CB func_cb;
1037 GDBusProxy *adapter_proxy;
1038 GapAgentPrivate *agent;
1040 adapter_proxy = _bt_get_adapter_proxy();
1044 func_cb.pincode_func = __pincode_request;
1045 func_cb.display_func = __display_request;
1046 func_cb.passkey_func = __passkey_request;
1047 func_cb.confirm_func = __confirm_request;
1048 func_cb.authorize_func = __authorize_request;
1049 func_cb.pairing_cancel_func = __pairing_cancel_request;
1050 func_cb.authorization_cancel_func = __authorization_cancel_request;
1052 /* Allocate memory*/
1053 agent = g_new0(GapAgentPrivate, 1);
1055 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
1058 if (!_gap_agent_register(agent)) {
1059 _bt_destroy_agent(agent);
1067 gboolean _bt_agent_register_osp_server(const gint type,
1068 const char *uuid, char *path, int fd)
1070 void *agent = _bt_get_adapter_agent();
1074 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
1078 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
1080 void *agent = _bt_get_adapter_agent();
1085 return _gap_agent_unregister_osp_server(agent, type, uuid);
1088 gboolean _bt_agent_reply_authorize(gboolean accept)
1092 void *agent = _bt_get_adapter_agent();
1096 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
1098 return gap_agent_reply_authorize(agent, accept_val, NULL);
1101 gboolean _bt_agent_is_canceled(void)
1103 void *agent = _bt_get_adapter_agent();
1107 return _gap_agent_is_canceled(agent);
1110 void _bt_agent_set_canceled(gboolean value)
1112 void *agent = _bt_get_adapter_agent();
1116 return _gap_agent_set_canceled(agent, value);
1119 int _bt_agent_reply_cancellation(void)
1121 void *agent = _bt_get_adapter_agent();
1124 return BLUETOOTH_ERROR_INTERNAL;
1126 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
1127 BT_ERR("Fail to reply agent");
1128 return BLUETOOTH_ERROR_INTERNAL;
1131 return BLUETOOTH_ERROR_NONE;
1134 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1136 switch ((dev_class & 0x1f00) >> 8) {
1138 switch ((dev_class & 0xc0) >> 6) {
1140 /* input-keyboard" */
1149 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1150 const char *address)
1155 pch = strtok_r(buffer, "= ,", &last);
1160 while ((pch = strtok_r(NULL, ",", &last))) {
1161 if (0 == g_strcmp0(pch, address)) {
1162 BT_DBG("Match found\n");
1169 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1170 const char *partial_name)
1175 pch = strtok_r(buffer, "= ,", &last);
1180 while ((pch = strtok_r(NULL, ",", &last))) {
1181 if (g_str_has_prefix(partial_name, pch)) {
1182 BT_DBG("Match found\n");
1189 static gboolean __bt_agent_is_device_blacklist(const char *address,
1201 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1204 BT_ERR("Unable to open blacklist file");
1208 fseek(fp, 0, SEEK_END);
1211 BT_DBG("size is not a positive number");
1218 buffer = g_malloc0(sizeof(char) * size);
1219 /* Fix : NULL_RETURNS */
1220 if (buffer == NULL) {
1221 BT_ERR("Fail to allocate memory");
1225 result = fread((char *)buffer, 1, size, fp);
1227 if (result != size) {
1228 BT_ERR("Read Error");
1233 BT_DBG("Buffer = %s", buffer);
1235 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1238 if (lines == NULL) {
1239 BT_ERR("No lines in the file");
1243 for (i = 0; lines[i] != NULL; i++) {
1244 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1245 if (__bt_agent_find_device_by_address_exactname(
1248 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1249 if (__bt_agent_find_device_by_address_exactname(
1252 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1253 if (__bt_agent_find_device_by_partial_name(lines[i],
1256 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1257 if (__bt_agent_find_device_by_address_exactname(
1265 BT_DBG("Found the device");
1270 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1271 const gchar *address, const gchar *name)
1273 gboolean is_headset = FALSE;
1274 gboolean is_mouse = FALSE;
1275 char lap_address[BT_LOWER_ADDRESS_LENGTH];
1277 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1279 if (address == NULL)
1282 switch ((dev_class & 0x1f00) >> 8) {
1284 switch ((dev_class & 0xfc) >> 2) {
1294 case 0x0b: /* VCR */
1295 case 0x0c: /* Video Camera */
1296 case 0x0d: /* Camcorder */
1299 /* Other audio device */
1305 switch (dev_class & 0xff) {
1306 case 0x80: /* 0x80: Pointing device(Mouse) */
1310 case 0x40: /* 0x40: input device (BT keyboard) */
1312 /* Get the LAP(Lower Address part) */
1313 g_strlcpy(lap_address, address, sizeof(lap_address));
1315 /* Need to Auto pair the blacklisted Keyboard */
1316 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1317 BT_DBG("Device is not black listed\n");
1320 BT_ERR("Device is black listed\n");
1326 if ((!is_headset) && (!is_mouse))
1329 /* Get the LAP(Lower Address part) */
1330 g_strlcpy(lap_address, address, sizeof(lap_address));
1332 BT_DBG("Device address = %s\n", address);
1333 BT_DBG("Address 3 byte = %s\n", lap_address);
1335 if (__bt_agent_is_device_blacklist(lap_address, name)) {
1336 BT_ERR("Device is black listed\n");
1343 static int __bt_agent_generate_passkey(char *passkey, int size)
1348 unsigned int value = 0;
1350 if (passkey == NULL)
1356 random_fd = open("/dev/urandom", O_RDONLY);
1361 for (i = 0; i < size; i++) {
1362 len = read(random_fd, &value, sizeof(value));
1364 passkey[i] = '0' + (value % 10);
1369 BT_DBG("passkey: %s", passkey);