Merge tag 'upstream/1.40' into tizen.
[platform/upstream/connman.git] / src / manager.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2013  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
28 #include <gdbus.h>
29
30 #include <connman/agent.h>
31
32 #include "connman.h"
33
34 static bool connman_state_idle;
35 static dbus_bool_t sessionmode;
36
37 static DBusMessage *get_properties(DBusConnection *conn,
38                                         DBusMessage *msg, void *data)
39 {
40         DBusMessage *reply;
41         DBusMessageIter array, dict;
42         dbus_bool_t offlinemode;
43         const char *str;
44 #if defined TIZEN_EXT
45         dbus_bool_t autoconnectmode;
46 #endif
47
48         DBG("conn %p", conn);
49
50         reply = dbus_message_new_method_return(msg);
51         if (!reply)
52                 return NULL;
53
54         dbus_message_iter_init_append(reply, &array);
55
56         connman_dbus_dict_open(&array, &dict);
57
58         str = __connman_notifier_get_state();
59         connman_dbus_dict_append_basic(&dict, "State",
60                                                 DBUS_TYPE_STRING, &str);
61
62         offlinemode = __connman_technology_get_offlinemode();
63         connman_dbus_dict_append_basic(&dict, "OfflineMode",
64                                         DBUS_TYPE_BOOLEAN, &offlinemode);
65
66         connman_dbus_dict_append_basic(&dict, "SessionMode",
67                                         DBUS_TYPE_BOOLEAN,
68                                         &sessionmode);
69 #if defined TIZEN_EXT
70         autoconnectmode = __connman_service_get_auto_connect_mode();
71         connman_dbus_dict_append_basic(&dict, "AutoConnectMode",
72                                         DBUS_TYPE_BOOLEAN,
73                                         &autoconnectmode);
74 #endif
75
76         connman_dbus_dict_close(&array, &dict);
77
78         return reply;
79 }
80
81 static DBusMessage *set_property(DBusConnection *conn,
82                                         DBusMessage *msg, void *data)
83 {
84         DBusMessageIter iter, value;
85         const char *name;
86         int type;
87
88         DBG("conn %p", conn);
89
90         if (!dbus_message_iter_init(msg, &iter))
91                 return __connman_error_invalid_arguments(msg);
92
93         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
94                 return __connman_error_invalid_arguments(msg);
95
96         dbus_message_iter_get_basic(&iter, &name);
97         dbus_message_iter_next(&iter);
98
99         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
100                 return __connman_error_invalid_arguments(msg);
101
102         dbus_message_iter_recurse(&iter, &value);
103
104         type = dbus_message_iter_get_arg_type(&value);
105
106         if (g_str_equal(name, "OfflineMode")) {
107                 dbus_bool_t offlinemode;
108
109                 if (type != DBUS_TYPE_BOOLEAN)
110                         return __connman_error_invalid_arguments(msg);
111
112                 dbus_message_iter_get_basic(&value, &offlinemode);
113
114                 __connman_technology_set_offlinemode(offlinemode);
115         } else if (g_str_equal(name, "SessionMode")) {
116
117                 if (type != DBUS_TYPE_BOOLEAN)
118                         return __connman_error_invalid_arguments(msg);
119
120                 dbus_message_iter_get_basic(&value, &sessionmode);
121 #if defined TIZEN_EXT
122         } else if (g_str_equal(name, "AutoConnectMode") == TRUE) {
123                 bool automode;
124
125                 if (type != DBUS_TYPE_BOOLEAN)
126                         return __connman_error_invalid_arguments(msg);
127
128                 dbus_message_iter_get_basic(&value, &automode);
129
130                 __connman_service_set_auto_connect_mode(automode);
131 #endif
132         } else
133                 return __connman_error_invalid_property(msg);
134
135         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
136 }
137
138 static void append_technology_structs(DBusMessageIter *iter, void *user_data)
139 {
140         __connman_technology_list_struct(iter);
141 }
142
143 static DBusMessage *get_technologies(DBusConnection *conn,
144                 DBusMessage *msg, void *data)
145 {
146         DBusMessage *reply;
147
148 #if !defined TIZEN_EXT
149         DBG("");
150 #endif
151
152         reply = dbus_message_new_method_return(msg);
153         if (!reply)
154                 return NULL;
155
156         __connman_dbus_append_objpath_dict_array(reply,
157                         append_technology_structs, NULL);
158
159         return reply;
160 }
161
162 static DBusMessage *remove_provider(DBusConnection *conn,
163                                     DBusMessage *msg, void *data)
164 {
165         const char *path;
166         int err;
167
168         DBG("conn %p", conn);
169
170         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
171                                                         DBUS_TYPE_INVALID);
172
173         err = __connman_provider_remove_by_path(path);
174         if (err < 0)
175                 return __connman_error_failed(msg, -err);
176
177         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
178 }
179
180 static DBusConnection *connection = NULL;
181
182 static void idle_state(bool idle)
183 {
184
185         DBG("idle %d", idle);
186
187         connman_state_idle = idle;
188
189         if (!connman_state_idle)
190                 return;
191 }
192
193 static const struct connman_notifier technology_notifier = {
194         .name           = "manager",
195         .priority       = CONNMAN_NOTIFIER_PRIORITY_HIGH,
196         .idle_state     = idle_state,
197 };
198
199 static void append_service_structs(DBusMessageIter *iter, void *user_data)
200 {
201         __connman_service_list_struct(iter);
202 }
203
204 static DBusMessage *get_services(DBusConnection *conn,
205                                         DBusMessage *msg, void *data)
206 {
207         DBusMessage *reply;
208
209         reply = dbus_message_new_method_return(msg);
210         if (!reply)
211                 return NULL;
212
213         __connman_dbus_append_objpath_dict_array(reply,
214                         append_service_structs, NULL);
215
216         return reply;
217 }
218
219 #if defined TIZEN_EXT
220 static DBusMessage *get_interfaces(DBusConnection *conn, DBusMessage *msg, void *data)
221 {
222         DBusMessage *reply;
223         DBusMessageIter iter, array;
224         const char *default_interface = connman_setting_get_string("DefaultWifiInterface");
225
226         DBG("DefaultWifiInterface %s", default_interface);
227
228         reply = dbus_message_new_method_return(msg);
229         if (!reply)
230                 return NULL;
231
232         dbus_message_iter_init_append(reply, &iter);
233         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
234                                         DBUS_TYPE_STRING_AS_STRING, &array);
235
236         dbus_message_iter_append_basic(&array,
237                                 DBUS_TYPE_STRING, &default_interface);
238
239         __connman_technology_append_interfaces(&array,
240                         CONNMAN_SERVICE_TYPE_WIFI, default_interface);
241
242         dbus_message_iter_close_container(&iter, &array);
243         return reply;
244 }
245
246 static DBusMessage *get_default_service(DBusConnection *conn,
247                                         DBusMessage *msg, void *data)
248 {
249         struct connman_service *service = connman_service_get_default_connection();
250         DBG("service %p", service);
251
252         return connman_service_create_dbus_service_reply(msg, service);
253 }
254
255 static DBusMessage *get_connected_service(DBusConnection *conn,
256                                         DBusMessage *msg, void *data)
257 {
258         const char *ifname;
259         struct connman_service *service;
260
261         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ifname,
262                                                         DBUS_TYPE_INVALID);
263
264         service = connman_service_get_connected_service(ifname);
265         DBG("Interface Name %s, service %p", ifname, service);
266
267         return connman_service_create_dbus_service_reply(msg, service);
268 }
269 #endif
270
271 #if defined TIZEN_EXT_INS
272 static void append_ins_structs(DBusMessageIter *iter, void *user_data)
273 {
274         __connman_ins_list_struct(iter);
275 }
276
277 static DBusMessage *get_ins(DBusConnection *conn,
278                                         DBusMessage *msg, void *data)
279 {
280         DBusMessage *reply;
281
282         reply = dbus_message_new_method_return(msg);
283         if (!reply)
284                 return NULL;
285
286         __connman_dbus_append_objpath_dict_array(reply,
287                         append_ins_structs, NULL);
288
289         return reply;
290 }
291 #endif
292
293 static void append_peer_structs(DBusMessageIter *iter, void *user_data)
294 {
295         __connman_peer_list_struct(iter);
296 }
297
298 static DBusMessage *get_peers(DBusConnection *conn,
299                                         DBusMessage *msg, void *data)
300 {
301         DBusMessage *reply;
302
303         reply = dbus_message_new_method_return(msg);
304         if (!reply)
305                 return NULL;
306
307         __connman_dbus_append_objpath_dict_array(reply,
308                                         append_peer_structs, NULL);
309         return reply;
310 }
311
312 static DBusMessage *get_tethering_clients(DBusConnection *conn,
313                                         DBusMessage *msg, void *data)
314 {
315         DBusMessage *reply;
316         DBusMessageIter iter, array;
317
318         reply = dbus_message_new_method_return(msg);
319         if (!reply)
320                 return NULL;
321
322         dbus_message_iter_init_append(reply, &iter);
323
324         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
325                                 DBUS_TYPE_STRING_AS_STRING, &array);
326
327         __connman_tethering_list_clients(&array);
328
329         dbus_message_iter_close_container(&iter, &array);
330         return reply;
331 }
332
333 static DBusMessage *connect_provider(DBusConnection *conn,
334                                         DBusMessage *msg, void *data)
335 {
336         int err;
337
338         DBG("conn %p", conn);
339
340         err = __connman_provider_create_and_connect(msg);
341         if (err < 0)
342                 return __connman_error_failed(msg, -err);
343
344         return NULL;
345 }
346
347 static DBusMessage *register_agent(DBusConnection *conn,
348                                         DBusMessage *msg, void *data)
349 {
350         const char *sender, *path;
351         int err;
352
353         DBG("conn %p", conn);
354
355         sender = dbus_message_get_sender(msg);
356
357         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
358                                                         DBUS_TYPE_INVALID);
359
360         err = connman_agent_register(sender, path);
361         if (err < 0)
362                 return __connman_error_failed(msg, -err);
363
364         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
365 }
366
367 static DBusMessage *unregister_agent(DBusConnection *conn,
368                                         DBusMessage *msg, void *data)
369 {
370         const char *sender, *path;
371         int err;
372
373         DBG("conn %p", conn);
374
375         sender = dbus_message_get_sender(msg);
376
377         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
378                                                         DBUS_TYPE_INVALID);
379
380         err = connman_agent_unregister(sender, path);
381         if (err < 0)
382                 return __connman_error_failed(msg, -err);
383
384         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
385 }
386
387 static DBusMessage *register_counter(DBusConnection *conn,
388                                         DBusMessage *msg, void *data)
389 {
390         const char *sender, *path;
391         unsigned int accuracy, period;
392         int err;
393
394         DBG("conn %p", conn);
395
396         sender = dbus_message_get_sender(msg);
397
398         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
399                                                 DBUS_TYPE_UINT32, &accuracy,
400                                                 DBUS_TYPE_UINT32, &period,
401                                                         DBUS_TYPE_INVALID);
402
403         /* FIXME: add handling of accuracy parameter */
404
405         err = __connman_counter_register(sender, path, period);
406         if (err < 0)
407                 return __connman_error_failed(msg, -err);
408
409         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
410 }
411
412 static DBusMessage *unregister_counter(DBusConnection *conn,
413                                         DBusMessage *msg, void *data)
414 {
415         const char *sender, *path;
416         int err;
417
418         DBG("conn %p", conn);
419
420         sender = dbus_message_get_sender(msg);
421
422         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
423                                                         DBUS_TYPE_INVALID);
424
425         err = __connman_counter_unregister(sender, path);
426         if (err < 0)
427                 return __connman_error_failed(msg, -err);
428
429         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
430 }
431
432 static DBusMessage *create_session(DBusConnection *conn,
433                                         DBusMessage *msg, void *data)
434 {
435         int err;
436
437         DBG("conn %p", conn);
438
439         err = __connman_session_create(msg);
440         if (err < 0) {
441                 if (err == -EINPROGRESS)
442                         return NULL;
443
444                 return __connman_error_failed(msg, -err);
445         }
446
447         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
448 }
449
450 static DBusMessage *destroy_session(DBusConnection *conn,
451                                         DBusMessage *msg, void *data)
452 {
453         int err;
454
455         DBG("conn %p", conn);
456
457         err = __connman_session_destroy(msg);
458         if (err < 0)
459                 return __connman_error_failed(msg, -err);
460
461         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
462 }
463
464 static DBusMessage *request_private_network(DBusConnection *conn,
465                                         DBusMessage *msg, void *data)
466 {
467         const char *sender;
468         int  err;
469
470         DBG("conn %p", conn);
471
472         sender = dbus_message_get_sender(msg);
473
474         err = __connman_private_network_request(msg, sender);
475         if (err < 0)
476                 return __connman_error_failed(msg, -err);
477
478         return NULL;
479 }
480
481 static DBusMessage *release_private_network(DBusConnection *conn,
482                                         DBusMessage *msg, void *data)
483 {
484         const char *path;
485         int err;
486
487         DBG("conn %p", conn);
488
489         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
490                                                         DBUS_TYPE_INVALID);
491
492         err = __connman_private_network_release(path);
493         if (err < 0)
494                 return __connman_error_failed(msg, -err);
495
496         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
497 }
498
499 static int parse_peers_service_specs(DBusMessageIter *array,
500                         const unsigned char **spec, int *spec_len,
501                         const unsigned char **query, int *query_len,
502                         int *version)
503 {
504         *spec = *query = NULL;
505         *spec_len = *query_len = *version = 0;
506
507         while (dbus_message_iter_get_arg_type(array) ==
508                                                         DBUS_TYPE_DICT_ENTRY) {
509                 DBusMessageIter entry, inter, value;
510                 const char *key;
511
512                 dbus_message_iter_recurse(array, &entry);
513                 dbus_message_iter_get_basic(&entry, &key);
514
515                 dbus_message_iter_next(&entry);
516
517                 dbus_message_iter_recurse(&entry, &inter);
518
519                 if  (!g_strcmp0(key, "BonjourResponse")) {
520                         dbus_message_iter_recurse(&inter, &value);
521                         dbus_message_iter_get_fixed_array(&value,
522                                                         spec, spec_len);
523                 } else if (!g_strcmp0(key, "BonjourQuery")) {
524                         dbus_message_iter_recurse(&inter, &value);
525                         dbus_message_iter_get_fixed_array(&value,
526                                                         query, query_len);
527                 } else if (!g_strcmp0(key, "UpnpService")) {
528                         dbus_message_iter_get_basic(&inter, spec);
529                         *spec_len = strlen((const char *)*spec)+1;
530                 } else if (!g_strcmp0(key, "UpnpVersion")) {
531                         dbus_message_iter_get_basic(&inter, version);
532                 } else if (!g_strcmp0(key, "WiFiDisplayIEs")) {
533                         if (*spec || *query)
534                                 return -EINVAL;
535
536                         dbus_message_iter_recurse(&inter, &value);
537                         dbus_message_iter_get_fixed_array(&value,
538                                                         spec, spec_len);
539                 } else
540                         return -EINVAL;
541
542                 dbus_message_iter_next(array);
543         }
544
545         if ((*query && !*spec && !*version) ||
546                                 (!*spec && !*query) || (!*spec && *version))
547                 return -EINVAL;
548
549         return 0;
550 }
551
552 static DBusMessage *register_peer_service(DBusConnection *conn,
553                                                 DBusMessage *msg, void *data)
554 {
555         const unsigned char *spec, *query;
556         DBusMessageIter iter, array;
557         int spec_len, query_len;
558         dbus_bool_t master;
559         const char *owner;
560         int version;
561         int ret;
562
563         DBG("");
564
565         owner = dbus_message_get_sender(msg);
566
567         dbus_message_iter_init(msg, &iter);
568         dbus_message_iter_recurse(&iter, &array);
569
570         ret = parse_peers_service_specs(&array, &spec, &spec_len,
571                                                 &query, &query_len, &version);
572         if (ret)
573                 goto error;
574
575         dbus_message_iter_next(&iter);
576         dbus_message_iter_get_basic(&iter, &master);
577
578         ret = __connman_peer_service_register(owner, msg, spec, spec_len,
579                                         query, query_len, version,master);
580         if (!ret)
581                 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
582         if (ret == -EINPROGRESS)
583                 return NULL;
584 error:
585         return __connman_error_failed(msg, -ret);
586 }
587
588 static DBusMessage *unregister_peer_service(DBusConnection *conn,
589                                                 DBusMessage *msg, void *data)
590 {
591         const unsigned char *spec, *query;
592         DBusMessageIter iter, array;
593         int spec_len, query_len;
594         const char *owner;
595         int version;
596         int ret;
597
598         DBG("");
599
600         owner = dbus_message_get_sender(msg);
601
602         dbus_message_iter_init(msg, &iter);
603         dbus_message_iter_recurse(&iter, &array);
604
605         ret = parse_peers_service_specs(&array, &spec, &spec_len,
606                                                 &query, &query_len, &version);
607         if (ret)
608                 goto error;
609
610         ret = __connman_peer_service_unregister(owner, spec, spec_len,
611                                                 query, query_len, version);
612         if (!ret)
613                 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
614 error:
615         return __connman_error_failed(msg, -ret);
616
617 }
618
619 #if defined TIZEN_EXT_WIFI_MESH
620 static void append_mesh_peer_structs(DBusMessageIter *iter, void *user_data)
621 {
622         __connman_mesh_peer_list_struct(iter);
623 }
624
625 static DBusMessage *get_mesh_peers(DBusConnection *conn,
626                                         DBusMessage *msg, void *data)
627 {
628         DBusMessage *reply;
629
630         reply = dbus_message_new_method_return(msg);
631         if (!reply)
632                 return NULL;
633
634         __connman_dbus_append_objpath_dict_array(reply,
635                                         append_mesh_peer_structs, NULL);
636         return reply;
637 }
638
639 static DBusMessage *get_connected_mesh_peers(DBusConnection *conn,
640                                         DBusMessage *msg, void *data)
641 {
642         DBusMessage *reply;
643         DBusMessageIter iter, array;
644
645         reply = dbus_message_new_method_return(msg);
646         if (!reply)
647                 return NULL;
648
649         dbus_message_iter_init_append(reply, &iter);
650         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
651                         DBUS_STRUCT_BEGIN_CHAR_AS_STRING
652                         DBUS_TYPE_ARRAY_AS_STRING
653                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
654                                         DBUS_TYPE_STRING_AS_STRING
655                                         DBUS_TYPE_VARIANT_AS_STRING
656                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
657                         DBUS_STRUCT_END_CHAR_AS_STRING, &array);
658
659         __connman_mesh_connected_peer_list_struct(&array);
660         dbus_message_iter_close_container(&iter, &array);
661         return reply;
662 }
663
664 static DBusMessage *get_disconnected_mesh_peers(DBusConnection *conn,
665                                         DBusMessage *msg, void *data)
666 {
667         DBusMessage *reply;
668         DBusMessageIter iter, array;
669
670         reply = dbus_message_new_method_return(msg);
671         if (!reply)
672                 return NULL;
673
674         dbus_message_iter_init_append(reply, &iter);
675         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
676                         DBUS_STRUCT_BEGIN_CHAR_AS_STRING
677                         DBUS_TYPE_ARRAY_AS_STRING
678                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
679                                         DBUS_TYPE_STRING_AS_STRING
680                                         DBUS_TYPE_VARIANT_AS_STRING
681                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
682                         DBUS_STRUCT_END_CHAR_AS_STRING, &array);
683
684         __connman_mesh_disconnected_peer_list_struct(&array);
685         dbus_message_iter_close_container(&iter, &array);
686         return reply;
687 }
688
689 static DBusMessage *mesh_add_peer(DBusConnection *conn,
690                                         DBusMessage *msg, void *user_data)
691 {
692         const char *addr;
693         int err;
694
695         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
696                                                         DBUS_TYPE_INVALID);
697
698         DBG("Address %s", addr);
699
700         err = __connman_mesh_change_peer_status(msg, addr, CONNMAN_MESH_PEER_ADD);
701         if (err < 0)
702                 return __connman_error_failed(msg, -err);
703
704         return NULL;
705 }
706
707 static DBusMessage *mesh_remove_peer(DBusConnection *conn,
708                                         DBusMessage *msg, void *user_data)
709 {
710         const char *addr;
711         int err;
712
713         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
714                                                         DBUS_TYPE_INVALID);
715
716         DBG("Address %s", addr);
717
718         err = __connman_mesh_change_peer_status(msg, addr,
719                                                                                 CONNMAN_MESH_PEER_REMOVE);
720         if (err < 0)
721                 return __connman_error_failed(msg, -err);
722
723         return NULL;
724 }
725 #endif
726
727 static const GDBusMethodTable manager_methods[] = {
728         { GDBUS_METHOD("GetProperties",
729                         NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
730                         get_properties) },
731         { GDBUS_ASYNC_METHOD("SetProperty",
732                         GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
733                         NULL, set_property) },
734         { GDBUS_METHOD("GetTechnologies",
735                         NULL, GDBUS_ARGS({ "technologies", "a(oa{sv})" }),
736                         get_technologies) },
737         { GDBUS_DEPRECATED_METHOD("RemoveProvider",
738                         GDBUS_ARGS({ "provider", "o" }), NULL,
739                         remove_provider) },
740         { GDBUS_METHOD("GetServices",
741                         NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
742                         get_services) },
743 #if defined TIZEN_EXT
744         { GDBUS_METHOD("GetInterfaces",
745                         NULL, GDBUS_ARGS({ "interface_list", "as" }),
746                         get_interfaces) },
747         { GDBUS_METHOD("GetDefaultService",
748                         NULL, GDBUS_ARGS({ "service", "oa{sv}" }),
749                         get_default_service) },
750         { GDBUS_METHOD("GetConnectedService",
751                         GDBUS_ARGS({ "ifname", "s" }),
752                         GDBUS_ARGS({ "service", "oa{sv}" }),
753                         get_connected_service) },
754 #endif
755 #if defined TIZEN_EXT_INS
756         { GDBUS_METHOD("GetINS",
757                         NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
758                         get_ins) },
759 #endif
760         { GDBUS_METHOD("GetPeers",
761                         NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
762                         get_peers) },
763         { GDBUS_METHOD("GetTetheringClients",
764                         NULL, GDBUS_ARGS({ "tethering_clients", "as" }),
765                         get_tethering_clients) },
766         { GDBUS_DEPRECATED_ASYNC_METHOD("ConnectProvider",
767                               GDBUS_ARGS({ "provider", "a{sv}" }),
768                               GDBUS_ARGS({ "path", "o" }),
769                               connect_provider) },
770         { GDBUS_METHOD("RegisterAgent",
771                         GDBUS_ARGS({ "path", "o" }), NULL,
772                         register_agent) },
773         { GDBUS_METHOD("UnregisterAgent",
774                         GDBUS_ARGS({ "path", "o" }), NULL,
775                         unregister_agent) },
776         { GDBUS_METHOD("RegisterCounter",
777                         GDBUS_ARGS({ "path", "o" }, { "accuracy", "u" },
778                                         { "period", "u" }),
779                         NULL, register_counter) },
780         { GDBUS_METHOD("UnregisterCounter",
781                         GDBUS_ARGS({ "path", "o" }), NULL,
782                         unregister_counter) },
783         { GDBUS_ASYNC_METHOD("CreateSession",
784                         GDBUS_ARGS({ "settings", "a{sv}" },
785                                                 { "notifier", "o" }),
786                         GDBUS_ARGS({ "session", "o" }),
787                         create_session) },
788         { GDBUS_METHOD("DestroySession",
789                         GDBUS_ARGS({ "session", "o" }), NULL,
790                         destroy_session) },
791         { GDBUS_ASYNC_METHOD("RequestPrivateNetwork",
792                               NULL, GDBUS_ARGS({ "path", "o" },
793                                                { "settings", "a{sv}" },
794                                                { "socket", "h" }),
795                               request_private_network) },
796         { GDBUS_METHOD("ReleasePrivateNetwork",
797                         GDBUS_ARGS({ "path", "o" }), NULL,
798                         release_private_network) },
799         { GDBUS_ASYNC_METHOD("RegisterPeerService",
800                         GDBUS_ARGS({ "specification", "a{sv}" },
801                                    { "master", "b" }), NULL,
802                         register_peer_service) },
803         { GDBUS_METHOD("UnregisterPeerService",
804                         GDBUS_ARGS({ "specification", "a{sv}" }), NULL,
805                         unregister_peer_service) },
806 #if defined TIZEN_EXT_WIFI_MESH
807         { GDBUS_METHOD("GetMeshPeers",
808                         NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
809                         get_mesh_peers) },
810         { GDBUS_METHOD("GetConnectedMeshPeers",
811                         NULL, GDBUS_ARGS({ "peers", "a(a{sv})" }),
812                         get_connected_mesh_peers) },
813         { GDBUS_METHOD("GetDisconnectedMeshPeers",
814                         NULL, GDBUS_ARGS({ "peers", "a(a{sv})" }),
815                         get_disconnected_mesh_peers) },
816         { GDBUS_ASYNC_METHOD("MeshAddPeer", GDBUS_ARGS({ "address", "s" }), NULL,
817                                    mesh_add_peer) },
818         { GDBUS_ASYNC_METHOD("MeshRemovePeer", GDBUS_ARGS({ "address", "s" }), NULL,
819                                    mesh_remove_peer) },
820 #endif
821         { },
822 };
823
824 static const GDBusSignalTable manager_signals[] = {
825         { GDBUS_SIGNAL("PropertyChanged",
826                         GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
827         { GDBUS_SIGNAL("TechnologyAdded",
828                         GDBUS_ARGS({ "path", "o" },
829                                    { "properties", "a{sv}" })) },
830         { GDBUS_SIGNAL("TechnologyRemoved",
831                         GDBUS_ARGS({ "path", "o" })) },
832         { GDBUS_SIGNAL("ServicesChanged",
833                         GDBUS_ARGS({ "changed", "a(oa{sv})" },
834                                         { "removed", "ao" })) },
835         { GDBUS_SIGNAL("PeersChanged",
836                         GDBUS_ARGS({ "changed", "a(oa{sv})" },
837                                         { "removed", "ao" })) },
838         { },
839 };
840
841 int __connman_manager_init(void)
842 {
843         DBG("");
844
845         connection = connman_dbus_get_connection();
846         if (!connection)
847                 return -1;
848
849         if (connman_notifier_register(&technology_notifier) < 0)
850                 connman_error("Failed to register technology notifier");
851
852         g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
853                                         CONNMAN_MANAGER_INTERFACE,
854                                         manager_methods,
855                                         manager_signals, NULL, NULL, NULL);
856
857         connman_state_idle = true;
858
859         return 0;
860 }
861
862 void __connman_manager_cleanup(void)
863 {
864         DBG("");
865
866         if (!connection)
867                 return;
868
869         connman_notifier_unregister(&technology_notifier);
870
871         g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
872                                                 CONNMAN_MANAGER_INTERFACE);
873
874         dbus_connection_unref(connection);
875 }