Merge "Update settings when device information in device_list is changed" into tizen
[platform/upstream/connman.git] / tools / session-api.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2011-2014  BMW Car IT GmbH.
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                                 g_free(info->bearer);
162                                 info->bearer = g_strdup(val);
163
164                         } else if (g_str_equal(key, "Name")) {
165                                 const char *val;
166                                 dbus_message_iter_get_basic(&value, &val);
167
168                                 g_free(info->name);
169                                 info->name = g_strdup(val);
170
171                         } else if (g_str_equal(key, "Interface")) {
172                                 const char *val;
173                                 dbus_message_iter_get_basic(&value, &val);
174
175                                 g_free(info->interface);
176                                 info->interface = g_strdup(val);
177
178                         } else if (g_str_equal(key, "ConnectionType")) {
179                                 const char *val;
180                                 dbus_message_iter_get_basic(&value, &val);
181
182                                 info->type = string2type(val);
183
184                         } else if (g_str_equal(key, "Allowedinterface")) {
185                                 const char *val;
186                                 dbus_message_iter_get_basic(&value, &val);
187
188                                 g_free(info->allowed_interface);
189                                 info->allowed_interface = g_strdup(val);
190
191                         } else if (g_str_equal(key, "ContextIdentifier")) {
192                                 const char *val;
193                                 dbus_message_iter_get_basic(&value, &val);
194
195                                 g_free(info->context_identifier);
196                                 info->context_identifier = g_strdup(val);
197
198                         } else {
199                                 g_assert(FALSE);
200                                 return __connman_error_invalid_arguments(msg);
201                         }
202                         break;
203                 case DBUS_TYPE_BOOLEAN:
204                         if (g_str_equal(key, "SourceIPRule")) {
205                                 dbus_bool_t val;
206                                 dbus_message_iter_get_basic(&value, &val);
207
208                                 info->source_ip_rule = val;
209
210                         } else {
211                                 g_assert(FALSE);
212                                 return __connman_error_invalid_arguments(msg);
213                         }
214                         break;
215                 default:
216                         g_assert(FALSE);
217                         return __connman_error_invalid_arguments(msg);
218                 }
219                 dbus_message_iter_next(&array);
220         }
221
222         if (session->notify)
223                 session->notify(session);
224
225         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
226 }
227
228 static const GDBusMethodTable notify_methods[] = {
229         { GDBUS_METHOD("Release", NULL, NULL, notify_release) },
230         { GDBUS_METHOD("Update",
231                         GDBUS_ARGS({ "settings", "a{sv}" }), NULL,
232                         notify_update) },
233         { },
234 };
235
236 int session_notify_register(struct test_session *session,
237                                 const char *notify_path)
238 {
239         if (!g_dbus_register_interface(session->connection, notify_path, CONNMAN_NOTIFICATION_INTERFACE, notify_methods, NULL, NULL, session, NULL)) {
240                 return -EINVAL;
241         }
242
243         return 0;
244 }
245
246 int session_notify_unregister(struct test_session *session,
247                                 const char *notify_path)
248 {
249         if (!g_dbus_unregister_interface(session->connection, notify_path, CONNMAN_NOTIFICATION_INTERFACE)) {
250                 return -EINVAL;
251         }
252
253         return 0;
254 }
255
256 static void append_allowed_bearers(DBusMessageIter *iter, void *user_data)
257 {
258         struct test_session_info *info = user_data;
259         GSList *list;
260
261         for (list = info->allowed_bearers;
262                         list; list = list->next) {
263                 struct test_bearer_info *bearer_info = list->data;
264
265                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
266                                                 &bearer_info->name);
267         }
268 }
269
270 void session_append_settings(DBusMessageIter *dict,
271                                 struct test_session_info *info)
272 {
273         if (!info->allowed_bearers)
274                 return;
275
276         connman_dbus_dict_append_array(dict, "AllowedBearers",
277                                                 DBUS_TYPE_STRING,
278                                                 append_allowed_bearers,
279                                                 info);
280 }
281
282 DBusMessage *session_connect(DBusConnection *connection,
283                                 struct test_session *session)
284 {
285         DBusMessage *message, *reply;
286         DBusError error;
287
288         message = dbus_message_new_method_call(CONNMAN_SERVICE,
289                                                 session->session_path,
290                                                 CONNMAN_SESSION_INTERFACE,
291                                                         "Connect");
292         if (!message)
293                 return NULL;
294
295         dbus_error_init(&error);
296
297         reply = dbus_connection_send_with_reply_and_block(connection,
298                                                         message, -1, &error);
299         if (!reply) {
300                 if (dbus_error_is_set(&error)) {
301                         LOG("%s", error.message);
302                         dbus_error_free(&error);
303                 } else {
304                         LOG("Failed to get properties");
305                 }
306                 dbus_message_unref(message);
307                 return NULL;
308         }
309
310         dbus_message_unref(message);
311
312         return reply;
313 }
314
315 DBusMessage *session_disconnect(DBusConnection *connection,
316                                         struct test_session *session)
317 {
318         DBusMessage *message, *reply;
319         DBusError error;
320
321         message = dbus_message_new_method_call(CONNMAN_SERVICE,
322                                                 session->session_path,
323                                                 CONNMAN_SESSION_INTERFACE,
324                                                         "Disconnect");
325         if (!message)
326                 return NULL;
327
328         dbus_error_init(&error);
329
330         reply = dbus_connection_send_with_reply_and_block(connection,
331                                                         message, -1, &error);
332         if (!reply) {
333                 if (dbus_error_is_set(&error)) {
334                         LOG("%s", error.message);
335                         dbus_error_free(&error);
336                 } else {
337                         LOG("Failed to get properties");
338                 }
339                 dbus_message_unref(message);
340                 return NULL;
341         }
342
343         dbus_message_unref(message);
344
345         return reply;
346 }