2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <stacktrim.h>
24 #if defined(LIBNOTIFY_SUPPORT)
26 #elif defined(LIBNOTIFICATION_SUPPORT)
27 #include "bt-service-agent-notification.h"
29 #include <syspopup_caller.h>
33 #include <bundle_internal.h>
35 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
36 #include <tethering.h>
39 #include "bt-internal-types.h"
40 #include "bt-service-common.h"
41 #include "bt-service-agent.h"
42 #include "bt-service-gap-agent.h"
43 #include "bt-service-adapter.h"
44 #include "bt-service-event.h"
45 #include "bt-service-rfcomm-server.h"
46 #include "bt-service-device.h"
47 #include "bt-service-audio.h"
49 #ifdef TIZEN_DPM_ENABLE
50 #include "bt-service-dpm.h"
53 #define BT_APP_AUTHENTICATION_TIMEOUT 35
54 #define BT_APP_AUTHORIZATION_TIMEOUT 15
56 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
57 #define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
58 #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
59 #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
60 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
61 #define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
62 #define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
63 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
64 #define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
65 #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
66 #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
67 #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
68 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
69 #define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
70 #define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
72 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
74 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
76 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
77 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
79 #define BT_PIN_MAX_LENGTH 16
80 #define BT_PASSKEY_MAX_LENGTH 4
82 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
83 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
84 #define BT_PAN_MAX_CONNECTION 4
85 extern guint nap_connected_device_count;
87 #define G_VARIANT_UNREF(variant) \
88 g_variant_unref(variant); \
91 static gboolean syspopup_mode = TRUE;
93 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
95 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
96 static int __bt_agent_generate_passkey(char *passkey, int size);
98 static void __bt_agent_release_memory(void)
100 /* Release Malloc Memory*/
103 /* Release Stack Memory*/
107 static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
110 static int retry_count;
111 bundle *b = (bundle *)user_data;
112 retv_if(user_data == NULL, FALSE);
115 #if defined(LIBNOTIFY_SUPPORT)
116 ret = notify_launch(b);
117 #elif defined(LIBNOTIFICATION_SUPPORT)
118 ret = notification_launch(b);
120 ret = syspopup_launch("bt-syspopup", b);
123 BT_ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..",
125 if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) {
126 BT_ERR("Sorry!! Max retry %d reached", retry_count);
132 BT_DBG("Hurray!! Finally Popup launched");
137 return (ret < 0) ? TRUE : FALSE;
140 #ifdef TIZEN_WEARABLE
141 static void __bt_popup_event_filter(GDBusConnection *connection,
142 const gchar *sender_name,
143 const gchar *object_path,
144 const gchar *interface_name,
145 const gchar *signal_name,
146 GVariant *parameters,
149 BT_DBG("Sender Name[%s] Object Path[%s] Interface[%s] Signal[%s]",
150 sender_name, object_path, interface_name, signal_name);
152 if (g_strcmp0(interface_name, "User.Bluetooth.syspopup") == 0 &&
153 g_strcmp0(signal_name, "ResetResponse") == 0) {
156 g_variant_get(parameters, "(i)", &response);
157 BT_DBG("response = %d", response);
161 int __bt_service_subscribe_popup(GDBusConnection *conn,
164 static guint subs_interface_added_id = 0;
167 return BLUETOOTH_ERROR_INVALID_PARAM;
170 if (subs_interface_added_id == 0) {
171 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
172 NULL, "User.Bluetooth.syspopup", "ResetResponse", NULL, NULL, 0,
173 __bt_popup_event_filter, NULL, NULL);
176 if (subs_interface_added_id > 0) {
177 g_dbus_connection_signal_unsubscribe(conn,
178 subs_interface_added_id);
179 subs_interface_added_id = 0;
182 return BLUETOOTH_ERROR_NONE;
185 static void __bt_register_popup_event_signal(void)
187 GDBusConnection *conn;
191 conn = _bt_get_system_gconn();
195 __bt_service_subscribe_popup(conn, TRUE);
201 static gboolean __is_reset_required(const gchar *address)
204 uint32_t no_of_device;
206 bluetooth_device_info_t info;
207 gboolean is_required = FALSE;
209 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
210 if (device_list == NULL) {
211 BT_ERR("g_array_new is failed");
215 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
216 BT_ERR("_bt_get_bonded_devices is failed");
217 g_array_free(device_list, TRUE);
221 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
222 for (i = 0; i < no_of_device; i++) {
223 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
225 info = g_array_index(device_list, bluetooth_device_info_t, i);
227 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
228 if (g_strcmp0(address, addr) == 0) {
229 BT_DBG("This device is already in paired list");
234 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
239 g_array_free(device_list, TRUE);
245 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
246 const char *device_name,
248 const char *filename,
249 const char *agent_path)
253 char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
257 BT_ERR("Launching system popup failed");
261 bundle_add(b, "device-name", device_name);
262 bundle_add(b, "passkey", passkey);
263 bundle_add(b, "file", filename);
264 bundle_add(b, "agent-path", agent_path);
266 switch (event_type) {
267 case BT_AGENT_EVENT_PIN_REQUEST:
268 g_strlcpy(event_str, "pin-request", sizeof(event_str));
271 case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
272 g_strlcpy(event_str, "passkey-confirm-request",
276 case BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED:
277 g_strlcpy(event_str, "passkey-auto-accepted",
281 case BT_AGENT_EVENT_PASSKEY_REQUEST:
282 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
285 case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
286 g_strlcpy(event_str, "passkey-display-request",
290 case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
291 g_strlcpy(event_str, "authorize-request",
295 case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
296 g_strlcpy(event_str, "confirm-mode-request",
300 case BT_AGENT_EVENT_FILE_RECEIVED:
301 g_strlcpy(event_str, "file-received", sizeof(event_str));
304 case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
305 g_strlcpy(event_str, "keyboard-passkey-request",
309 case BT_AGENT_EVENT_TERMINATE:
310 g_strlcpy(event_str, "terminate", sizeof(event_str));
313 case BT_AGENT_EVENT_EXCHANGE_REQUEST:
314 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
317 case BT_AGENT_EVENT_PBAP_REQUEST:
318 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
321 case BT_AGENT_EVENT_MAP_REQUEST:
322 g_strlcpy(event_str, "message-request", sizeof(event_str));
325 #ifdef TIZEN_WEARABLE
326 case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
327 __bt_register_popup_event_signal();
328 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
332 case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
333 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
337 BT_ERR("Invalid event type");
343 bundle_add(b, "event-type", event_str);
345 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
346 ret = syspopup_launch("bt-syspopup", b);
349 BT_ERR("Popup launch failed...retry %d", ret);
351 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
352 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
357 BT_INFO("_bt_agent_launch_system_popup");
361 static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
363 GError *error = NULL;
366 reply = g_dbus_proxy_call_sync(device,
367 "GetAll", g_variant_new("(s)", interface),
368 G_DBUS_CALL_FLAGS_NONE, -1,
371 ERR("GetAll dBUS-RPC failed");
373 ERR("D-Bus API failure: errCode[%x], message[%s]",
374 error->code, error->message);
375 g_clear_error(&error);
383 static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
385 uint32_t device_class;
386 const gchar *address;
388 GVariant *reply = NULL;
389 GVariant *reply_temp = NULL;
392 int result = BLUETOOTH_ERROR_NONE;
396 #ifdef TIZEN_DPM_ENABLE
397 if (_bt_dpm_get_bluetooth_pairing_state() == DPM_RESTRICTED) {
398 BT_ERR("Not allow to pair the device");
399 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
400 __bt_agent_release_memory();
405 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
407 if (reply_temp == NULL) {
408 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
413 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
415 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
416 g_variant_get(tmp_value, "u", &device_class);
417 G_VARIANT_UNREF(tmp_value);
419 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
420 g_variant_get(tmp_value, "s", &address);
421 G_VARIANT_UNREF(tmp_value);
423 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
427 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
428 g_variant_get(tmp_value, "s", &name);
429 G_VARIANT_UNREF(tmp_value);
433 if (_bt_is_device_creating() == TRUE &&
434 _bt_is_bonding_device_address(address) == TRUE &&
435 __bt_agent_is_auto_response(device_class, address, name)) {
436 BT_DBG("0000 Auto Pair");
437 /* Use Fixed PIN "0000" for basic pairing */
438 _bt_set_autopair_status_in_bonding_info(TRUE);
439 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
441 } else if (__bt_agent_is_hid_keyboard(device_class)) {
442 BT_DBG("HID Keyboard");
443 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
445 if (__bt_agent_generate_passkey(str_passkey,
446 BT_PASSKEY_MAX_LENGTH) != 0) {
447 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
452 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
456 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
460 BT_DBG("LAUNCH SYSPOPUP");
461 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
462 name, str_passkey, NULL,
463 _gap_agent_get_path(agent));
465 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
466 param = g_variant_new("(isss)", result, address, name, str_passkey);
467 _bt_send_event(BT_ADAPTER_EVENT,
468 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
472 BT_DBG("Show Pin entry");
475 BT_DBG("LAUNCH SYSPOPUP");
476 _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
477 NULL, _gap_agent_get_path(agent));
479 BT_DBG("Send BLUETOOTH_EVENT_PIN_REQUEST");
480 param = g_variant_new("(iss)", result, address, name);
481 _bt_send_event(BT_ADAPTER_EVENT,
482 BLUETOOTH_EVENT_PIN_REQUEST, param);
487 g_variant_unref(reply);
488 g_variant_unref(reply_temp);
489 __bt_agent_release_memory();
495 static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
497 const gchar *address;
499 GVariant *reply = NULL;
500 GVariant *reply_temp = NULL;
504 #ifdef TIZEN_DPM_ENABLE
505 if (_bt_dpm_get_bluetooth_pairing_state() == DPM_RESTRICTED) {
506 BT_ERR("Not allow to pair the device");
507 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
508 __bt_agent_release_memory();
513 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
515 if (reply_temp == NULL) {
516 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
521 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
523 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
524 g_variant_get(tmp_value, "s", &address);
525 G_VARIANT_UNREF(tmp_value);
527 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
531 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
532 g_variant_get(tmp_value, "s", &name);
533 G_VARIANT_UNREF(tmp_value);
538 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
542 BT_DBG("LAUNCH SYSPOPUP");
543 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
544 _gap_agent_get_path(agent));
546 int result = BLUETOOTH_ERROR_NONE;
549 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_REQUEST");
550 param = g_variant_new("(iss)", result, address, name);
551 _bt_send_event(BT_ADAPTER_EVENT,
552 BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
557 g_variant_unref(reply);
558 g_variant_unref(reply_temp);
559 __bt_agent_release_memory();
565 static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
568 const gchar *address;
571 GVariant *reply = NULL;
572 GVariant *reply_temp = NULL;
573 GVariant *tmp_value = NULL;
577 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
578 if (reply_temp == NULL) {
579 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
584 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
586 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
587 g_variant_get(tmp_value, "s", &address);
588 G_VARIANT_UNREF(tmp_value);
590 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
594 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
595 g_variant_get(tmp_value, "s", &name);
596 G_VARIANT_UNREF(tmp_value);
600 str_passkey = g_strdup_printf("%d", passkey);
603 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, str_passkey,
607 BT_DBG("LAUNCH SYSPOPUP");
608 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
610 _gap_agent_get_path(agent));
612 int result = BLUETOOTH_ERROR_NONE;
615 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
616 param = g_variant_new("(isss)", result, address, name, str_passkey);
617 _bt_send_event(BT_ADAPTER_EVENT,
618 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
625 g_variant_unref(reply);
626 g_variant_unref(reply_temp);
627 __bt_agent_release_memory();
633 static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
636 const gchar *address;
639 GVariant *reply_temp = NULL;
640 GVariant *reply = NULL;
642 BT_DBG("+ passkey[%.6d]", passkey);
644 #ifdef TIZEN_DPM_ENABLE
645 if (_bt_dpm_get_bluetooth_pairing_state() == DPM_RESTRICTED) {
646 BT_ERR("Not allow to pair the device");
647 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
648 __bt_agent_release_memory();
653 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
655 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
657 if (reply_temp == NULL) {
658 BT_ERR("Device doesn't exist");
659 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
664 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
666 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
667 g_variant_get(tmp_value, "s", &address);
668 G_VARIANT_UNREF(tmp_value);
670 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
674 tmp_value = g_variant_lookup_value (reply, "Name", G_VARIANT_TYPE_STRING);
675 g_variant_get(tmp_value, "s", &name);
676 G_VARIANT_UNREF(tmp_value);
680 #ifdef TIZEN_WEARABLE
681 uint32_t device_class = 0x00;
682 uint32_t major_class;
684 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
685 g_variant_get(tmp_value, "u", &device_class);
686 G_VARIANT_UNREF(tmp_value);
688 major_class = (device_class & 0x1f00) >> 8;
690 if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
691 BT_DBG("Audio device. Launch passkey pop-up");
692 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
693 str_passkey, NULL, _gap_agent_get_path(agent));
697 if (__is_reset_required(address)) {
698 BT_INFO("Launch system reset pop-up");
699 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
700 NULL, NULL, _gap_agent_get_path(agent));
702 BT_INFO("Launch passkey pop-up");
703 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED, name,
704 str_passkey, NULL, _gap_agent_get_path(agent));
706 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
710 BT_DBG("Confirm reply");
711 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
714 BT_DBG("LAUNCH SYSPOPUP");
715 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
717 _gap_agent_get_path(agent));
719 int result = BLUETOOTH_ERROR_NONE;
722 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST");
723 param = g_variant_new("(isss)", result, address, name, str_passkey);
724 _bt_send_event(BT_ADAPTER_EVENT,
725 BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
731 g_variant_unref(reply);
732 g_variant_unref(reply_temp);
733 __bt_agent_release_memory();
739 static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
741 BT_DBG("On Going Pairing is cancelled by remote\n");
743 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
744 syspopup_destroy_all();
747 __bt_agent_release_memory();
752 static gboolean __a2dp_authorize_request_check(void)
754 /* Check for existing Media device to disconnect */
755 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
758 static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
761 const gchar *address;
765 GVariant *reply = NULL;
766 GVariant *reply_temp = NULL;
768 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
770 tethering_h tethering = NULL;
772 int result = BLUETOOTH_ERROR_NONE;
774 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
780 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
785 /* Check if already Media connection exsist */
786 if (!strcasecmp(uuid, A2DP_UUID)) {
787 gboolean ret = FALSE;
789 ret = __a2dp_authorize_request_check();
792 BT_ERR("Already one A2DP device connected \n");
793 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
798 /* Check completed */
800 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
801 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
802 !strcasecmp(uuid, HFP_HS_UUID) ||
803 !strcasecmp(uuid, HSP_HS_UUID) ||
804 !strcasecmp(uuid, A2DP_UUID) ||
805 !strcasecmp(uuid, HID_UUID) ||
806 !strcasecmp(uuid, SAP_UUID_OLD) ||
807 !strcasecmp(uuid, SAP_UUID_NEW) ||
808 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
809 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
810 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
816 if (!strcasecmp(uuid, NAP_UUID) ||
817 !strcasecmp(uuid, GN_UUID) ||
818 !strcasecmp(uuid, BNEP_UUID)) {
820 BT_DBG("Network connection request: %s", uuid);
821 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
822 if (nap_connected_device_count >=
823 BT_PAN_MAX_CONNECTION) {
824 BT_ERR("Max connection exceeded");
828 ret = tethering_create(&tethering);
830 if (ret != TETHERING_ERROR_NONE) {
831 BT_ERR("Fail to create tethering: %d", ret);
835 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
837 ret = tethering_destroy(tethering);
839 if (ret != TETHERING_ERROR_NONE) {
840 BT_ERR("Fail to create tethering: %d", ret);
843 if (enabled != true) {
844 BT_ERR("BT tethering is not enabled");
849 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
852 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
854 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
861 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
862 if (reply_temp == NULL) {
863 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
868 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
870 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
871 g_variant_get(tmp_value, "s", &address);
872 G_VARIANT_UNREF(tmp_value);
874 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
878 tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
879 g_variant_get(tmp_value, "s", &name);
880 G_VARIANT_UNREF(tmp_value);
884 tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
885 g_variant_get(tmp_value, "b", &trust);
886 G_VARIANT_UNREF(tmp_value);
888 tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
889 g_variant_get(tmp_value, "b", &paired);
890 G_VARIANT_UNREF(tmp_value);
891 if ((paired == FALSE) && (trust == FALSE)) {
892 BT_ERR("No paired & No trusted device");
893 gap_agent_reply_authorize(agent,
894 GAP_AGENT_REJECT, NULL);
898 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
900 if (strcasecmp(uuid, OPP_UUID) == 0 &&
901 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
903 _bt_send_event(BT_OPP_SERVER_EVENT,
904 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
905 g_variant_new("(iss)", result, address, name));
910 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
911 (char *)uuid) == TRUE) {
912 bt_agent_osp_server_t *osp_serv;
913 osp_serv = _gap_agent_get_osp_server(agent,
914 BT_RFCOMM_SERVER, (char *)uuid);
917 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
918 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
919 g_variant_new("(issssn)", result, address, uuid,
920 name, osp_serv->path, osp_serv->fd));
927 BT_INFO("Trusted device, so authorize\n");
928 gap_agent_reply_authorize(agent,
929 GAP_AGENT_ACCEPT, NULL);
932 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL);
934 if (!strcasecmp(uuid, OPP_UUID))
935 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
936 else if (!strcasecmp(uuid, PBAP_UUID))
937 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
938 else if (!strcasecmp(uuid, MAP_UUID))
939 request_type = BT_AGENT_EVENT_MAP_REQUEST;
941 _bt_launch_system_popup(request_type, name, NULL, NULL,
942 _gap_agent_get_path(agent));
947 g_variant_unref(reply);
948 g_variant_unref(reply_temp);
949 __bt_agent_release_memory();
955 static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
958 BT_DBG("On Going Authorization is cancelled by remote\n");
960 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
962 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
963 syspopup_destroy_all();
966 __bt_agent_release_memory();
971 void _bt_destroy_agent(void *agent)
976 _gap_agent_reset_dbus((GapAgentPrivate *)agent);
981 void* _bt_create_agent(const char *path, gboolean adapter)
983 GAP_AGENT_FUNC_CB func_cb;
984 GDBusProxy *adapter_proxy;
985 GapAgentPrivate *agent;
987 adapter_proxy = _bt_get_adapter_proxy();
991 func_cb.pincode_func = __pincode_request;
992 func_cb.display_func = __display_request;
993 func_cb.passkey_func = __passkey_request;
994 func_cb.confirm_func = __confirm_request;
995 func_cb.authorize_func = __authorize_request;
996 func_cb.pairing_cancel_func = __pairing_cancel_request;
997 func_cb.authorization_cancel_func = __authorization_cancel_request;
1000 agent = g_new0(GapAgentPrivate, 1);
1002 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
1005 if (!_gap_agent_register(agent)) {
1006 _bt_destroy_agent(agent);
1014 gboolean _bt_agent_register_osp_server(const gint type,
1015 const char *uuid, char *path, int fd)
1017 void *agent = _bt_get_adapter_agent();
1021 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
1025 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
1027 void *agent = _bt_get_adapter_agent();
1032 return _gap_agent_unregister_osp_server(agent, type, uuid);
1035 gboolean _bt_agent_reply_authorize(gboolean accept)
1039 void *agent = _bt_get_adapter_agent();
1043 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
1045 return gap_agent_reply_authorize(agent, accept_val, NULL);
1048 gboolean _bt_agent_is_canceled(void)
1050 void *agent = _bt_get_adapter_agent();
1054 return _gap_agent_is_canceled(agent);
1057 void _bt_agent_set_canceled(gboolean value)
1059 void *agent = _bt_get_adapter_agent();
1063 return _gap_agent_set_canceled(agent, value);
1066 int _bt_agent_reply_cancellation(void)
1068 void *agent = _bt_get_adapter_agent();
1071 return BLUETOOTH_ERROR_INTERNAL;
1073 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
1074 BT_ERR("Fail to reply agent");
1075 return BLUETOOTH_ERROR_INTERNAL;
1078 return BLUETOOTH_ERROR_NONE;
1081 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1083 switch ((dev_class & 0x1f00) >> 8) {
1085 switch ((dev_class & 0xc0) >> 6) {
1087 /* input-keyboard" */
1096 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1097 const char *address)
1102 pch = strtok_r(buffer, "= ,", &last);
1107 while ((pch = strtok_r(NULL, ",", &last))) {
1108 if (0 == g_strcmp0(pch, address)) {
1109 BT_DBG("Match found\n");
1116 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1117 const char *partial_name)
1122 pch = strtok_r(buffer, "= ,", &last);
1127 while ((pch = strtok_r(NULL, ",", &last))) {
1128 if (g_str_has_prefix(partial_name, pch)) {
1129 BT_DBG("Match found\n");
1136 static gboolean __bt_agent_is_device_blacklist(const char *address,
1148 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1151 BT_ERR("Unable to open blacklist file");
1155 fseek(fp, 0, SEEK_END);
1158 BT_DBG("size is not a positive number");
1165 buffer = g_malloc0(sizeof(char) * size);
1166 /* Fix : NULL_RETURNS */
1167 if (buffer == NULL) {
1168 BT_ERR("Fail to allocate memory");
1172 result = fread((char *)buffer, 1, size, fp);
1174 if (result != size) {
1175 BT_ERR("Read Error");
1180 BT_DBG("Buffer = %s", buffer);
1182 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1185 if (lines == NULL) {
1186 BT_ERR("No lines in the file");
1190 for (i = 0; lines[i] != NULL; i++) {
1191 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1192 if (__bt_agent_find_device_by_address_exactname(
1195 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1196 if (__bt_agent_find_device_by_address_exactname(
1199 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1200 if (__bt_agent_find_device_by_partial_name(lines[i],
1203 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1204 if (__bt_agent_find_device_by_address_exactname(
1212 BT_DBG("Found the device");
1217 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1218 const gchar *address, const gchar *name)
1220 gboolean is_headset = FALSE;
1221 gboolean is_mouse = FALSE;
1222 char lap_address[BT_LOWER_ADDRESS_LENGTH];
1224 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1226 if (address == NULL)
1229 switch ((dev_class & 0x1f00) >> 8) {
1231 switch ((dev_class & 0xfc) >> 2) {
1241 case 0x0b: /* VCR */
1242 case 0x0c: /* Video Camera */
1243 case 0x0d: /* Camcorder */
1246 /* Other audio device */
1252 switch (dev_class & 0xff) {
1253 case 0x80: /* 0x80: Pointing device(Mouse) */
1257 case 0x40: /* 0x40: input device (BT keyboard) */
1259 /* Get the LAP(Lower Address part) */
1260 g_strlcpy(lap_address, address, sizeof(lap_address));
1262 /* Need to Auto pair the blacklisted Keyboard */
1263 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1264 BT_DBG("Device is not black listed\n");
1267 BT_ERR("Device is black listed\n");
1273 if ((!is_headset) && (!is_mouse))
1276 /* Get the LAP(Lower Address part) */
1277 g_strlcpy(lap_address, address, sizeof(lap_address));
1279 BT_DBG("Device address = %s\n", address);
1280 BT_DBG("Address 3 byte = %s\n", lap_address);
1282 if (__bt_agent_is_device_blacklist(lap_address, name)) {
1283 BT_ERR("Device is black listed\n");
1290 static int __bt_agent_generate_passkey(char *passkey, int size)
1295 unsigned int value = 0;
1297 if (passkey == NULL)
1303 random_fd = open("/dev/urandom", O_RDONLY);
1308 for (i = 0; i < size; i++) {
1309 len = read(random_fd, &value, sizeof(value));
1311 passkey[i] = '0' + (value % 10);
1316 BT_DBG("passkey: %s", passkey);