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 #define BT_APP_AUTHENTICATION_TIMEOUT 35
50 #define BT_APP_AUTHORIZATION_TIMEOUT 15
52 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
53 #define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
54 #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
55 #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
56 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
57 #define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
58 #define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
59 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
60 #define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
61 #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
62 #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
63 #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
64 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
65 #define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
66 #define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
68 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
70 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
72 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
73 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
75 #define BT_PIN_MAX_LENGTH 16
76 #define BT_PASSKEY_MAX_LENGTH 4
78 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
79 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
80 #define BT_PAN_MAX_CONNECTION 4
81 extern guint nap_connected_device_count;
83 #define G_VARIANT_UNREF(variant) \
84 g_variant_unref(variant); \
87 static gboolean syspopup_mode = TRUE;
89 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
91 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
92 static int __bt_agent_generate_passkey(char *passkey, int size);
94 static void __bt_agent_release_memory(void)
96 /* Release Malloc Memory*/
99 /* Release Stack Memory*/
103 static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
106 static int retry_count;
107 bundle *b = (bundle *)user_data;
108 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(GDBusProxy *proxy,
138 GAsyncResult *res, gpointer user_data)
143 value = g_dbus_proxy_call_finish(proxy, res, &err);
145 BT_ERR("Error: Unbond Failed");
147 BT_ERR("errCode[%x], message[%s]\n", err->code, err->message);
152 g_variant_unref(value);
153 BT_INFO("Unbonding is done");
157 static gboolean __bt_unpair_device(void)
163 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
164 if (device_list == NULL) {
165 BT_ERR("g_array_new is failed");
169 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
170 BT_ERR("_bt_get_bonded_devices is failed");
171 g_array_free(device_list, TRUE);
175 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
176 for (i = 0; i < no_of_device; i++) {
177 GDBusProxy *adapter_proxy;
178 bluetooth_device_info_t info;
179 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
180 char *device_path = NULL;
182 info = g_array_index(device_list, bluetooth_device_info_t, i);
183 if (info.device_class.major_class ==
184 BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO)
187 adapter_proxy = _bt_get_adapter_proxy();
188 if (!adapter_proxy) {
189 BT_ERR("adapter_proxy is NULL");
190 g_array_free(device_list, TRUE);
194 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
195 device_path = _bt_get_device_object_path(addr);
196 if (device_path == NULL) {
197 BT_ERR("device_path is NULL");
198 g_array_free(device_list, TRUE);
202 g_dbus_proxy_call(adapter_proxy,
203 "UnpairDevice", g_variant_new("o", device_path),
204 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
205 (GAsyncReadyCallback)__bt_unbond_cb, NULL);
207 BT_INFO("unbonding %s is requested", addr);
209 g_array_free(device_list, TRUE);
213 g_array_free(device_list, TRUE);
217 static void __bt_popup_event_filter(GDBusConnection *connection,
218 const gchar *sender_name,
219 const gchar *object_path,
220 const gchar *interface_name,
221 const gchar *signal_name,
222 GVariant *parameters,
225 BT_DBG("Sender Name[%s] Object Path[%s] Interface[%s] Signal[%s]",
226 sender_name, object_path, interface_name, signal_name);
228 if (g_strcmp0(interface_name, "User.Bluetooth.syspopup") == 0 &&
229 g_strcmp0(signal_name, "ResetResponse") == 0) {
232 g_variant_get(parameters, "(i)", &response);
233 BT_DBG("response = %d", response);
237 int __bt_service_subscribe_popup(GDBusConnection *conn,
240 static guint subs_interface_added_id = 0;
243 return BLUETOOTH_ERROR_INVALID_PARAM;
246 if (subs_interface_added_id == 0) {
247 subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
248 NULL, "User.Bluetooth.syspopup", "ResetResponse", NULL, NULL, 0,
249 __bt_popup_event_filter, NULL, NULL);
252 if (subs_interface_added_id > 0) {
253 g_dbus_connection_signal_unsubscribe(conn,
254 subs_interface_added_id);
255 subs_interface_added_id = 0;
258 return BLUETOOTH_ERROR_NONE;
261 static void __bt_register_popup_event_signal(void)
263 GDBusConnection *conn;
267 conn = _bt_get_system_gconn();
271 __bt_service_subscribe_popup(conn, TRUE);
277 static gboolean __is_reset_required(const gchar *address)
280 uint32_t no_of_device;
282 bluetooth_device_info_t info;
283 gboolean is_required = FALSE;
285 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
286 if (device_list == NULL) {
287 BT_ERR("g_array_new is failed");
291 if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
292 BT_ERR("_bt_get_bonded_devices is failed");
293 g_array_free(device_list, TRUE);
297 no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
298 for (i = 0; i < no_of_device; i++) {
299 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
301 info = g_array_index(device_list, bluetooth_device_info_t, i);
303 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
304 if (g_strcmp0(address, addr) == 0) {
305 BT_DBG("This device is already in paired list");
310 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
315 g_array_free(device_list, TRUE);
321 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
322 const char *device_name,
324 const char *filename,
325 const char *agent_path)
329 char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
333 BT_ERR("Launching system popup failed");
337 bundle_add(b, "device-name", device_name);
338 bundle_add(b, "passkey", passkey);
339 bundle_add(b, "file", filename);
340 bundle_add(b, "agent-path", agent_path);
342 switch (event_type) {
343 case BT_AGENT_EVENT_PIN_REQUEST:
344 g_strlcpy(event_str, "pin-request", sizeof(event_str));
347 case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
348 g_strlcpy(event_str, "passkey-confirm-request",
352 case BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED:
353 g_strlcpy(event_str, "passkey-auto-accepted",
357 case BT_AGENT_EVENT_PASSKEY_REQUEST:
358 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
361 case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
362 g_strlcpy(event_str, "passkey-display-request",
366 case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
367 g_strlcpy(event_str, "authorize-request",
371 case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
372 g_strlcpy(event_str, "confirm-mode-request",
376 case BT_AGENT_EVENT_FILE_RECEIVED:
377 g_strlcpy(event_str, "file-received", sizeof(event_str));
380 case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
381 g_strlcpy(event_str, "keyboard-passkey-request",
385 case BT_AGENT_EVENT_TERMINATE:
386 g_strlcpy(event_str, "terminate", sizeof(event_str));
389 case BT_AGENT_EVENT_EXCHANGE_REQUEST:
390 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
393 case BT_AGENT_EVENT_PBAP_REQUEST:
394 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
397 case BT_AGENT_EVENT_MAP_REQUEST:
398 g_strlcpy(event_str, "message-request", sizeof(event_str));
401 #ifdef TIZEN_WEARABLE
402 case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
403 __bt_register_popup_event_signal();
404 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
408 case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
409 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
413 BT_ERR("Invalid event type");
419 bundle_add(b, "event-type", event_str);
421 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
422 ret = syspopup_launch("bt-syspopup", b);
425 BT_ERR("Popup launch failed...retry %d", ret);
427 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
428 (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
433 BT_INFO("_bt_agent_launch_system_popup");
437 static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
439 GError *error = NULL;
442 reply = g_dbus_proxy_call_sync(device,
443 "GetAll", g_variant_new("(s)", interface),
444 G_DBUS_CALL_FLAGS_NONE, -1,
447 ERR("GetAll dBUS-RPC failed");
449 ERR("D-Bus API failure: errCode[%x], message[%s]",
450 error->code, error->message);
451 g_clear_error(&error);
459 static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
461 uint32_t device_class;
462 const gchar *address;
464 GVariant *reply = NULL;
465 GVariant *reply_temp = NULL;
468 int result = BLUETOOTH_ERROR_NONE;
472 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
474 if (reply_temp == NULL) {
475 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
480 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
482 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
483 g_variant_get(tmp_value, "u", &device_class);
484 G_VARIANT_UNREF(tmp_value);
486 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
487 g_variant_get(tmp_value, "s", &address);
488 G_VARIANT_UNREF(tmp_value);
490 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
494 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
495 g_variant_get(tmp_value, "s", &name);
496 G_VARIANT_UNREF(tmp_value);
500 if (_bt_is_device_creating() == TRUE &&
501 _bt_is_bonding_device_address(address) == TRUE &&
502 __bt_agent_is_auto_response(device_class, address, name)) {
503 BT_DBG("0000 Auto Pair");
504 /* Use Fixed PIN "0000" for basic pairing */
505 _bt_set_autopair_status_in_bonding_info(TRUE);
506 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
508 } else if (__bt_agent_is_hid_keyboard(device_class)) {
509 BT_DBG("HID Keyboard");
510 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
512 if (__bt_agent_generate_passkey(str_passkey,
513 BT_PASSKEY_MAX_LENGTH) != 0) {
514 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
519 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
523 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
527 BT_DBG("LAUNCH SYSPOPUP");
528 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
529 name, str_passkey, NULL,
530 _gap_agent_get_path(agent));
532 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
533 param = g_variant_new("(isss)", result, address, name, str_passkey);
534 _bt_send_event(BT_ADAPTER_EVENT,
535 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
539 BT_DBG("Show Pin entry");
542 BT_DBG("LAUNCH SYSPOPUP");
543 _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
544 NULL, _gap_agent_get_path(agent));
546 BT_DBG("Send BLUETOOTH_EVENT_PIN_REQUEST");
547 param = g_variant_new("(iss)", result, address, name);
548 _bt_send_event(BT_ADAPTER_EVENT,
549 BLUETOOTH_EVENT_PIN_REQUEST, param);
554 g_variant_unref(reply);
555 g_variant_unref(reply_temp);
556 __bt_agent_release_memory();
562 static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
564 const gchar *address;
566 GVariant *reply = NULL;
567 GVariant *reply_temp = NULL;
571 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
573 if (reply_temp == NULL) {
574 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
579 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
581 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
582 g_variant_get(tmp_value, "s", &address);
583 G_VARIANT_UNREF(tmp_value);
585 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
589 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
590 g_variant_get(tmp_value, "s", &name);
591 G_VARIANT_UNREF(tmp_value);
596 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
600 BT_DBG("LAUNCH SYSPOPUP");
601 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
602 _gap_agent_get_path(agent));
604 int result = BLUETOOTH_ERROR_NONE;
607 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_REQUEST");
608 param = g_variant_new("(iss)", result, address, name);
609 _bt_send_event(BT_ADAPTER_EVENT,
610 BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
615 g_variant_unref(reply);
616 g_variant_unref(reply_temp);
617 __bt_agent_release_memory();
623 static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
626 const gchar *address;
629 GVariant *reply = NULL;
630 GVariant *reply_temp = NULL;
631 GVariant *tmp_value = NULL;
635 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
636 if (reply_temp == NULL) {
637 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
642 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
644 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
645 g_variant_get(tmp_value, "s", &address);
646 G_VARIANT_UNREF(tmp_value);
648 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
652 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
653 g_variant_get(tmp_value, "s", &name);
654 G_VARIANT_UNREF(tmp_value);
658 str_passkey = g_strdup_printf("%d", passkey);
661 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, str_passkey,
665 BT_DBG("LAUNCH SYSPOPUP");
666 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
668 _gap_agent_get_path(agent));
670 int result = BLUETOOTH_ERROR_NONE;
673 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
674 param = g_variant_new("(isss)", result, address, name, str_passkey);
675 _bt_send_event(BT_ADAPTER_EVENT,
676 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
683 g_variant_unref(reply);
684 g_variant_unref(reply_temp);
685 __bt_agent_release_memory();
691 static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
694 const gchar *address;
697 GVariant *reply_temp = NULL;
698 GVariant *reply = NULL;
700 BT_DBG("+ passkey[%.6d]", passkey);
702 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
704 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
706 if (reply_temp == NULL) {
707 BT_ERR("Device doesn't exist");
708 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
713 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
715 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
716 g_variant_get(tmp_value, "s", &address);
717 G_VARIANT_UNREF(tmp_value);
719 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
723 tmp_value = g_variant_lookup_value (reply, "Name", G_VARIANT_TYPE_STRING);
724 g_variant_get(tmp_value, "s", &name);
725 G_VARIANT_UNREF(tmp_value);
729 #ifdef TIZEN_WEARABLE
730 uint32_t device_class = 0x00;
731 uint32_t major_class;
733 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
734 g_variant_get(tmp_value, "u", &device_class);
735 G_VARIANT_UNREF(tmp_value);
737 major_class = (device_class & 0x1f00) >> 8;
739 if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
740 BT_DBG("Audio device. Launch passkey pop-up");
741 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
742 str_passkey, NULL, _gap_agent_get_path(agent));
746 if (__is_reset_required(address)) {
747 BT_INFO("Launch system reset pop-up");
748 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
749 NULL, NULL, _gap_agent_get_path(agent));
751 BT_INFO("Launch passkey pop-up");
752 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED, name,
753 str_passkey, NULL, _gap_agent_get_path(agent));
755 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
759 BT_DBG("Confirm reply");
760 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
763 BT_DBG("LAUNCH SYSPOPUP");
764 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
766 _gap_agent_get_path(agent));
768 int result = BLUETOOTH_ERROR_NONE;
771 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST");
772 param = g_variant_new("(isss)", result, address, name, str_passkey);
773 _bt_send_event(BT_ADAPTER_EVENT,
774 BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
780 g_variant_unref(reply);
781 g_variant_unref(reply_temp);
782 __bt_agent_release_memory();
788 static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
790 BT_DBG("On Going Pairing is cancelled by remote\n");
792 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
793 syspopup_destroy_all();
796 __bt_agent_release_memory();
801 static gboolean __a2dp_authorize_request_check(void)
803 /* Check for existing Media device to disconnect */
804 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
807 static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
810 const gchar *address;
814 GVariant *reply = NULL;
815 GVariant *reply_temp = NULL;
817 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
819 tethering_h tethering = NULL;
821 int result = BLUETOOTH_ERROR_NONE;
822 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
827 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
832 /* Check if already Media connection exsist */
833 if (!strcasecmp(uuid, A2DP_UUID)) {
834 gboolean ret = FALSE;
836 ret = __a2dp_authorize_request_check();
839 BT_ERR("Already one A2DP device connected \n");
840 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
845 /* Check completed */
847 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
848 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
849 !strcasecmp(uuid, HFP_HS_UUID) ||
850 !strcasecmp(uuid, HSP_HS_UUID) ||
851 !strcasecmp(uuid, A2DP_UUID) ||
852 !strcasecmp(uuid, HID_UUID) ||
853 !strcasecmp(uuid, SAP_UUID_OLD) ||
854 !strcasecmp(uuid, SAP_UUID_NEW) ||
855 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
856 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
857 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
863 if (!strcasecmp(uuid, NAP_UUID) ||
864 !strcasecmp(uuid, GN_UUID) ||
865 !strcasecmp(uuid, BNEP_UUID)) {
867 BT_DBG("Network connection request: %s", uuid);
868 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
869 if (nap_connected_device_count >=
870 BT_PAN_MAX_CONNECTION) {
871 BT_ERR("Max connection exceeded");
875 ret = tethering_create(&tethering);
877 if (ret != TETHERING_ERROR_NONE) {
878 BT_ERR("Fail to create tethering: %d", ret);
882 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
884 ret = tethering_destroy(tethering);
886 if (ret != TETHERING_ERROR_NONE) {
887 BT_ERR("Fail to create tethering: %d", ret);
890 if (enabled != true) {
891 BT_ERR("BT tethering is not enabled");
896 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
899 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
901 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
908 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
909 if (reply_temp == NULL) {
910 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
915 g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
917 tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
918 g_variant_get(tmp_value, "s", &address);
919 G_VARIANT_UNREF(tmp_value);
921 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
925 tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
926 g_variant_get(tmp_value, "s", &name);
927 G_VARIANT_UNREF(tmp_value);
931 tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
932 g_variant_get(tmp_value, "b", &trust);
933 G_VARIANT_UNREF(tmp_value);
935 tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
936 g_variant_get(tmp_value, "b", &paired);
937 G_VARIANT_UNREF(tmp_value);
938 if ((paired == FALSE) && (trust == FALSE)) {
939 BT_ERR("No paired & No trusted device");
940 gap_agent_reply_authorize(agent,
941 GAP_AGENT_REJECT, NULL);
945 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
947 if (strcasecmp(uuid, OPP_UUID) == 0 &&
948 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
950 _bt_send_event(BT_OPP_SERVER_EVENT,
951 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
952 g_variant_new("(iss)", result, address, name));
957 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
958 (char *)uuid) == TRUE) {
959 bt_agent_osp_server_t *osp_serv;
960 osp_serv = _gap_agent_get_osp_server(agent,
961 BT_RFCOMM_SERVER, (char *)uuid);
964 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
965 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
966 g_variant_new("(issssn)", result, address, uuid,
967 name, osp_serv->path, osp_serv->fd));
973 if (!strcasecmp(uuid, OPP_UUID))
974 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
975 else if (!strcasecmp(uuid, PBAP_UUID))
976 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
977 else if (!strcasecmp(uuid, MAP_UUID))
978 request_type = BT_AGENT_EVENT_MAP_REQUEST;
981 BT_INFO("Trusted device, so authorize\n");
982 gap_agent_reply_authorize(agent,
983 GAP_AGENT_ACCEPT, NULL);
986 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL);
988 _bt_launch_system_popup(request_type, name, NULL, NULL,
989 _gap_agent_get_path(agent));
994 g_variant_unref(reply);
995 g_variant_unref(reply_temp);
996 __bt_agent_release_memory();
1002 static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
1003 const char *address)
1005 BT_DBG("On Going Authorization is cancelled by remote\n");
1007 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
1009 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
1010 syspopup_destroy_all();
1013 __bt_agent_release_memory();
1018 void _bt_destroy_agent(void *agent)
1023 _gap_agent_reset_dbus((GapAgentPrivate *)agent);
1028 void* _bt_create_agent(const char *path, gboolean adapter)
1030 GAP_AGENT_FUNC_CB func_cb;
1031 GDBusProxy *adapter_proxy;
1032 GapAgentPrivate *agent;
1034 adapter_proxy = _bt_get_adapter_proxy();
1038 func_cb.pincode_func = __pincode_request;
1039 func_cb.display_func = __display_request;
1040 func_cb.passkey_func = __passkey_request;
1041 func_cb.confirm_func = __confirm_request;
1042 func_cb.authorize_func = __authorize_request;
1043 func_cb.pairing_cancel_func = __pairing_cancel_request;
1044 func_cb.authorization_cancel_func = __authorization_cancel_request;
1046 /* Allocate memory*/
1047 agent = g_new0(GapAgentPrivate, 1);
1049 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
1052 if (!_gap_agent_register(agent)) {
1053 _bt_destroy_agent(agent);
1061 gboolean _bt_agent_register_osp_server(const gint type,
1062 const char *uuid, char *path, int fd)
1064 void *agent = _bt_get_adapter_agent();
1068 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
1072 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
1074 void *agent = _bt_get_adapter_agent();
1079 return _gap_agent_unregister_osp_server(agent, type, uuid);
1082 gboolean _bt_agent_reply_authorize(gboolean accept)
1086 void *agent = _bt_get_adapter_agent();
1090 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
1092 return gap_agent_reply_authorize(agent, accept_val, NULL);
1095 gboolean _bt_agent_is_canceled(void)
1097 void *agent = _bt_get_adapter_agent();
1101 return _gap_agent_is_canceled(agent);
1104 void _bt_agent_set_canceled(gboolean value)
1106 void *agent = _bt_get_adapter_agent();
1110 return _gap_agent_set_canceled(agent, value);
1113 int _bt_agent_reply_cancellation(void)
1115 void *agent = _bt_get_adapter_agent();
1118 return BLUETOOTH_ERROR_INTERNAL;
1120 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
1121 BT_ERR("Fail to reply agent");
1122 return BLUETOOTH_ERROR_INTERNAL;
1125 return BLUETOOTH_ERROR_NONE;
1128 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1130 switch ((dev_class & 0x1f00) >> 8) {
1132 switch ((dev_class & 0xc0) >> 6) {
1134 /* input-keyboard" */
1143 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1144 const char *address)
1149 pch = strtok_r(buffer, "= ,", &last);
1154 while ((pch = strtok_r(NULL, ",", &last))) {
1155 if (0 == g_strcmp0(pch, address)) {
1156 BT_DBG("Match found\n");
1163 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1164 const char *partial_name)
1169 pch = strtok_r(buffer, "= ,", &last);
1174 while ((pch = strtok_r(NULL, ",", &last))) {
1175 if (g_str_has_prefix(partial_name, pch)) {
1176 BT_DBG("Match found\n");
1183 static gboolean __bt_agent_is_device_blacklist(const char *address,
1195 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1198 BT_ERR("Unable to open blacklist file");
1202 fseek(fp, 0, SEEK_END);
1205 BT_DBG("size is not a positive number");
1212 buffer = g_malloc0(sizeof(char) * size);
1213 /* Fix : NULL_RETURNS */
1214 if (buffer == NULL) {
1215 BT_ERR("Fail to allocate memory");
1219 result = fread((char *)buffer, 1, size, fp);
1221 if (result != size) {
1222 BT_ERR("Read Error");
1227 BT_DBG("Buffer = %s", buffer);
1229 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1232 if (lines == NULL) {
1233 BT_ERR("No lines in the file");
1237 for (i = 0; lines[i] != NULL; i++) {
1238 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1239 if (__bt_agent_find_device_by_address_exactname(
1242 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1243 if (__bt_agent_find_device_by_address_exactname(
1246 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1247 if (__bt_agent_find_device_by_partial_name(lines[i],
1250 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1251 if (__bt_agent_find_device_by_address_exactname(
1259 BT_DBG("Found the device");
1264 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1265 const gchar *address, const gchar *name)
1267 gboolean is_headset = FALSE;
1268 gboolean is_mouse = FALSE;
1269 char lap_address[BT_LOWER_ADDRESS_LENGTH];
1271 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1273 if (address == NULL)
1276 switch ((dev_class & 0x1f00) >> 8) {
1278 switch ((dev_class & 0xfc) >> 2) {
1288 case 0x0b: /* VCR */
1289 case 0x0c: /* Video Camera */
1290 case 0x0d: /* Camcorder */
1293 /* Other audio device */
1299 switch (dev_class & 0xff) {
1300 case 0x80: /* 0x80: Pointing device(Mouse) */
1304 case 0x40: /* 0x40: input device (BT keyboard) */
1306 /* Get the LAP(Lower Address part) */
1307 g_strlcpy(lap_address, address, sizeof(lap_address));
1309 /* Need to Auto pair the blacklisted Keyboard */
1310 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1311 BT_DBG("Device is not black listed\n");
1314 BT_ERR("Device is black listed\n");
1320 if ((!is_headset) && (!is_mouse))
1323 /* Get the LAP(Lower Address part) */
1324 g_strlcpy(lap_address, address, sizeof(lap_address));
1326 BT_DBG("Device address = %s\n", address);
1327 BT_DBG("Address 3 byte = %s\n", lap_address);
1329 if (__bt_agent_is_device_blacklist(lap_address, name)) {
1330 BT_ERR("Device is black listed\n");
1337 static int __bt_agent_generate_passkey(char *passkey, int size)
1342 unsigned int value = 0;
1344 if (passkey == NULL)
1350 random_fd = open("/dev/urandom", O_RDONLY);
1355 for (i = 0; i < size; i++) {
1356 len = read(random_fd, &value, sizeof(value));
1358 passkey[i] = '0' + (value % 10);
1363 BT_DBG("passkey: %s", passkey);