Remove unused connection interface
[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_available_technologies(DBusMessageIter *dict)
103 {
104         DBusMessageIter entry, value, iter;
105         const char *key = "AvailableTechnologies";
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_STRING_AS_STRING,
114                                                                 &value);
115
116         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
117                                         DBUS_TYPE_STRING_AS_STRING, &iter);
118         __connman_notifier_list_registered(&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_enabled_technologies(DBusMessageIter *dict)
127 {
128         DBusMessageIter entry, value, iter;
129         const char *key = "EnabledTechnologies";
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_enabled(&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_connected_technologies(DBusMessageIter *dict)
151 {
152         DBusMessageIter entry, value, iter;
153         const char *key = "ConnectedTechnologies";
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_connected(&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_available_debugs(DBusMessageIter *dict)
175 {
176         DBusMessageIter entry, value, iter;
177         const char *key = "AvailableDebugs";
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_debug_list_available(&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 void append_enabled_debugs(DBusMessageIter *dict)
199 {
200         DBusMessageIter entry, value, iter;
201         const char *key = "EnabledDebugs";
202
203         dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
204                                                                 NULL, &entry);
205
206         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
207
208         dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
209                         DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
210                                                                 &value);
211
212         dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
213                                         DBUS_TYPE_STRING_AS_STRING, &iter);
214         __connman_debug_list_enabled(&iter);
215         dbus_message_iter_close_container(&value, &iter);
216
217         dbus_message_iter_close_container(&entry, &value);
218
219         dbus_message_iter_close_container(dict, &entry);
220 }
221
222 static DBusMessage *get_properties(DBusConnection *conn,
223                                         DBusMessage *msg, void *data)
224 {
225         DBusMessage *reply;
226         DBusMessageIter array, dict;
227         connman_bool_t offlinemode;
228         const char *str;
229
230         DBG("conn %p", conn);
231
232         if (__connman_security_check_privilege(msg,
233                                         CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
234                 return __connman_error_permission_denied(msg);
235
236         reply = dbus_message_new_method_return(msg);
237         if (reply == NULL)
238                 return NULL;
239
240         dbus_message_iter_init_append(reply, &array);
241
242         dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
243                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
244                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
245                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
246
247         str = __connman_profile_active_path();
248         if (str != NULL)
249                 connman_dbus_dict_append_variant(&dict, "ActiveProfile",
250                                                 DBUS_TYPE_OBJECT_PATH, &str);
251
252         append_profiles(&dict);
253         append_services(&dict);
254
255         append_devices(&dict);
256
257         if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
258                 str = "online";
259         else
260                 str = "offline";
261
262         connman_dbus_dict_append_variant(&dict, "State",
263                                                 DBUS_TYPE_STRING, &str);
264
265         offlinemode = __connman_profile_get_offlinemode();
266         connman_dbus_dict_append_variant(&dict, "OfflineMode",
267                                         DBUS_TYPE_BOOLEAN, &offlinemode);
268
269         append_available_technologies(&dict);
270         append_enabled_technologies(&dict);
271         append_connected_technologies(&dict);
272
273         str = __connman_service_default();
274         if (str != NULL)
275                 connman_dbus_dict_append_variant(&dict, "DefaultTechnology",
276                                                 DBUS_TYPE_STRING, &str);
277
278         append_available_debugs(&dict);
279         append_enabled_debugs(&dict);
280
281         dbus_message_iter_close_container(&array, &dict);
282
283         return reply;
284 }
285
286 static DBusMessage *set_property(DBusConnection *conn,
287                                         DBusMessage *msg, void *data)
288 {
289         DBusMessageIter iter, value;
290         const char *name;
291         int type;
292
293         DBG("conn %p", conn);
294
295         if (dbus_message_iter_init(msg, &iter) == FALSE)
296                 return __connman_error_invalid_arguments(msg);
297
298         dbus_message_iter_get_basic(&iter, &name);
299         dbus_message_iter_next(&iter);
300         dbus_message_iter_recurse(&iter, &value);
301
302         if (__connman_security_check_privilege(msg,
303                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
304                 return __connman_error_permission_denied(msg);
305
306         type = dbus_message_iter_get_arg_type(&value);
307
308         if (g_str_equal(name, "OfflineMode") == TRUE) {
309                 connman_bool_t offlinemode;
310
311                 if (type != DBUS_TYPE_BOOLEAN)
312                         return __connman_error_invalid_arguments(msg);
313
314                 dbus_message_iter_get_basic(&value, &offlinemode);
315
316                 __connman_profile_set_offlinemode(offlinemode);
317
318                 __connman_profile_save_default();
319         } else if (g_str_equal(name, "ActiveProfile") == TRUE) {
320                 const char *str;
321
322                 dbus_message_iter_get_basic(&value, &str);
323
324                 return __connman_error_not_supported(msg);
325         } else
326                 return __connman_error_invalid_property(msg);
327
328         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
329 }
330
331 static DBusMessage *get_state(DBusConnection *conn,
332                                         DBusMessage *msg, void *data)
333 {
334         const char *str;
335
336         DBG("conn %p", conn);
337
338         if (__connman_security_check_privilege(msg,
339                                         CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0)
340                 return __connman_error_permission_denied(msg);
341
342         if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
343                 str = "online";
344         else
345                 str = "offline";
346
347         return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str,
348                                                 DBUS_TYPE_INVALID);
349 }
350
351 static DBusMessage *create_profile(DBusConnection *conn,
352                                         DBusMessage *msg, void *data)
353 {
354         const char *name, *path;
355         int err;
356
357         DBG("conn %p", conn);
358
359         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
360                                                         DBUS_TYPE_INVALID);
361
362         if (__connman_security_check_privilege(msg,
363                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
364                 return __connman_error_permission_denied(msg);
365
366         err = __connman_profile_create(name, &path);
367         if (err < 0)
368                 return __connman_error_failed(msg, -err);
369
370         return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
371                                                         DBUS_TYPE_INVALID);
372 }
373
374 static DBusMessage *remove_profile(DBusConnection *conn,
375                                         DBusMessage *msg, void *data)
376 {
377         const char *path;
378         int err;
379
380         DBG("conn %p", conn);
381
382         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
383                                                         DBUS_TYPE_INVALID);
384
385         if (__connman_security_check_privilege(msg,
386                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
387                 return __connman_error_permission_denied(msg);
388
389         err = __connman_profile_remove(path);
390         if (err < 0)
391                 return __connman_error_failed(msg, -err);
392
393         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
394 }
395
396 static DBusMessage *request_scan(DBusConnection *conn,
397                                         DBusMessage *msg, void *data)
398 {
399         enum connman_service_type type;
400         const char *str;
401         int err;
402
403         DBG("conn %p", conn);
404
405         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
406                                                         DBUS_TYPE_INVALID);
407
408         if (g_strcmp0(str, "") == 0)
409                 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
410         else if (g_strcmp0(str, "wifi") == 0)
411                 type = CONNMAN_SERVICE_TYPE_WIFI;
412         else if (g_strcmp0(str, "wimax") == 0)
413                 type = CONNMAN_SERVICE_TYPE_WIMAX;
414         else
415                 return __connman_error_invalid_arguments(msg);
416
417         err = __connman_element_request_scan(type);
418         if (err < 0) {
419                 if (err == -EINPROGRESS) {
420                         connman_error("Invalid return code from scan");
421                         err = -EINVAL;
422                 }
423
424                 return __connman_error_failed(msg, -err);
425         }
426
427         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
428 }
429
430 static DBusConnection *connection = NULL;
431
432 static enum connman_service_type technology_type;
433 static connman_bool_t technology_enabled;
434 static DBusMessage *technology_pending = NULL;
435 static guint technology_timeout = 0;
436
437 static void technology_reply(int error)
438 {
439         DBG("");
440
441         if (technology_timeout > 0) {
442                 g_source_remove(technology_timeout);
443                 technology_timeout = 0;
444         }
445
446         if (technology_pending != NULL) {
447                 if (error > 0) {
448                         DBusMessage *reply;
449
450                         reply = __connman_error_failed(technology_pending,
451                                                                 error);
452                         if (reply != NULL)
453                                 g_dbus_send_message(connection, reply);
454                 } else
455                         g_dbus_send_reply(connection, technology_pending,
456                                                         DBUS_TYPE_INVALID);
457
458                 dbus_message_unref(technology_pending);
459                 technology_pending = NULL;
460         }
461
462         technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
463 }
464
465 static gboolean technology_abort(gpointer user_data)
466 {
467         DBG("");
468
469         technology_timeout = 0;
470
471         technology_reply(ETIMEDOUT);
472
473         return FALSE;
474 }
475
476 static void technology_notify(enum connman_service_type type,
477                                                 connman_bool_t enabled)
478 {
479         DBG("type %d enabled %d", type, enabled);
480
481         if (type == technology_type && enabled == technology_enabled)
482                 technology_reply(0);
483 }
484
485 static struct connman_notifier technology_notifier = {
486         .name           = "manager",
487         .priority       = CONNMAN_NOTIFIER_PRIORITY_HIGH,
488         .service_enabled= technology_notify,
489 };
490
491 static DBusMessage *enable_technology(DBusConnection *conn,
492                                         DBusMessage *msg, void *data)
493 {
494         enum connman_service_type type;
495         const char *str;
496         int err;
497
498         DBG("conn %p", conn);
499
500         if (technology_pending != NULL)
501                 return __connman_error_in_progress(msg);
502
503         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
504                                                         DBUS_TYPE_INVALID);
505
506         if (g_strcmp0(str, "ethernet") == 0)
507                 type = CONNMAN_SERVICE_TYPE_ETHERNET;
508         else if (g_strcmp0(str, "wifi") == 0)
509                 type = CONNMAN_SERVICE_TYPE_WIFI;
510         else if (g_strcmp0(str, "wimax") == 0)
511                 type = CONNMAN_SERVICE_TYPE_WIMAX;
512         else if (g_strcmp0(str, "bluetooth") == 0)
513                 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
514         else if (g_strcmp0(str, "cellular") == 0)
515                 type = CONNMAN_SERVICE_TYPE_CELLULAR;
516         else
517                 return __connman_error_invalid_arguments(msg);
518
519         if (__connman_notifier_is_enabled(type) == TRUE)
520                 return __connman_error_already_enabled(msg);
521
522         technology_type = type;
523         technology_enabled = TRUE;
524         technology_pending = dbus_message_ref(msg);
525
526         err = __connman_element_enable_technology(type);
527         if (err < 0 && err != -EINPROGRESS)
528                 technology_reply(-err);
529         else
530                 technology_timeout = g_timeout_add_seconds(15,
531                                                 technology_abort, NULL);
532
533         return NULL;
534 }
535
536 static DBusMessage *disable_technology(DBusConnection *conn,
537                                         DBusMessage *msg, void *data)
538 {
539         enum connman_service_type type;
540         const char *str;
541         int err;
542
543         DBG("conn %p", conn);
544
545         if (technology_pending != NULL)
546                 return __connman_error_in_progress(msg);
547
548         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
549                                                         DBUS_TYPE_INVALID);
550
551         if (g_strcmp0(str, "ethernet") == 0)
552                 type = CONNMAN_SERVICE_TYPE_ETHERNET;
553         else if (g_strcmp0(str, "wifi") == 0)
554                 type = CONNMAN_SERVICE_TYPE_WIFI;
555         else if (g_strcmp0(str, "wimax") == 0)
556                 type = CONNMAN_SERVICE_TYPE_WIMAX;
557         else if (g_strcmp0(str, "bluetooth") == 0)
558                 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
559         else if (g_strcmp0(str, "cellular") == 0)
560                 type = CONNMAN_SERVICE_TYPE_CELLULAR;
561         else
562                 return __connman_error_invalid_arguments(msg);
563
564         if (__connman_notifier_is_enabled(type) == FALSE)
565                 return __connman_error_already_disabled(msg);
566
567         technology_type = type;
568         technology_enabled = FALSE;
569         technology_pending = dbus_message_ref(msg);
570
571         err = __connman_element_disable_technology(type);
572         if (err < 0 && err != -EINPROGRESS)
573                 technology_reply(-err);
574         else
575                 technology_timeout = g_timeout_add_seconds(10,
576                                                 technology_abort, NULL);
577
578         return NULL;
579 }
580
581 static DBusMessage *connect_service(DBusConnection *conn,
582                                         DBusMessage *msg, void *data)
583 {
584         int err;
585
586         DBG("conn %p", conn);
587
588         if (__connman_security_check_privilege(msg,
589                                         CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
590                 return __connman_error_permission_denied(msg);
591
592         err = __connman_service_create_and_connect(msg);
593         if (err < 0) {
594                 if (err == -EINPROGRESS) {
595                         connman_error("Invalid return code from connect");
596                         err = -EINVAL;
597                 }
598
599                 return __connman_error_failed(msg, -err);
600         }
601
602         return NULL;
603 }
604
605 static DBusMessage *register_agent(DBusConnection *conn,
606                                         DBusMessage *msg, void *data)
607 {
608         const char *sender, *path;
609         int err;
610
611         DBG("conn %p", conn);
612
613         sender = dbus_message_get_sender(msg);
614
615         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
616                                                         DBUS_TYPE_INVALID);
617
618         err = __connman_agent_register(sender, path);
619         if (err < 0)
620                 return __connman_error_failed(msg, -err);
621
622         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
623 }
624
625 static DBusMessage *unregister_agent(DBusConnection *conn,
626                                         DBusMessage *msg, void *data)
627 {
628         const char *sender, *path;
629         int err;
630
631         DBG("conn %p", conn);
632
633         sender = dbus_message_get_sender(msg);
634
635         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
636                                                         DBUS_TYPE_INVALID);
637
638         err = __connman_agent_unregister(sender, path);
639         if (err < 0)
640                 return __connman_error_failed(msg, -err);
641
642         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
643 }
644
645 static GDBusMethodTable manager_methods[] = {
646         { "GetProperties",     "",      "a{sv}", get_properties     },
647         { "SetProperty",       "sv",    "",      set_property       },
648         { "GetState",          "",      "s",     get_state          },
649         { "CreateProfile",     "s",     "o",     create_profile     },
650         { "RemoveProfile",     "o",     "",      remove_profile     },
651         { "RequestScan",       "s",     "",      request_scan       },
652         { "EnableTechnology",  "s",     "",      enable_technology,
653                                                 G_DBUS_METHOD_FLAG_ASYNC },
654         { "DisableTechnology", "s",     "",      disable_technology,
655                                                 G_DBUS_METHOD_FLAG_ASYNC },
656         { "ConnectService",    "a{sv}", "o",     connect_service,
657                                                 G_DBUS_METHOD_FLAG_ASYNC },
658         { "RegisterAgent",     "o",     "",      register_agent     },
659         { "UnregisterAgent",   "o",     "",      unregister_agent   },
660         { },
661 };
662
663 static GDBusSignalTable manager_signals[] = {
664         { "PropertyChanged", "sv" },
665         { "StateChanged",    "s"  },
666         { },
667 };
668
669 static DBusMessage *nm_sleep(DBusConnection *conn,
670                                         DBusMessage *msg, void *data)
671 {
672         DBusMessage *reply;
673
674         DBG("conn %p", conn);
675
676         reply = dbus_message_new_method_return(msg);
677         if (reply == NULL)
678                 return NULL;
679
680         dbus_message_append_args(reply, DBUS_TYPE_INVALID);
681
682         return reply;
683 }
684
685 static DBusMessage *nm_wake(DBusConnection *conn,
686                                         DBusMessage *msg, void *data)
687 {
688         DBusMessage *reply;
689
690         DBG("conn %p", conn);
691
692         reply = dbus_message_new_method_return(msg);
693         if (reply == NULL)
694                 return NULL;
695
696         dbus_message_append_args(reply, DBUS_TYPE_INVALID);
697
698         return reply;
699 }
700
701 enum {
702         NM_STATE_UNKNOWN = 0,
703         NM_STATE_ASLEEP,
704         NM_STATE_CONNECTING,
705         NM_STATE_CONNECTED,
706         NM_STATE_DISCONNECTED
707 };
708
709 static DBusMessage *nm_state(DBusConnection *conn,
710                                         DBusMessage *msg, void *data)
711 {
712         DBusMessage *reply;
713         dbus_uint32_t state;
714
715         DBG("conn %p", conn);
716
717         reply = dbus_message_new_method_return(msg);
718         if (reply == NULL)
719                 return NULL;
720
721         if (__connman_element_count(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION) > 0)
722                 state = NM_STATE_CONNECTED;
723         else
724                 state = NM_STATE_DISCONNECTED;
725
726         dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state,
727                                                         DBUS_TYPE_INVALID);
728
729         return reply;
730 }
731
732 static GDBusMethodTable nm_methods[] = {
733         { "sleep", "",  "",   nm_sleep        },
734         { "wake",  "",  "",   nm_wake         },
735         { "state", "",  "u",  nm_state        },
736         { },
737 };
738
739 static gboolean nm_compat = FALSE;
740
741 int __connman_manager_init(gboolean compat)
742 {
743         DBG("");
744
745         connection = connman_dbus_get_connection();
746         if (connection == NULL)
747                 return -1;
748
749         if (connman_notifier_register(&technology_notifier) < 0)
750                 connman_error("Failed to register technology notifier");
751
752         g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
753                                         CONNMAN_MANAGER_INTERFACE,
754                                         manager_methods,
755                                         manager_signals, NULL, NULL, NULL);
756
757         if (compat == TRUE) {
758                 g_dbus_register_interface(connection, NM_PATH, NM_INTERFACE,
759                                         nm_methods, NULL, NULL, NULL, NULL);
760
761                 nm_compat = TRUE;
762         }
763
764         return 0;
765 }
766
767 void __connman_manager_cleanup(void)
768 {
769         DBG("");
770
771         connman_notifier_unregister(&technology_notifier);
772
773         if (connection == NULL)
774                 return;
775
776         if (nm_compat == TRUE) {
777                 g_dbus_unregister_interface(connection, NM_PATH, NM_INTERFACE);
778         }
779
780         g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
781                                                 CONNMAN_MANAGER_INTERFACE);
782
783         dbus_connection_unref(connection);
784 }