unit: Support ConnectionType unknown
[platform/upstream/connman.git] / unit / 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/gdbus.h>
29
30 #include "test-connman.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_state 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 == NULL) {
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 != NULL)
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") == TRUE) {
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") == TRUE) {
141                                 /* XXX */
142
143                         } else if (g_str_equal(key, "IPv6") == TRUE) {
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") == TRUE) {
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") == TRUE) {
158                                 const char *val;
159                                 dbus_message_iter_get_basic(&value, &val);
160
161                                 if (info->bearer != NULL)
162                                         g_free(info->bearer);
163
164                                 info->bearer = g_strdup(val);
165
166                         } else if (g_str_equal(key, "Name") == TRUE) {
167                                 const char *val;
168                                 dbus_message_iter_get_basic(&value, &val);
169
170                                 if (info->name != NULL)
171                                         g_free(info->name);
172
173                                 info->name = g_strdup(val);
174
175                         } else if (g_str_equal(key, "Interface") == TRUE) {
176                                 const char *val;
177                                 dbus_message_iter_get_basic(&value, &val);
178
179                                 if (info->interface != NULL)
180                                         g_free(info->interface);
181
182                                 info->interface = g_strdup(val);
183
184                         } else if (g_str_equal(key, "ConnectionType")
185                                                                 == TRUE) {
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 != NULL)
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,
220                         CONNMAN_NOTIFICATION_INTERFACE,
221                         notify_methods, NULL, NULL,
222                         session, NULL) == FALSE) {
223                 return -EINVAL;
224         }
225
226         return 0;
227 }
228
229 int session_notify_unregister(struct test_session *session,
230                                 const char *notify_path)
231 {
232         if (g_dbus_unregister_interface(session->connection, notify_path,
233                                 CONNMAN_NOTIFICATION_INTERFACE) == FALSE) {
234                 return -EINVAL;
235         }
236
237         return 0;
238 }
239
240 static void append_allowed_bearers(DBusMessageIter *iter, void *user_data)
241 {
242         struct test_session_info *info = user_data;
243         GSList *list;
244
245         for (list = info->allowed_bearers;
246                         list != NULL; list = list->next) {
247                 struct test_bearer_info *bearer_info = list->data;
248
249                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
250                                                 &bearer_info->name);
251         }
252 }
253
254 void session_append_settings(DBusMessageIter *dict,
255                                 struct test_session_info *info)
256 {
257         connman_dbus_dict_append_array(dict, "AllowedBearers",
258                                                 DBUS_TYPE_STRING,
259                                                 append_allowed_bearers,
260                                                 info);
261 }
262
263 DBusMessage *session_connect(DBusConnection *connection,
264                                 struct test_session *session)
265 {
266         DBusMessage *message, *reply;
267         DBusError error;
268
269         message = dbus_message_new_method_call(CONNMAN_SERVICE,
270                                                 session->session_path,
271                                                 CONNMAN_SESSION_INTERFACE,
272                                                         "Connect");
273         if (message == NULL)
274                 return NULL;
275
276         dbus_error_init(&error);
277
278         reply = dbus_connection_send_with_reply_and_block(connection,
279                                                         message, -1, &error);
280         if (reply == NULL) {
281                 if (dbus_error_is_set(&error) == TRUE) {
282                         LOG("%s", error.message);
283                         dbus_error_free(&error);
284                 } else {
285                         LOG("Failed to get properties");
286                 }
287                 dbus_message_unref(message);
288                 return NULL;
289         }
290
291         dbus_message_unref(message);
292
293         return reply;
294 }
295
296 DBusMessage *session_disconnect(DBusConnection *connection,
297                                         struct test_session *session)
298 {
299         DBusMessage *message, *reply;
300         DBusError error;
301
302         message = dbus_message_new_method_call(CONNMAN_SERVICE,
303                                                 session->session_path,
304                                                 CONNMAN_SESSION_INTERFACE,
305                                                         "Disconnect");
306         if (message == NULL)
307                 return NULL;
308
309         dbus_error_init(&error);
310
311         reply = dbus_connection_send_with_reply_and_block(connection,
312                                                         message, -1, &error);
313         if (reply == NULL) {
314                 if (dbus_error_is_set(&error) == TRUE) {
315                         LOG("%s", error.message);
316                         dbus_error_free(&error);
317                 } else {
318                         LOG("Failed to get properties");
319                 }
320                 dbus_message_unref(message);
321                 return NULL;
322         }
323
324         dbus_message_unref(message);
325
326         return reply;
327 }