Merge "Fix SIGSEV on freeing server domains list" 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
270 static DBusMessage *get_dhcp_status(DBusConnection *conn, DBusMessage *msg, void *data)
271 {
272         const char *ifname;
273         const char *dhcp_status;
274         DBusMessage *reply;
275         DBusMessageIter iter;
276
277         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ifname, DBUS_TYPE_INVALID);
278         dhcp_status = __connman_network_get_dhcp_status(ifname);
279
280         reply = dbus_message_new_method_return(msg);
281         if (!reply)
282                 return NULL;
283
284         if (!dhcp_status)
285                 dhcp_status = "Unknown";
286
287         dbus_message_iter_init_append(reply, &iter);
288         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &dhcp_status);
289
290         return reply;
291 }
292
293 static void append_ins_structs(DBusMessageIter *iter, void *user_data)
294 {
295         __connman_ins_list_struct(iter);
296 }
297
298 static DBusMessage *get_ins(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         if (TIZEN_INS_ENABLED)
308                 __connman_dbus_append_objpath_dict_array(reply,
309                                 append_ins_structs, NULL);
310
311         return reply;
312 }
313 #endif
314
315 static void append_peer_structs(DBusMessageIter *iter, void *user_data)
316 {
317         __connman_peer_list_struct(iter);
318 }
319
320 static DBusMessage *get_peers(DBusConnection *conn,
321                                         DBusMessage *msg, void *data)
322 {
323         DBusMessage *reply;
324
325         reply = dbus_message_new_method_return(msg);
326         if (!reply)
327                 return NULL;
328
329         __connman_dbus_append_objpath_dict_array(reply,
330                                         append_peer_structs, NULL);
331         return reply;
332 }
333
334 static DBusMessage *get_tethering_clients(DBusConnection *conn,
335                                         DBusMessage *msg, void *data)
336 {
337         DBusMessage *reply;
338         DBusMessageIter iter, array;
339
340         reply = dbus_message_new_method_return(msg);
341         if (!reply)
342                 return NULL;
343
344         dbus_message_iter_init_append(reply, &iter);
345
346         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
347                                 DBUS_TYPE_STRING_AS_STRING, &array);
348
349         __connman_tethering_list_clients(&array);
350
351         dbus_message_iter_close_container(&iter, &array);
352         return reply;
353 }
354
355 static DBusMessage *connect_provider(DBusConnection *conn,
356                                         DBusMessage *msg, void *data)
357 {
358         int err;
359
360         DBG("conn %p", conn);
361
362         err = __connman_provider_create_and_connect(msg);
363         if (err < 0)
364                 return __connman_error_failed(msg, -err);
365
366         return NULL;
367 }
368
369 static DBusMessage *register_agent(DBusConnection *conn,
370                                         DBusMessage *msg, void *data)
371 {
372         const char *sender, *path;
373         int err;
374
375         DBG("conn %p", conn);
376
377         sender = dbus_message_get_sender(msg);
378
379         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
380                                                         DBUS_TYPE_INVALID);
381
382         err = connman_agent_register(sender, path);
383         if (err < 0)
384                 return __connman_error_failed(msg, -err);
385
386         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
387 }
388
389 static DBusMessage *unregister_agent(DBusConnection *conn,
390                                         DBusMessage *msg, void *data)
391 {
392         const char *sender, *path;
393         int err;
394
395         DBG("conn %p", conn);
396
397         sender = dbus_message_get_sender(msg);
398
399         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
400                                                         DBUS_TYPE_INVALID);
401
402         err = connman_agent_unregister(sender, path);
403         if (err < 0)
404                 return __connman_error_failed(msg, -err);
405
406         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
407 }
408
409 static DBusMessage *register_counter(DBusConnection *conn,
410                                         DBusMessage *msg, void *data)
411 {
412         const char *sender, *path;
413         unsigned int accuracy, period;
414         int err;
415
416         DBG("conn %p", conn);
417
418         sender = dbus_message_get_sender(msg);
419
420         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
421                                                 DBUS_TYPE_UINT32, &accuracy,
422                                                 DBUS_TYPE_UINT32, &period,
423                                                         DBUS_TYPE_INVALID);
424
425         /* FIXME: add handling of accuracy parameter */
426
427         err = __connman_counter_register(sender, path, period);
428         if (err < 0)
429                 return __connman_error_failed(msg, -err);
430
431         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
432 }
433
434 static DBusMessage *unregister_counter(DBusConnection *conn,
435                                         DBusMessage *msg, void *data)
436 {
437         const char *sender, *path;
438         int err;
439
440         DBG("conn %p", conn);
441
442         sender = dbus_message_get_sender(msg);
443
444         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
445                                                         DBUS_TYPE_INVALID);
446
447         err = __connman_counter_unregister(sender, path);
448         if (err < 0)
449                 return __connman_error_failed(msg, -err);
450
451         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
452 }
453
454 static DBusMessage *create_session(DBusConnection *conn,
455                                         DBusMessage *msg, void *data)
456 {
457         int err;
458
459         DBG("conn %p", conn);
460
461         err = __connman_session_create(msg);
462         if (err < 0) {
463                 if (err == -EINPROGRESS)
464                         return NULL;
465
466                 return __connman_error_failed(msg, -err);
467         }
468
469         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
470 }
471
472 static DBusMessage *destroy_session(DBusConnection *conn,
473                                         DBusMessage *msg, void *data)
474 {
475         int err;
476
477         DBG("conn %p", conn);
478
479         err = __connman_session_destroy(msg);
480         if (err < 0)
481                 return __connman_error_failed(msg, -err);
482
483         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
484 }
485
486 static DBusMessage *request_private_network(DBusConnection *conn,
487                                         DBusMessage *msg, void *data)
488 {
489         const char *sender;
490         int  err;
491
492         DBG("conn %p", conn);
493
494         sender = dbus_message_get_sender(msg);
495
496         err = __connman_private_network_request(msg, sender);
497         if (err < 0)
498                 return __connman_error_failed(msg, -err);
499
500         return NULL;
501 }
502
503 static DBusMessage *release_private_network(DBusConnection *conn,
504                                         DBusMessage *msg, void *data)
505 {
506         const char *path;
507         int err;
508
509         DBG("conn %p", conn);
510
511         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
512                                                         DBUS_TYPE_INVALID);
513
514         err = __connman_private_network_release(path);
515         if (err < 0)
516                 return __connman_error_failed(msg, -err);
517
518         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
519 }
520
521 static int parse_peers_service_specs(DBusMessageIter *array,
522                         const unsigned char **spec, int *spec_len,
523                         const unsigned char **query, int *query_len,
524                         int *version)
525 {
526         *spec = *query = NULL;
527         *spec_len = *query_len = *version = 0;
528
529         while (dbus_message_iter_get_arg_type(array) ==
530                                                         DBUS_TYPE_DICT_ENTRY) {
531                 DBusMessageIter entry, inter, value;
532                 const char *key;
533
534                 dbus_message_iter_recurse(array, &entry);
535                 dbus_message_iter_get_basic(&entry, &key);
536
537                 dbus_message_iter_next(&entry);
538
539                 dbus_message_iter_recurse(&entry, &inter);
540
541                 if  (!g_strcmp0(key, "BonjourResponse")) {
542                         dbus_message_iter_recurse(&inter, &value);
543                         dbus_message_iter_get_fixed_array(&value,
544                                                         spec, spec_len);
545                 } else if (!g_strcmp0(key, "BonjourQuery")) {
546                         dbus_message_iter_recurse(&inter, &value);
547                         dbus_message_iter_get_fixed_array(&value,
548                                                         query, query_len);
549                 } else if (!g_strcmp0(key, "UpnpService")) {
550                         dbus_message_iter_get_basic(&inter, spec);
551                         *spec_len = strlen((const char *)*spec)+1;
552                 } else if (!g_strcmp0(key, "UpnpVersion")) {
553                         dbus_message_iter_get_basic(&inter, version);
554                 } else if (!g_strcmp0(key, "WiFiDisplayIEs")) {
555                         if (*spec || *query)
556                                 return -EINVAL;
557
558                         dbus_message_iter_recurse(&inter, &value);
559                         dbus_message_iter_get_fixed_array(&value,
560                                                         spec, spec_len);
561                 } else
562                         return -EINVAL;
563
564                 dbus_message_iter_next(array);
565         }
566
567         if ((*query && !*spec && !*version) ||
568                                 (!*spec && !*query) || (!*spec && *version))
569                 return -EINVAL;
570
571         return 0;
572 }
573
574 static DBusMessage *register_peer_service(DBusConnection *conn,
575                                                 DBusMessage *msg, void *data)
576 {
577         const unsigned char *spec, *query;
578         DBusMessageIter iter, array;
579         int spec_len, query_len;
580         dbus_bool_t master;
581         const char *owner;
582         int version;
583         int ret;
584
585         DBG("");
586
587         owner = dbus_message_get_sender(msg);
588
589         dbus_message_iter_init(msg, &iter);
590         dbus_message_iter_recurse(&iter, &array);
591
592         ret = parse_peers_service_specs(&array, &spec, &spec_len,
593                                                 &query, &query_len, &version);
594         if (ret)
595                 goto error;
596
597         dbus_message_iter_next(&iter);
598         dbus_message_iter_get_basic(&iter, &master);
599
600         ret = __connman_peer_service_register(owner, msg, spec, spec_len,
601                                         query, query_len, version,master);
602         if (!ret)
603                 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
604         if (ret == -EINPROGRESS)
605                 return NULL;
606 error:
607         return __connman_error_failed(msg, -ret);
608 }
609
610 static DBusMessage *unregister_peer_service(DBusConnection *conn,
611                                                 DBusMessage *msg, void *data)
612 {
613         const unsigned char *spec, *query;
614         DBusMessageIter iter, array;
615         int spec_len, query_len;
616         const char *owner;
617         int version;
618         int ret;
619
620         DBG("");
621
622         owner = dbus_message_get_sender(msg);
623
624         dbus_message_iter_init(msg, &iter);
625         dbus_message_iter_recurse(&iter, &array);
626
627         ret = parse_peers_service_specs(&array, &spec, &spec_len,
628                                                 &query, &query_len, &version);
629         if (ret)
630                 goto error;
631
632         ret = __connman_peer_service_unregister(owner, spec, spec_len,
633                                                 query, query_len, version);
634         if (!ret)
635                 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
636 error:
637         return __connman_error_failed(msg, -ret);
638
639 }
640
641 #if defined TIZEN_EXT_WIFI_MESH
642 static void append_mesh_peer_structs(DBusMessageIter *iter, void *user_data)
643 {
644         __connman_mesh_peer_list_struct(iter);
645 }
646
647 static DBusMessage *get_mesh_peers(DBusConnection *conn,
648                                         DBusMessage *msg, void *data)
649 {
650         DBusMessage *reply;
651
652         reply = dbus_message_new_method_return(msg);
653         if (!reply)
654                 return NULL;
655
656         __connman_dbus_append_objpath_dict_array(reply,
657                                         append_mesh_peer_structs, NULL);
658         return reply;
659 }
660
661 static DBusMessage *get_connected_mesh_peers(DBusConnection *conn,
662                                         DBusMessage *msg, void *data)
663 {
664         DBusMessage *reply;
665         DBusMessageIter iter, array;
666
667         reply = dbus_message_new_method_return(msg);
668         if (!reply)
669                 return NULL;
670
671         dbus_message_iter_init_append(reply, &iter);
672         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
673                         DBUS_STRUCT_BEGIN_CHAR_AS_STRING
674                         DBUS_TYPE_ARRAY_AS_STRING
675                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
676                                         DBUS_TYPE_STRING_AS_STRING
677                                         DBUS_TYPE_VARIANT_AS_STRING
678                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
679                         DBUS_STRUCT_END_CHAR_AS_STRING, &array);
680
681         __connman_mesh_connected_peer_list_struct(&array);
682         dbus_message_iter_close_container(&iter, &array);
683         return reply;
684 }
685
686 static DBusMessage *get_disconnected_mesh_peers(DBusConnection *conn,
687                                         DBusMessage *msg, void *data)
688 {
689         DBusMessage *reply;
690         DBusMessageIter iter, array;
691
692         reply = dbus_message_new_method_return(msg);
693         if (!reply)
694                 return NULL;
695
696         dbus_message_iter_init_append(reply, &iter);
697         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
698                         DBUS_STRUCT_BEGIN_CHAR_AS_STRING
699                         DBUS_TYPE_ARRAY_AS_STRING
700                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
701                                         DBUS_TYPE_STRING_AS_STRING
702                                         DBUS_TYPE_VARIANT_AS_STRING
703                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
704                         DBUS_STRUCT_END_CHAR_AS_STRING, &array);
705
706         __connman_mesh_disconnected_peer_list_struct(&array);
707         dbus_message_iter_close_container(&iter, &array);
708         return reply;
709 }
710
711 static DBusMessage *mesh_add_peer(DBusConnection *conn,
712                                         DBusMessage *msg, void *user_data)
713 {
714         const char *addr;
715         int err;
716
717         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
718                                                         DBUS_TYPE_INVALID);
719
720         DBG("Address %s", addr);
721
722         err = __connman_mesh_change_peer_status(msg, addr, CONNMAN_MESH_PEER_ADD);
723         if (err < 0)
724                 return __connman_error_failed(msg, -err);
725
726         return NULL;
727 }
728
729 static DBusMessage *mesh_remove_peer(DBusConnection *conn,
730                                         DBusMessage *msg, void *user_data)
731 {
732         const char *addr;
733         int err;
734
735         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
736                                                         DBUS_TYPE_INVALID);
737
738         DBG("Address %s", addr);
739
740         err = __connman_mesh_change_peer_status(msg, addr,
741                                                                                 CONNMAN_MESH_PEER_REMOVE);
742         if (err < 0)
743                 return __connman_error_failed(msg, -err);
744
745         return NULL;
746 }
747 #endif
748
749 static const GDBusMethodTable manager_methods[] = {
750         { GDBUS_METHOD("GetProperties",
751                         NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
752                         get_properties) },
753         { GDBUS_ASYNC_METHOD("SetProperty",
754                         GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
755                         NULL, set_property) },
756         { GDBUS_METHOD("GetTechnologies",
757                         NULL, GDBUS_ARGS({ "technologies", "a(oa{sv})" }),
758                         get_technologies) },
759         { GDBUS_DEPRECATED_METHOD("RemoveProvider",
760                         GDBUS_ARGS({ "provider", "o" }), NULL,
761                         remove_provider) },
762         { GDBUS_METHOD("GetServices",
763                         NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
764                         get_services) },
765 #if defined TIZEN_EXT
766         { GDBUS_METHOD("GetInterfaces",
767                         NULL, GDBUS_ARGS({ "interface_list", "as" }),
768                         get_interfaces) },
769         { GDBUS_METHOD("GetDefaultService",
770                         NULL, GDBUS_ARGS({ "service", "oa{sv}" }),
771                         get_default_service) },
772         { GDBUS_METHOD("GetConnectedService",
773                         GDBUS_ARGS({ "ifname", "s" }),
774                         GDBUS_ARGS({ "service", "oa{sv}" }),
775                         get_connected_service) },
776         { GDBUS_METHOD("GetDhcpStatus",
777                         GDBUS_ARGS({ "ifname", "s" }),
778                         GDBUS_ARGS({ "status", "s" }),
779                         get_dhcp_status) },
780         { GDBUS_METHOD("GetINS",
781                         NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
782                         get_ins) },
783 #endif
784         { GDBUS_METHOD("GetPeers",
785                         NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
786                         get_peers) },
787         { GDBUS_METHOD("GetTetheringClients",
788                         NULL, GDBUS_ARGS({ "tethering_clients", "as" }),
789                         get_tethering_clients) },
790         { GDBUS_DEPRECATED_ASYNC_METHOD("ConnectProvider",
791                               GDBUS_ARGS({ "provider", "a{sv}" }),
792                               GDBUS_ARGS({ "path", "o" }),
793                               connect_provider) },
794         { GDBUS_METHOD("RegisterAgent",
795                         GDBUS_ARGS({ "path", "o" }), NULL,
796                         register_agent) },
797         { GDBUS_METHOD("UnregisterAgent",
798                         GDBUS_ARGS({ "path", "o" }), NULL,
799                         unregister_agent) },
800         { GDBUS_METHOD("RegisterCounter",
801                         GDBUS_ARGS({ "path", "o" }, { "accuracy", "u" },
802                                         { "period", "u" }),
803                         NULL, register_counter) },
804         { GDBUS_METHOD("UnregisterCounter",
805                         GDBUS_ARGS({ "path", "o" }), NULL,
806                         unregister_counter) },
807         { GDBUS_ASYNC_METHOD("CreateSession",
808                         GDBUS_ARGS({ "settings", "a{sv}" },
809                                                 { "notifier", "o" }),
810                         GDBUS_ARGS({ "session", "o" }),
811                         create_session) },
812         { GDBUS_METHOD("DestroySession",
813                         GDBUS_ARGS({ "session", "o" }), NULL,
814                         destroy_session) },
815         { GDBUS_ASYNC_METHOD("RequestPrivateNetwork",
816                               NULL, GDBUS_ARGS({ "path", "o" },
817                                                { "settings", "a{sv}" },
818                                                { "socket", "h" }),
819                               request_private_network) },
820         { GDBUS_METHOD("ReleasePrivateNetwork",
821                         GDBUS_ARGS({ "path", "o" }), NULL,
822                         release_private_network) },
823         { GDBUS_ASYNC_METHOD("RegisterPeerService",
824                         GDBUS_ARGS({ "specification", "a{sv}" },
825                                    { "master", "b" }), NULL,
826                         register_peer_service) },
827         { GDBUS_METHOD("UnregisterPeerService",
828                         GDBUS_ARGS({ "specification", "a{sv}" }), NULL,
829                         unregister_peer_service) },
830 #if defined TIZEN_EXT_WIFI_MESH
831         { GDBUS_METHOD("GetMeshPeers",
832                         NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
833                         get_mesh_peers) },
834         { GDBUS_METHOD("GetConnectedMeshPeers",
835                         NULL, GDBUS_ARGS({ "peers", "a(a{sv})" }),
836                         get_connected_mesh_peers) },
837         { GDBUS_METHOD("GetDisconnectedMeshPeers",
838                         NULL, GDBUS_ARGS({ "peers", "a(a{sv})" }),
839                         get_disconnected_mesh_peers) },
840         { GDBUS_ASYNC_METHOD("MeshAddPeer", GDBUS_ARGS({ "address", "s" }), NULL,
841                                    mesh_add_peer) },
842         { GDBUS_ASYNC_METHOD("MeshRemovePeer", GDBUS_ARGS({ "address", "s" }), NULL,
843                                    mesh_remove_peer) },
844 #endif
845         { },
846 };
847
848 static const GDBusSignalTable manager_signals[] = {
849         { GDBUS_SIGNAL("PropertyChanged",
850                         GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
851         { GDBUS_SIGNAL("TechnologyAdded",
852                         GDBUS_ARGS({ "path", "o" },
853                                    { "properties", "a{sv}" })) },
854         { GDBUS_SIGNAL("TechnologyRemoved",
855                         GDBUS_ARGS({ "path", "o" })) },
856         { GDBUS_SIGNAL("ServicesChanged",
857                         GDBUS_ARGS({ "changed", "a(oa{sv})" },
858                                         { "removed", "ao" })) },
859         { GDBUS_SIGNAL("PeersChanged",
860                         GDBUS_ARGS({ "changed", "a(oa{sv})" },
861                                         { "removed", "ao" })) },
862         { GDBUS_SIGNAL("TetheringClientsChanged",
863                         GDBUS_ARGS({ "registered", "as" },
864                                         { "removed", "as" })) },
865         { },
866 };
867
868 int __connman_manager_init(void)
869 {
870         DBG("");
871
872         connection = connman_dbus_get_connection();
873         if (!connection)
874                 return -1;
875
876         if (connman_notifier_register(&technology_notifier) < 0)
877                 connman_error("Failed to register technology notifier");
878
879         g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
880                                         CONNMAN_MANAGER_INTERFACE,
881                                         manager_methods,
882                                         manager_signals, NULL, NULL, NULL);
883
884         connman_state_idle = true;
885
886         return 0;
887 }
888
889 void __connman_manager_cleanup(void)
890 {
891         DBG("");
892
893         if (!connection)
894                 return;
895
896         connman_notifier_unregister(&technology_notifier);
897
898         g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
899                                                 CONNMAN_MANAGER_INTERFACE);
900
901         dbus_connection_unref(connection);
902 }