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