Merge the code from tizen_2.4
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-agent.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
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
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
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.
21  *
22  */
23
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <malloc.h>
28 #include <stacktrim.h>
29
30 #if defined(LIBNOTIFY_SUPPORT)
31 #include "bt-popup.h"
32 #elif defined(LIBNOTIFICATION_SUPPORT)
33 #include "bt-service-agent-notification.h"
34 #else
35 #include <syspopup_caller.h>
36 #endif
37
38 #include <vconf.h>
39 #include <bundle_internal.h>
40
41 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
42 #include <tethering.h>
43 #endif
44
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"
54
55 #define BT_APP_AUTHENTICATION_TIMEOUT           35
56 #define BT_APP_AUTHORIZATION_TIMEOUT            15
57
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"
73
74 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
75
76 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
77
78 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
79 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
80
81 #define BT_PIN_MAX_LENGTH 16
82 #define BT_PASSKEY_MAX_LENGTH 4
83
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;
88
89 #define G_VARIANT_UNREF(variant) \
90         g_variant_unref(variant); \
91         variant = NULL
92
93 static gboolean syspopup_mode = TRUE;
94
95 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
96                                                         const gchar *name);
97 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
98 static int __bt_agent_generate_passkey(char *passkey, int size);
99
100 static void __bt_agent_release_memory(void)
101 {
102         /* Release Malloc Memory*/
103         malloc_trim(0);
104
105         /* Release Stack Memory*/
106         stack_trim();
107 }
108
109 static gboolean __bt_agent_system_popup_timer_cb(gpointer user_data)
110 {
111         int ret;
112         static int retry_count;
113         bundle *b = (bundle *)user_data;
114         retv_if(user_data == NULL, FALSE);
115
116         ++retry_count;
117 #if defined(LIBNOTIFY_SUPPORT)
118         ret = notify_launch(b);
119 #elif defined(LIBNOTIFICATION_SUPPORT)
120         ret = notification_launch(b);
121 #else
122         ret = syspopup_launch("bt-syspopup", b);
123 #endif
124         if (ret < 0) {
125                 BT_ERR("Sorry! Can't launch popup, ret=%d, Re-try[%d] time..",
126                                                         ret, retry_count);
127                 if (retry_count >= BT_AGENT_SYSPOPUP_MAX_ATTEMPT) {
128                         BT_ERR("Sorry!! Max retry %d reached", retry_count);
129                         bundle_free(b);
130                         retry_count = 0;
131                         return FALSE;
132                 }
133         } else {
134                 BT_DBG("Hurray!! Finally Popup launched");
135                 retry_count = 0;
136                 bundle_free(b);
137         }
138
139         return (ret < 0) ? TRUE : FALSE;
140 }
141
142 #ifdef TIZEN_WEARABLE
143 static void __bt_unbond_cb(GDBusProxy *proxy,
144                 GAsyncResult *res, gpointer user_data)
145 {
146         GError *err = NULL;
147         GVariant *value;
148
149         value = g_dbus_proxy_call_finish(proxy, res, &err);
150         if (value == NULL) {
151                 BT_ERR("Error: Unbond Failed");
152                 if (err) {
153                         BT_ERR("errCode[%x], message[%s]\n", err->code, err->message);
154                         g_clear_error(&err);
155                 }
156                 return;
157         }
158         g_variant_unref(value);
159         BT_INFO("Unbonding is done");
160         return;
161 }
162
163 static gboolean __bt_unpair_device(void)
164 {
165         GArray *device_list;
166         int no_of_device;
167         int i;
168
169         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
170         if (device_list == NULL) {
171                 BT_ERR("g_array_new is failed");
172                 return FALSE;
173         }
174
175         if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
176                 BT_ERR("_bt_get_bonded_devices is failed");
177                 g_array_free(device_list, TRUE);
178                 return FALSE;
179         }
180
181         no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
182         for (i = 0; i < no_of_device; i++) {
183                 GDBusProxy *adapter_proxy;
184                 bluetooth_device_info_t info;
185                 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
186                 char *device_path = NULL;
187
188                 info = g_array_index(device_list, bluetooth_device_info_t, i);
189                 if (info.device_class.major_class ==
190                                 BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO)
191                         continue;
192
193                 adapter_proxy = _bt_get_adapter_proxy();
194                 if (!adapter_proxy) {
195                         BT_ERR("adapter_proxy is NULL");
196                         g_array_free(device_list, TRUE);
197                         return FALSE;
198                 }
199
200                 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
201                 device_path = _bt_get_device_object_path(addr);
202                 if (device_path == NULL) {
203                         BT_ERR("device_path is NULL");
204                         g_array_free(device_list, TRUE);
205                         return FALSE;
206                 }
207
208                 g_dbus_proxy_call(adapter_proxy,
209                                 "UnpairDevice", g_variant_new("o", device_path),
210                                 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
211                                 (GAsyncReadyCallback)__bt_unbond_cb, NULL);
212
213                 BT_INFO("unbonding %s is requested", addr);
214
215                 g_array_free(device_list, TRUE);
216                 return TRUE;
217         }
218
219         g_array_free(device_list, TRUE);
220         return FALSE;
221 }
222
223 static void __bt_popup_event_filter(GDBusConnection *connection,
224                 const gchar *sender_name,
225                 const gchar *object_path,
226                 const gchar *interface_name,
227                 const gchar *signal_name,
228                 GVariant *parameters,
229                 gpointer user_data)
230 {
231         BT_DBG("Sender Name[%s] Object Path[%s] Interface[%s] Signal[%s]",
232                         sender_name, object_path, interface_name, signal_name);
233
234         if (g_strcmp0(interface_name, "User.Bluetooth.syspopup") == 0 &&
235                         g_strcmp0(signal_name, "ResetResponse") == 0) {
236                 int response;
237
238                 g_variant_get(parameters, "(i)", &response);
239                 BT_DBG("response = %d", response);
240         }
241 }
242
243 int __bt_service_subscribe_popup(GDBusConnection *conn,
244                 gboolean subscribe)
245 {
246         static guint subs_interface_added_id = 0;
247
248         if (conn == NULL)
249                 return BLUETOOTH_ERROR_INVALID_PARAM;
250
251         if (subscribe) {
252                 if (subs_interface_added_id == 0) {
253                         subs_interface_added_id = g_dbus_connection_signal_subscribe(conn,
254                                         NULL, "User.Bluetooth.syspopup", "ResetResponse", NULL, NULL, 0,
255                                         __bt_popup_event_filter, NULL, NULL);
256                 }
257         } else {
258                 if (subs_interface_added_id > 0) {
259                         g_dbus_connection_signal_unsubscribe(conn,
260                                         subs_interface_added_id);
261                         subs_interface_added_id = 0;
262                 }
263         }
264         return BLUETOOTH_ERROR_NONE;
265 }
266
267 static void  __bt_register_popup_event_signal(void)
268 {
269         GDBusConnection *conn;
270
271         BT_DBG("+\n");
272
273         conn = _bt_get_system_gconn();
274         if (conn == NULL)
275                 return;
276
277         __bt_service_subscribe_popup(conn, TRUE);
278
279         BT_DBG("-\n");
280         return;
281 }
282
283 static gboolean __is_reset_required(const gchar *address)
284 {
285         GArray *device_list;
286         uint32_t no_of_device;
287         uint32_t i;
288         bluetooth_device_info_t info;
289         gboolean is_required = FALSE;
290
291         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
292         if (device_list == NULL) {
293                 BT_ERR("g_array_new is failed");
294                 return FALSE;
295         }
296
297         if (_bt_get_bonded_devices(&device_list) != BLUETOOTH_ERROR_NONE) {
298                 BT_ERR("_bt_get_bonded_devices is failed");
299                 g_array_free(device_list, TRUE);
300                 return FALSE;
301         }
302
303         no_of_device = device_list->len / sizeof(bluetooth_device_info_t);
304         for (i = 0; i < no_of_device; i++) {
305                 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
306
307                 info = g_array_index(device_list, bluetooth_device_info_t, i);
308
309                 _bt_convert_addr_type_to_string(addr, info.device_address.addr);
310                 if (g_strcmp0(address, addr) == 0) {
311                         BT_DBG("This device is already in paired list");
312                         is_required = FALSE;
313                         break;
314                 }
315
316                 if (info.device_class.major_class != BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
317                         is_required = TRUE;
318                         break;
319                 }
320         }
321         g_array_free(device_list, TRUE);
322
323         return is_required;
324 }
325 #endif
326
327 int _bt_launch_system_popup(bt_agent_event_type_t event_type,
328                                                         const char *device_name,
329                                                         char *passkey,
330                                                         const char *filename,
331                                                         const char *agent_path)
332 {
333         int ret;
334         bundle *b;
335         char event_str[BT_MAX_EVENT_STR_LENGTH + 1];
336
337         b = bundle_create();
338         if (!b) {
339                 BT_ERR("Launching system popup failed");
340                 return -1;
341         }
342
343         bundle_add(b, "device-name", device_name);
344         bundle_add(b, "passkey", passkey);
345         bundle_add(b, "file", filename);
346         bundle_add(b, "agent-path", agent_path);
347
348         switch (event_type) {
349         case BT_AGENT_EVENT_PIN_REQUEST:
350                 g_strlcpy(event_str, "pin-request", sizeof(event_str));
351                 break;
352
353         case BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST:
354                 g_strlcpy(event_str, "passkey-confirm-request",
355                                                 sizeof(event_str));
356                 break;
357
358         case BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED:
359                 g_strlcpy(event_str, "passkey-auto-accepted",
360                                                 sizeof(event_str));
361                 break;
362
363         case BT_AGENT_EVENT_PASSKEY_REQUEST:
364                 g_strlcpy(event_str, "passkey-request", sizeof(event_str));
365                 break;
366
367         case BT_AGENT_EVENT_PASSKEY_DISPLAY_REQUEST:
368                 g_strlcpy(event_str, "passkey-display-request",
369                                                 sizeof(event_str));
370                 break;
371
372         case BT_AGENT_EVENT_AUTHORIZE_REQUEST:
373                 g_strlcpy(event_str, "authorize-request",
374                                                 sizeof(event_str));
375                 break;
376
377         case BT_AGENT_EVENT_CONFIRM_MODE_REQUEST:
378                 g_strlcpy(event_str, "confirm-mode-request",
379                                                 sizeof(event_str));
380                 break;
381
382         case BT_AGENT_EVENT_FILE_RECEIVED:
383                 g_strlcpy(event_str, "file-received", sizeof(event_str));
384                 break;
385
386         case BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST:
387                 g_strlcpy(event_str, "keyboard-passkey-request",
388                                                 sizeof(event_str));
389                 break;
390
391         case BT_AGENT_EVENT_TERMINATE:
392                 g_strlcpy(event_str, "terminate", sizeof(event_str));
393                 break;
394
395         case BT_AGENT_EVENT_EXCHANGE_REQUEST:
396                 g_strlcpy(event_str, "exchange-request", sizeof(event_str));
397                 break;
398
399         case BT_AGENT_EVENT_PBAP_REQUEST:
400                 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
401                 break;
402
403         case BT_AGENT_EVENT_MAP_REQUEST:
404                 g_strlcpy(event_str, "message-request", sizeof(event_str));
405                 break;
406
407 #ifdef TIZEN_WEARABLE
408         case BT_AGENT_EVENT_SYSTEM_RESET_REQUEST:
409                 __bt_register_popup_event_signal();
410                 g_strlcpy(event_str, "system-reset-request", sizeof(event_str));
411                 break;
412 #endif
413
414         case BT_AGENT_EVENT_LEGACY_PAIR_FAILED_FROM_REMOTE:
415                 g_strlcpy(event_str, "remote-legacy-pair-failed", sizeof(event_str));
416                 break;
417
418         default:
419                 BT_ERR("Invalid event type");
420                 bundle_free(b);
421                 return -1;
422
423         }
424
425         bundle_add(b, "event-type", event_str);
426
427 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
428         ret = syspopup_launch("bt-syspopup", b);
429 #endif
430         if (0 > ret) {
431                 BT_ERR("Popup launch failed...retry %d", ret);
432
433                 g_timeout_add(BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS,
434                               (GSourceFunc)__bt_agent_system_popup_timer_cb, b);
435         } else {
436                 bundle_free(b);
437         }
438
439         BT_INFO("_bt_agent_launch_system_popup");
440         return 0;
441 }
442
443 static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
444 {
445         GError *error = NULL;
446         GVariant *reply;
447
448         reply = g_dbus_proxy_call_sync(device,
449                         "GetAll", g_variant_new("(s)", interface),
450                         G_DBUS_CALL_FLAGS_NONE, -1,
451                         NULL, &error);
452         if (reply == NULL) {
453                 ERR("GetAll dBUS-RPC failed");
454                 if (error) {
455                         ERR("D-Bus API failure: errCode[%x], message[%s]",
456                                 error->code, error->message);
457                         g_clear_error(&error);
458                 }
459                 return NULL;
460         }
461
462         return reply;
463 }
464
465 static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
466 {
467         uint32_t device_class;
468         const gchar *address;
469         const gchar *name;
470         GVariant *reply = NULL;
471         GVariant *reply_temp = NULL;
472         GVariant *tmp_value;
473         GVariant *param;
474         int result = BLUETOOTH_ERROR_NONE;
475
476         BT_DBG("+");
477
478         reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
479
480         if (reply_temp == NULL) {
481                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
482                                 NULL);
483                 goto done;
484         }
485
486         g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
487
488         tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
489         g_variant_get(tmp_value, "u", &device_class);
490         G_VARIANT_UNREF(tmp_value);
491
492         tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
493         g_variant_get(tmp_value, "s", &address);
494         G_VARIANT_UNREF(tmp_value);
495         if (!address) {
496                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
497                 goto done;
498         }
499
500         tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
501         g_variant_get(tmp_value, "s", &name);
502         G_VARIANT_UNREF(tmp_value);
503         if (!name)
504                 name = address;
505
506         if (_bt_is_device_creating() == TRUE &&
507                 _bt_is_bonding_device_address(address) == TRUE &&
508                 __bt_agent_is_auto_response(device_class, address, name)) {
509                 BT_DBG("0000 Auto Pair");
510                 /* Use Fixed PIN "0000" for basic pairing */
511                 _bt_set_autopair_status_in_bonding_info(TRUE);
512                 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
513                                                                         NULL);
514         } else if (__bt_agent_is_hid_keyboard(device_class)) {
515                 BT_DBG("HID Keyboard");
516                 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
517
518                 if (__bt_agent_generate_passkey(str_passkey,
519                                         BT_PASSKEY_MAX_LENGTH) != 0) {
520                         gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
521                                                 "", NULL);
522                         goto done;
523                 }
524
525                 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
526                                                         str_passkey, NULL);
527
528 #ifdef AUTO_ACCEPT
529                 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
530                                                                                         NULL);
531 #else
532                 if (syspopup_mode) {
533                         BT_DBG("LAUNCH SYSPOPUP");
534                         _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
535                                         name, str_passkey, NULL,
536                                         _gap_agent_get_path(agent));
537                 } else {
538                         BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
539                         param = g_variant_new("(isss)", result, address, name, str_passkey);
540                         _bt_send_event(BT_ADAPTER_EVENT,
541                                         BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
542                 }
543 #endif
544         } else {
545                 BT_DBG("Show Pin entry");
546
547                 if (syspopup_mode) {
548                         BT_DBG("LAUNCH SYSPOPUP");
549                         _bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, NULL,
550                                         NULL, _gap_agent_get_path(agent));
551                 } else {
552                         BT_DBG("Send BLUETOOTH_EVENT_PIN_REQUEST");
553                         param = g_variant_new("(iss)", result, address, name);
554                         _bt_send_event(BT_ADAPTER_EVENT,
555                                         BLUETOOTH_EVENT_PIN_REQUEST, param);
556                 }
557         }
558
559 done:
560         g_variant_unref(reply);
561         g_variant_unref(reply_temp);
562         __bt_agent_release_memory();
563         BT_DBG("-");
564
565         return TRUE;
566 }
567
568 static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
569 {
570         const gchar *address;
571         const gchar *name;
572         GVariant *reply = NULL;
573         GVariant *reply_temp = NULL;
574         GVariant *tmp_value;
575         BT_DBG("+");
576
577         reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
578
579         if (reply_temp == NULL) {
580                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
581                                              NULL);
582                 goto done;
583         }
584
585         g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
586
587         tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
588         g_variant_get(tmp_value, "s", &address);
589         G_VARIANT_UNREF(tmp_value);
590         if (!address) {
591                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
592                 goto done;
593         }
594
595         tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
596         g_variant_get(tmp_value, "s", &name);
597         G_VARIANT_UNREF(tmp_value);
598         if (!name)
599                 name = address;
600
601 #ifdef AUTO_ACCEPT
602         gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
603                                                                                 NULL);
604 #else
605         if (syspopup_mode) {
606                 BT_DBG("LAUNCH SYSPOPUP");
607                 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, NULL, NULL,
608                                         _gap_agent_get_path(agent));
609         } else {
610                 int result = BLUETOOTH_ERROR_NONE;
611                 GVariant *param;
612
613                 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_REQUEST");
614                 param = g_variant_new("(iss)", result, address, name);
615                 _bt_send_event(BT_ADAPTER_EVENT,
616                                 BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
617         }
618 #endif
619
620 done:
621         g_variant_unref(reply);
622         g_variant_unref(reply_temp);
623         __bt_agent_release_memory();
624
625         BT_DBG("-");
626         return TRUE;
627 }
628
629 static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
630                                                                 guint passkey)
631 {
632         const gchar *address;
633         const gchar *name;
634         char *str_passkey;
635         GVariant *reply = NULL;
636         GVariant *reply_temp = NULL;
637         GVariant *tmp_value = NULL;
638
639         BT_DBG("+");
640
641         reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
642         if (reply_temp == NULL) {
643                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
644                                              NULL);
645                 goto done;
646         }
647
648         g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
649
650         tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
651         g_variant_get(tmp_value, "s", &address);
652         G_VARIANT_UNREF(tmp_value);
653         if (!address) {
654                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
655                 goto done;
656         }
657
658         tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
659         g_variant_get(tmp_value, "s", &name);
660         G_VARIANT_UNREF(tmp_value);
661         if (!name)
662                 name = address;
663
664         str_passkey = g_strdup_printf("%d", passkey);
665
666 #ifdef AUTO_ACCEPT
667         gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, str_passkey,
668                                                                                 NULL);
669 #else
670         if (syspopup_mode) {
671                 BT_DBG("LAUNCH SYSPOPUP");
672                 _bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
673                                 str_passkey, NULL,
674                                 _gap_agent_get_path(agent));
675         } else {
676                 int result = BLUETOOTH_ERROR_NONE;
677                 GVariant *param;
678
679                 BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
680                 param = g_variant_new("(isss)", result, address, name, str_passkey);
681                 _bt_send_event(BT_ADAPTER_EVENT,
682                                 BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
683         }
684
685 #endif
686         g_free(str_passkey);
687
688 done:
689         g_variant_unref(reply);
690         g_variant_unref(reply_temp);
691         __bt_agent_release_memory();
692
693         BT_DBG("-");
694         return TRUE;
695 }
696
697 static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
698                                                                 guint passkey)
699 {
700         const gchar *address;
701         const gchar *name;
702         char str_passkey[7];
703         GVariant *reply_temp = NULL;
704         GVariant *reply = NULL;
705         GVariant *tmp_value;
706         BT_DBG("+ passkey[%.6d]", passkey);
707
708         snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
709
710         reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
711
712         if (reply_temp == NULL) {
713                 BT_ERR("Device doesn't exist");
714                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
715                                              NULL);
716                 goto done;
717         }
718
719         g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
720
721         tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
722         g_variant_get(tmp_value, "s", &address);
723         G_VARIANT_UNREF(tmp_value);
724         if (!address) {
725                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
726                 goto done;
727         }
728
729         tmp_value = g_variant_lookup_value (reply, "Name", G_VARIANT_TYPE_STRING);
730         g_variant_get(tmp_value, "s", &name);
731         G_VARIANT_UNREF(tmp_value);
732         if (!name)
733                 name = address;
734
735 #ifdef TIZEN_WEARABLE
736         uint32_t device_class = 0x00;
737         uint32_t major_class;
738
739         tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
740         g_variant_get(tmp_value, "u", &device_class);
741         G_VARIANT_UNREF(tmp_value);
742
743         major_class = (device_class & 0x1f00) >> 8;
744
745         if (major_class == BLUETOOTH_DEVICE_MAJOR_CLASS_AUDIO) {
746                 BT_DBG("Audio device. Launch passkey pop-up");
747                 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
748                                 str_passkey, NULL, _gap_agent_get_path(agent));
749                 goto done;
750         }
751
752         if (__is_reset_required(address)) {
753                 BT_INFO("Launch system reset pop-up");
754                 _bt_launch_system_popup(BT_AGENT_EVENT_SYSTEM_RESET_REQUEST, name,
755                                 NULL, NULL, _gap_agent_get_path(agent));
756         } else {
757                 BT_INFO("Launch passkey pop-up");
758                 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_AUTO_ACCEPTED, name,
759                                 str_passkey, NULL, _gap_agent_get_path(agent));
760
761                 gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
762         }
763 #else
764 #ifdef AUTO_ACCEPT
765         BT_DBG("Confirm reply");
766         gap_agent_reply_confirmation(agent, GAP_AGENT_ACCEPT, NULL);
767 #else
768         if (syspopup_mode) {
769                 BT_DBG("LAUNCH SYSPOPUP");
770                 _bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
771                                 str_passkey, NULL,
772                                 _gap_agent_get_path(agent));
773         } else {
774                 int result = BLUETOOTH_ERROR_NONE;
775                 GVariant *param;
776
777                 BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST");
778                 param = g_variant_new("(isss)", result, address, name, str_passkey);
779                 _bt_send_event(BT_ADAPTER_EVENT,
780                                 BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
781         }
782 #endif
783 #endif
784
785 done:
786         g_variant_unref(reply);
787         g_variant_unref(reply_temp);
788         __bt_agent_release_memory();
789         BT_DBG("-");
790
791         return TRUE;
792 }
793
794 static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
795 {
796         BT_DBG("On Going Pairing is cancelled by remote\n");
797
798 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
799         syspopup_destroy_all();
800 #endif
801
802         __bt_agent_release_memory();
803
804         return TRUE;
805 }
806
807 static gboolean __a2dp_authorize_request_check(void)
808 {
809         /* Check for existing Media device to disconnect */
810         return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
811 }
812
813 static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
814                                                         const char *uuid)
815 {
816         const gchar *address;
817         const gchar *name;
818         gboolean trust;
819         gboolean paired;
820         GVariant *reply = NULL;
821         GVariant *reply_temp = NULL;
822         GVariant *tmp_value;
823 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
824         bool enabled;
825         tethering_h tethering = NULL;
826 #endif
827         int result = BLUETOOTH_ERROR_NONE;
828         int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
829
830         BT_DBG("+");
831
832 #ifdef AUTO_ACCEPT
833         gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
834                                           NULL);
835         goto done;
836 #endif
837
838         /* Check if already Media connection exsist */
839         if (!strcasecmp(uuid, A2DP_UUID)) {
840                 gboolean ret = FALSE;
841
842                 ret = __a2dp_authorize_request_check();
843
844                 if (ret) {
845                         BT_ERR("Already one A2DP device connected \n");
846                         gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
847                                               NULL);
848                         goto done;
849                 }
850         }
851         /* Check completed */
852
853         if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
854              !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
855              !strcasecmp(uuid, HFP_HS_UUID) ||
856              !strcasecmp(uuid, HSP_HS_UUID) ||
857              !strcasecmp(uuid, A2DP_UUID) ||
858              !strcasecmp(uuid, HID_UUID) ||
859              !strcasecmp(uuid, SAP_UUID_OLD) ||
860              !strcasecmp(uuid, SAP_UUID_NEW) ||
861              !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
862                 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
863                 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
864                                               NULL);
865
866                 goto done;
867         }
868
869         if (!strcasecmp(uuid, NAP_UUID) ||
870              !strcasecmp(uuid, GN_UUID) ||
871               !strcasecmp(uuid, BNEP_UUID)) {
872
873                 BT_DBG("Network connection request: %s", uuid);
874 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
875                 if (nap_connected_device_count >=
876                                         BT_PAN_MAX_CONNECTION) {
877                         BT_ERR("Max connection exceeded");
878                         goto fail;
879                 }
880                 int ret;
881                 ret = tethering_create(&tethering);
882
883                 if (ret != TETHERING_ERROR_NONE) {
884                         BT_ERR("Fail to create tethering: %d", ret);
885                         goto fail;
886                 }
887
888                 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
889
890                 ret = tethering_destroy(tethering);
891
892                 if (ret != TETHERING_ERROR_NONE) {
893                         BT_ERR("Fail to create tethering: %d", ret);
894                 }
895
896                 if (enabled != true) {
897                         BT_ERR("BT tethering is not enabled");
898                         goto fail;
899                 }
900 #endif
901
902                 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
903                                               NULL);
904                 goto done;
905 #ifdef TIZEN_NETWORK_TETHERING_ENABLE
906 fail:
907                 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
908                       NULL);
909
910                 goto done;
911 #endif
912         }
913
914         reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
915         if (reply_temp == NULL) {
916                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
917                                              NULL);
918                 goto done;
919         }
920
921         g_variant_get(reply_temp,"(@a{sv})", &reply); /* Format of reply a{sv}*/
922
923         tmp_value = g_variant_lookup_value (reply, "Address", G_VARIANT_TYPE_STRING);
924         g_variant_get(tmp_value, "s", &address);
925         G_VARIANT_UNREF(tmp_value);
926         if (!address) {
927                 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
928                 goto done;
929         }
930
931         tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
932         g_variant_get(tmp_value, "s", &name);
933         G_VARIANT_UNREF(tmp_value);
934         if (!name)
935                 name = address;
936
937         tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
938         g_variant_get(tmp_value, "b", &trust);
939         G_VARIANT_UNREF(tmp_value);
940
941         tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
942         g_variant_get(tmp_value, "b", &paired);
943         G_VARIANT_UNREF(tmp_value);
944         if ((paired == FALSE) && (trust == FALSE)) {
945                 BT_ERR("No paired & No trusted device");
946                 gap_agent_reply_authorize(agent,
947                                 GAP_AGENT_REJECT, NULL);
948                 goto done;
949         }
950
951         BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
952
953         if (strcasecmp(uuid, OPP_UUID) == 0 &&
954              _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
955                                         NULL) == TRUE) {
956                 _bt_send_event(BT_OPP_SERVER_EVENT,
957                                 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
958                                 g_variant_new("(iss)", result, address, name));
959
960                 goto done;
961         }
962
963         if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
964                                         (char *)uuid) == TRUE) {
965                 bt_agent_osp_server_t *osp_serv;
966                 osp_serv = _gap_agent_get_osp_server(agent,
967                                                 BT_RFCOMM_SERVER, (char *)uuid);
968
969                 if (osp_serv) {
970                         _bt_send_event(BT_RFCOMM_SERVER_EVENT,
971                                 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
972                                 g_variant_new("(issssn)", result, address, uuid,
973                                                 name, osp_serv->path, osp_serv->fd));
974                 }
975
976                 goto done;
977         }
978
979         if (!strcasecmp(uuid, OPP_UUID))
980                 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
981         else if (!strcasecmp(uuid, PBAP_UUID))
982                 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
983         else if (!strcasecmp(uuid, MAP_UUID))
984                 request_type = BT_AGENT_EVENT_MAP_REQUEST;
985
986         if (trust) {
987                 BT_INFO("Trusted device, so authorize\n");
988                 gap_agent_reply_authorize(agent,
989                                               GAP_AGENT_ACCEPT, NULL);
990         } else {
991 #ifdef AUTO_ACCEPT
992                 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL);
993 #else
994                 _bt_launch_system_popup(request_type, name, NULL, NULL,
995                                                 _gap_agent_get_path(agent));
996 #endif
997         }
998
999 done:
1000         g_variant_unref(reply);
1001         g_variant_unref(reply_temp);
1002         __bt_agent_release_memory();
1003         BT_DBG("-");
1004
1005         return TRUE;
1006 }
1007
1008 static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
1009                                                         const char *address)
1010 {
1011         BT_DBG("On Going Authorization is cancelled by remote\n");
1012
1013         gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
1014
1015 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
1016         syspopup_destroy_all();
1017 #endif
1018
1019         __bt_agent_release_memory();
1020
1021         return TRUE;
1022 }
1023
1024 void _bt_destroy_agent(void *agent)
1025 {
1026         if (!agent)
1027                 return;
1028
1029         _gap_agent_reset_dbus((GapAgentPrivate *)agent);
1030
1031         g_free(agent);
1032 }
1033
1034 void* _bt_create_agent(const char *path, gboolean adapter)
1035 {
1036         GAP_AGENT_FUNC_CB func_cb;
1037         GDBusProxy *adapter_proxy;
1038         GapAgentPrivate *agent;
1039
1040         adapter_proxy = _bt_get_adapter_proxy();
1041         if (!adapter_proxy)
1042                 return NULL;
1043
1044         func_cb.pincode_func = __pincode_request;
1045         func_cb.display_func = __display_request;
1046         func_cb.passkey_func = __passkey_request;
1047         func_cb.confirm_func = __confirm_request;
1048         func_cb.authorize_func = __authorize_request;
1049         func_cb.pairing_cancel_func = __pairing_cancel_request;
1050         func_cb.authorization_cancel_func = __authorization_cancel_request;
1051
1052         /* Allocate memory*/
1053         agent = g_new0(GapAgentPrivate, 1);
1054
1055         _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
1056
1057         if (adapter) {
1058                 if (!_gap_agent_register(agent)) {
1059                         _bt_destroy_agent(agent);
1060                         agent = NULL;
1061                 }
1062         }
1063
1064         return agent;
1065 }
1066
1067 gboolean _bt_agent_register_osp_server(const gint type,
1068                 const char *uuid, char *path, int fd)
1069 {
1070         void *agent = _bt_get_adapter_agent();
1071         if (!agent)
1072                 return FALSE;
1073
1074         return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
1075
1076 }
1077
1078 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
1079 {
1080         void *agent = _bt_get_adapter_agent();
1081
1082         if (!agent)
1083                 return FALSE;
1084
1085         return _gap_agent_unregister_osp_server(agent, type, uuid);
1086 }
1087
1088 gboolean _bt_agent_reply_authorize(gboolean accept)
1089 {
1090         guint accept_val;
1091
1092         void *agent = _bt_get_adapter_agent();
1093         if (!agent)
1094                 return FALSE;
1095
1096         accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
1097
1098         return gap_agent_reply_authorize(agent, accept_val, NULL);
1099 }
1100
1101 gboolean _bt_agent_is_canceled(void)
1102 {
1103         void *agent = _bt_get_adapter_agent();
1104         if (!agent)
1105                 return FALSE;
1106
1107         return _gap_agent_is_canceled(agent);
1108 }
1109
1110 void _bt_agent_set_canceled(gboolean value)
1111 {
1112         void *agent = _bt_get_adapter_agent();
1113         if (!agent)
1114                 return;
1115
1116         return _gap_agent_set_canceled(agent, value);
1117 }
1118
1119 int _bt_agent_reply_cancellation(void)
1120 {
1121         void *agent = _bt_get_adapter_agent();
1122
1123         if (!agent)
1124                 return BLUETOOTH_ERROR_INTERNAL;
1125
1126         if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
1127                 BT_ERR("Fail to reply agent");
1128                 return BLUETOOTH_ERROR_INTERNAL;
1129         }
1130
1131         return BLUETOOTH_ERROR_NONE;
1132 }
1133
1134 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
1135 {
1136         switch ((dev_class & 0x1f00) >> 8) {
1137         case 0x05:
1138                 switch ((dev_class & 0xc0) >> 6) {
1139                 case 0x01:
1140                         /* input-keyboard" */
1141                         return TRUE;
1142                 }
1143                 break;
1144         }
1145
1146         return FALSE;
1147 }
1148
1149 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
1150                                                         const char *address)
1151 {
1152         char *pch;
1153         char *last;
1154
1155         pch = strtok_r(buffer, "= ,", &last);
1156
1157         if (pch == NULL)
1158                 return FALSE;
1159
1160         while ((pch = strtok_r(NULL, ",", &last))) {
1161                 if (0 == g_strcmp0(pch, address)) {
1162                         BT_DBG("Match found\n");
1163                         return TRUE;
1164                 }
1165         }
1166         return FALSE;
1167 }
1168
1169 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
1170                                                 const char *partial_name)
1171 {
1172         char *pch;
1173         char *last;
1174
1175         pch = strtok_r(buffer, "= ,", &last);
1176
1177         if (pch == NULL)
1178                 return FALSE;
1179
1180         while ((pch = strtok_r(NULL, ",", &last))) {
1181                 if (g_str_has_prefix(partial_name, pch)) {
1182                         BT_DBG("Match found\n");
1183                         return TRUE;
1184                 }
1185         }
1186         return FALSE;
1187 }
1188
1189 static gboolean __bt_agent_is_device_blacklist(const char *address,
1190                                                         const char *name)
1191 {
1192         char *buffer;
1193         char **lines;
1194         int i;
1195         FILE *fp;
1196         long size;
1197         size_t result;
1198
1199         BT_DBG("+");
1200
1201         fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
1202
1203         if (fp == NULL) {
1204                 BT_ERR("Unable to open blacklist file");
1205                 return FALSE;
1206         }
1207
1208         fseek(fp, 0, SEEK_END);
1209         size = ftell(fp);
1210         if (size <= 0) {
1211                 BT_DBG("size is not a positive number");
1212                 fclose(fp);
1213                 return FALSE;
1214         }
1215
1216         rewind(fp);
1217
1218         buffer = g_malloc0(sizeof(char) * size);
1219         /* Fix : NULL_RETURNS */
1220         if (buffer == NULL) {
1221                 BT_ERR("Fail to allocate memory");
1222                 fclose(fp);
1223                 return FALSE;
1224         }
1225         result = fread((char *)buffer, 1, size, fp);
1226         fclose(fp);
1227         if (result != size) {
1228                 BT_ERR("Read Error");
1229                 g_free(buffer);
1230                 return FALSE;
1231         }
1232
1233         BT_DBG("Buffer = %s", buffer);
1234
1235         lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
1236         g_free(buffer);
1237
1238         if (lines == NULL) {
1239                 BT_ERR("No lines in the file");
1240                 return FALSE;
1241         }
1242
1243         for (i = 0; lines[i] != NULL; i++) {
1244                 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
1245                         if (__bt_agent_find_device_by_address_exactname(
1246                                                 lines[i], address))
1247                                 goto done;
1248                 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1249                         if (__bt_agent_find_device_by_address_exactname(
1250                                                 lines[i], name))
1251                                 goto done;
1252                 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1253                         if (__bt_agent_find_device_by_partial_name(lines[i],
1254                                                                 name))
1255                                 goto done;
1256                 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1257                         if (__bt_agent_find_device_by_address_exactname(
1258                                                 lines[i], address))
1259                                 goto done;
1260         }
1261         g_strfreev(lines);
1262         BT_DBG("-");
1263         return FALSE;
1264 done:
1265         BT_DBG("Found the device");
1266         g_strfreev(lines);
1267         return TRUE;
1268 }
1269
1270 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
1271                                 const gchar *address, const gchar *name)
1272 {
1273         gboolean is_headset = FALSE;
1274         gboolean is_mouse = FALSE;
1275         char lap_address[BT_LOWER_ADDRESS_LENGTH];
1276
1277         BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
1278
1279         if (address == NULL)
1280                 return FALSE;
1281
1282         switch ((dev_class & 0x1f00) >> 8) {
1283         case 0x04:
1284                 switch ((dev_class & 0xfc) >> 2) {
1285                 case 0x01:
1286                 case 0x02:
1287                         /* Headset */
1288                         is_headset = TRUE;
1289                         break;
1290                 case 0x06:
1291                         /* Headphone */
1292                         is_headset = TRUE;
1293                         break;
1294                 case 0x0b:      /* VCR */
1295                 case 0x0c:      /* Video Camera */
1296                 case 0x0d:      /* Camcorder */
1297                         break;
1298                 default:
1299                         /* Other audio device */
1300                         is_headset = TRUE;
1301                         break;
1302                 }
1303                 break;
1304         case 0x05:
1305                 switch (dev_class & 0xff) {
1306                 case 0x80:  /* 0x80: Pointing device(Mouse) */
1307                         is_mouse = TRUE;
1308                         break;
1309
1310                 case 0x40: /* 0x40: input device (BT keyboard) */
1311
1312                         /* Get the LAP(Lower Address part) */
1313                         g_strlcpy(lap_address, address, sizeof(lap_address));
1314
1315                         /* Need to Auto pair the blacklisted Keyboard */
1316                         if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
1317                                 BT_DBG("Device is not black listed\n");
1318                                 return FALSE;
1319                         } else {
1320                                 BT_ERR("Device is black listed\n");
1321                                 return TRUE;
1322                         }
1323                 }
1324         }
1325
1326         if ((!is_headset) && (!is_mouse))
1327                 return FALSE;
1328
1329         /* Get the LAP(Lower Address part) */
1330         g_strlcpy(lap_address, address, sizeof(lap_address));
1331
1332         BT_DBG("Device address = %s\n", address);
1333         BT_DBG("Address 3 byte = %s\n", lap_address);
1334
1335         if (__bt_agent_is_device_blacklist(lap_address, name)) {
1336                 BT_ERR("Device is black listed\n");
1337                 return FALSE;
1338         }
1339
1340         return TRUE;
1341 }
1342
1343 static int __bt_agent_generate_passkey(char *passkey, int size)
1344 {
1345         int i;
1346         ssize_t len;
1347         int random_fd;
1348         unsigned int value = 0;
1349
1350         if (passkey == NULL)
1351                 return -1;
1352
1353         if (size <= 0)
1354                 return -1;
1355
1356         random_fd = open("/dev/urandom", O_RDONLY);
1357
1358         if (random_fd < 0)
1359                 return -1;
1360
1361         for (i = 0; i < size; i++) {
1362                 len = read(random_fd, &value, sizeof(value));
1363                 if (len > 0)
1364                         passkey[i] = '0' + (value % 10);
1365         }
1366
1367         close(random_fd);
1368
1369         BT_DBG("passkey: %s", passkey);
1370
1371         return 0;
1372 }