7162ade6d52f36c33c8d633e3f8acd1fb527bf15
[platform/upstream/connman.git] / tools / session-api.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2011  BWM CarIT GmbH. 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 "session-test.h"
31
32 static enum connman_session_state string2state(const char *state)
33 {
34         if (g_strcmp0(state, "connected") == 0)
35                 return CONNMAN_SESSION_STATE_CONNECTED;
36         if (g_strcmp0(state, "online") == 0)
37                 return CONNMAN_SESSION_STATE_ONLINE;
38
39         return CONNMAN_SESSION_STATE_DISCONNECTED;
40 }
41
42 static enum connman_session_type string2type(const char *type)
43 {
44         if (g_strcmp0(type, "any") == 0)
45                 return CONNMAN_SESSION_TYPE_ANY;
46         if (g_strcmp0(type, "local") == 0)
47                 return CONNMAN_SESSION_TYPE_LOCAL;
48         if (g_strcmp0(type, "internet") == 0)
49                 return CONNMAN_SESSION_TYPE_INTERNET;
50
51         return CONNMAN_SESSION_TYPE_UNKNOWN;
52 }
53
54 void bearer_info_cleanup(gpointer data, gpointer user_data)
55 {
56         struct test_bearer_info *info = data;
57
58         g_free(info->name);
59         g_free(info);
60 }
61
62 static GSList *session_parse_allowed_bearers(DBusMessageIter *iter)
63 {
64         struct test_bearer_info *info;
65         DBusMessageIter array;
66         GSList *list = NULL;
67
68         dbus_message_iter_recurse(iter, &array);
69
70         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
71                 char *bearer = NULL;
72
73                 dbus_message_iter_get_basic(&array, &bearer);
74
75                 info = g_try_new0(struct test_bearer_info, 1);
76                 if (!info) {
77                         g_slist_foreach(list, bearer_info_cleanup, NULL);
78                         g_slist_free(list);
79
80                         return NULL;
81                 }
82
83                 info->name = g_strdup(bearer);
84
85                 list = g_slist_append(list, info);
86
87                 dbus_message_iter_next(&array);
88         }
89
90         return list;
91 }
92
93 static DBusMessage *notify_release(DBusConnection *conn,
94                                         DBusMessage *msg, void *user_data)
95 {
96         struct test_session *session = user_data;
97
98         LOG("session %p", session);
99
100         if (session->notify)
101                 session->notify(session);
102
103         return NULL;
104 }
105
106 static DBusMessage *notify_update(DBusConnection *conn,
107                                         DBusMessage *msg, void *user_data)
108 {
109         struct test_session *session = user_data;
110         struct test_session_info *info = session->info;
111         DBusMessageIter iter, array;
112         GSList *allowed_bearers;
113
114         LOG("session %p notify %s", session, session->notify_path);
115
116         dbus_message_iter_init(msg, &iter);
117         dbus_message_iter_recurse(&iter, &array);
118
119         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
120                 DBusMessageIter entry, value;
121                 const char *key;
122
123                 dbus_message_iter_recurse(&array, &entry);
124                 dbus_message_iter_get_basic(&entry, &key);
125
126                 dbus_message_iter_next(&entry);
127                 dbus_message_iter_recurse(&entry, &value);
128
129                 switch (dbus_message_iter_get_arg_type(&value)) {
130                 case DBUS_TYPE_ARRAY:
131                         if (g_str_equal(key, "AllowedBearers")) {
132                                 allowed_bearers = session_parse_allowed_bearers(&value);
133
134                                 g_slist_foreach(info->allowed_bearers,
135                                                 bearer_info_cleanup, NULL);
136                                 g_slist_free(info->allowed_bearers);
137
138                                 info->allowed_bearers = allowed_bearers;
139
140                         } else if (g_str_equal(key, "IPv4")) {
141                                 /* XXX */
142
143                         } else if (g_str_equal(key, "IPv6")) {
144                                 /* XXX */
145
146                         } else {
147                                 g_assert(FALSE);
148                                 return __connman_error_invalid_arguments(msg);
149                         }
150                         break;
151                 case DBUS_TYPE_STRING:
152                         if (g_str_equal(key, "State")) {
153                                 const char *val;
154                                 dbus_message_iter_get_basic(&value, &val);
155
156                                 info->state = string2state(val);
157                         } else if (g_str_equal(key, "Bearer")) {
158                                 const char *val;
159                                 dbus_message_iter_get_basic(&value, &val);
160
161                                 if (info->bearer)
162                                         g_free(info->bearer);
163
164                                 info->bearer = g_strdup(val);
165
166                         } else if (g_str_equal(key, "Name")) {
167                                 const char *val;
168                                 dbus_message_iter_get_basic(&value, &val);
169
170                                 if (info->name)
171                                         g_free(info->name);
172
173                                 info->name = g_strdup(val);
174
175                         } else if (g_str_equal(key, "Interface")) {
176                                 const char *val;
177                                 dbus_message_iter_get_basic(&value, &val);
178
179                                 if (info->interface)
180                                         g_free(info->interface);
181
182                                 info->interface = g_strdup(val);
183
184                         } else if (g_str_equal(key, "ConnectionType")
185                                                                 ) {
186                                 const char *val;
187                                 dbus_message_iter_get_basic(&value, &val);
188
189                                 info->type = string2type(val);
190                         } else {
191                                 g_assert(FALSE);
192                                 return __connman_error_invalid_arguments(msg);
193                         }
194                         break;
195                 default:
196                         g_assert(FALSE);
197                         return __connman_error_invalid_arguments(msg);
198                 }
199                 dbus_message_iter_next(&array);
200         }
201
202         if (session->notify)
203                 session->notify(session);
204
205         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
206 }
207
208 static const GDBusMethodTable notify_methods[] = {
209         { GDBUS_METHOD("Release", NULL, NULL, notify_release) },
210         { GDBUS_METHOD("Update",
211                         GDBUS_ARGS({ "settings", "a{sv}" }), NULL,
212                         notify_update) },
213         { },
214 };
215
216 int session_notify_register(struct test_session *session,
217                                 const char *notify_path)
218 {
219         if (!g_dbus_register_interface(session->connection, notify_path, CONNMAN_NOTIFICATION_INTERFACE, notify_methods, NULL, NULL, session, NULL)) {
220                 return -EINVAL;
221         }
222
223         return 0;
224 }
225
226 int session_notify_unregister(struct test_session *session,
227                                 const char *notify_path)
228 {
229         if (!g_dbus_unregister_interface(session->connection, notify_path, CONNMAN_NOTIFICATION_INTERFACE)) {
230                 return -EINVAL;
231         }
232
233         return 0;
234 }
235
236 static void append_allowed_bearers(DBusMessageIter *iter, void *user_data)
237 {
238         struct test_session_info *info = user_data;
239         GSList *list;
240
241         for (list = info->allowed_bearers;
242                         list; list = list->next) {
243                 struct test_bearer_info *bearer_info = list->data;
244
245                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
246                                                 &bearer_info->name);
247         }
248 }
249
250 void session_append_settings(DBusMessageIter *dict,
251                                 struct test_session_info *info)
252 {
253         if (!info->allowed_bearers)
254                 return;
255
256         connman_dbus_dict_append_array(dict, "AllowedBearers",
257                                                 DBUS_TYPE_STRING,
258                                                 append_allowed_bearers,
259                                                 info);
260 }
261
262 DBusMessage *session_connect(DBusConnection *connection,
263                                 struct test_session *session)
264 {
265         DBusMessage *message, *reply;
266         DBusError error;
267
268         message = dbus_message_new_method_call(CONNMAN_SERVICE,
269                                                 session->session_path,
270                                                 CONNMAN_SESSION_INTERFACE,
271                                                         "Connect");
272         if (!message)
273                 return NULL;
274
275         dbus_error_init(&error);
276
277         reply = dbus_connection_send_with_reply_and_block(connection,
278                                                         message, -1, &error);
279         if (!reply) {
280                 if (dbus_error_is_set(&error)) {
281                         LOG("%s", error.message);
282                         dbus_error_free(&error);
283                 } else {
284                         LOG("Failed to get properties");
285                 }
286                 dbus_message_unref(message);
287                 return NULL;
288         }
289
290         dbus_message_unref(message);
291
292         return reply;
293 }
294
295 DBusMessage *session_disconnect(DBusConnection *connection,
296                                         struct test_session *session)
297 {
298         DBusMessage *message, *reply;
299         DBusError error;
300
301         message = dbus_message_new_method_call(CONNMAN_SERVICE,
302                                                 session->session_path,
303                                                 CONNMAN_SESSION_INTERFACE,
304                                                         "Disconnect");
305         if (!message)
306                 return NULL;
307
308         dbus_error_init(&error);
309
310         reply = dbus_connection_send_with_reply_and_block(connection,
311                                                         message, -1, &error);
312         if (!reply) {
313                 if (dbus_error_is_set(&error)) {
314                         LOG("%s", error.message);
315                         dbus_error_free(&error);
316                 } else {
317                         LOG("Failed to get properties");
318                 }
319                 dbus_message_unref(message);
320                 return NULL;
321         }
322
323         dbus_message_unref(message);
324
325         return reply;
326 }