Revert "Rollback changes to submit TIZEN:COMMON project"
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-gap-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 <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <vconf.h>
28 #include <vconf-keys.h>
29
30 #include "bt-internal-types.h"
31 #include "bt-service-common.h"
32 #include "bt-service-agent.h"
33 #include "bt-service-gap-agent.h"
34 #include "bt-service-adapter.h"
35 #include "bt-service-device.h"
36
37 static DBusGConnection *connection = NULL;
38
39 typedef enum {
40         GAP_AGENT_EXEC_NO_OPERATION,
41         GAP_AGENT_EXEC_PAIRING,
42         GAP_AGENT_EXEC_AUTHORZATION,
43         GAP_AGENT_EXEC_CONFIRM_MODE,
44 } GapAgentExecType;
45
46 typedef struct _GapAgentPrivate GapAgentPrivate;
47
48 struct _GapAgentPrivate {
49         gchar *busname;
50         gchar *path;
51         DBusGProxy *adapter;
52
53         DBusGProxy *agent_manager;
54
55         DBusGProxy *dbus_proxy;
56
57         GapAgentExecType exec_type;
58         DBusGMethodInvocation *reply_context;
59
60         char pairing_addr[18];
61         char authorize_addr[18];
62
63         GSList *osp_servers;
64
65         GAP_AGENT_FUNC_CB cb;
66         gboolean canceled;
67 };
68
69 G_DEFINE_TYPE(GapAgent, gap_agent, G_TYPE_OBJECT);
70
71 static gboolean gap_agent_request_pin_code(GapAgent *agent,
72                                                 const char *path,
73                                                 DBusGMethodInvocation *context);
74
75 static gboolean gap_agent_request_passkey(GapAgent *agent, const char *path,
76                                                 DBusGMethodInvocation *context);
77
78 static gboolean gap_agent_display_passkey(GapAgent *agent, const char *path,
79                                                 guint passkey, guint16 entered,
80                                                 DBusGMethodInvocation *context);
81
82 static gboolean gap_agent_request_confirmation(GapAgent *agent,
83                                                 const char *path,
84                                                 guint passkey,
85                                                 DBusGMethodInvocation *context);
86
87 static gboolean gap_agent_authorize_service(GapAgent *agent, const char *path,
88                                                 const char *uuid,
89                                                 DBusGMethodInvocation *context);
90
91 static gboolean gap_agent_request_authorization(GapAgent *agent,
92                                                 const char *path,
93                                                 DBusGMethodInvocation *context);
94
95 static gboolean gap_agent_cancel(GapAgent *agent,
96                                                 DBusGMethodInvocation *context);
97
98 static gboolean gap_agent_release(GapAgent *agent,
99                                                 DBusGMethodInvocation *context);
100
101 static gboolean gap_agent_confirm_mode_change(GapAgent *agent,
102                                                 const char *mode,
103                                                 DBusGMethodInvocation *context);
104
105 static gboolean gap_agent_get_discoverable_timeout(GapAgent *agent,
106                                                 DBusGMethodInvocation *context);
107
108 #include "bt-gap-agent-method.h"
109
110 typedef enum {
111         GAP_AGENT_ERROR_REJECT,
112         GAP_AGENT_ERROR_CANCEL,
113         GAP_AGENT_ERROR_TIMEOUT,
114 } GapAgentError;
115
116 #define GAP_AGENT_ERROR (gap_agent_error_quark())
117
118 static GQuark gap_agent_error_quark(void)
119 {
120         static GQuark quark = 0;
121         if (!quark)
122                 quark = g_quark_from_static_string("agent");
123
124         return quark;
125 }
126
127 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
128
129 static GError *gap_agent_error(GapAgentError error, const char *err_msg)
130 {
131         return g_error_new(GAP_AGENT_ERROR, error, err_msg, NULL);
132 }
133
134 static void gap_agent_init(GapAgent *agent)
135 {
136         BT_DBG("agent %p", agent);
137 }
138
139 static void gap_agent_finalize(GObject *agent)
140 {
141         BT_DBG("Free agent %p", agent);
142
143         G_OBJECT_CLASS(gap_agent_parent_class)->finalize(agent);
144 }
145
146 static void gap_agent_class_init(GapAgentClass *klass)
147 {
148         GObjectClass *object_class = (GObjectClass *) klass;
149         GError *error = NULL;
150
151         BT_DBG("class %p", klass);
152
153         g_type_class_add_private(klass, sizeof(GapAgentPrivate));
154
155         object_class->finalize = gap_agent_finalize;
156
157         connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
158
159         if (error != NULL) {
160                 g_printerr("Connecting to system bus failed: %s",
161                                                                 error->message);
162                 g_error_free(error);
163         }
164
165         dbus_g_object_type_install_info(GAP_TYPE_AGENT,
166                                         &dbus_glib_gap_agent_object_info);
167 }
168
169 GapAgent *_gap_agent_new(void)
170 {
171         GapAgent *agent;
172
173         agent = GAP_GET_AGENT(g_object_new(GAP_TYPE_AGENT, NULL));
174
175         BT_DBG("agent %p", agent);
176
177         return agent;
178 }
179
180 static gboolean gap_agent_request_pin_code(GapAgent *agent,
181                                                 const char *path,
182                                                 DBusGMethodInvocation *context)
183 {
184         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
185         char *sender = dbus_g_method_get_sender(context);
186         DBusGProxy *device;
187         gboolean result;
188         char *addr;
189
190         DBusGConnection *conn;
191
192         if (sender == NULL)
193                 return FALSE;
194
195         BT_INFO("Request pin code, Device Path :%s", path);
196
197         if (g_strcmp0(sender, priv->busname) != 0) {
198                 g_free(sender);
199                 return FALSE;
200         }
201
202         if (!priv->cb.passkey_func) {
203                 g_free(sender);
204                 return FALSE;
205         }
206
207         conn = _bt_get_system_gconn();
208         if (conn == NULL) {
209                 g_free(sender);
210                 return FALSE;
211         }
212
213         device = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
214                                 path, BT_PROPERTIES_INTERFACE);
215         if (device == NULL) {
216                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
217                                                         "No proxy for device");
218                 BT_ERR("Fail to make device proxy");
219                 dbus_g_method_return_error(context, error);
220                 g_error_free(error);
221                 g_free(sender);
222                 return FALSE;
223         }
224
225         priv->exec_type = GAP_AGENT_EXEC_PAIRING;
226         priv->reply_context = context;
227
228         addr = strstr(path, "dev_");
229         if (addr != NULL) {
230                 char *pos = NULL;
231                 addr += 4;
232                 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
233
234                 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
235                         *pos = ':';
236                 }
237         }
238
239         result = priv->cb.pincode_func(agent, device);
240
241         g_object_unref(device);
242
243         g_free(sender);
244         return result;
245 }
246
247 static gboolean gap_agent_request_passkey(GapAgent *agent, const char *path,
248                                                 DBusGMethodInvocation *context)
249 {
250         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
251         char *sender = dbus_g_method_get_sender(context);
252         DBusGProxy *device;
253         gboolean result;
254         char *addr;
255         DBusGConnection *conn;
256
257         if (sender == NULL)
258                 return FALSE;
259
260         BT_INFO("Request passkey : agent %p sender %s priv->busname %s Device Path :%s", agent,
261             sender, priv->busname, path);
262
263         if (g_strcmp0(sender, priv->busname) != 0) {
264                 g_free(sender);
265                 return FALSE;
266         }
267
268         if (!priv->cb.passkey_func) {
269                 g_free(sender);
270                 return FALSE;
271         }
272
273         conn = _bt_get_system_gconn();
274         if (conn == NULL) {
275                 g_free(sender);
276                 return FALSE;
277         }
278
279         device = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
280                                 path, BT_PROPERTIES_INTERFACE);
281
282         if (device == NULL) {
283                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
284                                                         "No proxy for device");
285                 BT_ERR("Fail to make device proxy");
286                 dbus_g_method_return_error(context, error);
287                 g_error_free(error);
288                 g_free(sender);
289                 return FALSE;
290         }
291
292         priv->exec_type = GAP_AGENT_EXEC_PAIRING;
293         priv->reply_context = context;
294
295         addr = strstr(path, "dev_");
296         if (addr != NULL) {
297                 char *pos = NULL;
298                 addr += 4;
299                 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
300
301                 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
302                         *pos = ':';
303                 }
304         }
305
306         result = priv->cb.passkey_func(agent, device);
307
308         g_object_unref(device);
309
310         g_free(sender);
311         return result;
312
313 }
314
315 static gboolean gap_agent_display_passkey(GapAgent *agent, const char *path,
316                                                 guint passkey, guint16 entered,
317                                                 DBusGMethodInvocation *context)
318 {
319         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
320         char *sender = dbus_g_method_get_sender(context);
321         DBusGProxy *device;
322         gboolean result;
323         DBusGConnection *conn;
324
325         if (sender == NULL)
326                 return FALSE;
327
328         /* Do not show popup for Key event while typing*/
329         if (entered) {
330                 g_free(sender);
331                 return FALSE;
332         }
333         BT_INFO("Request passkey display : agent %p sender %s priv->busname %s Device Path :%s\n",
334                         agent, sender, priv->busname, path);
335
336         if (g_strcmp0(sender, priv->busname) != 0) {
337                 g_free(sender);
338                 return FALSE;
339         }
340
341         if (!priv->cb.display_func) {
342                 g_free(sender);
343                 return FALSE;
344         }
345
346         conn = _bt_get_system_gconn();
347         if (conn == NULL) {
348                 g_free(sender);
349                 return FALSE;
350         }
351
352         device = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
353                                 path, BT_PROPERTIES_INTERFACE);
354
355         if (device == NULL) {
356                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
357                                                         "No proxy for device");
358                 BT_ERR("Fail to make device proxy");
359                 dbus_g_method_return_error(context, error);
360                 g_error_free(error);
361                 g_free(sender);
362                 return FALSE;
363         }
364
365         dbus_g_method_return(context);
366
367         result = priv->cb.display_func(agent, device, passkey);
368
369         g_object_unref(device);
370
371         g_free(sender);
372         return result;
373 }
374
375 static gboolean gap_agent_request_confirmation(GapAgent *agent,
376                                                 const char *path,
377                                                 guint passkey,
378                                                 DBusGMethodInvocation *context)
379 {
380         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
381         char *sender = dbus_g_method_get_sender(context);
382         DBusGProxy *device;
383         gboolean result;
384         char *addr;
385         DBusGConnection *conn;
386
387         if (sender == NULL)
388                 return FALSE;
389
390         BT_INFO("Request passkey confirmation, Device Path :%s", path);
391
392         if (g_strcmp0(sender, priv->busname) != 0) {
393                 g_free(sender);
394                 return FALSE;
395         }
396
397         if (!priv->cb.confirm_func) {
398                 g_free(sender);
399                 return FALSE;
400         }
401
402         conn = _bt_get_system_gconn();
403         if (conn == NULL) {
404                 g_free(sender);
405                 return FALSE;
406         }
407
408         device = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
409                                 path, BT_PROPERTIES_INTERFACE);
410         if (device == NULL) {
411                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
412                                                         "No proxy for device");
413                 BT_ERR("Fail to make device proxy");
414                 dbus_g_method_return_error(context, error);
415                 g_error_free(error);
416                 g_free(sender);
417                 return FALSE;
418         }
419
420         priv->exec_type = GAP_AGENT_EXEC_PAIRING;
421         priv->reply_context = context;
422
423         addr = strstr(path, "dev_");
424         if (addr != NULL) {
425                 char *pos = NULL;
426                 addr += 4;
427                 g_strlcpy(priv->pairing_addr, addr, sizeof(priv->pairing_addr));
428
429                 while ((pos = strchr(priv->pairing_addr, '_')) != NULL) {
430                         *pos = ':';
431                 }
432         }
433
434         result = priv->cb.confirm_func(agent, device, passkey);
435
436         g_object_unref(device);
437
438         g_free(sender);
439         return result;
440 }
441
442 static gboolean gap_agent_authorize_service(GapAgent *agent, const char *path,
443                                                 const char *uuid,
444                                                 DBusGMethodInvocation *context)
445 {
446         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
447         char *sender = dbus_g_method_get_sender(context);
448         DBusGProxy *device;
449         DBusGConnection *conn;
450         gboolean result;
451         char *addr;
452
453         if (sender == NULL)
454                 return FALSE;
455
456         BT_DBG("Request authorization : agent %p sender %s priv->busname %s Device Path :%s", agent,
457             sender, priv->busname, path);
458
459         if (g_strcmp0(sender, priv->busname) != 0) {
460                 g_free(sender);
461                 return FALSE;
462         }
463
464         if (!priv->cb.authorize_func) {
465                 g_free(sender);
466                 return FALSE;
467         }
468
469         conn = _bt_get_system_gconn();
470         if (conn == NULL) {
471                 g_free(sender);
472                 return FALSE;
473         }
474
475         device = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
476                                 path, BT_PROPERTIES_INTERFACE);
477
478         if (device == NULL) {
479                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
480                                                         "No proxy for device");
481                 BT_DBG("Fail to make device proxy\n");
482                 dbus_g_method_return_error(context, error);
483                 g_error_free(error);
484                 g_free(sender);
485                 return FALSE;
486         }
487
488         priv->exec_type = GAP_AGENT_EXEC_AUTHORZATION;
489         priv->reply_context = context;
490
491         addr = strstr(path, "dev_");
492         if (addr != NULL) {
493                 char *pos = NULL;
494                 addr += 4;
495                 g_strlcpy(priv->authorize_addr, addr,
496                                                 sizeof(priv->authorize_addr));
497
498                 while ((pos = strchr(priv->authorize_addr, '_')) != NULL) {
499                         *pos = ':';
500                 }
501         }
502
503         result = priv->cb.authorize_func(agent, device, uuid);
504
505         g_object_unref(device);
506
507         g_free(sender);
508         return result;
509 }
510
511 static gboolean gap_agent_request_authorization(GapAgent *agent,
512                                                 const char *path,
513                                                 DBusGMethodInvocation *context)
514 {
515         dbus_g_method_return(context);
516         return TRUE;
517 }
518
519
520 static gboolean gap_agent_confirm_mode_change(GapAgent *agent,
521                                                 const char *mode,
522                                                 DBusGMethodInvocation *context)
523 {
524         BT_DBG("");
525
526         dbus_g_method_return(context);
527         return TRUE;
528 }
529
530 static gboolean gap_agent_cancel(GapAgent *agent,
531                                                 DBusGMethodInvocation *context)
532 {
533         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
534         char *sender = dbus_g_method_get_sender(context);
535         gboolean result = FALSE;
536
537         if (sender == NULL)
538                 return FALSE;
539
540         BT_DBG("Cancelled : agent %p sender %s", agent, sender);
541
542         if (g_strcmp0(sender, priv->busname) != 0) {
543                 g_free(sender);
544                 return FALSE;
545         }
546
547         if (priv->cb.authorization_cancel_func &&
548                         priv->exec_type == GAP_AGENT_EXEC_AUTHORZATION) {
549                 result = priv->cb.authorization_cancel_func(agent,
550                                                         priv->authorize_addr);
551                 memset(priv->authorize_addr, 0x00,
552                                                 sizeof(priv->authorize_addr));
553         } else if (priv->cb.pairing_cancel_func &&
554                                 priv->exec_type == GAP_AGENT_EXEC_PAIRING) {
555                 result = priv->cb.pairing_cancel_func(agent,
556                                                         priv->pairing_addr);
557                 memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
558         }
559
560         if (priv->exec_type != GAP_AGENT_EXEC_CONFIRM_MODE &&
561                         priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
562                                                 priv->reply_context != NULL) {
563                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
564                                                 "Rejected by remote cancel");
565                 dbus_g_method_return_error(priv->reply_context, error);
566                 g_error_free(error);
567         }
568
569         /* Canceled flag is set when user cancels pairing request
570          * Since here bluez has cancelled pairing request, we set the flag to false
571          */
572         priv->canceled = FALSE;
573         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
574         priv->reply_context = NULL;
575
576         g_free(sender);
577         return result;
578 }
579
580 static gboolean gap_agent_release(GapAgent *agent,
581                                                 DBusGMethodInvocation *context)
582 {
583         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
584         char *sender = dbus_g_method_get_sender(context);
585
586         if (sender == NULL)
587                 return FALSE;
588
589         BT_DBG("Released : agent %p sender %s\n", agent, sender);
590
591         if (g_strcmp0(sender, priv->busname) != 0) {
592                 g_free(sender);
593                 return FALSE;
594         }
595
596         dbus_g_method_return(context);
597
598         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
599         priv->reply_context = NULL;
600
601         memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
602         memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
603
604         g_free(sender);
605         return TRUE;
606 }
607
608 static bt_agent_osp_server_t *__gap_agent_find_server(GSList *servers,
609                                                         int type,
610                                                         const char *uuid)
611 {
612         GSList *l;
613         bt_agent_osp_server_t *transfer;
614
615         for (l = servers; l != NULL; l = l->next) {
616                 transfer = l->data;
617
618                 if (transfer == NULL)
619                         continue;
620
621                 /* No uuid in obex server */
622                 if (type == BT_OBEX_SERVER &&
623                         transfer->type == BT_OBEX_SERVER)
624                         return transfer;
625
626                 if (g_strcmp0(transfer->uuid, uuid) == 0)
627                         return transfer;
628         }
629
630         return NULL;
631 }
632
633 static void __gap_agent_remove_osp_servers(GSList *osp_servers)
634 {
635         GSList *l;
636         bt_agent_osp_server_t *server;
637
638         for (l = osp_servers; l != NULL; l = g_slist_next(l)) {
639                 server = l->data;
640
641                 if (server == NULL)
642                         continue;
643
644                 g_free(server->uuid);
645                 g_free(server);
646         }
647 }
648
649 gboolean _gap_agent_register_osp_server(GapAgent *agent,
650                                         const gint type,
651                                         const char *uuid,
652                                         const char *path,
653                                         int fd)
654 {
655         bt_agent_osp_server_t *server;
656
657         BT_DBG("+");
658
659         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
660
661         if (priv == NULL)
662                 return FALSE;
663
664         /* type:  BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
665         if (type > BT_RFCOMM_SERVER)
666                 return FALSE;
667
668         server = g_malloc0(sizeof(bt_agent_osp_server_t));
669
670         server->type = type;
671         if (type == BT_RFCOMM_SERVER) {
672                 server->uuid = g_strdup(uuid);
673                 server->path = g_strdup(path);
674                 server->fd = fd;
675         }
676
677         priv->osp_servers = g_slist_append(priv->osp_servers, server);
678
679         BT_DBG("-");
680
681         return TRUE;
682 }
683
684 gboolean _gap_agent_unregister_osp_server(GapAgent *agent,
685                                                 const gint type,
686                                                 const char *uuid)
687 {
688         bt_agent_osp_server_t *server;
689
690         BT_DBG("+");
691
692         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
693
694         if (priv == NULL)
695                 return FALSE;
696
697         /* type:  BT_OBEX_SERVER / BT_RFCOMM_SERVER*/
698         if (type > BT_RFCOMM_SERVER)
699                 return FALSE;
700
701         server = __gap_agent_find_server(priv->osp_servers, type, uuid);
702
703         if (server == NULL)
704                 return FALSE;
705
706         priv->osp_servers = g_slist_remove(priv->osp_servers, server);
707
708         g_free(server->uuid);
709         g_free(server);
710
711         BT_DBG("-");
712
713         return TRUE;
714 }
715
716 gboolean gap_agent_reply_pin_code(GapAgent *agent, const guint accept,
717                                                 const char *pin_code,
718                                                 DBusGMethodInvocation *context)
719 {
720         BT_DBG("+");
721
722         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
723
724         if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
725                                                 priv->reply_context != NULL) {
726                 if (accept == GAP_AGENT_ACCEPT) {
727                         dbus_g_method_return(priv->reply_context, pin_code);
728                         priv->canceled = FALSE;
729                 } else {
730                         GError *error = NULL;
731                         switch (accept) {
732                         case GAP_AGENT_CANCEL:
733                                 error = gap_agent_error(GAP_AGENT_ERROR_CANCEL,
734                                                                 "CanceledbyUser");
735                                 priv->canceled = TRUE;
736                                 break;
737                         case GAP_AGENT_TIMEOUT:
738                         case GAP_AGENT_REJECT:
739                         default:
740                                 error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
741                                                                 "Pairing request rejected");
742                                 priv->canceled = FALSE;
743                                 break;
744                         }
745                         dbus_g_method_return_error(priv->reply_context, error);
746                         g_error_free(error);
747                 }
748         }
749
750         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
751         priv->reply_context = NULL;
752         memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
753
754         BT_DBG("-");
755
756         return TRUE;
757 }
758
759 gboolean gap_agent_reply_passkey(GapAgent *agent, const guint accept,
760                                                 const char *passkey,
761                                                 DBusGMethodInvocation *context)
762 {
763         BT_DBG("+");
764
765         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
766
767         if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
768                                                 priv->reply_context != NULL) {
769                 if (accept == GAP_AGENT_ACCEPT) {
770                         guint pass_key = atoi(passkey);
771                         dbus_g_method_return(priv->reply_context, pass_key);
772                         priv->canceled = FALSE;
773                 } else {
774                         GError *error = NULL;
775                         switch (accept) {
776                         case GAP_AGENT_CANCEL:
777                                 error = gap_agent_error(GAP_AGENT_ERROR_CANCEL,
778                                                                 "CanceledbyUser");
779                                 priv->canceled = TRUE;
780                                 break;
781                         case GAP_AGENT_TIMEOUT:
782                         case GAP_AGENT_REJECT:
783                         default:
784                                 error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
785                                                                 "Passkey request rejected");
786                                 priv->canceled = FALSE;
787                                 break;
788                         }
789                         dbus_g_method_return_error(priv->reply_context, error);
790                         g_error_free(error);
791                 }
792         }
793
794         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
795         priv->reply_context = NULL;
796         memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
797
798         BT_DBG("-");
799
800         return TRUE;
801 }
802
803 gboolean gap_agent_reply_confirmation(GapAgent *agent, const guint accept,
804                                           DBusGMethodInvocation *context)
805 {
806         BT_DBG("+");
807
808         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
809
810         if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
811                                                 priv->reply_context != NULL) {
812                 if (accept == GAP_AGENT_ACCEPT) {
813                         dbus_g_method_return(priv->reply_context);
814                         priv->canceled = FALSE;
815                 } else {
816                         GError *error = NULL;
817                         switch (accept) {
818                         case GAP_AGENT_CANCEL:
819                                 error = gap_agent_error(GAP_AGENT_ERROR_CANCEL,
820                                                                 "CanceledbyUser");
821                                 priv->canceled = TRUE;
822                                 break;
823                         case GAP_AGENT_TIMEOUT:
824                         case GAP_AGENT_REJECT:
825                         default:
826                                 error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
827                                                                 "Confirmation request rejected");
828                                 priv->canceled = FALSE;
829                                 break;
830                         }
831                         dbus_g_method_return_error(priv->reply_context, error);
832                         g_error_free(error);
833                 }
834         }
835
836         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
837         priv->reply_context = NULL;
838         memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
839
840         BT_DBG("-");
841
842         return TRUE;
843 }
844
845 gboolean gap_agent_reply_authorize(GapAgent *agent, const guint accept,
846                                        DBusGMethodInvocation *context)
847 {
848         gboolean ret = TRUE;
849
850         BT_DBG("+");
851
852         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
853
854         if (priv->exec_type != GAP_AGENT_EXEC_NO_OPERATION &&
855                                                 priv->reply_context != NULL) {
856                 if (accept == GAP_AGENT_ACCEPT) {
857                         dbus_g_method_return(priv->reply_context);
858                 } else if (accept == GAP_AGENT_ACCEPT_ALWAYS) {
859                         bluetooth_device_address_t addr = {{0,}};
860                         int result;
861
862                         _bt_convert_addr_string_to_type(addr.addr,
863                                                         priv->authorize_addr);
864
865                         result = _bt_set_authorization(&addr, TRUE);
866                         if (result == BLUETOOTH_ERROR_NONE) {
867                                 BT_INFO("[%s] Device added to trusted", priv->authorize_addr);
868                         }
869
870                         dbus_g_method_return(priv->reply_context);
871                 } else {
872                         GError *error = NULL;
873                         switch (accept) {
874                         case GAP_AGENT_CANCEL:
875                                 error = gap_agent_error(GAP_AGENT_ERROR_CANCEL,
876                                                                 "CanceledbyUser");
877                                 break;
878                         case GAP_AGENT_TIMEOUT:
879                         case GAP_AGENT_REJECT:
880                         default:
881                                 error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
882                                                                 "Authorization request rejected");
883                                 break;
884                         }
885                         dbus_g_method_return_error(priv->reply_context, error);
886                         g_error_free(error);
887                 }
888
889                 if (context)
890                         dbus_g_method_return(context);
891         } else {
892                 GError *error = gap_agent_error(GAP_AGENT_ERROR_REJECT,
893                                                         "No context");
894                 BT_ERR("No context");
895
896                 if (context)
897                         dbus_g_method_return_error(context, error);
898
899                 g_error_free(error);
900                 ret = FALSE;
901         }
902
903         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
904         priv->reply_context = NULL;
905         memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
906
907         BT_DBG("-");
908
909         return ret;
910 }
911
912 static gboolean gap_agent_get_discoverable_timeout(GapAgent *agent,
913                                                 DBusGMethodInvocation *context)
914 {
915         BT_DBG("+");
916
917         int timeout;
918
919         _bt_get_timeout_value(&timeout);
920
921         dbus_g_method_return(context, timeout);
922
923         BT_DBG("-");
924
925         return TRUE;
926 }
927
928 gboolean _gap_agent_register(GapAgent *agent)
929 {
930         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
931         DBusGProxy *agent_manager;
932         GError *error = NULL;
933
934         retv_if(priv == NULL, FALSE);
935         retv_if(connection == NULL, FALSE);
936
937         if (priv->agent_manager == NULL) {
938                 agent_manager = dbus_g_proxy_new_for_name(connection,
939                                         BT_BLUEZ_NAME, BT_BLUEZ_PATH,
940                                         BT_AGENT_MANAGER_INTERFACE);
941
942                 retv_if(agent_manager == NULL, FALSE);
943         } else {
944                 agent_manager = priv->agent_manager;
945         }
946
947 #ifdef __TIZEN_MOBILE_
948         dbus_g_proxy_call(agent_manager, "RegisterAgent", &error,
949                                 DBUS_TYPE_G_OBJECT_PATH, priv->path,
950                                 G_TYPE_STRING, "DisplayYesNo", G_TYPE_INVALID,
951                                 G_TYPE_INVALID);
952 else
953         dbus_g_proxy_call(agent_manager, "RegisterAgent", &error,
954                         DBUS_TYPE_G_OBJECT_PATH, priv->path,
955                         G_TYPE_STRING, "NoInputNoOutput", G_TYPE_INVALID,
956                         G_TYPE_INVALID);
957 #endif
958         if (error != NULL) {
959                 BT_DBG("Agent registration failed: %s\n", error->message);
960                 g_error_free(error);
961                 g_object_unref(agent_manager);
962                 priv->agent_manager = NULL;
963                 return FALSE;
964         }
965
966         /* Set the defalut agent */
967         dbus_g_proxy_call(agent_manager, "RequestDefaultAgent", &error,
968                                 DBUS_TYPE_G_OBJECT_PATH, priv->path,
969                                 G_TYPE_INVALID, G_TYPE_INVALID);
970
971         if (error != NULL) {
972                 BT_DBG("Request agent failed: %s\n", error->message);
973                 g_error_free(error);
974                 g_object_unref(agent_manager);
975                 priv->agent_manager = NULL;
976                 return FALSE;
977         }
978
979         priv->agent_manager = agent_manager;
980
981         return TRUE;
982 }
983
984 static gboolean __gap_agent_unregister(GapAgent *agent)
985 {
986         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
987         DBusGProxy *agent_manager;
988         GError *error = NULL;
989
990         retv_if(priv == NULL, FALSE);
991         retv_if(priv->path == NULL, FALSE);
992         retv_if(connection == NULL, FALSE);
993
994         if (priv->agent_manager == NULL) {
995                 agent_manager = dbus_g_proxy_new_for_name(connection,
996                                         BT_BLUEZ_NAME, BT_BLUEZ_PATH,
997                                         BT_AGENT_MANAGER_INTERFACE);
998
999                 retv_if(agent_manager == NULL, FALSE);
1000         } else {
1001                 agent_manager = priv->agent_manager;
1002         }
1003
1004         dbus_g_proxy_call(agent_manager, "UnregisterAgent", &error,
1005                                 DBUS_TYPE_G_OBJECT_PATH, priv->path,
1006                                 G_TYPE_INVALID, G_TYPE_INVALID);
1007
1008         g_object_unref(agent_manager);
1009         priv->agent_manager = NULL;
1010
1011         if (error != NULL) {
1012                 BT_DBG("Agent unregistration failed: %s\n", error->message);
1013                 g_error_free(error);
1014                 return FALSE;
1015         }
1016
1017         return TRUE;
1018 }
1019
1020 void _gap_agent_setup_dbus(GapAgent *agent, GAP_AGENT_FUNC_CB *func_cb,
1021                                                         const char *path)
1022 {
1023         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1024         GObject *object;
1025         DBusGProxy *proxy;
1026
1027         priv->path = g_strdup(path);
1028
1029         object = dbus_g_connection_lookup_g_object(connection, priv->path);
1030         if (object != NULL)
1031                 g_object_unref(object);
1032
1033         dbus_g_connection_register_g_object(connection, priv->path,
1034                                                         G_OBJECT(agent));
1035
1036         memcpy(&priv->cb, func_cb, sizeof(GAP_AGENT_FUNC_CB));
1037
1038         priv->exec_type = GAP_AGENT_EXEC_NO_OPERATION;
1039         memset(priv->pairing_addr, 0x00, sizeof(priv->pairing_addr));
1040         memset(priv->authorize_addr, 0x00, sizeof(priv->authorize_addr));
1041         priv->reply_context = NULL;
1042
1043         BT_DBG("patt: %s", path);
1044
1045         proxy = dbus_g_proxy_new_for_name_owner(connection,
1046                                 BT_BLUEZ_NAME,
1047                                 path,
1048                                 BT_AGENT_INTERFACE,
1049                                 NULL);
1050         if (proxy != NULL) {
1051                 priv->busname = g_strdup(dbus_g_proxy_get_bus_name(proxy));
1052                 g_object_unref(proxy);
1053         } else {
1054                 priv->busname = NULL;
1055         }
1056 }
1057
1058 void _gap_agent_reset_dbus(GapAgent *agent)
1059 {
1060         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1061
1062         __gap_agent_unregister(agent);
1063
1064         dbus_g_connection_unregister_g_object(connection, G_OBJECT(agent));
1065
1066         if (priv->osp_servers) {
1067                 __gap_agent_remove_osp_servers(priv->osp_servers);
1068                 g_slist_free(priv->osp_servers);
1069                 priv->osp_servers = NULL;
1070         }
1071
1072         if (priv->adapter) {
1073                 g_object_unref(priv->adapter);
1074                 priv->adapter = NULL;
1075         }
1076
1077         g_free(priv->path);
1078         priv->path = NULL;
1079
1080         g_free(priv->busname);
1081         priv->busname = NULL;
1082 }
1083
1084 gboolean _gap_agent_exist_osp_server(GapAgent *agent, int type, char *uuid)
1085 {
1086         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1087
1088         if (priv == NULL)
1089                 return FALSE;
1090
1091         if (__gap_agent_find_server(priv->osp_servers,
1092                                 type, uuid) != NULL) {
1093                 return TRUE;
1094         }
1095
1096         return FALSE;
1097 }
1098
1099 bt_agent_osp_server_t *_gap_agent_get_osp_server(GapAgent *agent, int type,
1100                                         char *uuid)
1101 {
1102         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1103         bt_agent_osp_server_t *osp_serv = NULL;
1104         if (priv == NULL)
1105                 return NULL;
1106
1107         osp_serv = __gap_agent_find_server(priv->osp_servers,
1108                         type, uuid);
1109         if (!osp_serv) {
1110                 return NULL;
1111         }
1112
1113         return osp_serv;
1114 }
1115
1116 gchar* _gap_agent_get_path(GapAgent *agent)
1117 {
1118         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1119
1120         return priv->path;
1121 }
1122
1123 gboolean _gap_agent_is_canceled(GapAgent *agent)
1124 {
1125         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1126
1127         return priv->canceled;
1128 }
1129
1130 void _gap_agent_set_canceled(GapAgent *agent, gboolean value)
1131 {
1132         GapAgentPrivate *priv = GAP_AGENT_GET_PRIVATE(agent);
1133
1134         priv->canceled = value;
1135 }