client: Add pretty-printing for ServicesChanged signal
[platform/upstream/connman.git] / client / data_manager.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2012  Intel Corporation. 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 as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <errno.h>
33
34 #include <glib.h>
35 #include <gdbus.h>
36
37 #include "services.h"
38 #include "technology.h"
39 #include "data_manager.h"
40 #include "dbus.h"
41
42 static void extract_manager_properties(DBusMessage *message)
43 {
44         DBusMessageIter iter, array;
45
46         dbus_message_iter_init(message, &iter);
47         dbus_message_iter_recurse(&iter, &array);
48         extract_properties(&array);
49 }
50
51 int store_proxy_input(DBusConnection *connection, DBusMessage *message,
52                                 char *name, int num_args, char *argv[])
53 {
54         int i, j, k;
55         int error = 0;
56         gchar **servers = NULL;
57         gchar **excludes = NULL;
58
59         for (i = 0; argv[i] != NULL && strcmp(argv[i], "excludes") != 0 &&
60                      strncmp(argv[i], "--", 2) != 0; i++) {
61                 servers = g_try_realloc(servers, (i + 1) * sizeof(char *));
62                 if (servers == NULL) {
63                         fprintf(stderr, "Could not allocate memory for list\n");
64                         return -ENOMEM;
65                 }
66                 servers[i] = g_strdup(argv[i]);
67                 /* In case the user doesn't enter "excludes" */
68                 if (i + 1 == num_args) {
69                         i++;
70                         j = 0;
71                         goto free_servers;
72                 }
73         }
74         for (j = 0; j + (i + 1) != num_args && argv[j + (i + 1)] != NULL &&
75                      strncmp(argv[j + i + 1], "--", 2) != 0; j++) {
76                 excludes = g_try_realloc(excludes, (j + 1) * sizeof(char *));
77                 if (excludes == NULL) {
78                         fprintf(stderr, "Could not allocate memory for list\n");
79                         return -ENOMEM;
80                 }
81                 excludes[j] = g_strdup(argv[j + (i + 1)]);
82         }
83
84 free_servers:
85         error = set_proxy_manual(connection, message, name, servers, excludes,
86                                                                         i, j);
87
88         for (k = 0; k < j - 1; k++)
89                 g_free(excludes[k]);
90         g_free(excludes);
91
92         for (k = 0; k < i - 1; k++)
93                 g_free(servers[k]);
94         g_free(servers);
95
96         if (error < 0)
97                 return error;
98
99         if (i > 0)
100                 i++;
101         if (j > 0)
102                 j++;
103         return i + j;
104 }
105
106 int connect_service(DBusConnection *connection, char *name)
107 {
108         DBusMessage *message, *message_connect = NULL;
109         char *path = NULL;
110         const char *path_name;
111         DBusError err;
112         int err_ret = 0;
113
114         message = get_message(connection, "GetServices");
115         if (message == NULL)
116                 return -ENOMEM;
117
118         path_name = strip_service_path(name);
119
120         path = g_strdup_printf("/net/connman/service/%s", path_name);
121         message_connect = dbus_message_new_method_call("net.connman", path,
122                                                 "net.connman.Service",
123                                                 "Connect");
124         if (message_connect == NULL) {
125                 err_ret = -ENOMEM;
126                 goto error;
127         }
128
129         dbus_error_init(&err);
130         dbus_connection_send_with_reply_and_block(connection, message_connect,
131                                                                 -1, &err);
132
133         if (dbus_error_is_set(&err)) {
134                 printf("Error '%s': %s\n", path, err.message);
135                 dbus_error_free(&err);
136                 err_ret = -EINVAL;
137                 goto error;
138         }
139
140         dbus_connection_send(connection, message_connect, NULL);
141         dbus_connection_flush(connection);
142
143 error:
144         if (message != NULL)
145                 dbus_message_unref(message);
146         if (message_connect != NULL)
147                 dbus_message_unref(message_connect);
148         g_free(path);
149
150         return err_ret;
151 }
152
153 int disconnect_service(DBusConnection *connection, char *name)
154 {
155         DBusMessage *message, *message_disconnect = NULL;
156         char *path = NULL;
157         const char *path_name;
158         DBusError err;
159         int err_ret = 0;
160
161         message = get_message(connection, "GetServices");
162         if (message == NULL)
163                 return -ENOMEM;
164
165         path_name = strip_service_path(name);
166         path = g_strdup_printf("/net/connman/service/%s", path_name);
167
168         message_disconnect = dbus_message_new_method_call("net.connman", path,
169                                                           "net.connman.Service",
170                                                           "Disconnect");
171         if (message_disconnect == NULL) {
172                 err_ret = -ENOMEM;
173                 goto error;
174         }
175
176         dbus_error_init(&err);
177         dbus_connection_send_with_reply_and_block(connection,
178                                                   message_disconnect,
179                                                   -1, &err);
180
181         if (dbus_error_is_set(&err)) {
182                 printf("Error '%s': %s\n", path, err.message);
183                 dbus_error_free(&err);
184                 err_ret = -EINVAL;
185                 goto error;
186         }
187
188         dbus_connection_send(connection, message_disconnect, NULL);
189         dbus_connection_flush(connection);
190
191 error:
192         if (message != NULL)
193                 dbus_message_unref(message);
194         if (message_disconnect != NULL)
195                 dbus_message_unref(message_disconnect);
196         g_free(path);
197
198         return err_ret;
199 }
200
201 int set_manager(DBusConnection *connection, char *key, dbus_bool_t value)
202 {
203         DBusMessage *message;
204         DBusMessageIter iter;
205         DBusError err;
206
207         message = dbus_message_new_method_call("net.connman", "/",
208                                                 "net.connman.Manager",
209                                                 "SetProperty");
210         if (message == NULL)
211                 return -ENOMEM;
212
213         dbus_message_iter_init_append(message, &iter);
214         dbus_property_append_basic(&iter, (const char *) key,
215                                                 DBUS_TYPE_BOOLEAN, &value);
216
217         dbus_error_init(&err);
218         dbus_connection_send_with_reply_and_block(connection, message,
219                         -1, &err);
220         if (dbus_error_is_set(&err) == TRUE) {
221                 printf("Error 'net.connman.Manager' %s\n", err.message);
222                 dbus_error_free(&err);
223         }
224
225         dbus_message_unref(message);
226
227         return 0;
228 }
229
230 /* Call with any given function we want connman to respond to */
231 DBusMessage *get_message(DBusConnection *connection, char *function)
232 {
233         DBusMessage *message, *reply;
234         DBusError error;
235
236         message = dbus_message_new_method_call(CONNMAN_SERVICE,
237                                                 CONNMAN_MANAGER_PATH,
238                                                 CONNMAN_MANAGER_INTERFACE,
239                                                 function);
240         if (message == NULL)
241                 return NULL;
242
243         dbus_error_init(&error);
244
245         reply = dbus_connection_send_with_reply_and_block(connection,
246                                                            message, -1, &error);
247         if (dbus_error_is_set(&error) == TRUE) {
248                 fprintf(stderr, "%s\n", error.message);
249                 dbus_error_free(&error);
250         } else if (reply == NULL)
251                 fprintf(stderr, "Failed to receive message\n");
252
253         dbus_message_unref(message);
254
255         return reply;
256 }
257
258 int list_properties(DBusConnection *connection, char *function,
259                         char *service_name)
260 {
261         DBusMessage *message;
262
263         message = get_message(connection, function);
264         if (message == NULL)
265                 return -ENOMEM;
266
267         if (strcmp(function, "GetProperties") == 0)
268                 extract_manager_properties(message);
269
270         else if (strcmp(function, "GetServices") == 0 && service_name != NULL)
271                 extract_services(message, service_name);
272
273         else if (strcmp(function, "GetServices") == 0 && service_name == NULL)
274                 get_services(message);
275
276         else if (strcmp(function, "GetTechnologies") == 0)
277                 extract_tech(message);
278
279         dbus_message_unref(message);
280
281         return 0;
282 }