Remove all the useless D-Bus connection passing
[platform/upstream/connman.git] / src / manager.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2009  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 <gdbus.h>
27
28 #include "connman.h"
29
30 static void append_profiles(DBusMessageIter *dict)
31 {
32         DBusMessageIter entry, value, iter;
33         const char *key = "Profiles";
34
35         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
36                                                                 NULL, &entry);
37
38         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
39
40         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
41                 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
42                                                                 &value);
43
44         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
45                                 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
46         __connman_profile_list(&iter);
47         dbus_message_iter_close_container(&value, &iter);
48
49         dbus_message_iter_close_container(&entry, &value);
50
51         dbus_message_iter_close_container(dict, &entry);
52 }
53
54 static void append_services(DBusMessageIter *dict)
55 {
56         DBusMessageIter entry, value, iter;
57         const char *key = "Services";
58
59         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
60                                                                 NULL, &entry);
61
62         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
63
64         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
65                 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
66                                                                 &value);
67
68         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
69                                 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
70         __connman_service_list(&iter);
71         dbus_message_iter_close_container(&value, &iter);
72
73         dbus_message_iter_close_container(&entry, &value);
74
75         dbus_message_iter_close_container(dict, &entry);
76 }
77
78 static void append_devices(DBusMessageIter *dict)
79 {
80         DBusMessageIter entry, value, iter;
81         const char *key = "Devices";
82
83         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
84                                                                 NULL, &entry);
85
86         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
87
88         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
89                 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
90                                                                 &value);
91
92         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
93                                 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
94         __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
95         dbus_message_iter_close_container(&value, &iter);
96
97         dbus_message_iter_close_container(&entry, &value);
98
99         dbus_message_iter_close_container(dict, &entry);
100 }
101
102 static void append_connections(DBusMessageIter *dict)
103 {
104         DBusMessageIter entry, value, iter;
105         const char *key = "Connections";
106
107         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
108                                                                 NULL, &entry);
109
110         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
111
112         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
113                 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
114                                                                 &value);
115
116         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
117                                 DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
118         __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION, &iter);
119         dbus_message_iter_close_container(&value, &iter);
120
121         dbus_message_iter_close_container(&entry, &value);
122
123         dbus_message_iter_close_container(dict, &entry);
124 }
125
126 static void append_available_technologies(DBusMessageIter *dict)
127 {
128         DBusMessageIter entry, value, iter;
129         const char *key = "AvailableTechnologies";
130
131         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
132                                                                 NULL, &entry);
133
134         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
135
136         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
137                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
138                                                                 &value);
139
140         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
141                                         DBUS_TYPE_STRING_AS_STRING, &iter);
142         __connman_notifier_list_registered(&iter);
143         dbus_message_iter_close_container(&value, &iter);
144
145         dbus_message_iter_close_container(&entry, &value);
146
147         dbus_message_iter_close_container(dict, &entry);
148 }
149
150 static void append_enabled_technologies(DBusMessageIter *dict)
151 {
152         DBusMessageIter entry, value, iter;
153         const char *key = "EnabledTechnologies";
154
155         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
156                                                                 NULL, &entry);
157
158         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
159
160         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
161                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
162                                                                 &value);
163
164         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
165                                         DBUS_TYPE_STRING_AS_STRING, &iter);
166         __connman_notifier_list_enabled(&iter);
167         dbus_message_iter_close_container(&value, &iter);
168
169         dbus_message_iter_close_container(&entry, &value);
170
171         dbus_message_iter_close_container(dict, &entry);
172 }
173
174 static void append_connected_technologies(DBusMessageIter *dict)
175 {
176         DBusMessageIter entry, value, iter;
177         const char *key = "ConnectedTechnologies";
178
179         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
180                                                                 NULL, &entry);
181
182         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
183
184         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
185                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
186                                                                 &value);
187
188         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
189                                         DBUS_TYPE_STRING_AS_STRING, &iter);
190         __connman_notifier_list_connected(&iter);
191         dbus_message_iter_close_container(&value, &iter);
192
193         dbus_message_iter_close_container(&entry, &value);
194
195         dbus_message_iter_close_container(dict, &entry);
196 }
197
198 static DBusMessage *get_properties(DBusConnection *conn,
199                                         DBusMessage *msg, void *data)
200 {
201         DBusMessage *reply;
202         DBusMessageIter array, dict;
203         connman_bool_t offlinemode;
204         const char *str;
205
206         DBG("conn %p", conn);
207
208         if (__connman_security_check_privilege(msg,
209                                         CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
210                 return __connman_error_permission_denied(msg);
211
212         reply = dbus_message_new_method_return(msg);
213         if (reply == NULL)
214                 return NULL;
215
216         dbus_message_iter_init_append(reply, &array);
217
218         dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
219                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
220                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
221                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
222
223         str = __connman_profile_active_path();
224         if (str != NULL)
225                 connman_dbus_dict_append_variant(&dict, "ActiveProfile",
226                                                 DBUS_TYPE_OBJECT_PATH, &str);
227
228         append_profiles(&dict);
229         append_services(&dict);
230
231         append_devices(&dict);
232         append_connections(&dict);
233
234         if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
235                 str = "online";
236         else
237                 str = "offline";
238
239         connman_dbus_dict_append_variant(&dict, "State",
240                                                 DBUS_TYPE_STRING, &str);
241
242         offlinemode = __connman_profile_get_offlinemode();
243         connman_dbus_dict_append_variant(&dict, "OfflineMode",
244                                         DBUS_TYPE_BOOLEAN, &offlinemode);
245
246         append_available_technologies(&dict);
247         append_enabled_technologies(&dict);
248         append_connected_technologies(&dict);
249
250         str = __connman_service_default();
251         if (str != NULL)
252                 connman_dbus_dict_append_variant(&dict, "DefaultTechnology",
253                                                 DBUS_TYPE_STRING, &str);
254
255         dbus_message_iter_close_container(&array, &dict);
256
257         return reply;
258 }
259
260 static DBusMessage *set_property(DBusConnection *conn,
261                                         DBusMessage *msg, void *data)
262 {
263         DBusMessageIter iter, value;
264         const char *name;
265         int type;
266
267         DBG("conn %p", conn);
268
269         if (dbus_message_iter_init(msg, &iter) == FALSE)
270                 return __connman_error_invalid_arguments(msg);
271
272         dbus_message_iter_get_basic(&iter, &name);
273         dbus_message_iter_next(&iter);
274         dbus_message_iter_recurse(&iter, &value);
275
276         if (__connman_security_check_privilege(msg,
277                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
278                 return __connman_error_permission_denied(msg);
279
280         type = dbus_message_iter_get_arg_type(&value);
281
282         if (g_str_equal(name, "OfflineMode") == TRUE) {
283                 connman_bool_t offlinemode;
284
285                 if (type != DBUS_TYPE_BOOLEAN)
286                         return __connman_error_invalid_arguments(msg);
287
288                 dbus_message_iter_get_basic(&value, &offlinemode);
289
290                 __connman_profile_set_offlinemode(offlinemode);
291
292                 __connman_profile_save_default();
293         } else if (g_str_equal(name, "ActiveProfile") == TRUE) {
294                 const char *str;
295
296                 dbus_message_iter_get_basic(&value, &str);
297
298                 return __connman_error_not_supported(msg);
299         } else
300                 return __connman_error_invalid_property(msg);
301
302         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
303 }
304
305 static DBusMessage *get_state(DBusConnection *conn,
306                                         DBusMessage *msg, void *data)
307 {
308         const char *str;
309
310         DBG("conn %p", conn);
311
312         if (__connman_security_check_privilege(msg,
313                                         CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
314                 return __connman_error_permission_denied(msg);
315
316         if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
317                 str = "online";
318         else
319                 str = "offline";
320
321         return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
322                                                 DBUS_TYPE_INVALID);
323 }
324
325 static DBusMessage *create_profile(DBusConnection *conn,
326                                         DBusMessage *msg, void *data)
327 {
328         const char *name, *path;
329         int err;
330
331         DBG("conn %p", conn);
332
333         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
334                                                         DBUS_TYPE_INVALID);
335
336         if (__connman_security_check_privilege(msg,
337                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
338                 return __connman_error_permission_denied(msg);
339
340         err = __connman_profile_create(name, &path);
341         if (err < 0)
342                 return __connman_error_failed(msg, -err);
343
344         return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
345                                                         DBUS_TYPE_INVALID);
346 }
347
348 static DBusMessage *remove_profile(DBusConnection *conn,
349                                         DBusMessage *msg, void *data)
350 {
351         const char *path;
352         int err;
353
354         DBG("conn %p", conn);
355
356         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
357                                                         DBUS_TYPE_INVALID);
358
359         if (__connman_security_check_privilege(msg,
360                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
361                 return __connman_error_permission_denied(msg);
362
363         err = __connman_profile_remove(path);
364         if (err < 0)
365                 return __connman_error_failed(msg, -err);
366
367         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
368 }
369
370 static DBusMessage *request_scan(DBusConnection *conn,
371                                         DBusMessage *msg, void *data)
372 {
373         enum connman_service_type type;
374         const char *str;
375         int err;
376
377         DBG("conn %p", conn);
378
379         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
380                                                         DBUS_TYPE_INVALID);
381
382         if (g_strcmp0(str, "") == 0)
383                 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
384         else if (g_strcmp0(str, "wifi") == 0)
385                 type = CONNMAN_SERVICE_TYPE_WIFI;
386         else if (g_strcmp0(str, "wimax") == 0)
387                 type = CONNMAN_SERVICE_TYPE_WIMAX;
388         else
389                 return __connman_error_invalid_arguments(msg);
390
391         err = __connman_element_request_scan(type);
392         if (err < 0) {
393                 if (err == -EINPROGRESS) {
394                         connman_error("Invalid return code from scan");
395                         err = -EINVAL;
396                 }
397
398                 return __connman_error_failed(msg, -err);
399         }
400
401         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
402 }
403
404 static DBusConnection *connection = NULL;
405
406 static enum connman_service_type technology_type;
407 static connman_bool_t technology_enabled;
408 static DBusMessage *technology_pending = NULL;
409 static guint technology_timeout = 0;
410
411 static void technology_reply(int error)
412 {
413         DBG("");
414
415         if (technology_timeout > 0) {
416                 g_source_remove(technology_timeout);
417                 technology_timeout = 0;
418         }
419
420         if (technology_pending != NULL) {
421                 if (error > 0) {
422                         DBusMessage *reply;
423
424                         reply = __connman_error_failed(technology_pending,
425                                                                 error);
426                         if (reply != NULL)
427                                 g_dbus_send_message(connection, reply);
428                 } else
429                         g_dbus_send_reply(connection, technology_pending,
430                                                         DBUS_TYPE_INVALID);
431
432                 dbus_message_unref(technology_pending);
433                 technology_pending = NULL;
434         }
435
436         technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
437 }
438
439 static gboolean technology_abort(gpointer user_data)
440 {
441         DBG("");
442
443         technology_timeout = 0;
444
445         technology_reply(ETIMEDOUT);
446
447         return FALSE;
448 }
449
450 static void technology_notify(enum connman_service_type type,
451                                                 connman_bool_t enabled)
452 {
453         DBG("type %d enabled %d", type, enabled);
454
455         if (type == technology_type && enabled == technology_enabled)
456                 technology_reply(0);
457 }
458
459 static struct connman_notifier technology_notifier = {
460         .name           = "manager",
461         .priority       = CONNMAN_NOTIFIER_PRIORITY_HIGH,
462         .service_enabled= technology_notify,
463 };
464
465 static DBusMessage *enable_technology(DBusConnection *conn,
466                                         DBusMessage *msg, void *data)
467 {
468         enum connman_service_type type;
469         const char *str;
470         int err;
471
472         DBG("conn %p", conn);
473
474         if (technology_pending != NULL)
475                 return __connman_error_in_progress(msg);
476
477         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
478                                                         DBUS_TYPE_INVALID);
479
480         if (g_strcmp0(str, "ethernet") == 0)
481                 type = CONNMAN_SERVICE_TYPE_ETHERNET;
482         else if (g_strcmp0(str, "wifi") == 0)
483                 type = CONNMAN_SERVICE_TYPE_WIFI;
484         else if (g_strcmp0(str, "wimax") == 0)
485                 type = CONNMAN_SERVICE_TYPE_WIMAX;
486         else if (g_strcmp0(str, "bluetooth") == 0)
487                 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
488         else if (g_strcmp0(str, "cellular") == 0)
489                 type = CONNMAN_SERVICE_TYPE_CELLULAR;
490         else
491                 return __connman_error_invalid_arguments(msg);
492
493         if (__connman_notifier_is_enabled(type) == TRUE)
494                 return __connman_error_already_enabled(msg);
495
496         technology_type = type;
497         technology_enabled = TRUE;
498         technology_pending = dbus_message_ref(msg);
499
500         err = __connman_element_enable_technology(type);
501         if (err < 0 && err != -EINPROGRESS)
502                 technology_reply(-err);
503         else
504                 technology_timeout = g_timeout_add_seconds(15,
505                                                 technology_abort, NULL);
506
507         return NULL;
508 }
509
510 static DBusMessage *disable_technology(DBusConnection *conn,
511                                         DBusMessage *msg, void *data)
512 {
513         enum connman_service_type type;
514         const char *str;
515         int err;
516
517         DBG("conn %p", conn);
518
519         if (technology_pending != NULL)
520                 return __connman_error_in_progress(msg);
521
522         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
523                                                         DBUS_TYPE_INVALID);
524
525         if (g_strcmp0(str, "ethernet") == 0)
526                 type = CONNMAN_SERVICE_TYPE_ETHERNET;
527         else if (g_strcmp0(str, "wifi") == 0)
528                 type = CONNMAN_SERVICE_TYPE_WIFI;
529         else if (g_strcmp0(str, "wimax") == 0)
530                 type = CONNMAN_SERVICE_TYPE_WIMAX;
531         else if (g_strcmp0(str, "bluetooth") == 0)
532                 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
533         else if (g_strcmp0(str, "cellular") == 0)
534                 type = CONNMAN_SERVICE_TYPE_CELLULAR;
535         else
536                 return __connman_error_invalid_arguments(msg);
537
538         if (__connman_notifier_is_enabled(type) == FALSE)
539                 return __connman_error_already_disabled(msg);
540
541         technology_type = type;
542         technology_enabled = FALSE;
543         technology_pending = dbus_message_ref(msg);
544
545         err = __connman_element_disable_technology(type);
546         if (err < 0 && err != -EINPROGRESS)
547                 technology_reply(-err);
548         else
549                 technology_timeout = g_timeout_add_seconds(10,
550                                                 technology_abort, NULL);
551
552         return NULL;
553 }
554
555 static DBusMessage *connect_service(DBusConnection *conn,
556                                         DBusMessage *msg, void *data)
557 {
558         int err;
559
560         DBG("conn %p", conn);
561
562         if (__connman_security_check_privilege(msg,
563                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
564                 return __connman_error_permission_denied(msg);
565
566         err = __connman_service_create_and_connect(msg);
567         if (err < 0) {
568                 if (err == -EINPROGRESS) {
569                         connman_error("Invalid return code from connect");
570                         err = -EINVAL;
571                 }
572
573                 return __connman_error_failed(msg, -err);
574         }
575
576         return NULL;
577 }
578
579 static DBusMessage *register_agent(DBusConnection *conn,
580                                         DBusMessage *msg, void *data)
581 {
582         DBusMessage *reply;
583         const char *sender, *path;
584
585         DBG("conn %p", conn);
586
587         sender = dbus_message_get_sender(msg);
588
589         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
590                                                         DBUS_TYPE_INVALID);
591
592         reply = dbus_message_new_method_return(msg);
593         if (reply == NULL)
594                 return NULL;
595
596         dbus_message_append_args(reply, DBUS_TYPE_INVALID);
597
598         __connman_agent_register(sender, path);
599
600         return reply;
601 }
602
603 static DBusMessage *unregister_agent(DBusConnection *conn,
604                                         DBusMessage *msg, void *data)
605 {
606         DBusMessage *reply;
607         const char *sender, *path;
608
609         DBG("conn %p", conn);
610
611         sender = dbus_message_get_sender(msg);
612
613         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
614                                                         DBUS_TYPE_INVALID);
615
616         reply = dbus_message_new_method_return(msg);
617         if (reply == NULL)
618                 return NULL;
619
620         dbus_message_append_args(reply, DBUS_TYPE_INVALID);
621
622         __connman_agent_unregister(sender, path);
623
624         return reply;
625 }
626
627 static GDBusMethodTable manager_methods[] = {
628         { "GetProperties",     "",      "a{sv}", get_properties     },
629         { "SetProperty",       "sv",    "",      set_property       },
630         { "GetState",          "",      "s",     get_state          },
631         { "CreateProfile",     "s",     "o",     create_profile     },
632         { "RemoveProfile",     "o",     "",      remove_profile     },
633         { "RequestScan",       "s",     "",      request_scan       },
634         { "EnableTechnology",  "s",     "",      enable_technology,
635                                                 G_DBUS_METHOD_FLAG_ASYNC },
636         { "DisableTechnology", "s",     "",      disable_technology,
637                                                 G_DBUS_METHOD_FLAG_ASYNC },
638         { "ConnectService",    "a{sv}", "o",     connect_service,
639                                                 G_DBUS_METHOD_FLAG_ASYNC },
640         { "RegisterAgent",     "o",     "",      register_agent     },
641         { "UnregisterAgent",   "o",     "",      unregister_agent   },
642         { },
643 };
644
645 static GDBusSignalTable manager_signals[] = {
646         { "PropertyChanged", "sv" },
647         { "StateChanged",    "s"  },
648         { },
649 };
650
651 static DBusMessage *nm_sleep(DBusConnection *conn,
652                                         DBusMessage *msg, void *data)
653 {
654         DBusMessage *reply;
655
656         DBG("conn %p", conn);
657
658         reply = dbus_message_new_method_return(msg);
659         if (reply == NULL)
660                 return NULL;
661
662         dbus_message_append_args(reply, DBUS_TYPE_INVALID);
663
664         return reply;
665 }
666
667 static DBusMessage *nm_wake(DBusConnection *conn,
668                                         DBusMessage *msg, void *data)
669 {
670         DBusMessage *reply;
671
672         DBG("conn %p", conn);
673
674         reply = dbus_message_new_method_return(msg);
675         if (reply == NULL)
676                 return NULL;
677
678         dbus_message_append_args(reply, DBUS_TYPE_INVALID);
679
680         return reply;
681 }
682
683 enum {
684         NM_STATE_UNKNOWN = 0,
685         NM_STATE_ASLEEP,
686         NM_STATE_CONNECTING,
687         NM_STATE_CONNECTED,
688         NM_STATE_DISCONNECTED
689 };
690
691 static DBusMessage *nm_state(DBusConnection *conn,
692                                         DBusMessage *msg, void *data)
693 {
694         DBusMessage *reply;
695         dbus_uint32_t state;
696
697         DBG("conn %p", conn);
698
699         reply = dbus_message_new_method_return(msg);
700         if (reply == NULL)
701                 return NULL;
702
703         if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
704                 state = NM_STATE_CONNECTED;
705         else
706                 state = NM_STATE_DISCONNECTED;
707
708         dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state,
709                                                         DBUS_TYPE_INVALID);
710
711         return reply;
712 }
713
714 static GDBusMethodTable nm_methods[] = {
715         { "sleep", "",  "",   nm_sleep        },
716         { "wake",  "",  "",   nm_wake         },
717         { "state", "",  "u",  nm_state        },
718         { },
719 };
720
721 static gboolean nm_compat = FALSE;
722
723 int __connman_manager_init(gboolean compat)
724 {
725         DBG("");
726
727         connection = connman_dbus_get_connection();
728         if (connection == NULL)
729                 return -1;
730
731         if (connman_notifier_register(&technology_notifier) < 0)
732                 connman_error("Failed to register technology notifier");
733
734         g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
735                                         CONNMAN_MANAGER_INTERFACE,
736                                         manager_methods,
737                                         manager_signals, NULL, NULL, NULL);
738
739         if (compat == TRUE) {
740                 g_dbus_register_interface(connection, NM_PATH, NM_INTERFACE,
741                                         nm_methods, NULL, NULL, NULL, NULL);
742
743                 nm_compat = TRUE;
744         }
745
746         return 0;
747 }
748
749 void __connman_manager_cleanup(void)
750 {
751         DBG("");
752
753         connman_notifier_unregister(&technology_notifier);
754
755         if (connection == NULL)
756                 return;
757
758         if (nm_compat == TRUE) {
759                 g_dbus_unregister_interface(connection, NM_PATH, NM_INTERFACE);
760         }
761
762         g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
763                                                 CONNMAN_MANAGER_INTERFACE);
764
765         dbus_connection_unref(connection);
766 }