manager: Remove AvailableTechnologies and associated function
[platform/upstream/connman.git] / src / manager.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  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.h"
31
32 connman_bool_t connman_state_idle;
33 DBusMessage *session_mode_pending = NULL;
34
35 static DBusMessage *get_properties(DBusConnection *conn,
36                                         DBusMessage *msg, void *data)
37 {
38         DBusMessage *reply;
39         DBusMessageIter array, dict;
40         connman_bool_t offlinemode, sessionmode;
41         const char *str;
42
43         DBG("conn %p", conn);
44
45         reply = dbus_message_new_method_return(msg);
46         if (reply == NULL)
47                 return NULL;
48
49         dbus_message_iter_init_append(reply, &array);
50
51         connman_dbus_dict_open(&array, &dict);
52
53         connman_dbus_dict_append_array(&dict, "Services",
54                         DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL);
55         connman_dbus_dict_append_array(&dict, "Technologies",
56                         DBUS_TYPE_OBJECT_PATH, __connman_technology_list, NULL);
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_array(&dict, "EnabledTechnologies",
67                 DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL);
68         connman_dbus_dict_append_array(&dict, "ConnectedTechnologies",
69                 DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL);
70
71         str = __connman_service_default();
72         if (str != NULL)
73                 connman_dbus_dict_append_basic(&dict, "DefaultTechnology",
74                                                 DBUS_TYPE_STRING, &str);
75
76         connman_dbus_dict_append_array(&dict, "AvailableDebugs",
77                         DBUS_TYPE_STRING, __connman_debug_list_available, NULL);
78         connman_dbus_dict_append_array(&dict, "EnabledDebugs",
79                         DBUS_TYPE_STRING, __connman_debug_list_enabled, NULL);
80
81         sessionmode = __connman_session_mode();
82         connman_dbus_dict_append_basic(&dict, "SessionMode",
83                                         DBUS_TYPE_BOOLEAN,
84                                         &sessionmode);
85
86         connman_dbus_dict_close(&array, &dict);
87
88         return reply;
89 }
90
91 static DBusMessage *set_property(DBusConnection *conn,
92                                         DBusMessage *msg, void *data)
93 {
94         DBusMessageIter iter, value;
95         const char *name;
96         int type;
97
98         DBG("conn %p", conn);
99
100         if (dbus_message_iter_init(msg, &iter) == FALSE)
101                 return __connman_error_invalid_arguments(msg);
102
103         dbus_message_iter_get_basic(&iter, &name);
104         dbus_message_iter_next(&iter);
105         dbus_message_iter_recurse(&iter, &value);
106
107         type = dbus_message_iter_get_arg_type(&value);
108
109         if (g_str_equal(name, "OfflineMode") == TRUE) {
110                 connman_bool_t offlinemode;
111
112                 if (type != DBUS_TYPE_BOOLEAN)
113                         return __connman_error_invalid_arguments(msg);
114
115                 dbus_message_iter_get_basic(&value, &offlinemode);
116
117                 __connman_technology_set_offlinemode(offlinemode);
118         } else if (g_str_equal(name, "SessionMode") == TRUE) {
119                 connman_bool_t sessionmode;
120
121                 if (type != DBUS_TYPE_BOOLEAN)
122                         return __connman_error_invalid_arguments(msg);
123
124                 dbus_message_iter_get_basic(&value, &sessionmode);
125
126                 if (session_mode_pending != NULL)
127                         return __connman_error_in_progress(msg);
128
129                 __connman_session_set_mode(sessionmode);
130
131                 if (sessionmode == TRUE && connman_state_idle == FALSE) {
132                         session_mode_pending = msg;
133                         return NULL;
134                 }
135
136         } else
137                 return __connman_error_invalid_property(msg);
138
139         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
140 }
141
142 static DBusMessage *remove_provider(DBusConnection *conn,
143                                     DBusMessage *msg, void *data)
144 {
145         const char *path;
146         int err;
147
148         DBG("conn %p", conn);
149
150         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
151                                                         DBUS_TYPE_INVALID);
152
153         err = __connman_provider_remove(path);
154         if (err < 0)
155                 return __connman_error_failed(msg, -err);
156
157         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
158 }
159
160 static DBusMessage *request_scan(DBusConnection *conn,
161                                         DBusMessage *msg, void *data)
162 {
163         enum connman_service_type type;
164         const char *str;
165         int err;
166
167         DBG("conn %p", conn);
168
169         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
170                                                         DBUS_TYPE_INVALID);
171
172         if (g_strcmp0(str, "") == 0)
173                 type = CONNMAN_SERVICE_TYPE_UNKNOWN;
174         else if (g_strcmp0(str, "wifi") == 0)
175                 type = CONNMAN_SERVICE_TYPE_WIFI;
176         else if (g_strcmp0(str, "wimax") == 0)
177                 type = CONNMAN_SERVICE_TYPE_WIMAX;
178         else
179                 return __connman_error_invalid_arguments(msg);
180
181         err = __connman_device_request_scan(type);
182         if (err < 0) {
183                 if (err == -EINPROGRESS) {
184                         connman_error("Invalid return code from scan");
185                         err = -EINVAL;
186                 }
187
188                 return __connman_error_failed(msg, -err);
189         }
190
191         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
192 }
193
194 static DBusConnection *connection = NULL;
195
196 static void session_mode_notify(void)
197 {
198         DBusMessage *reply;
199
200         reply = g_dbus_create_reply(session_mode_pending, DBUS_TYPE_INVALID);
201         g_dbus_send_message(connection, reply);
202
203         dbus_message_unref(session_mode_pending);
204         session_mode_pending = NULL;
205 }
206
207 static void idle_state(connman_bool_t idle)
208 {
209
210         DBG("idle %d", idle);
211
212         connman_state_idle = idle;
213
214         if (connman_state_idle == FALSE || session_mode_pending == NULL)
215                 return;
216
217         session_mode_notify();
218 }
219
220 static struct connman_notifier technology_notifier = {
221         .name           = "manager",
222         .priority       = CONNMAN_NOTIFIER_PRIORITY_HIGH,
223         .idle_state     = idle_state,
224 };
225
226 static DBusMessage *enable_technology(DBusConnection *conn,
227                                         DBusMessage *msg, void *data)
228 {
229         enum connman_service_type type;
230         const char *str;
231
232         DBG("conn %p", conn);
233
234         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
235                                                         DBUS_TYPE_INVALID);
236
237         if (g_strcmp0(str, "ethernet") == 0)
238                 type = CONNMAN_SERVICE_TYPE_ETHERNET;
239         else if (g_strcmp0(str, "wifi") == 0)
240                 type = CONNMAN_SERVICE_TYPE_WIFI;
241         else if (g_strcmp0(str, "wimax") == 0)
242                 type = CONNMAN_SERVICE_TYPE_WIMAX;
243         else if (g_strcmp0(str, "bluetooth") == 0)
244                 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
245         else if (g_strcmp0(str, "cellular") == 0)
246                 type = CONNMAN_SERVICE_TYPE_CELLULAR;
247         else
248                 return __connman_error_invalid_arguments(msg);
249
250         if (__connman_notifier_is_registered(type) == FALSE)
251                 return __connman_error_not_registered(msg);
252
253         if (__connman_notifier_is_enabled(type) == TRUE)
254                 return __connman_error_already_enabled(msg);
255
256          __connman_technology_enable(type, msg);
257
258         return NULL;
259 }
260
261 static DBusMessage *disable_technology(DBusConnection *conn,
262                                         DBusMessage *msg, void *data)
263 {
264         enum connman_service_type type;
265         const char *str;
266
267         DBG("conn %p", conn);
268
269         dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str,
270                                                         DBUS_TYPE_INVALID);
271
272         if (g_strcmp0(str, "ethernet") == 0)
273                 type = CONNMAN_SERVICE_TYPE_ETHERNET;
274         else if (g_strcmp0(str, "wifi") == 0)
275                 type = CONNMAN_SERVICE_TYPE_WIFI;
276         else if (g_strcmp0(str, "wimax") == 0)
277                 type = CONNMAN_SERVICE_TYPE_WIMAX;
278         else if (g_strcmp0(str, "bluetooth") == 0)
279                 type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
280         else if (g_strcmp0(str, "cellular") == 0)
281                 type = CONNMAN_SERVICE_TYPE_CELLULAR;
282         else
283                 return __connman_error_invalid_arguments(msg);
284
285         if (__connman_notifier_is_registered(type) == FALSE)
286                 return __connman_error_not_registered(msg);
287
288         if (__connman_notifier_is_enabled(type) == FALSE)
289                 return __connman_error_already_disabled(msg);
290
291         __connman_technology_disable(type, msg);
292
293         return NULL;
294 }
295
296 static DBusMessage *get_services(DBusConnection *conn,
297                                         DBusMessage *msg, void *data)
298 {
299         DBusMessage *reply;
300         DBusMessageIter iter, array;
301
302         reply = dbus_message_new_method_return(msg);
303         if (reply == NULL)
304                 return NULL;
305
306         dbus_message_iter_init_append(reply, &iter);
307
308         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
309                         DBUS_STRUCT_BEGIN_CHAR_AS_STRING
310                         DBUS_TYPE_OBJECT_PATH_AS_STRING
311                         DBUS_TYPE_ARRAY_AS_STRING
312                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
313                                         DBUS_TYPE_STRING_AS_STRING
314                                         DBUS_TYPE_VARIANT_AS_STRING
315                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
316                         DBUS_STRUCT_END_CHAR_AS_STRING, &array);
317
318         __connman_service_list_struct(&array);
319
320         dbus_message_iter_close_container(&iter, &array);
321
322         return reply;
323 }
324
325 static DBusMessage *connect_provider(DBusConnection *conn,
326                                         DBusMessage *msg, void *data)
327 {
328         int err;
329
330         DBG("conn %p", conn);
331
332         if (__connman_session_mode() == TRUE) {
333                 connman_info("Session mode enabled: "
334                                 "direct provider connect disabled");
335
336                 return __connman_error_failed(msg, -EINVAL);
337         }
338
339         err = __connman_provider_create_and_connect(msg);
340         if (err < 0) {
341                 if (err == -EINPROGRESS) {
342                         connman_error("Invalid return code from connect");
343                         err = -EINVAL;
344                 }
345
346                 return __connman_error_failed(msg, -err);
347         }
348
349         return NULL;
350 }
351
352 static DBusMessage *register_agent(DBusConnection *conn,
353                                         DBusMessage *msg, void *data)
354 {
355         const char *sender, *path;
356         int err;
357
358         DBG("conn %p", conn);
359
360         sender = dbus_message_get_sender(msg);
361
362         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
363                                                         DBUS_TYPE_INVALID);
364
365         err = __connman_agent_register(sender, path);
366         if (err < 0)
367                 return __connman_error_failed(msg, -err);
368
369         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
370 }
371
372 static DBusMessage *unregister_agent(DBusConnection *conn,
373                                         DBusMessage *msg, void *data)
374 {
375         const char *sender, *path;
376         int err;
377
378         DBG("conn %p", conn);
379
380         sender = dbus_message_get_sender(msg);
381
382         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
383                                                         DBUS_TYPE_INVALID);
384
385         err = __connman_agent_unregister(sender, path);
386         if (err < 0)
387                 return __connman_error_failed(msg, -err);
388
389         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
390 }
391
392 static DBusMessage *register_counter(DBusConnection *conn,
393                                         DBusMessage *msg, void *data)
394 {
395         const char *sender, *path;
396         unsigned int accuracy, period;
397         int err;
398
399         DBG("conn %p", conn);
400
401         sender = dbus_message_get_sender(msg);
402
403         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
404                                                 DBUS_TYPE_UINT32, &accuracy,
405                                                 DBUS_TYPE_UINT32, &period,
406                                                         DBUS_TYPE_INVALID);
407
408         /* FIXME: add handling of accuracy parameter */
409
410         err = __connman_counter_register(sender, path, period);
411         if (err < 0)
412                 return __connman_error_failed(msg, -err);
413
414         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
415 }
416
417 static DBusMessage *unregister_counter(DBusConnection *conn,
418                                         DBusMessage *msg, void *data)
419 {
420         const char *sender, *path;
421         int err;
422
423         DBG("conn %p", conn);
424
425         sender = dbus_message_get_sender(msg);
426
427         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
428                                                         DBUS_TYPE_INVALID);
429
430         err = __connman_counter_unregister(sender, path);
431         if (err < 0)
432                 return __connman_error_failed(msg, -err);
433
434         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
435 }
436
437 static DBusMessage *create_session(DBusConnection *conn,
438                                         DBusMessage *msg, void *data)
439 {
440         int err;
441
442         DBG("conn %p", conn);
443
444         err = __connman_session_create(msg);
445         if (err < 0)
446                 return __connman_error_failed(msg, -err);
447
448         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
449 }
450
451 static DBusMessage *destroy_session(DBusConnection *conn,
452                                         DBusMessage *msg, void *data)
453 {
454         int err;
455
456         DBG("conn %p", conn);
457
458         err = __connman_session_destroy(msg);
459         if (err < 0)
460                 return __connman_error_failed(msg, -err);
461
462         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
463 }
464
465 static DBusMessage *request_private_network(DBusConnection *conn,
466                                         DBusMessage *msg, void *data)
467 {
468         const char *sender;
469         int  err;
470
471         DBG("conn %p", conn);
472
473         sender = dbus_message_get_sender(msg);
474
475         err = __connman_private_network_request(msg, sender);
476         if (err < 0)
477                 return __connman_error_failed(msg, -err);
478
479         return NULL;
480 }
481
482 static DBusMessage *release_private_network(DBusConnection *conn,
483                                         DBusMessage *msg, void *data)
484 {
485         const char *path;
486         int err;
487
488         DBG("conn %p", conn);
489
490         dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
491                                                         DBUS_TYPE_INVALID);
492
493         err = __connman_private_network_release(path);
494         if (err < 0)
495                 return __connman_error_failed(msg, -err);
496
497         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
498 }
499
500 static GDBusMethodTable manager_methods[] = {
501         { "GetProperties",     "",      "a{sv}", get_properties     },
502         { "SetProperty",       "sv",    "",      set_property,
503                                                 G_DBUS_METHOD_FLAG_ASYNC },
504         { "RemoveProvider",    "o",     "",      remove_provider    },
505         { "RequestScan",       "s",     "",      request_scan       },
506         { "EnableTechnology",  "s",     "",      enable_technology,
507                                                 G_DBUS_METHOD_FLAG_ASYNC },
508         { "DisableTechnology", "s",     "",      disable_technology,
509                                                 G_DBUS_METHOD_FLAG_ASYNC },
510         { "GetServices",       "",      "a(oa{sv})", get_services   },
511         { "ConnectProvider",   "a{sv}", "o",     connect_provider,
512                                                 G_DBUS_METHOD_FLAG_ASYNC },
513         { "RegisterAgent",     "o",     "",      register_agent     },
514         { "UnregisterAgent",   "o",     "",      unregister_agent   },
515         { "RegisterCounter",   "ouu",   "",      register_counter   },
516         { "UnregisterCounter", "o",     "",      unregister_counter },
517         { "CreateSession",     "a{sv}o", "o",    create_session     },
518         { "DestroySession",    "o",     "",      destroy_session    },
519         { "RequestPrivateNetwork",    "",     "oa{sv}h",
520                                                 request_private_network,
521                                                 G_DBUS_METHOD_FLAG_ASYNC },
522         { "ReleasePrivateNetwork",    "o",    "",
523                                                 release_private_network },
524         { },
525 };
526
527 static GDBusSignalTable manager_signals[] = {
528         { "PropertyChanged", "sv" },
529         { },
530 };
531
532 int __connman_manager_init(void)
533 {
534         DBG("");
535
536         connection = connman_dbus_get_connection();
537         if (connection == NULL)
538                 return -1;
539
540         if (connman_notifier_register(&technology_notifier) < 0)
541                 connman_error("Failed to register technology notifier");
542
543         g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH,
544                                         CONNMAN_MANAGER_INTERFACE,
545                                         manager_methods,
546                                         manager_signals, NULL, NULL, NULL);
547
548         connman_state_idle = TRUE;
549
550         return 0;
551 }
552
553 void __connman_manager_cleanup(void)
554 {
555         DBG("");
556
557         if (connection == NULL)
558                 return;
559
560         connman_notifier_unregister(&technology_notifier);
561
562         g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH,
563                                                 CONNMAN_MANAGER_INTERFACE);
564
565         dbus_connection_unref(connection);
566 }