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>
29 #include <syspopup_caller.h>
31 #include <package-manager.h>
33 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
34 #include <tethering.h>
37 #include "bt-internal-types.h"
38 #include "bt-service-common.h"
39 #include "bt-service-agent.h"
40 #include "bt-service-gap-agent.h"
41 #include "bt-service-adapter.h"
42 #include "bt-service-event.h"
43 #include "bt-service-rfcomm-server.h"
44 #include "bt-service-device.h"
45 #include "bt-service-audio.h"
47 #define BT_APP_AUTHENTICATION_TIMEOUT 35
48 #define BT_APP_AUTHORIZATION_TIMEOUT 15
50 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
51 #define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
52 #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
53 #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
54 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
55 #define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
56 #define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
57 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
58 #define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
59 #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
60 #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
61 #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
62 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
63 #define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
64 #define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
66 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
68 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
70 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
71 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
73 #define BT_PIN_MAX_LENGTH 16
74 #define BT_PASSKEY_MAX_LENGTH 4
76 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
77 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
78 #define BT_PAN_MAX_CONNECTION 4
79 extern guint nap_connected_device_count;
81 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
83 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
84 static int __bt_agent_generate_passkey(char *passkey, int size);
86 static void __bt_agent_release_memory(void)
88 /* Release Malloc Memory*/
91 /* Release Stack Memory*/
95 static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
98 static int retry_count;
99 bundle *b = (bundle *)user_data;
100 retv_if(user_data == NULL, FALSE);
104 ret = syspopup_launch("bt-syspopup", b);
106 BT_ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..",
108 if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) {
109 BT_ERR("Sorry!! Max retry %d reached", retry_count);
115 BT_DBG("Hurray!! Finally Popup launched");
120 return (ret < 0) ? TRUE : FALSE;
123 #ifdef TIZEN_WEARABLE
124 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
129 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
131 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
136 BT_INFO("Unbonding is done");
140 static gboolean __bt_unpair_device(void)
146 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
147 if (device_list == NULL) {
148 BT_ERR("g_array_new is failed");
152 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
153 BT_ERR("_bt_get_bonded_devices is failed");
154 g_array_free(device_list, TRUE);
158 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
159 for (i = 0; i < no_of_device; i++) {
160 DBusGProxy *adapter_proxy;
161 bluetooth_device_info_t info;
162 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
163 char *device_path = NULL;
165 info = g_array_index(device_list, bluetooth_device_info_t, i);
166 if (info.device_class.major_class ==
167 BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO)
170 adapter_proxy = _bt_get_adapter_proxy();
171 if (!adapter_proxy) {
172 BT_ERR("adapter_proxy is NULL");
173 g_array_free(device_list, TRUE);
177 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
178 device_path = _bt_get_device_object_path(addr);
179 if (device_path == NULL) {
180 BT_ERR("device_path is NULL");
181 g_array_free(device_list, TRUE);
185 if (!dbus_g_proxy_begin_call(adapter_proxy, "UnpairDevice",
186 (DBusGProxyCallNotify)__bt_unbond_cb,
188 DBUS_TYPE_G_OBJECT_PATH, device_path,
190 BT_ERR("RemoveBonding begin failed\n");
191 g_array_free(device_list, TRUE);
194 BT_INFO("unbonding %s is requested", addr);
196 g_array_free(device_list, TRUE);
200 g_array_free(device_list, TRUE);
204 static DBusHandlerResult __bt_popup_event_filter(DBusConnection *conn,
205 DBusMessage *msg, void *data)
212 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
214 if (!dbus_message_is_signal(msg, "User.Bluetooth.syspopup", "ResetResponse"))
215 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
217 if (!dbus_message_get_args(msg, NULL,
218 DBUS_TYPE_INT32, &response,
219 DBUS_TYPE_INVALID)) {
220 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
223 BT_DBG("response = %d", response);
226 return DBUS_HANDLER_RESULT_HANDLED;
229 static void __bt_register_popup_event_signal(void)
231 DBusError dbus_error;
232 DBusGConnection *gconn;
233 DBusConnection *conn;
237 gconn = _bt_get_system_gconn();
241 conn = dbus_g_connection_get_connection(gconn);
245 dbus_connection_add_filter(conn, __bt_popup_event_filter, NULL, NULL);
247 dbus_error_init(&dbus_error);
248 dbus_bus_add_match(conn,
249 "type='signal',interface='User.Bluetooth.syspopup'"
250 ",member='ResetResponse'", &dbus_error);
251 if (dbus_error_is_set(&dbus_error)) {
252 BT_ERR("Error: %s\n", dbus_error.message);
253 dbus_error_free(&dbus_error);
261 static gboolean __is_reset_required(const gchar *address)
264 uint32_t no_of_device;
266 bluetooth_device_info_t info;
267 gboolean is_required = FALSE;
269 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
270 if (device_list == NULL) {
271 BT_ERR("g_array_new is failed");
275 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
276 BT_ERR("_bt_get_bonded_devices is failed");
277 g_array_free(device_list, TRUE);
281 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
282 for (i = 0; i < no_of_device; i++) {
283 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
285 info = g_array_index(device_list, bluetooth_device_info_t, i);
287 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
288 if (g_strcmp0(address, addr) == 0) {
289 BT_DBG("This device is already in paired list");
294 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
299 g_array_free(device_list, TRUE);
305 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
306 const char *device_name,
308 const char *filename,
309 const char *agent_path)
313 char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
317 BT_ERR("Launching system popup failed");
321 bundle_add(b, "device-name", device_name);
322 bundle_add(b, "passkey", passkey);
323 bundle_add(b, "file", filename);
324 bundle_add(b, "agent-path", agent_path);
326 switch (event_type) {
327 case BT_AGENT_EVENT_PIN_REQUEST:
328 g_strlcpy(event_str, "pin-request", sizeof(event_str));
331 case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
332 g_strlcpy(event_str, "passkey-confirm-request",
336 case BT_AGENT_EVENT_PASSKEY_REQUEST:
337 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
340 case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
341 g_strlcpy(event_str, "passkey-display-request",
345 case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
346 g_strlcpy(event_str, "authorize-request",
350 case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
351 g_strlcpy(event_str, "confirm-mode-request",
355 case BT_AGENT_EVENT_FILE_RECEIVED:
356 g_strlcpy(event_str, "file-received", sizeof(event_str));
359 case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
360 g_strlcpy(event_str, "keyboard-passkey-request",
364 case BT_AGENT_EVENT_TERMINATE:
365 g_strlcpy(event_str, "terminate", sizeof(event_str));
368 case BT_AGENT_EVENT_EXCHANGE_REQUEST:
369 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
372 case BT_AGENT_EVENT_PBAP_REQUEST:
373 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
376 case BT_AGENT_EVENT_MAP_REQUEST:
377 g_strlcpy(event_str, "message-request", sizeof(event_str));
380 #ifdef TIZEN_WEARABLE
381 case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
382 __bt_register_popup_event_signal();
383 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
387 case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
388 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
392 BT_ERR("Invalid event type");
398 bundle_add(b, "event-type", event_str);
400 ret = syspopup_launch("bt-syspopup", b);
402 BT_ERR("Popup launch failed...retry %d", ret);
404 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
405 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
410 BT_INFO("_bt_agent_launch_system_popup");
414 static gboolean __pincode_request(GapAgent *agent, DBusGProxy *device)
416 uint32_t device_class;
417 GHashTable *hash = NULL;
419 const gchar *address;
421 GError *error = NULL;
425 dbus_g_proxy_call(device, "GetAll", &error,
426 G_TYPE_STRING, BT_DEVICE_INTERFACE,
428 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
429 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
431 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
433 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
438 value = g_hash_table_lookup(hash, "Class");
439 device_class = value ? g_value_get_uint(value) : 0;
441 value = g_hash_table_lookup(hash, "Address");
442 address = value ? g_value_get_string(value) : NULL;
444 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
448 value = g_hash_table_lookup(hash, "Name");
449 name = value ? g_value_get_string(value) : NULL;
453 if (_bt_is_device_creating() == TRUE &&
454 _bt_is_bonding_device_address(address) == TRUE &&
455 __bt_agent_is_auto_response(device_class, address, name)) {
456 /* Use Fixed PIN "0000" for basic pairing*/
457 _bt_set_autopair_status_in_bonding_info(TRUE);
458 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
460 } else if (__bt_agent_is_hid_keyboard(device_class)) {
461 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
463 if (__bt_agent_generate_passkey(str_passkey,
464 BT_PASSKEY_MAX_LENGTH) != 0) {
465 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
470 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
473 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
474 name, str_passkey, NULL,
475 _gap_agent_get_path(agent));
477 _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
478 NULL, _gap_agent_get_path(agent));
482 g_hash_table_destroy(hash);
483 __bt_agent_release_memory();
490 static gboolean __passkey_request(GapAgent *agent, DBusGProxy *device)
492 GHashTable *hash = NULL;
494 const gchar *address;
496 GError *error = NULL;
500 dbus_g_proxy_call(device, "GetAll", &error,
501 G_TYPE_STRING, BT_DEVICE_INTERFACE,
503 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
504 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
506 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
508 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
513 value = g_hash_table_lookup(hash, "Address");
514 address = value ? g_value_get_string(value) : NULL;
516 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
520 value = g_hash_table_lookup(hash, "Name");
521 name = value ? g_value_get_string(value) : NULL;
525 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
526 _gap_agent_get_path(agent));
529 __bt_agent_release_memory();
530 g_hash_table_destroy(hash);
536 static gboolean __display_request(GapAgent *agent, DBusGProxy *device,
539 GHashTable *hash = NULL;
541 const gchar *address;
543 GError *error = NULL;
548 dbus_g_proxy_call(device, "GetAll", &error,
549 G_TYPE_STRING, BT_DEVICE_INTERFACE,
551 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
552 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
554 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
556 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
561 value = g_hash_table_lookup(hash, "Address");
562 address = value ? g_value_get_string(value) : NULL;
564 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
568 value = g_hash_table_lookup(hash, "Name");
569 name = value ? g_value_get_string(value) : NULL;
573 str_passkey = g_strdup_printf("%d", passkey);
575 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
577 _gap_agent_get_path(agent));
582 __bt_agent_release_memory();
583 g_hash_table_destroy(hash);
589 static gboolean __confirm_request(GapAgent *agent, DBusGProxy *device,
592 GHashTable *hash = NULL;
594 const gchar *address;
596 GError *error = NULL;
599 BT_DBG("+ passkey[%.6d]", passkey);
601 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
603 dbus_g_proxy_call(device, "GetAll", &error,
604 G_TYPE_STRING, BT_DEVICE_INTERFACE,
606 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
607 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
610 BT_ERR("error in GetBasicProperties [%s]", error->message);
612 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
617 value = g_hash_table_lookup(hash, "Address");
618 address = value ? g_value_get_string(value) : NULL;
620 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
624 value = g_hash_table_lookup(hash, "Name");
625 name = value ? g_value_get_string(value) : NULL;
629 #ifdef TIZEN_WEARABLE
630 uint32_t device_class = 0x00;
631 uint32_t major_class;
633 value = g_hash_table_lookup(hash, "Class");
634 device_class = value ? g_value_get_uint(value) : 0;
636 BT_INFO("COD : 0x%X", device_class);
638 major_class = (device_class & 0x1f00) >> 8;
640 if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
641 BT_DBG("Audio device. Launch passkey pop-up");
642 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
643 str_passkey, NULL, _gap_agent_get_path(agent));
647 if (__is_reset_required(address)) {
648 BT_INFO("Launch system reset pop-up");
649 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
650 NULL, NULL, _gap_agent_get_path(agent));
652 BT_INFO("Launch passkey pop-up");
653 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
654 str_passkey, NULL, _gap_agent_get_path(agent));
657 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
659 _gap_agent_get_path(agent));
663 __bt_agent_release_memory();
664 g_hash_table_destroy(hash);
671 static gboolean __pairing_cancel_request(GapAgent *agent, const char *address)
673 BT_DBG("On Going Pairing is cancelled by remote\n");
675 syspopup_destroy_all();
677 __bt_agent_release_memory();
682 static gboolean __a2dp_authorize_request_check(void)
684 /* Check for existing Media device to disconnect */
685 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
688 static gboolean __authorize_request(GapAgent *agent, DBusGProxy *device,
691 GHashTable *hash = NULL;
693 const gchar *address;
697 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
699 tethering_h tethering = NULL;
700 int ret = TETHERING_ERROR_NONE;
702 GError *error = NULL;
703 int result = BLUETOOTH_ERROR_NONE;
704 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
708 /* Check if already Media connection exsist */
709 if (!strcasecmp(uuid, A2DP_UUID)) {
710 gboolean ret = FALSE;
712 ret = __a2dp_authorize_request_check();
715 BT_ERR("Already one A2DP device connected \n");
716 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
721 /* Check completed */
723 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
724 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
725 !strcasecmp(uuid, HFP_HS_UUID) ||
726 !strcasecmp(uuid, HSP_HS_UUID) ||
727 !strcasecmp(uuid, A2DP_UUID) ||
728 !strcasecmp(uuid, HID_UUID) ||
729 !strcasecmp(uuid, SAP_UUID_OLD) ||
730 !strcasecmp(uuid, SAP_UUID_NEW) ||
731 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
732 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
733 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
739 if (!strcasecmp(uuid, NAP_UUID) ||
740 !strcasecmp(uuid, GN_UUID) ||
741 !strcasecmp(uuid, BNEP_UUID)) {
743 BT_DBG("Network connection request: %s", uuid);
744 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
745 if (nap_connected_device_count >=
746 BT_PAN_MAX_CONNECTION) {
747 BT_ERR("Max connection exceeded");
751 ret = tethering_create(&tethering);
753 if (ret != TETHERING_ERROR_NONE) {
754 BT_ERR("Fail to create tethering: %d", ret);
758 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
760 ret = tethering_destroy(tethering);
762 if (ret != TETHERING_ERROR_NONE) {
763 BT_ERR("Fail to create tethering: %d", ret);
766 if (enabled != true) {
767 BT_ERR("BT tethering is not enabled");
772 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
775 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
777 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
784 dbus_g_proxy_call(device, "GetAll", &error,
785 G_TYPE_STRING, BT_DEVICE_INTERFACE,
787 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
788 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
790 BT_ERR("error in GetBasicProperties [%s]\n", error->message);
792 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
797 value = g_hash_table_lookup(hash, "Address");
798 address = value ? g_value_get_string(value) : NULL;
800 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
804 value = g_hash_table_lookup(hash, "Alias");
805 name = value ? g_value_get_string(value) : NULL;
809 value = g_hash_table_lookup(hash, "Trusted");
810 trust = value ? g_value_get_boolean(value) : 0;
812 value = g_hash_table_lookup(hash, "Paired");
813 paired = value ? g_value_get_boolean(value) : 0;
814 if ((paired == FALSE) && (trust == FALSE)) {
815 BT_ERR("No paired & No trusted device");
816 gap_agent_reply_authorize(agent,
817 GAP_AGENT_REJECT, NULL);
821 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address,
824 if (strcasecmp(uuid, OPP_UUID) == 0 &&
825 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
827 _bt_send_event(BT_OPP_SERVER_EVENT,
828 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
829 DBUS_TYPE_INT32, &result,
830 DBUS_TYPE_STRING, &address,
831 DBUS_TYPE_STRING, &name,
837 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
838 (char *)uuid) == TRUE) {
839 bt_agent_osp_server_t *osp_serv;
840 osp_serv = _gap_agent_get_osp_server(agent,
841 BT_RFCOMM_SERVER, (char *)uuid);
843 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
844 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
845 DBUS_TYPE_INT32, &result,
846 DBUS_TYPE_STRING, &address,
847 DBUS_TYPE_STRING, &uuid,
848 DBUS_TYPE_STRING, &name,
849 DBUS_TYPE_STRING, &osp_serv->path,
850 DBUS_TYPE_INT16, &osp_serv->fd,
856 if (!strcasecmp(uuid, OPP_UUID))
857 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
858 else if (!strcasecmp(uuid, PBAP_UUID))
859 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
860 else if (!strcasecmp(uuid, MAP_UUID))
861 request_type = BT_AGENT_EVENT_MAP_REQUEST;
864 BT_INFO("Trusted device, so authorize\n");
865 gap_agent_reply_authorize(agent,
866 GAP_AGENT_ACCEPT, NULL);
868 _bt_launch_system_popup(request_type, name, NULL, NULL,
869 _gap_agent_get_path(agent));
873 __bt_agent_release_memory();
874 g_hash_table_destroy(hash);
881 static gboolean __authorization_cancel_request(GapAgent *agent,
884 BT_DBG("On Going Authorization is cancelled by remote\n");
886 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
888 syspopup_destroy_all();
890 __bt_agent_release_memory();
895 void _bt_destroy_agent(void *agent)
900 _gap_agent_reset_dbus(agent);
902 g_object_unref(agent);
905 void* _bt_create_agent(const char *path, gboolean adapter)
907 GAP_AGENT_FUNC_CB func_cb;
908 DBusGProxy *adapter_proxy;
911 adapter_proxy = _bt_get_adapter_proxy();
915 func_cb.pincode_func = __pincode_request;
916 func_cb.display_func = __display_request;
917 func_cb.passkey_func = __passkey_request;
918 func_cb.confirm_func = __confirm_request;
919 func_cb.authorize_func = __authorize_request;
920 func_cb.pairing_cancel_func = __pairing_cancel_request;
921 func_cb.authorization_cancel_func = __authorization_cancel_request;
923 agent = _gap_agent_new();
925 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
928 if (!_gap_agent_register(agent)) {
929 _bt_destroy_agent(agent);
937 gboolean _bt_agent_register_osp_server(const gint type,
938 const char *uuid, char *path, int fd)
940 void *agent = _bt_get_adapter_agent();
944 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
948 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
950 void *agent = _bt_get_adapter_agent();
954 return _gap_agent_unregister_osp_server(agent, type, uuid);
957 gboolean _bt_agent_reply_authorize(gboolean accept)
961 void *agent = _bt_get_adapter_agent();
965 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
967 return gap_agent_reply_authorize(agent, accept_val, NULL);
970 gboolean _bt_agent_is_canceled(void)
972 void *agent = _bt_get_adapter_agent();
976 return _gap_agent_is_canceled(agent);
979 void _bt_agent_set_canceled(gboolean value)
981 void *agent = _bt_get_adapter_agent();
985 return _gap_agent_set_canceled(agent, value);
988 int _bt_agent_reply_cancellation(void)
990 void *agent = _bt_get_adapter_agent();
993 return BLUETOOTH_ERROR_INTERNAL;
995 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
996 BT_ERR("Fail to reply agent");
997 return BLUETOOTH_ERROR_INTERNAL;
1000 return BLUETOOTH_ERROR_NONE;
1003 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1005 switch ((dev_class & 0x1f00) >> 8) {
1007 switch ((dev_class & 0xc0) >> 6) {
1009 /* input-keyboard" */
1018 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1019 const char *address)
1024 pch = strtok_r(buffer, "= ,", &last);
1029 while ((pch = strtok_r(NULL, ",", &last))) {
1030 if (0 == g_strcmp0(pch, address)) {
1031 BT_DBG("Match found\n");
1038 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1039 const char *partial_name)
1044 pch = strtok_r(buffer, "= ,", &last);
1049 while ((pch = strtok_r(NULL, ",", &last))) {
1050 if (g_str_has_prefix(partial_name, pch)) {
1051 BT_DBG("Match found\n");
1058 static gboolean __bt_agent_is_device_blacklist(const char *address,
1070 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1073 BT_ERR("Unable to open blacklist file");
1077 fseek(fp, 0, SEEK_END);
1080 BT_DBG("size is not a positive number");
1087 buffer = g_malloc0(sizeof(char) * size);
1088 result = fread((char *)buffer, 1, size, fp);
1090 if (result != size) {
1091 BT_ERR("Read Error");
1096 BT_DBG("Buffer = %s", buffer);
1098 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1101 if (lines == NULL) {
1102 BT_ERR("No lines in the file");
1106 for (i = 0; lines[i] != NULL; i++) {
1107 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1108 if (__bt_agent_find_device_by_address_exactname(
1111 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1112 if (__bt_agent_find_device_by_address_exactname(
1115 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1116 if (__bt_agent_find_device_by_partial_name(lines[i],
1119 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1120 if (__bt_agent_find_device_by_address_exactname(
1128 BT_DBG("Found the device");
1133 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1134 const gchar *address, const gchar *name)
1136 gboolean is_headset = FALSE;
1137 gboolean is_mouse = FALSE;
1138 char lap_address[BT_LOWER_ADDRESS_LENGTH];
1140 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1142 if (address == NULL)
1145 switch ((dev_class & 0x1f00) >> 8) {
1147 switch ((dev_class & 0xfc) >> 2) {
1157 case 0x0b: /* VCR */
1158 case 0x0c: /* Video Camera */
1159 case 0x0d: /* Camcorder */
1162 /* Other audio device */
1168 switch (dev_class & 0xff) {
1169 case 0x80: /* 0x80: Pointing device(Mouse) */
1173 case 0x40: /* 0x40: input device (BT keyboard) */
1175 /* Get the LAP(Lower Address part) */
1176 g_strlcpy(lap_address, address, sizeof(lap_address));
1178 /* Need to Auto pair the blacklisted Keyboard */
1179 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1180 BT_DBG("Device is not black listed\n");
1183 BT_ERR("Device is black listed\n");
1189 if ((!is_headset) && (!is_mouse))
1192 /* Get the LAP(Lower Address part) */
1193 g_strlcpy(lap_address, address, sizeof(lap_address));
1195 BT_DBG("Device address = %s\n", address);
1196 BT_DBG("Address 3 byte = %s\n", lap_address);
1198 if (__bt_agent_is_device_blacklist(lap_address, name)) {
1199 BT_ERR("Device is black listed\n");
1206 static int __bt_agent_generate_passkey(char *passkey, int size)
1211 unsigned int value = 0;
1213 if (passkey == NULL)
1219 random_fd = open("/dev/urandom", O_RDONLY);
1224 for (i = 0; i < size; i++) {
1225 len = read(random_fd, &value, sizeof(value));
1227 passkey[i] = '0' + (value % 10);
1232 BT_DBG("passkey: %s", passkey);