device: Combine two if statements with identical outcome
[framework/connectivity/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, "local") == 0)
45                 return CONNMAN_SESSION_TYPE_LOCAL;
46         if (g_strcmp0(type, "internet") == 0)
47                 return CONNMAN_SESSION_TYPE_INTERNET;
48
49         return CONNMAN_SESSION_TYPE_ANY;
50 }
51
52 static const char *roamingpolicy2string(enum connman_session_roaming_policy policy)
53 {
54         switch (policy) {
55         case CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN:
56                 break;
57         case CONNMAN_SESSION_ROAMING_POLICY_DEFAULT:
58                 return "default";
59         case CONNMAN_SESSION_ROAMING_POLICY_ALWAYS:
60                 return "always";
61         case CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN:
62                 return "forbidden";
63         case CONNMAN_SESSION_ROAMING_POLICY_NATIONAL:
64                 return "national";
65         case CONNMAN_SESSION_ROAMING_POLICY_INTERNATIONAL:
66                 return "international";
67         }
68
69         return "";
70 }
71
72 static enum connman_session_roaming_policy string2roamingpolicy(const char *policy)
73 {
74         if (g_strcmp0(policy, "default") == 0)
75                 return CONNMAN_SESSION_ROAMING_POLICY_DEFAULT;
76         else if (g_strcmp0(policy, "always") == 0)
77                 return CONNMAN_SESSION_ROAMING_POLICY_ALWAYS;
78         else if (g_strcmp0(policy, "forbidden") == 0)
79                 return CONNMAN_SESSION_ROAMING_POLICY_FORBIDDEN;
80         else if (g_strcmp0(policy, "national") == 0)
81                 return CONNMAN_SESSION_ROAMING_POLICY_NATIONAL;
82         else if (g_strcmp0(policy, "international") == 0)
83                 return CONNMAN_SESSION_ROAMING_POLICY_INTERNATIONAL;
84         else
85                 return CONNMAN_SESSION_ROAMING_POLICY_UNKNOWN;
86 }
87
88 void bearer_info_cleanup(gpointer data, gpointer user_data)
89 {
90         struct test_bearer_info *info = data;
91
92         g_free(info->name);
93         g_free(info);
94 }
95
96 static GSList *session_parse_allowed_bearers(DBusMessageIter *iter)
97 {
98         struct test_bearer_info *info;
99         DBusMessageIter array;
100         GSList *list = NULL;
101
102         dbus_message_iter_recurse(iter, &array);
103
104         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
105                 char *bearer = NULL;
106
107                 dbus_message_iter_get_basic(&array, &bearer);
108
109                 info = g_try_new0(struct test_bearer_info, 1);
110                 if (info == NULL) {
111                         g_slist_foreach(list, bearer_info_cleanup, NULL);
112                         g_slist_free(list);
113
114                         return NULL;
115                 }
116
117                 info->name = g_strdup(bearer);
118
119                 list = g_slist_append(list, info);
120
121                 dbus_message_iter_next(&array);
122         }
123
124         return list;
125 }
126
127 static DBusMessage *notify_release(DBusConnection *conn,
128                                         DBusMessage *msg, void *user_data)
129 {
130         struct test_session *session = user_data;
131
132         LOG("session %p", session);
133
134         if (session->notify != NULL)
135                 session->notify(session);
136
137         return NULL;
138 }
139
140 static DBusMessage *notify_update(DBusConnection *conn,
141                                         DBusMessage *msg, void *user_data)
142 {
143         struct test_session *session = user_data;
144         struct test_session_info *info = session->info;
145         DBusMessageIter iter, array;
146         GSList *allowed_bearers;
147
148         LOG("session %p notify %s", session, session->notify_path);
149
150         dbus_message_iter_init(msg, &iter);
151         dbus_message_iter_recurse(&iter, &array);
152
153         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
154                 DBusMessageIter entry, value;
155                 const char *key;
156
157                 dbus_message_iter_recurse(&array, &entry);
158                 dbus_message_iter_get_basic(&entry, &key);
159
160                 dbus_message_iter_next(&entry);
161                 dbus_message_iter_recurse(&entry, &value);
162
163                 switch (dbus_message_iter_get_arg_type(&value)) {
164                 case DBUS_TYPE_ARRAY:
165                         if (g_str_equal(key, "AllowedBearers") == TRUE) {
166                                 allowed_bearers = session_parse_allowed_bearers(&value);
167
168                                 g_slist_foreach(info->allowed_bearers,
169                                                 bearer_info_cleanup, NULL);
170                                 g_slist_free(info->allowed_bearers);
171
172                                 info->allowed_bearers = allowed_bearers;
173
174                         } else if (g_str_equal(key, "IPv4") == TRUE) {
175                                 /* XXX */
176
177                         } else if (g_str_equal(key, "IPv6") == TRUE) {
178                                 /* XXX */
179
180                         } else {
181                                 g_assert(FALSE);
182                                 return __connman_error_invalid_arguments(msg);
183                         }
184                         break;
185                 case DBUS_TYPE_BOOLEAN:
186                         if (g_str_equal(key, "Priority") == TRUE) {
187                                 dbus_message_iter_get_basic(&value,
188                                                         &info->priority);
189
190                         } else if (g_str_equal(key, "AvoidHandover") == TRUE) {
191                                 dbus_message_iter_get_basic(&value,
192                                                         &info->avoid_handover);
193
194                         } else if (g_str_equal(key, "StayConnected") == TRUE) {
195                                 dbus_message_iter_get_basic(&value,
196                                                         &info->stay_connected);
197
198                         } else if (g_str_equal(key, "EmergencyCall") == TRUE) {
199                                 dbus_message_iter_get_basic(&value,
200                                                         &info->ecall);
201
202                         } else {
203                                 g_assert(FALSE);
204                                 return __connman_error_invalid_arguments(msg);
205                         }
206                         break;
207                 case DBUS_TYPE_UINT32:
208                         if (g_str_equal(key, "PeriodicConnect") == TRUE) {
209                                 dbus_message_iter_get_basic(&value,
210                                                         &info->periodic_connect);
211
212                         } else if (g_str_equal(key, "IdleTimeout") == TRUE) {
213                                 dbus_message_iter_get_basic(&value,
214                                                         &info->idle_timeout);
215
216                         } else if (g_str_equal(key, "SessionMarker") == TRUE) {
217                                 dbus_message_iter_get_basic(&value,
218                                                         &info->marker);
219
220                         } else {
221                                 g_assert(FALSE);
222                                 return __connman_error_invalid_arguments(msg);
223                         }
224                         break;
225                 case DBUS_TYPE_STRING:
226                         if (g_str_equal(key, "State") == TRUE) {
227                                 const char *val;
228                                 dbus_message_iter_get_basic(&value, &val);
229
230                                 info->state = string2state(val);
231                         } else if (g_str_equal(key, "Bearer") == TRUE) {
232                                 const char *val;
233                                 dbus_message_iter_get_basic(&value, &val);
234
235                                 if (info->bearer != NULL)
236                                         g_free(info->bearer);
237
238                                 info->bearer = g_strdup(val);
239
240                         } else if (g_str_equal(key, "Name") == TRUE) {
241                                 const char *val;
242                                 dbus_message_iter_get_basic(&value, &val);
243
244                                 if (info->name != NULL)
245                                         g_free(info->name);
246
247                                 info->name = g_strdup(val);
248
249                         } else if (g_str_equal(key, "RoamingPolicy") == TRUE) {
250                                 const char *val;
251                                 dbus_message_iter_get_basic(&value, &val);
252                                 info->roaming_policy =
253                                         string2roamingpolicy(val);
254
255                         } else if (g_str_equal(key, "Interface") == TRUE) {
256                                 const char *val;
257                                 dbus_message_iter_get_basic(&value, &val);
258
259                                 if (info->interface != NULL)
260                                         g_free(info->interface);
261
262                                 info->interface = g_strdup(val);
263
264                         } else if (g_str_equal(key, "ConnectionType")
265                                                                 == TRUE) {
266                                 const char *val;
267                                 dbus_message_iter_get_basic(&value, &val);
268
269                                 info->type = string2type(val);
270                         } else {
271                                 g_assert(FALSE);
272                                 return __connman_error_invalid_arguments(msg);
273                         }
274                         break;
275                 default:
276                         g_assert(FALSE);
277                         return __connman_error_invalid_arguments(msg);
278                 }
279                 dbus_message_iter_next(&array);
280         }
281
282         if (session->notify != NULL)
283                 session->notify(session);
284
285         return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
286 }
287
288 static const GDBusMethodTable notify_methods[] = {
289         { GDBUS_METHOD("Release", NULL, NULL, notify_release) },
290         { GDBUS_METHOD("Update",
291                         GDBUS_ARGS({ "settings", "a{sv}" }), NULL,
292                         notify_update) },
293         { },
294 };
295
296 int session_notify_register(struct test_session *session,
297                                 const char *notify_path)
298 {
299         if (g_dbus_register_interface(session->connection, notify_path,
300                         CONNMAN_NOTIFICATION_INTERFACE,
301                         notify_methods, NULL, NULL,
302                         session, NULL) == FALSE) {
303                 return -EINVAL;
304         }
305
306         return 0;
307 }
308
309 int session_notify_unregister(struct test_session *session,
310                                 const char *notify_path)
311 {
312         if (g_dbus_unregister_interface(session->connection, notify_path,
313                                 CONNMAN_NOTIFICATION_INTERFACE) == FALSE) {
314                 return -EINVAL;
315         }
316
317         return 0;
318 }
319
320 static void append_allowed_bearers(DBusMessageIter *iter, void *user_data)
321 {
322         struct test_session_info *info = user_data;
323         GSList *list;
324
325         for (list = info->allowed_bearers;
326                         list != NULL; list = list->next) {
327                 struct test_bearer_info *info = list->data;
328
329                 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
330                                                 &info->name);
331         }
332 }
333
334 void session_append_settings(DBusMessageIter *dict,
335                                 struct test_session_info *info)
336 {
337         const char *policy;
338
339         connman_dbus_dict_append_basic(dict, "Priority",
340                                                 DBUS_TYPE_BOOLEAN,
341                                                 &info->priority);
342
343         connman_dbus_dict_append_array(dict, "AllowedBearers",
344                                                 DBUS_TYPE_STRING,
345                                                 append_allowed_bearers,
346                                                 info);
347
348         connman_dbus_dict_append_basic(dict, "AvoidHandover",
349                                                 DBUS_TYPE_BOOLEAN,
350                                                 &info->avoid_handover);
351
352         connman_dbus_dict_append_basic(dict, "StayConnected",
353                                                 DBUS_TYPE_BOOLEAN,
354                                                 &info->stay_connected);
355
356         connman_dbus_dict_append_basic(dict, "PeriodicConnect",
357                                                 DBUS_TYPE_UINT32,
358                                                 &info->periodic_connect);
359
360         connman_dbus_dict_append_basic(dict, "IdleTimeout",
361                                                 DBUS_TYPE_UINT32,
362                                                 &info->idle_timeout);
363
364         connman_dbus_dict_append_basic(dict, "EmergencyCall",
365                                                 DBUS_TYPE_BOOLEAN,
366                                                 &info->ecall);
367
368         policy = roamingpolicy2string(info->roaming_policy);
369         connman_dbus_dict_append_basic(dict, "RoamingPolicy",
370                                                 DBUS_TYPE_STRING,
371                                                 &policy);
372 }
373
374 DBusMessage *session_connect(DBusConnection *connection,
375                                 struct test_session *session)
376 {
377         DBusMessage *message, *reply;
378         DBusError error;
379
380         message = dbus_message_new_method_call(CONNMAN_SERVICE,
381                                                 session->session_path,
382                                                 CONNMAN_SESSION_INTERFACE,
383                                                         "Connect");
384         if (message == NULL)
385                 return NULL;
386
387         dbus_error_init(&error);
388
389         reply = dbus_connection_send_with_reply_and_block(connection,
390                                                         message, -1, &error);
391         if (reply == NULL) {
392                 if (dbus_error_is_set(&error) == TRUE) {
393                         LOG("%s", error.message);
394                         dbus_error_free(&error);
395                 } else {
396                         LOG("Failed to get properties");
397                 }
398                 dbus_message_unref(message);
399                 return NULL;
400         }
401
402         dbus_message_unref(message);
403
404         return reply;
405 }
406
407 DBusMessage *session_disconnect(DBusConnection *connection,
408                                         struct test_session *session)
409 {
410         DBusMessage *message, *reply;
411         DBusError error;
412
413         message = dbus_message_new_method_call(CONNMAN_SERVICE,
414                                                 session->session_path,
415                                                 CONNMAN_SESSION_INTERFACE,
416                                                         "Disconnect");
417         if (message == NULL)
418                 return NULL;
419
420         dbus_error_init(&error);
421
422         reply = dbus_connection_send_with_reply_and_block(connection,
423                                                         message, -1, &error);
424         if (reply == NULL) {
425                 if (dbus_error_is_set(&error) == TRUE) {
426                         LOG("%s", error.message);
427                         dbus_error_free(&error);
428                 } else {
429                         LOG("Failed to get properties");
430                 }
431                 dbus_message_unref(message);
432                 return NULL;
433         }
434
435         dbus_message_unref(message);
436
437         return reply;
438 }