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 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_unbond_cb(GDBusProxy *proxy,
142 GAsyncResult *res, gpointer user_data)
147 value = g_dbus_proxy_call_finish(proxy, res, &err);
149 BT_ERR("Error: Unbond Failed");
151 BT_ERR("errCode[%x], message[%s]\n", err->code, err->message);
156 g_variant_unref(value);
157 BT_INFO("Unbonding is done");
161 static gboolean __bt_unpair_device(void)
167 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
168 if (device_list == NULL) {
169 BT_ERR("g_array_new is failed");
173 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
174 BT_ERR("_bt_get_bonded_devices is failed");
175 g_array_free(device_list, TRUE);
179 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
180 for (i = 0; i < no_of_device; i++) {
181 GDBusProxy *adapter_proxy;
182 bluetooth_device_info_t info;
183 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
184 char *device_path = NULL;
186 info = g_array_index(device_list, bluetooth_device_info_t, i);
187 if (info.device_class.major_class ==
188 BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO)
191 adapter_proxy = _bt_get_adapter_proxy();
192 if (!adapter_proxy) {
193 BT_ERR("adapter_proxy is NULL");
194 g_array_free(device_list, TRUE);
198 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
199 device_path = _bt_get_device_object_path(addr);
200 if (device_path == NULL) {
201 BT_ERR("device_path is NULL");
202 g_array_free(device_list, TRUE);
206 g_dbus_proxy_call(adapter_proxy,
207 "UnpairDevice", g_variant_new("o", device_path),
208 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
209 (GAsyncReadyCallback)__bt_unbond_cb, NULL);
211 BT_INFO("unbonding %s is requested", addr);
213 g_array_free(device_list, TRUE);
217 g_array_free(device_list, TRUE);
221 static void __bt_popup_event_filter(GDBusConnection *connection,
222 const gchar *sender_name,
223 const gchar *object_path,
224 const gchar *interface_name,
225 const gchar *signal_name,
226 GVariant *parameters,
229 BT_DBG("Sender Name[%s] Object Path[%s] Interface[%s] Signal[%s]",
230 sender_name, object_path, interface_name, signal_name);
232 if (g_strcmp0(interface_name, "User.Bluetooth.syspopup") == 0 &&
233 g_strcmp0(signal_name, "ResetResponse") == 0) {
236 g_variant_get(parameters, "(i)", &response);
237 BT_DBG("response = %d", response);
241 int __bt_service_subscribe_popup(GDBusConnection *conn,
244 static guint subs_interface_added_id = 0;
247 return BLUETOOTH_ERROR_INVALID_PARAM;
250 if (subs_interface_added_id == 0) {
251 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
252 NULL, "User.Bluetooth.syspopup", "ResetResponse", NULL, NULL, 0,
253 __bt_popup_event_filter, NULL, NULL);
256 if (subs_interface_added_id > 0) {
257 g_dbus_connection_signal_unsubscribe(conn,
258 subs_interface_added_id);
259 subs_interface_added_id = 0;
262 return BLUETOOTH_ERROR_NONE;
265 static void __bt_register_popup_event_signal(void)
267 GDBusConnection *conn;
271 conn = _bt_get_system_gconn();
275 __bt_service_subscribe_popup(conn, TRUE);
281 static gboolean __is_reset_required(const gchar *address)
284 uint32_t no_of_device;
286 bluetooth_device_info_t info;
287 gboolean is_required = FALSE;
289 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
290 if (device_list == NULL) {
291 BT_ERR("g_array_new is failed");
295 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
296 BT_ERR("_bt_get_bonded_devices is failed");
297 g_array_free(device_list, TRUE);
301 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
302 for (i = 0; i < no_of_device; i++) {
303 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
305 info = g_array_index(device_list, bluetooth_device_info_t, i);
307 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
308 if (g_strcmp0(address, addr) == 0) {
309 BT_DBG("This device is already in paired list");
314 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
319 g_array_free(device_list, TRUE);
325 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
326 const char *device_name,
328 const char *filename,
329 const char *agent_path)
333 char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
337 BT_ERR("Launching system popup failed");
341 bundle_add(b, "device-name", device_name);
342 bundle_add(b, "passkey", passkey);
343 bundle_add(b, "file", filename);
344 bundle_add(b, "agent-path", agent_path);
346 switch (event_type) {
347 case BT_AGENT_EVENT_PIN_REQUEST:
348 g_strlcpy(event_str, "pin-request", sizeof(event_str));
351 case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
352 g_strlcpy(event_str, "passkey-confirm-request",
356 case BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED:
357 g_strlcpy(event_str, "passkey-auto-accepted",
361 case BT_AGENT_EVENT_PASSKEY_REQUEST:
362 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
365 case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
366 g_strlcpy(event_str, "passkey-display-request",
370 case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
371 g_strlcpy(event_str, "authorize-request",
375 case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
376 g_strlcpy(event_str, "confirm-mode-request",
380 case BT_AGENT_EVENT_FILE_RECEIVED:
381 g_strlcpy(event_str, "file-received", sizeof(event_str));
384 case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
385 g_strlcpy(event_str, "keyboard-passkey-request",
389 case BT_AGENT_EVENT_TERMINATE:
390 g_strlcpy(event_str, "terminate", sizeof(event_str));
393 case BT_AGENT_EVENT_EXCHANGE_REQUEST:
394 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
397 case BT_AGENT_EVENT_PBAP_REQUEST:
398 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
401 case BT_AGENT_EVENT_MAP_REQUEST:
402 g_strlcpy(event_str, "message-request", sizeof(event_str));
405 #ifdef TIZEN_WEARABLE
406 case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
407 __bt_register_popup_event_signal();
408 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
412 case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
413 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
417 BT_ERR("Invalid event type");
423 bundle_add(b, "event-type", event_str);
425 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
426 ret = syspopup_launch("bt-syspopup", b);
429 BT_ERR("Popup launch failed...retry %d", ret);
431 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
432 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
437 BT_INFO("_bt_agent_launch_system_popup");
441 static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
443 GError *error = NULL;
446 reply = g_dbus_proxy_call_sync(device,
447 "GetAll", g_variant_new("(s)", interface),
448 G_DBUS_CALL_FLAGS_NONE, -1,
451 ERR("GetAll dBUS-RPC failed");
453 ERR("D-Bus API failure: errCode[%x], message[%s]",
454 error->code, error->message);
455 g_clear_error(&error);
463 static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
465 uint32_t device_class;
466 const gchar *address;
468 GVariant *reply = NULL;
469 GVariant *reply_temp = NULL;
474 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
476 if (reply_temp == NULL) {
477 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
482 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
484 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
485 g_variant_get(tmp_value, "u", &device_class);
486 G_VARIANT_UNREF(tmp_value);
488 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
489 g_variant_get(tmp_value, "s", &address);
490 G_VARIANT_UNREF(tmp_value);
492 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
496 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
497 g_variant_get(tmp_value, "s", &name);
498 G_VARIANT_UNREF(tmp_value);
502 if (_bt_is_device_creating() == TRUE &&
503 _bt_is_bonding_device_address(address) == TRUE &&
504 __bt_agent_is_auto_response(device_class, address, name)) {
505 BT_DBG("0000 Auto Pair");
506 /* Use Fixed PIN "0000" for basic pairing */
507 _bt_set_autopair_status_in_bonding_info(TRUE);
508 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
510 } else if (__bt_agent_is_hid_keyboard(device_class)) {
511 BT_DBG("HID Keyboard");
512 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
514 if (__bt_agent_generate_passkey(str_passkey,
515 BT_PASSKEY_MAX_LENGTH) != 0) {
516 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
521 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
524 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
525 name, str_passkey, NULL,
526 _gap_agent_get_path(agent));
528 BT_DBG("Show Pin entry");
529 _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
530 NULL, _gap_agent_get_path(agent));
534 g_variant_unref(reply);
535 g_variant_unref(reply_temp);
536 __bt_agent_release_memory();
542 static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
544 const gchar *address;
546 GVariant *reply = NULL;
547 GVariant *reply_temp = NULL;
551 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
553 if (reply_temp == NULL) {
554 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
559 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
561 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
562 g_variant_get(tmp_value, "s", &address);
563 G_VARIANT_UNREF(tmp_value);
565 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
569 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
570 g_variant_get(tmp_value, "s", &name);
571 G_VARIANT_UNREF(tmp_value);
575 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
576 _gap_agent_get_path(agent));
579 g_variant_unref(reply);
580 g_variant_unref(reply_temp);
581 __bt_agent_release_memory();
587 static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
590 const gchar *address;
593 GVariant *reply = NULL;
594 GVariant *reply_temp = NULL;
595 GVariant *tmp_value = NULL;
599 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
600 if (reply_temp == NULL) {
601 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
606 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
608 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
609 g_variant_get(tmp_value, "s", &address);
610 G_VARIANT_UNREF(tmp_value);
612 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
616 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
617 g_variant_get(tmp_value, "s", &name);
618 G_VARIANT_UNREF(tmp_value);
622 str_passkey = g_strdup_printf("%d", passkey);
624 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
626 _gap_agent_get_path(agent));
631 g_variant_unref(reply);
632 g_variant_unref(reply_temp);
633 __bt_agent_release_memory();
639 static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
642 const gchar *address;
645 GVariant *reply_temp = NULL;
646 GVariant *reply = NULL;
648 BT_DBG("+ passkey[%.6d]", passkey);
650 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
652 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
654 if (reply_temp == NULL) {
655 BT_ERR("Device doesn't exist");
656 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
661 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
663 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
664 g_variant_get(tmp_value, "s", &address);
665 G_VARIANT_UNREF(tmp_value);
667 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
671 tmp_value = g_variant_lookup_value (reply, "Name", G_VARIANT_TYPE_STRING);
672 g_variant_get(tmp_value, "s", &name);
673 G_VARIANT_UNREF(tmp_value);
677 #ifdef TIZEN_WEARABLE
678 uint32_t device_class = 0x00;
679 uint32_t major_class;
681 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
682 g_variant_get(tmp_value, "u", &device_class);
683 G_VARIANT_UNREF(tmp_value);
685 major_class = (device_class & 0x1f00) >> 8;
687 if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
688 BT_DBG("Audio device. Launch passkey pop-up");
689 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
690 str_passkey, NULL, _gap_agent_get_path(agent));
694 if (__is_reset_required(address)) {
695 BT_INFO("Launch system reset pop-up");
696 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
697 NULL, NULL, _gap_agent_get_path(agent));
699 BT_INFO("Launch passkey pop-up");
700 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED, name,
701 str_passkey, NULL, _gap_agent_get_path(agent));
703 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
706 BT_DBG("LAUNCH SYSPOPUP");
707 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
709 _gap_agent_get_path(agent));
713 g_variant_unref(reply);
714 g_variant_unref(reply_temp);
715 __bt_agent_release_memory();
721 static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
723 BT_DBG("On Going Pairing is cancelled by remote\n");
724 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
725 syspopup_destroy_all();
728 __bt_agent_release_memory();
733 static gboolean __a2dp_authorize_request_check(void)
735 /* Check for existing Media device to disconnect */
736 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
739 static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
742 const gchar *address;
746 GVariant *reply = NULL;
747 GVariant *reply_temp = NULL;
749 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
751 tethering_h tethering = NULL;
753 int result = BLUETOOTH_ERROR_NONE;
754 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
758 /* Check if already Media connection exsist */
759 if (!strcasecmp(uuid, A2DP_UUID)) {
760 gboolean ret = FALSE;
762 ret = __a2dp_authorize_request_check();
765 BT_ERR("Already one A2DP device connected \n");
766 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
771 /* Check completed */
773 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
774 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
775 !strcasecmp(uuid, HFP_HS_UUID) ||
776 !strcasecmp(uuid, HSP_HS_UUID) ||
777 !strcasecmp(uuid, A2DP_UUID) ||
778 !strcasecmp(uuid, HID_UUID) ||
779 !strcasecmp(uuid, SAP_UUID_OLD) ||
780 !strcasecmp(uuid, SAP_UUID_NEW) ||
781 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
782 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
783 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
789 if (!strcasecmp(uuid, NAP_UUID) ||
790 !strcasecmp(uuid, GN_UUID) ||
791 !strcasecmp(uuid, BNEP_UUID)) {
793 BT_DBG("Network connection request: %s", uuid);
794 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
795 if (nap_connected_device_count >=
796 BT_PAN_MAX_CONNECTION) {
797 BT_ERR("Max connection exceeded");
801 ret = tethering_create(&tethering);
803 if (ret != TETHERING_ERROR_NONE) {
804 BT_ERR("Fail to create tethering: %d", ret);
808 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
810 ret = tethering_destroy(tethering);
812 if (ret != TETHERING_ERROR_NONE) {
813 BT_ERR("Fail to create tethering: %d", ret);
816 if (enabled != true) {
817 BT_ERR("BT tethering is not enabled");
822 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
825 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
827 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
834 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
835 if (reply_temp == NULL) {
836 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
841 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
843 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
844 g_variant_get(tmp_value, "s", &address);
845 G_VARIANT_UNREF(tmp_value);
847 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
851 tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
852 g_variant_get(tmp_value, "s", &name);
853 G_VARIANT_UNREF(tmp_value);
857 tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
858 g_variant_get(tmp_value, "b", &trust);
859 G_VARIANT_UNREF(tmp_value);
861 tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
862 g_variant_get(tmp_value, "b", &paired);
863 G_VARIANT_UNREF(tmp_value);
864 if ((paired == FALSE) && (trust == FALSE)) {
865 BT_ERR("No paired & No trusted device");
866 gap_agent_reply_authorize(agent,
867 GAP_AGENT_REJECT, NULL);
871 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
873 if (strcasecmp(uuid, OPP_UUID) == 0 &&
874 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
876 _bt_send_event(BT_OPP_SERVER_EVENT,
877 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
878 g_variant_new("iss", result, address, name));
883 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
884 (char *)uuid) == TRUE) {
885 bt_agent_osp_server_t *osp_serv;
886 osp_serv = _gap_agent_get_osp_server(agent,
887 BT_RFCOMM_SERVER, (char *)uuid);
889 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
890 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
891 g_variant_new("issssn", result, address, uuid,
892 name, osp_serv->path, osp_serv->fd));
897 if (!strcasecmp(uuid, OPP_UUID))
898 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
899 else if (!strcasecmp(uuid, PBAP_UUID))
900 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
901 else if (!strcasecmp(uuid, MAP_UUID))
902 request_type = BT_AGENT_EVENT_MAP_REQUEST;
905 BT_INFO("Trusted device, so authorize\n");
906 gap_agent_reply_authorize(agent,
907 GAP_AGENT_ACCEPT, NULL);
909 _bt_launch_system_popup(request_type, name, NULL, NULL,
910 _gap_agent_get_path(agent));
914 g_variant_unref(reply);
915 g_variant_unref(reply_temp);
916 __bt_agent_release_memory();
922 static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
925 BT_DBG("On Going Authorization is cancelled by remote\n");
927 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
929 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
930 syspopup_destroy_all();
933 __bt_agent_release_memory();
938 void _bt_destroy_agent(void *agent)
943 _gap_agent_reset_dbus((GapAgentPrivate *)agent);
948 void* _bt_create_agent(const char *path, gboolean adapter)
950 GAP_AGENT_FUNC_CB func_cb;
951 GDBusProxy *adapter_proxy;
952 GapAgentPrivate *agent;
954 adapter_proxy = _bt_get_adapter_proxy();
958 func_cb.pincode_func = __pincode_request;
959 func_cb.display_func = __display_request;
960 func_cb.passkey_func = __passkey_request;
961 func_cb.confirm_func = __confirm_request;
962 func_cb.authorize_func = __authorize_request;
963 func_cb.pairing_cancel_func = __pairing_cancel_request;
964 func_cb.authorization_cancel_func = __authorization_cancel_request;
967 agent = g_new0(GapAgentPrivate, 1);
969 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
972 if (!_gap_agent_register(agent)) {
973 _bt_destroy_agent(agent);
981 gboolean _bt_agent_register_osp_server(const gint type,
982 const char *uuid, char *path, int fd)
984 void *agent = _bt_get_adapter_agent();
988 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
992 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
994 void *agent = _bt_get_adapter_agent();
999 return _gap_agent_unregister_osp_server(agent, type, uuid);
1002 gboolean _bt_agent_reply_authorize(gboolean accept)
1006 void *agent = _bt_get_adapter_agent();
1010 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
1012 return gap_agent_reply_authorize(agent, accept_val, NULL);
1015 gboolean _bt_agent_is_canceled(void)
1017 void *agent = _bt_get_adapter_agent();
1021 return _gap_agent_is_canceled(agent);
1024 void _bt_agent_set_canceled(gboolean value)
1026 void *agent = _bt_get_adapter_agent();
1030 return _gap_agent_set_canceled(agent, value);
1033 int _bt_agent_reply_cancellation(void)
1035 void *agent = _bt_get_adapter_agent();
1038 return BLUETOOTH_ERROR_INTERNAL;
1040 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
1041 BT_ERR("Fail to reply agent");
1042 return BLUETOOTH_ERROR_INTERNAL;
1045 return BLUETOOTH_ERROR_NONE;
1048 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1050 switch ((dev_class & 0x1f00) >> 8) {
1052 switch ((dev_class & 0xc0) >> 6) {
1054 /* input-keyboard" */
1063 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1064 const char *address)
1069 pch = strtok_r(buffer, "= ,", &last);
1074 while ((pch = strtok_r(NULL, ",", &last))) {
1075 if (0 == g_strcmp0(pch, address)) {
1076 BT_DBG("Match found\n");
1083 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1084 const char *partial_name)
1089 pch = strtok_r(buffer, "= ,", &last);
1094 while ((pch = strtok_r(NULL, ",", &last))) {
1095 if (g_str_has_prefix(partial_name, pch)) {
1096 BT_DBG("Match found\n");
1103 static gboolean __bt_agent_is_device_blacklist(const char *address,
1115 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1118 BT_ERR("Unable to open blacklist file");
1122 fseek(fp, 0, SEEK_END);
1125 BT_DBG("size is not a positive number");
1132 buffer = g_malloc0(sizeof(char) * size);
1133 /* Fix : NULL_RETURNS */
1134 if (buffer == NULL) {
1135 BT_ERR("Fail to allocate memory");
1139 result = fread((char *)buffer, 1, size, fp);
1141 if (result != size) {
1142 BT_ERR("Read Error");
1147 BT_DBG("Buffer = %s", buffer);
1149 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1152 if (lines == NULL) {
1153 BT_ERR("No lines in the file");
1157 for (i = 0; lines[i] != NULL; i++) {
1158 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1159 if (__bt_agent_find_device_by_address_exactname(
1162 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1163 if (__bt_agent_find_device_by_address_exactname(
1166 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1167 if (__bt_agent_find_device_by_partial_name(lines[i],
1170 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1171 if (__bt_agent_find_device_by_address_exactname(
1179 BT_DBG("Found the device");
1184 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1185 const gchar *address, const gchar *name)
1187 gboolean is_headset = FALSE;
1188 gboolean is_mouse = FALSE;
1189 char lap_address[BT_LOWER_ADDRESS_LENGTH];
1191 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1193 if (address == NULL)
1196 switch ((dev_class & 0x1f00) >> 8) {
1198 switch ((dev_class & 0xfc) >> 2) {
1208 case 0x0b: /* VCR */
1209 case 0x0c: /* Video Camera */
1210 case 0x0d: /* Camcorder */
1213 /* Other audio device */
1219 switch (dev_class & 0xff) {
1220 case 0x80: /* 0x80: Pointing device(Mouse) */
1224 case 0x40: /* 0x40: input device (BT keyboard) */
1226 /* Get the LAP(Lower Address part) */
1227 g_strlcpy(lap_address, address, sizeof(lap_address));
1229 /* Need to Auto pair the blacklisted Keyboard */
1230 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1231 BT_DBG("Device is not black listed\n");
1234 BT_ERR("Device is black listed\n");
1240 if ((!is_headset) && (!is_mouse))
1243 /* Get the LAP(Lower Address part) */
1244 g_strlcpy(lap_address, address, sizeof(lap_address));
1246 BT_DBG("Device address = %s\n", address);
1247 BT_DBG("Address 3 byte = %s\n", lap_address);
1249 if (__bt_agent_is_device_blacklist(lap_address, name)) {
1250 BT_ERR("Device is black listed\n");
1257 static int __bt_agent_generate_passkey(char *passkey, int size)
1262 unsigned int value = 0;
1264 if (passkey == NULL)
1270 random_fd = open("/dev/urandom", O_RDONLY);
1275 for (i = 0; i < size; i++) {
1276 len = read(random_fd, &value, sizeof(value));
1278 passkey[i] = '0' + (value % 10);
1283 BT_DBG("passkey: %s", passkey);