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