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 #include <package-manager.h>
32 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
33 #include <tethering.h>
36 #include "bt-internal-types.h"
37 #include "bt-service-common.h"
38 #include "bt-service-agent.h"
39 #include "bt-service-gap-agent.h"
40 #include "bt-service-adapter.h"
41 #include "bt-service-event.h"
42 #include "bt-service-rfcomm-server.h"
43 #include "bt-service-device.h"
44 #include "bt-service-audio.h"
46 #if defined(LIBNOTIFY_SUPPORT)
48 #elif defined(LIBNOTIFICATION_SUPPORT)
49 #include "bt-service-agent-notification.h"
51 #include <syspopup_caller.h>
54 #define BT_APP_AUTHENTICATION_TIMEOUT 35
55 #define BT_APP_AUTHORIZATION_TIMEOUT 15
57 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
58 #define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
59 #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
60 #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
61 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
62 #define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
63 #define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
64 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
65 #define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
66 #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
67 #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
68 #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
69 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
70 #define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
71 #define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
73 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
75 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
77 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
78 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
80 #define BT_PIN_MAX_LENGTH 16
81 #define BT_PASSKEY_MAX_LENGTH 4
83 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
84 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
85 #define BT_PAN_MAX_CONNECTION 4
86 extern guint nap_connected_device_count;
88 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
90 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
91 static int __bt_agent_generate_passkey(char *passkey, int size);
93 static void __bt_agent_release_memory(void)
95 /* Release Malloc Memory*/
98 /* Release Stack Memory*/
102 static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
105 static int retry_count;
106 bundle *b = (bundle *)user_data;
107 retv_if(user_data == NULL, FALSE);
111 #if defined(LIBNOTIFY_SUPPORT)
112 ret = notify_launch(b);
113 #elif defined(LIBNOTIFICATION_SUPPORT)
114 ret = notification_launch(b);
116 ret = syspopup_launch("bt-syspopup", b);
119 BT_ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..",
121 if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) {
122 BT_ERR("Sorry!! Max retry %d reached", retry_count);
128 BT_DBG("Hurray!! Finally Popup launched");
133 return (ret < 0) ? TRUE : FALSE;
136 #ifdef TIZEN_WEARABLE
137 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
142 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
144 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
149 BT_INFO("Unbonding is done");
153 static gboolean __bt_unpair_device(void)
159 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
160 if (device_list == NULL) {
161 BT_ERR("g_array_new is failed");
165 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
166 BT_ERR("_bt_get_bonded_devices is failed");
167 g_array_free(device_list, TRUE);
171 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
172 for (i = 0; i < no_of_device; i++) {
173 DBusGProxy *adapter_proxy;
174 bluetooth_device_info_t info;
175 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
176 char *device_path = NULL;
178 info = g_array_index(device_list, bluetooth_device_info_t, i);
179 if (info.device_class.major_class ==
180 BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO)
183 adapter_proxy = _bt_get_adapter_proxy();
184 if (!adapter_proxy) {
185 BT_ERR("adapter_proxy is NULL");
186 g_array_free(device_list, TRUE);
190 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
191 device_path = _bt_get_device_object_path(addr);
192 if (device_path == NULL) {
193 BT_ERR("device_path is NULL");
194 g_array_free(device_list, TRUE);
198 if (!dbus_g_proxy_begin_call(adapter_proxy, "UnpairDevice",
199 (DBusGProxyCallNotify)__bt_unbond_cb,
201 DBUS_TYPE_G_OBJECT_PATH, device_path,
203 BT_ERR("RemoveBonding begin failed\n");
204 g_array_free(device_list, TRUE);
207 BT_INFO("unbonding %s is requested", addr);
209 g_array_free(device_list, TRUE);
213 g_array_free(device_list, TRUE);
217 static DBusHandlerResult __bt_popup_event_filter(DBusConnection *conn,
218 DBusMessage *msg, void *data)
225 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
227 if (!dbus_message_is_signal(msg, "User.Bluetooth.syspopup", "ResetResponse"))
228 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
230 if (!dbus_message_get_args(msg, NULL,
231 DBUS_TYPE_INT32, &response,
232 DBUS_TYPE_INVALID)) {
233 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
236 BT_DBG("response = %d", response);
239 return DBUS_HANDLER_RESULT_HANDLED;
242 static void __bt_register_popup_event_signal(void)
244 DBusError dbus_error;
245 DBusGConnection *gconn;
246 DBusConnection *conn;
250 gconn = _bt_get_system_gconn();
254 conn = dbus_g_connection_get_connection(gconn);
258 dbus_connection_add_filter(conn, __bt_popup_event_filter, NULL, NULL);
260 dbus_error_init(&dbus_error);
261 dbus_bus_add_match(conn,
262 "type='signal',interface='User.Bluetooth.syspopup'"
263 ",member='ResetResponse'", &dbus_error);
264 if (dbus_error_is_set(&dbus_error)) {
265 BT_ERR("Error: %s\n", dbus_error.message);
266 dbus_error_free(&dbus_error);
274 static gboolean __is_reset_required(const gchar *address)
277 uint32_t no_of_device;
279 bluetooth_device_info_t info;
280 gboolean is_required = FALSE;
282 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
283 if (device_list == NULL) {
284 BT_ERR("g_array_new is failed");
288 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
289 BT_ERR("_bt_get_bonded_devices is failed");
290 g_array_free(device_list, TRUE);
294 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
295 for (i = 0; i < no_of_device; i++) {
296 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
298 info = g_array_index(device_list, bluetooth_device_info_t, i);
300 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
301 if (g_strcmp0(address, addr) == 0) {
302 BT_DBG("This device is already in paired list");
307 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
312 g_array_free(device_list, TRUE);
318 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
319 const char *device_name,
321 const char *filename,
322 const char *agent_path)
326 char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
330 BT_ERR("Launching system popup failed");
334 bundle_add(b, "device-name", device_name);
335 bundle_add(b, "passkey", passkey);
336 bundle_add(b, "file", filename);
337 bundle_add(b, "agent-path", agent_path);
339 switch (event_type) {
340 case BT_AGENT_EVENT_PIN_REQUEST:
341 g_strlcpy(event_str, "pin-request", sizeof(event_str));
344 case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
345 g_strlcpy(event_str, "passkey-confirm-request",
349 case BT_AGENT_EVENT_PASSKEY_REQUEST:
350 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
353 case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
354 g_strlcpy(event_str, "passkey-display-request",
358 case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
359 g_strlcpy(event_str, "authorize-request",
363 case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
364 g_strlcpy(event_str, "confirm-mode-request",
368 case BT_AGENT_EVENT_FILE_RECEIVED:
369 g_strlcpy(event_str, "file-received", sizeof(event_str));
372 case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
373 g_strlcpy(event_str, "keyboard-passkey-request",
377 case BT_AGENT_EVENT_TERMINATE:
378 g_strlcpy(event_str, "terminate", sizeof(event_str));
381 case BT_AGENT_EVENT_EXCHANGE_REQUEST:
382 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
385 case BT_AGENT_EVENT_PBAP_REQUEST:
386 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
389 case BT_AGENT_EVENT_MAP_REQUEST:
390 g_strlcpy(event_str, "message-request", sizeof(event_str));
393 #ifdef TIZEN_WEARABLE
394 case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
395 __bt_register_popup_event_signal();
396 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
400 case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
401 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
405 BT_ERR("Invalid event type");
411 bundle_add(b, "event-type", event_str);
413 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
414 ret = syspopup_launch("bt-syspopup", b);
417 BT_ERR("Popup launch failed...retry %d", ret);
419 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
420 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
425 BT_INFO("_bt_agent_launch_system_popup");
429 static gboolean __pincode_request(GapAgent *agent, DBusGProxy *device)
431 uint32_t device_class;
432 GHashTable *hash = NULL;
434 const gchar *address;
436 GError *error = NULL;
440 dbus_g_proxy_call(device, "GetAll", &error,
441 G_TYPE_STRING, BT_DEVICE_INTERFACE,
443 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
444 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
446 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
448 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
453 value = g_hash_table_lookup(hash, "Class");
454 device_class = value ? g_value_get_uint(value) : 0;
456 value = g_hash_table_lookup(hash, "Address");
457 address = value ? g_value_get_string(value) : NULL;
459 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
463 value = g_hash_table_lookup(hash, "Name");
464 name = value ? g_value_get_string(value) : NULL;
468 if (_bt_is_device_creating() == TRUE &&
469 _bt_is_bonding_device_address(address) == TRUE &&
470 __bt_agent_is_auto_response(device_class, address, name)) {
471 /* Use Fixed PIN "0000" for basic pairing*/
472 _bt_set_autopair_status_in_bonding_info(TRUE);
473 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
475 } else if (__bt_agent_is_hid_keyboard(device_class)) {
476 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
478 if (__bt_agent_generate_passkey(str_passkey,
479 BT_PASSKEY_MAX_LENGTH) != 0) {
480 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
485 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
488 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
489 name, str_passkey, NULL,
490 _gap_agent_get_path(agent));
492 _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
493 NULL, _gap_agent_get_path(agent));
497 g_hash_table_destroy(hash);
498 __bt_agent_release_memory();
505 static gboolean __passkey_request(GapAgent *agent, DBusGProxy *device)
507 GHashTable *hash = NULL;
509 const gchar *address;
511 GError *error = NULL;
515 dbus_g_proxy_call(device, "GetAll", &error,
516 G_TYPE_STRING, BT_DEVICE_INTERFACE,
518 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
519 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
521 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
523 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
528 value = g_hash_table_lookup(hash, "Address");
529 address = value ? g_value_get_string(value) : NULL;
531 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
535 value = g_hash_table_lookup(hash, "Name");
536 name = value ? g_value_get_string(value) : NULL;
540 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
541 _gap_agent_get_path(agent));
544 __bt_agent_release_memory();
545 g_hash_table_destroy(hash);
551 static gboolean __display_request(GapAgent *agent, DBusGProxy *device,
554 GHashTable *hash = NULL;
556 const gchar *address;
558 GError *error = NULL;
563 dbus_g_proxy_call(device, "GetAll", &error,
564 G_TYPE_STRING, BT_DEVICE_INTERFACE,
566 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
567 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
569 BT_ERR("error in GetAll [%s]\n", error->message);
571 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
576 value = g_hash_table_lookup(hash, "Address");
577 address = value ? g_value_get_string(value) : NULL;
579 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
583 value = g_hash_table_lookup(hash, "Name");
584 name = value ? g_value_get_string(value) : NULL;
588 str_passkey = g_strdup_printf("%d", passkey);
590 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
592 _gap_agent_get_path(agent));
597 __bt_agent_release_memory();
598 g_hash_table_destroy(hash);
604 static gboolean __confirm_request(GapAgent *agent, DBusGProxy *device,
607 GHashTable *hash = NULL;
609 const gchar *address;
611 GError *error = NULL;
614 BT_DBG("+ passkey[%.6d]", passkey);
616 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
618 dbus_g_proxy_call(device, "GetAll", &error,
619 G_TYPE_STRING, BT_DEVICE_INTERFACE,
621 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
622 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
625 BT_ERR("error in GetAll [%s]", error->message);
627 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
632 value = g_hash_table_lookup(hash, "Address");
633 address = value ? g_value_get_string(value) : NULL;
635 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
639 value = g_hash_table_lookup(hash, "Name");
640 name = value ? g_value_get_string(value) : NULL;
644 #ifdef TIZEN_WEARABLE
645 uint32_t device_class = 0x00;
646 uint32_t major_class;
648 value = g_hash_table_lookup(hash, "Class");
649 device_class = value ? g_value_get_uint(value) : 0;
651 BT_INFO("COD : 0x%X", device_class);
653 major_class = (device_class & 0x1f00) >> 8;
655 if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
656 BT_DBG("Audio device. Launch passkey pop-up");
657 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
658 str_passkey, NULL, _gap_agent_get_path(agent));
662 if (__is_reset_required(address)) {
663 BT_INFO("Launch system reset pop-up");
664 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
665 NULL, NULL, _gap_agent_get_path(agent));
667 BT_INFO("Launch passkey pop-up");
668 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
669 str_passkey, NULL, _gap_agent_get_path(agent));
672 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
674 _gap_agent_get_path(agent));
678 __bt_agent_release_memory();
679 g_hash_table_destroy(hash);
686 static gboolean __pairing_cancel_request(GapAgent *agent, const char *address)
688 BT_DBG("On Going Pairing is cancelled by remote\n");
690 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
691 syspopup_destroy_all();
694 __bt_agent_release_memory();
699 static gboolean __a2dp_authorize_request_check(void)
701 /* Check for existing Media device to disconnect */
702 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
705 static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device,
708 GHashTable *hash = NULL;
710 const gchar *address;
714 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
716 tethering_h tethering = NULL;
717 int ret = TETHERING_ERROR_NONE;
719 GError *error = NULL;
720 int result = BLUETOOTH_ERROR_NONE;
721 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
725 /* Check if already Media connection exsist */
726 if (!strcasecmp(uuid, A2DP_UUID)) {
727 gboolean ret = FALSE;
729 ret = __a2dp_authorize_request_check();
732 BT_ERR("Already one A2DP device connected \n");
733 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
738 /* Check completed */
740 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
741 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
742 !strcasecmp(uuid, HFP_HS_UUID) ||
743 !strcasecmp(uuid, HSP_HS_UUID) ||
744 !strcasecmp(uuid, A2DP_UUID) ||
745 !strcasecmp(uuid, HID_UUID) ||
746 !strcasecmp(uuid, SAP_UUID_OLD) ||
747 !strcasecmp(uuid, SAP_UUID_NEW) ||
748 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
749 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
750 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
756 if (!strcasecmp(uuid, NAP_UUID) ||
757 !strcasecmp(uuid, GN_UUID) ||
758 !strcasecmp(uuid, BNEP_UUID)) {
760 BT_DBG("Network connection request: %s", uuid);
761 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
762 if (nap_connected_device_count >=
763 BT_PAN_MAX_CONNECTION) {
764 BT_ERR("Max connection exceeded");
768 ret = tethering_create(&tethering);
770 if (ret != TETHERING_ERROR_NONE) {
771 BT_ERR("Fail to create tethering: %d", ret);
775 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
777 ret = tethering_destroy(tethering);
779 if (ret != TETHERING_ERROR_NONE) {
780 BT_ERR("Fail to create tethering: %d", ret);
783 if (enabled != true) {
784 BT_ERR("BT tethering is not enabled");
789 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
792 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
794 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
801 dbus_g_proxy_call(device, "GetAll", &error,
802 G_TYPE_STRING, BT_DEVICE_INTERFACE,
804 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
805 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
807 BT_ERR("error in GetAll [%s]\n", error->message);
809 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
814 value = g_hash_table_lookup(hash, "Address");
815 address = value ? g_value_get_string(value) : NULL;
817 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
821 value = g_hash_table_lookup(hash, "Alias");
822 name = value ? g_value_get_string(value) : NULL;
826 value = g_hash_table_lookup(hash, "Trusted");
827 trust = value ? g_value_get_boolean(value) : 0;
829 value = g_hash_table_lookup(hash, "Paired");
830 paired = value ? g_value_get_boolean(value) : 0;
831 if ((paired == FALSE) && (trust == FALSE)) {
832 BT_ERR("No paired & No trusted device");
833 gap_agent_reply_authorize(agent,
834 GAP_AGENT_REJECT, NULL);
838 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address,
841 if (strcasecmp(uuid, OPP_UUID) == 0 &&
842 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
844 _bt_send_event(BT_OPP_SERVER_EVENT,
845 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
846 DBUS_TYPE_INT32, &result,
847 DBUS_TYPE_STRING, &address,
848 DBUS_TYPE_STRING, &name,
854 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
855 (char *)uuid) == TRUE) {
856 bt_agent_osp_server_t *osp_serv;
857 osp_serv = _gap_agent_get_osp_server(agent,
858 BT_RFCOMM_SERVER, (char *)uuid);
860 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
861 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
862 DBUS_TYPE_INT32, &result,
863 DBUS_TYPE_STRING, &address,
864 DBUS_TYPE_STRING, &uuid,
865 DBUS_TYPE_STRING, &name,
866 DBUS_TYPE_STRING, &osp_serv->path,
867 DBUS_TYPE_INT16, &osp_serv->fd,
873 if (!strcasecmp(uuid, OPP_UUID))
874 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
875 else if (!strcasecmp(uuid, PBAP_UUID))
876 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
877 else if (!strcasecmp(uuid, MAP_UUID))
878 request_type = BT_AGENT_EVENT_MAP_REQUEST;
881 BT_INFO("Trusted device, so authorize\n");
882 gap_agent_reply_authorize(agent,
883 GAP_AGENT_ACCEPT, NULL);
885 _bt_launch_system_popup(request_type, name, NULL, NULL,
886 _gap_agent_get_path(agent));
890 __bt_agent_release_memory();
891 g_hash_table_destroy(hash);
898 static gboolean __authorization_cancel_request(GapAgent *agent,
901 BT_DBG("On Going Authorization is cancelled by remote\n");
903 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
905 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
906 syspopup_destroy_all();
909 __bt_agent_release_memory();
914 void _bt_destroy_agent(void *agent)
919 _gap_agent_reset_dbus(agent);
921 g_object_unref(agent);
924 void* _bt_create_agent(const char *path, gboolean adapter)
926 GAP_AGENT_FUNC_CB func_cb;
927 DBusGProxy *adapter_proxy;
930 adapter_proxy = _bt_get_adapter_proxy();
934 func_cb.pincode_func = __pincode_request;
935 func_cb.display_func = __display_request;
936 func_cb.passkey_func = __passkey_request;
937 func_cb.confirm_func = __confirm_request;
938 func_cb.authorize_func = __authorize_request;
939 func_cb.pairing_cancel_func = __pairing_cancel_request;
940 func_cb.authorization_cancel_func = __authorization_cancel_request;
942 agent = _gap_agent_new();
944 _gap_agent_setup_dbus(agent, &func_cb, path);
947 if (!_gap_agent_register(agent)) {
948 _bt_destroy_agent(agent);
956 gboolean _bt_agent_register_osp_server(const gint type,
957 const char *uuid, char *path, int fd)
959 void *agent = _bt_get_adapter_agent();
963 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
967 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
969 void *agent = _bt_get_adapter_agent();
973 return _gap_agent_unregister_osp_server(agent, type, uuid);
976 gboolean _bt_agent_reply_authorize(gboolean accept)
980 void *agent = _bt_get_adapter_agent();
984 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
986 return gap_agent_reply_authorize(agent, accept_val, NULL);
989 gboolean _bt_agent_is_canceled(void)
991 void *agent = _bt_get_adapter_agent();
995 return _gap_agent_is_canceled(agent);
998 void _bt_agent_set_canceled(gboolean value)
1000 void *agent = _bt_get_adapter_agent();
1004 return _gap_agent_set_canceled(agent, value);
1007 int _bt_agent_reply_cancellation(void)
1009 void *agent = _bt_get_adapter_agent();
1012 return BLUETOOTH_ERROR_INTERNAL;
1014 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
1015 BT_ERR("Fail to reply agent");
1016 return BLUETOOTH_ERROR_INTERNAL;
1019 return BLUETOOTH_ERROR_NONE;
1022 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1024 switch ((dev_class & 0x1f00) >> 8) {
1026 switch ((dev_class & 0xc0) >> 6) {
1028 /* input-keyboard" */
1037 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1038 const char *address)
1043 pch = strtok_r(buffer, "= ,", &last);
1048 while ((pch = strtok_r(NULL, ",", &last))) {
1049 if (0 == g_strcmp0(pch, address)) {
1050 BT_DBG("Match found\n");
1057 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1058 const char *partial_name)
1063 pch = strtok_r(buffer, "= ,", &last);
1068 while ((pch = strtok_r(NULL, ",", &last))) {
1069 if (g_str_has_prefix(partial_name, pch)) {
1070 BT_DBG("Match found\n");
1077 static gboolean __bt_agent_is_device_blacklist(const char *address,
1089 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1092 BT_ERR("Unable to open blacklist file");
1096 fseek(fp, 0, SEEK_END);
1099 BT_DBG("size is not a positive number");
1106 buffer = g_malloc0(sizeof(char) * size);
1107 result = fread((char *)buffer, 1, size, fp);
1109 if (result != size) {
1110 BT_ERR("Read Error");
1115 BT_DBG("Buffer = %s", buffer);
1117 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1120 if (lines == NULL) {
1121 BT_ERR("No lines in the file");
1125 for (i = 0; lines[i] != NULL; i++) {
1126 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1127 if (__bt_agent_find_device_by_address_exactname(
1130 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1131 if (__bt_agent_find_device_by_address_exactname(
1134 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1135 if (__bt_agent_find_device_by_partial_name(lines[i],
1138 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1139 if (__bt_agent_find_device_by_address_exactname(
1147 BT_DBG("Found the device");
1152 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1153 const gchar *address, const gchar *name)
1155 gboolean is_headset = FALSE;
1156 gboolean is_mouse = FALSE;
1157 char lap_address[BT_LOWER_ADDRESS_LENGTH];
1159 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1161 if (address == NULL)
1164 switch ((dev_class & 0x1f00) >> 8) {
1166 switch ((dev_class & 0xfc) >> 2) {
1176 case 0x0b: /* VCR */
1177 case 0x0c: /* Video Camera */
1178 case 0x0d: /* Camcorder */
1181 /* Other audio device */
1187 switch (dev_class & 0xff) {
1188 case 0x80: /* 0x80: Pointing device(Mouse) */
1192 case 0x40: /* 0x40: input device (BT keyboard) */
1194 /* Get the LAP(Lower Address part) */
1195 g_strlcpy(lap_address, address, sizeof(lap_address));
1197 /* Need to Auto pair the blacklisted Keyboard */
1198 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1199 BT_DBG("Device is not black listed\n");
1202 BT_ERR("Device is black listed\n");
1208 if ((!is_headset) && (!is_mouse))
1211 /* Get the LAP(Lower Address part) */
1212 g_strlcpy(lap_address, address, sizeof(lap_address));
1214 BT_DBG("Device address = %s\n", address);
1215 BT_DBG("Address 3 byte = %s\n", lap_address);
1217 if (__bt_agent_is_device_blacklist(lap_address, name)) {
1218 BT_ERR("Device is black listed\n");
1225 static int __bt_agent_generate_passkey(char *passkey, int size)
1230 unsigned int value = 0;
1232 if (passkey == NULL)
1238 random_fd = open("/dev/urandom", O_RDONLY);
1243 for (i = 0; i < size; i++) {
1244 len = read(random_fd, &value, sizeof(value));
1246 passkey[i] = '0' + (value % 10);
1251 BT_DBG("passkey: %s", passkey);