agent: Update __connman_agent_report_error to return -EINPROGRESS
[framework/connectivity/connman.git] / src / agent.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2012  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include <gdbus.h>
31
32 #include "connman.h"
33
34 #define REQUEST_TIMEOUT (120 * 1000)            /* 120 seconds */
35
36 static DBusConnection *connection = NULL;
37 static guint agent_watch = 0;
38 static gchar *agent_path = NULL;
39 static gchar *agent_sender = NULL;
40
41 static void agent_free(void)
42 {
43         agent_watch = 0;
44
45         g_free(agent_sender);
46         agent_sender = NULL;
47
48         g_free(agent_path);
49         agent_path = NULL;
50 }
51
52 static void agent_disconnect(DBusConnection *connection, void *data)
53 {
54         DBG("data %p", data);
55
56         agent_free();
57 }
58
59 int __connman_agent_register(const char *sender, const char *path)
60 {
61         DBG("sender %s path %s", sender, path);
62
63         if (agent_path != NULL)
64                 return -EEXIST;
65
66         agent_sender = g_strdup(sender);
67         agent_path = g_strdup(path);
68
69         agent_watch = g_dbus_add_disconnect_watch(connection, sender,
70                                                 agent_disconnect, NULL, NULL);
71
72         return 0;
73 }
74
75 int __connman_agent_unregister(const char *sender, const char *path)
76 {
77         DBG("sender %s path %s", sender, path);
78
79         if (agent_path == NULL)
80                 return -ESRCH;
81
82         if (agent_watch > 0)
83                 g_dbus_remove_watch(connection, agent_watch);
84
85         agent_free();
86
87         return 0;
88 }
89
90 static connman_bool_t check_reply_has_dict(DBusMessage *reply)
91 {
92         const char *signature = DBUS_TYPE_ARRAY_AS_STRING
93                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
94                 DBUS_TYPE_STRING_AS_STRING
95                 DBUS_TYPE_VARIANT_AS_STRING
96                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
97
98         if (dbus_message_has_signature(reply, signature) == TRUE)
99                 return TRUE;
100
101         connman_warn("Reply %s to %s from %s has wrong signature %s",
102                         signature,
103                         dbus_message_get_interface(reply),
104                         dbus_message_get_sender(reply),
105                         dbus_message_get_signature(reply));
106
107         return FALSE;
108 }
109
110 struct request_input_reply {
111         struct connman_service *service;
112         authentication_cb_t callback;
113         void *user_data;
114 };
115
116 static void request_input_passphrase_reply(DBusPendingCall *call, void *user_data)
117 {
118         struct request_input_reply *passphrase_reply = user_data;
119         connman_bool_t values_received = FALSE;
120         connman_bool_t wps = FALSE;
121         const char *error = NULL;
122         char *identity = NULL;
123         char *passphrase = NULL;
124         char *wpspin = NULL;
125         char *key;
126         char *name = NULL;
127         int name_len = 0;
128         DBusMessageIter iter, dict;
129         DBusMessage *reply = dbus_pending_call_steal_reply(call);
130
131         if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
132                 error = dbus_message_get_error_name(reply);
133                 goto done;
134         }
135
136         if (check_reply_has_dict(reply) == FALSE)
137                 goto done;
138
139         values_received = TRUE;
140
141         dbus_message_iter_init(reply, &iter);
142         dbus_message_iter_recurse(&iter, &dict);
143         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
144                 DBusMessageIter entry, value;
145
146                 dbus_message_iter_recurse(&dict, &entry);
147                 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
148                         break;
149
150                 dbus_message_iter_get_basic(&entry, &key);
151
152                 if (g_str_equal(key, "Identity")) {
153                         dbus_message_iter_next(&entry);
154                         if (dbus_message_iter_get_arg_type(&entry)
155                                                         != DBUS_TYPE_VARIANT)
156                                 break;
157                         dbus_message_iter_recurse(&entry, &value);
158                         dbus_message_iter_get_basic(&value, &identity);
159
160                 } else if (g_str_equal(key, "Passphrase")) {
161                         dbus_message_iter_next(&entry);
162                         if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
163                                 break;
164                         dbus_message_iter_recurse(&entry, &value);
165                         dbus_message_iter_get_basic(&value, &passphrase);
166
167                 } else if (g_str_equal(key, "WPS")) {
168                         wps = TRUE;
169
170                         dbus_message_iter_next(&entry);
171                         if (dbus_message_iter_get_arg_type(&entry)
172                                                         != DBUS_TYPE_VARIANT)
173                                 break;
174                         dbus_message_iter_recurse(&entry, &value);
175                         dbus_message_iter_get_basic(&value, &wpspin);
176                         break;
177                 } else if (g_str_equal(key, "Name")) {
178                         dbus_message_iter_next(&entry);
179                         if (dbus_message_iter_get_arg_type(&entry)
180                                                         != DBUS_TYPE_VARIANT)
181                                 break;
182                         dbus_message_iter_recurse(&entry, &value);
183                         dbus_message_iter_get_basic(&value, &name);
184                         name_len = strlen(name);
185                 } else if (g_str_equal(key, "SSID")) {
186                         dbus_message_iter_next(&entry);
187                         if (dbus_message_iter_get_arg_type(&entry)
188                                                         != DBUS_TYPE_VARIANT)
189                                 break;
190                         dbus_message_iter_recurse(&entry, &value);
191                         if (dbus_message_iter_get_arg_type(&value)
192                                                         != DBUS_TYPE_VARIANT)
193                                 break;
194                         if (dbus_message_iter_get_element_type(&value)
195                                                         != DBUS_TYPE_VARIANT)
196                                 break;
197                         dbus_message_iter_get_fixed_array(&value, &name,
198                                                         &name_len);
199                 }
200                 dbus_message_iter_next(&dict);
201         }
202
203 done:
204         passphrase_reply->callback(passphrase_reply->service, values_received,
205                                 name, name_len,
206                                 identity, passphrase,
207                                 wps, wpspin, error,
208                                 passphrase_reply->user_data);
209         connman_service_unref(passphrase_reply->service);
210         dbus_message_unref(reply);
211         dbus_pending_call_unref(call);
212         g_free(passphrase_reply);
213 }
214
215 static void request_input_append_alternates(DBusMessageIter *iter,
216                                                         void *user_data)
217 {
218         const char *str = user_data;
219         char **alternates, **alternative;
220
221         if (str == NULL)
222                 return;
223
224         alternates = g_strsplit(str, ",", 0);
225         if (alternates == NULL)
226                 return;
227
228         for (alternative = alternates; *alternative != NULL; alternative++)
229                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
230                                                                 alternative);
231
232         g_strfreev(alternates);
233 }
234
235 static void request_input_append_identity(DBusMessageIter *iter,
236                                                         void *user_data)
237 {
238         char *str = "string";
239
240         connman_dbus_dict_append_basic(iter, "Type",
241                                 DBUS_TYPE_STRING, &str);
242         str = "mandatory";
243         connman_dbus_dict_append_basic(iter, "Requirement",
244                                 DBUS_TYPE_STRING, &str);
245 }
246
247 static void request_input_append_passphrase(DBusMessageIter *iter,
248                                                         void *user_data)
249 {
250         struct connman_service *service = user_data;
251         char *value;
252         const char *phase2;
253
254         switch (__connman_service_get_security(service)) {
255         case CONNMAN_SERVICE_SECURITY_WEP:
256                 value = "wep";
257                 break;
258         case CONNMAN_SERVICE_SECURITY_PSK:
259                 value = "psk";
260                 break;
261         case CONNMAN_SERVICE_SECURITY_8021X:
262                 phase2 = __connman_service_get_phase2(service);
263
264                 if (phase2 != NULL && (
265                                 g_str_has_suffix(phase2, "GTC") == TRUE ||
266                                 g_str_has_suffix(phase2, "OTP") == TRUE))
267                         value = "response";
268                 else
269                         value = "passphrase";
270
271                 break;
272         default:
273                 value = "string";
274                 break;
275         }
276         connman_dbus_dict_append_basic(iter, "Type",
277                                 DBUS_TYPE_STRING, &value);
278         value = "mandatory";
279         connman_dbus_dict_append_basic(iter, "Requirement",
280                                 DBUS_TYPE_STRING, &value);
281
282         if (__connman_service_wps_enabled(service) == TRUE) {
283                 connman_dbus_dict_append_array(iter, "Alternates",
284                                         DBUS_TYPE_STRING,
285                                         request_input_append_alternates,
286                                         "WPS");
287         }
288 }
289
290 static void request_input_append_wps(DBusMessageIter *iter, void *user_data)
291 {
292         const char *str = "wpspin";
293
294         connman_dbus_dict_append_basic(iter, "Type",
295                                 DBUS_TYPE_STRING, &str);
296         str = "alternate";
297         connman_dbus_dict_append_basic(iter, "Requirement",
298                                 DBUS_TYPE_STRING, &str);
299 }
300
301 static void request_input_append_name(DBusMessageIter *iter, void *user_data)
302 {
303         const char *str = "string";
304
305         connman_dbus_dict_append_basic(iter, "Type",
306                                 DBUS_TYPE_STRING, &str);
307         str = "mandatory";
308         connman_dbus_dict_append_basic(iter, "Requirement",
309                                 DBUS_TYPE_STRING, &str);
310         connman_dbus_dict_append_array(iter, "Alternates",
311                                 DBUS_TYPE_STRING,
312                                 request_input_append_alternates,
313                                 "SSID");
314 }
315
316 static void request_input_append_ssid(DBusMessageIter *iter, void *user_data)
317 {
318         const char *str = "ssid";
319
320         connman_dbus_dict_append_basic(iter, "Type",
321                                 DBUS_TYPE_STRING, &str);
322         str = "alternate";
323         connman_dbus_dict_append_basic(iter, "Requirement",
324                                 DBUS_TYPE_STRING, &str);
325 }
326
327 static void request_input_append_password(DBusMessageIter *iter,
328                                                         void *user_data)
329 {
330         char *str = "passphrase";
331
332         connman_dbus_dict_append_basic(iter, "Type",
333                                 DBUS_TYPE_STRING, &str);
334         str = "mandatory";
335         connman_dbus_dict_append_basic(iter, "Requirement",
336                                 DBUS_TYPE_STRING, &str);
337 }
338
339 static void request_input_login_reply(DBusPendingCall *call, void *user_data)
340 {
341         struct request_input_reply *username_password_reply = user_data;
342         const char *error = NULL;
343         connman_bool_t values_received = FALSE;
344         char *username = NULL;
345         char *password = NULL;
346         char *key;
347         DBusMessageIter iter, dict;
348         DBusMessage *reply = dbus_pending_call_steal_reply(call);
349
350         if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
351                 error = dbus_message_get_error_name(reply);
352                 goto done;
353         }
354
355         if (check_reply_has_dict(reply) == FALSE)
356                 goto done;
357
358         values_received = TRUE;
359
360         dbus_message_iter_init(reply, &iter);
361         dbus_message_iter_recurse(&iter, &dict);
362         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
363                 DBusMessageIter entry, value;
364
365                 dbus_message_iter_recurse(&dict, &entry);
366                 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
367                         break;
368
369                 dbus_message_iter_get_basic(&entry, &key);
370
371                 if (g_str_equal(key, "Username")) {
372                         dbus_message_iter_next(&entry);
373                         if (dbus_message_iter_get_arg_type(&entry)
374                                                         != DBUS_TYPE_VARIANT)
375                                 break;
376                         dbus_message_iter_recurse(&entry, &value);
377                         dbus_message_iter_get_basic(&value, &username);
378
379                 } else if (g_str_equal(key, "Password")) {
380                         dbus_message_iter_next(&entry);
381                         if (dbus_message_iter_get_arg_type(&entry) !=
382                                                         DBUS_TYPE_VARIANT)
383                                 break;
384                         dbus_message_iter_recurse(&entry, &value);
385                         dbus_message_iter_get_basic(&value, &password);
386                 }
387
388                 dbus_message_iter_next(&dict);
389         }
390
391 done:
392         username_password_reply->callback(username_password_reply->service,
393                                         values_received, NULL, 0,
394                                         username, password,
395                                         FALSE, NULL, error,
396                                         username_password_reply->user_data);
397         connman_service_unref(username_password_reply->service);
398         dbus_message_unref(reply);
399         g_free(username_password_reply);
400 }
401
402 int __connman_agent_request_passphrase_input(struct connman_service *service,
403                                 authentication_cb_t callback, void *user_data)
404 {
405         DBusMessage *message;
406         const char *path;
407         DBusMessageIter iter;
408         DBusMessageIter dict;
409         DBusPendingCall *call;
410         struct request_input_reply *passphrase_reply;
411
412         if (service == NULL || agent_path == NULL || callback == NULL)
413                 return -ESRCH;
414
415         message = dbus_message_new_method_call(agent_sender, agent_path,
416                                         CONNMAN_AGENT_INTERFACE,
417                                         "RequestInput");
418         if (message == NULL)
419                 return -ENOMEM;
420
421         dbus_message_iter_init_append(message, &iter);
422
423         path = __connman_service_get_path(service);
424         dbus_message_iter_append_basic(&iter,
425                                 DBUS_TYPE_OBJECT_PATH, &path);
426
427         connman_dbus_dict_open(&iter, &dict);
428
429         if (__connman_service_is_hidden(service)) {
430                 connman_dbus_dict_append_dict(&dict, "Name",
431                                         request_input_append_name, NULL);
432                 connman_dbus_dict_append_dict(&dict, "SSID",
433                                         request_input_append_ssid, NULL);
434         }
435
436         if (__connman_service_get_security(service) ==
437                         CONNMAN_SERVICE_SECURITY_8021X) {
438                 connman_dbus_dict_append_dict(&dict, "Identity",
439                                         request_input_append_identity, service);
440         }
441
442         if (__connman_service_get_security(service) !=
443                         CONNMAN_SERVICE_SECURITY_NONE) {
444                 connman_dbus_dict_append_dict(&dict, "Passphrase",
445                                         request_input_append_passphrase, service);
446         }
447
448         if (__connman_service_wps_enabled(service) == TRUE) {
449             connman_dbus_dict_append_dict(&dict, "WPS",
450                                 request_input_append_wps, NULL);
451         }
452
453         connman_dbus_dict_close(&iter, &dict);
454
455         passphrase_reply = g_try_new0(struct request_input_reply, 1);
456         if (passphrase_reply == NULL) {
457                 dbus_message_unref(message);
458                 return -ENOMEM;
459         }
460
461         if (dbus_connection_send_with_reply(connection, message, &call,
462                                                 REQUEST_TIMEOUT) == FALSE) {
463                 dbus_message_unref(message);
464                 g_free(passphrase_reply);
465                 return -ESRCH;
466         }
467
468         if (call == NULL) {
469                 dbus_message_unref(message);
470                 g_free(passphrase_reply);
471                 return -ESRCH;
472         }
473
474         passphrase_reply->service = connman_service_ref(service);
475         passphrase_reply->callback = callback;
476         passphrase_reply->user_data = user_data;
477
478         dbus_pending_call_set_notify(call, request_input_passphrase_reply,
479                                 passphrase_reply, NULL);
480
481         dbus_message_unref(message);
482
483         return -EINPROGRESS;
484 }
485
486 int __connman_agent_request_login_input(struct connman_service *service,
487                                 authentication_cb_t callback, void *user_data)
488 {
489         DBusMessage *message;
490         const char *path;
491         DBusMessageIter iter;
492         DBusMessageIter dict;
493         DBusPendingCall *call;
494         struct request_input_reply *username_password_reply;
495
496         if (service == NULL || agent_path == NULL || callback == NULL)
497                 return -ESRCH;
498
499         message = dbus_message_new_method_call(agent_sender, agent_path,
500                                         CONNMAN_AGENT_INTERFACE,
501                                         "RequestInput");
502         if (message == NULL)
503                 return -ENOMEM;
504
505         dbus_message_iter_init_append(message, &iter);
506
507         path = __connman_service_get_path(service);
508         dbus_message_iter_append_basic(&iter,
509                                 DBUS_TYPE_OBJECT_PATH, &path);
510
511         connman_dbus_dict_open(&iter, &dict);
512
513         connman_dbus_dict_append_dict(&dict, "Username",
514                                 request_input_append_identity, service);
515
516         connman_dbus_dict_append_dict(&dict, "Password",
517                                 request_input_append_password, service);
518
519         connman_dbus_dict_close(&iter, &dict);
520
521         username_password_reply = g_try_new0(struct request_input_reply, 1);
522         if (username_password_reply == NULL) {
523                 dbus_message_unref(message);
524                 return -ENOMEM;
525         }
526
527         if (dbus_connection_send_with_reply(connection, message, &call,
528                                                 REQUEST_TIMEOUT) == FALSE) {
529                 dbus_message_unref(message);
530                 g_free(username_password_reply);
531                 return -ESRCH;
532         }
533
534         if (call == NULL) {
535                 dbus_message_unref(message);
536                 g_free(username_password_reply);
537                 return -ESRCH;
538         }
539
540         username_password_reply->service = connman_service_ref(service);
541         username_password_reply->callback = callback;
542         username_password_reply->user_data = user_data;
543
544         dbus_pending_call_set_notify(call, request_input_login_reply,
545                                                 username_password_reply, NULL);
546
547         dbus_message_unref(message);
548
549         return -EINPROGRESS;
550 }
551
552 struct request_browser_reply_data {
553         struct connman_service *service;
554         browser_authentication_cb_t callback;
555         void *user_data;
556 };
557
558 static void request_browser_reply(DBusPendingCall *call, void *user_data)
559 {
560         struct request_browser_reply_data *browser_reply_data = user_data;
561         DBusMessage *reply = dbus_pending_call_steal_reply(call);
562         connman_bool_t result = FALSE;
563         const char *error = NULL;
564
565         if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
566                 error = dbus_message_get_error_name(reply);
567                 goto done;
568         }
569
570         result = TRUE;
571
572 done:
573         browser_reply_data->callback(browser_reply_data->service, result,
574                                         error, browser_reply_data->user_data);
575         connman_service_unref(browser_reply_data->service);
576         dbus_message_unref(reply);
577         g_free(browser_reply_data);
578 }
579
580 int __connman_agent_request_browser(struct connman_service *service,
581                                 browser_authentication_cb_t callback,
582                                 const char *url, void *user_data)
583 {
584         struct request_browser_reply_data *browser_reply_data;
585         DBusPendingCall *call;
586         DBusMessage *message;
587         DBusMessageIter iter;
588         const char *path;
589
590         if (service == NULL || agent_path == NULL || callback == NULL)
591                 return -ESRCH;
592
593         if (url == NULL)
594                 url = "";
595
596         message = dbus_message_new_method_call(agent_sender, agent_path,
597                                         CONNMAN_AGENT_INTERFACE,
598                                         "RequestBrowser");
599         if (message == NULL)
600                 return -ENOMEM;
601
602         dbus_message_iter_init_append(message, &iter);
603
604         path = __connman_service_get_path(service);
605         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
606
607         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &url);
608
609         browser_reply_data = g_try_new0(struct request_browser_reply_data, 1);
610         if (browser_reply_data == NULL) {
611                 dbus_message_unref(message);
612                 return -ENOMEM;
613         }
614
615         if (dbus_connection_send_with_reply(connection, message, &call,
616                                                 REQUEST_TIMEOUT) == FALSE) {
617                 dbus_message_unref(message);
618                 g_free(browser_reply_data);
619                 return -ESRCH;
620         }
621
622         if (call == NULL) {
623                 dbus_message_unref(message);
624                 g_free(browser_reply_data);
625                 return -ESRCH;
626         }
627
628         browser_reply_data->service = connman_service_ref(service);
629         browser_reply_data->callback = callback;
630         browser_reply_data->user_data = user_data;
631
632         dbus_pending_call_set_notify(call, request_browser_reply,
633                                                 browser_reply_data, NULL);
634
635         dbus_message_unref(message);
636
637         return -EINPROGRESS;
638 }
639
640 struct report_error_data {
641         struct connman_service *service;
642         report_error_cb_t callback;
643         void *user_data;
644 };
645
646 static void report_error_reply(DBusPendingCall *call, void *user_data)
647 {
648         struct report_error_data *report_error = user_data;
649         DBusMessage *reply = dbus_pending_call_steal_reply(call);
650         gboolean retry = FALSE;
651         const char *dbus_err;
652
653         if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
654                 dbus_err = dbus_message_get_error_name(reply);
655                 if (dbus_err != NULL &&
656                         strcmp(dbus_err,
657                                 CONNMAN_AGENT_INTERFACE ".Error.Retry") == 0)
658                         retry = TRUE;
659         }
660
661         report_error->callback(report_error->service, retry,
662                         report_error->user_data);
663         connman_service_unref(report_error->service);
664         g_free(report_error);
665         dbus_message_unref(reply);
666         dbus_pending_call_unref(call);
667 }
668
669 int __connman_agent_report_error(struct connman_service *service,
670                                 const char *error,
671                                 report_error_cb_t callback, void *user_data)
672 {
673         DBusMessage *message;
674         DBusMessageIter iter;
675         const char *path;
676         struct report_error_data *report_error;
677         DBusPendingCall *call;
678
679         if (service == NULL || agent_path == NULL || error == NULL ||
680                 callback == NULL)
681                 return -ESRCH;
682
683         message = dbus_message_new_method_call(agent_sender, agent_path,
684                                         CONNMAN_AGENT_INTERFACE,
685                                         "ReportError");
686         if (message == NULL)
687                 return -ENOMEM;
688
689         dbus_message_iter_init_append(message, &iter);
690
691         path = __connman_service_get_path(service);
692         dbus_message_iter_append_basic(&iter,
693                                 DBUS_TYPE_OBJECT_PATH, &path);
694         dbus_message_iter_append_basic(&iter,
695                                 DBUS_TYPE_STRING, &error);
696
697         report_error = g_try_new0(struct report_error_data, 1);
698         if (report_error == NULL) {
699                 dbus_message_unref(message);
700                 return -ENOMEM;
701         }
702
703         if (dbus_connection_send_with_reply(connection, message, &call,
704                                                 REQUEST_TIMEOUT) == FALSE) {
705                 dbus_message_unref(message);
706                 g_free(report_error);
707                 return -ESRCH;
708         }
709
710         if (call == NULL) {
711                 dbus_message_unref(message);
712                 g_free(report_error);
713                 return -ESRCH;
714         }
715
716         report_error->service = connman_service_ref(service);
717         report_error->callback = callback;
718         report_error->user_data = user_data;
719         dbus_pending_call_set_notify(call, report_error_reply,
720                                 report_error, NULL);
721         dbus_message_unref(message);
722
723         return -EINPROGRESS;
724 }
725
726 int __connman_agent_init(void)
727 {
728         DBG("");
729
730         connection = connman_dbus_get_connection();
731         if (connection == NULL)
732                 return -1;
733
734         return 0;
735 }
736
737 void __connman_agent_cleanup(void)
738 {
739         DBusMessage *message;
740
741         DBG("");
742
743         if (connection == NULL)
744                 return;
745
746         if (agent_watch > 0)
747                 g_dbus_remove_watch(connection, agent_watch);
748
749         if (agent_path == NULL)
750                 return;
751
752         message = dbus_message_new_method_call(agent_sender, agent_path,
753                                         CONNMAN_AGENT_INTERFACE, "Release");
754         if (message == NULL)
755                 return;
756
757         dbus_message_set_no_reply(message, TRUE);
758
759         g_dbus_send_message(connection, message);
760
761         agent_free();
762
763         dbus_connection_unref(connection);
764 }