f11a385d6a2b15970155c7cb2ca1592198729a9c
[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
36 #include "src/connman.h"
37 #include "client/services.h"
38 #include "client/technology.h"
39 #include "client/data_manager.h"
40 #include "gdbus/gdbus.h"
41 #include "dbus.h"
42
43 static void extract_manager_properties(DBusMessage *message)
44 {
45         DBusMessageIter iter, array;
46
47         dbus_message_iter_init(message, &iter);
48         dbus_message_iter_recurse(&iter, &array);
49         extract_properties(&array);
50 }
51
52 int store_proxy_input(DBusConnection *connection, DBusMessage *message,
53                                 char *name, int num_args, char *argv[])
54 {
55         int i, j, k;
56         int error = 0;
57         gchar **servers = NULL;
58         gchar **excludes = NULL;
59
60         for (i = 0; strcmp(argv[i], "excludes") != 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; j++) {
75                 excludes = g_try_realloc(excludes, (j + 1) * sizeof(char *));
76                 if (excludes == NULL) {
77                         fprintf(stderr, "Could not allocate memory for list\n");
78                         return -ENOMEM;
79                 }
80                 excludes[j] = g_strdup(argv[j + (i + 1)]);
81         }
82
83 free_servers:
84         error = set_proxy_manual(connection, message, name, servers, excludes,
85                                                                         i, j);
86
87         for (k = 0; k < j - 1; k++)
88                 g_free(excludes[k]);
89         g_free(excludes);
90
91         for (k = 0; k < i - 1; k++)
92                 g_free(servers[k]);
93         g_free(servers);
94
95         return error;
96 }
97
98 int connect_service(DBusConnection *connection, char *name)
99 {
100         DBusMessage *message, *message_connect = NULL;
101         struct service_data service;
102         char *path = NULL;
103         const char *path_name;
104         DBusError err;
105         int err_ret = 0;
106
107         message = get_message(connection, "GetServices");
108         if (message == NULL)
109                 return -ENOMEM;
110
111         path_name = find_service(connection, message, name, &service);
112         if (path_name == NULL) {
113                 err_ret = -ENXIO;
114                 goto error;
115         }
116
117         path = g_strdup_printf("/net/connman/service/%s", path_name);
118         message_connect = dbus_message_new_method_call("net.connman", path,
119                                                 "net.connman.Service",
120                                                 "Connect");
121         if (message_connect == NULL) {
122                 err_ret = -ENOMEM;
123                 goto error;
124         }
125
126         dbus_error_init(&err);
127         dbus_connection_send_with_reply_and_block(connection, message_connect,
128                                                                 -1, &err);
129
130         if (dbus_error_is_set(&err)) {
131                 printf("Connection failed; error: '%s'\n", err.message);
132                 err_ret = -EINVAL;
133                 goto error;
134         }
135
136         dbus_connection_send(connection, message_connect, NULL);
137         dbus_connection_flush(connection);
138
139 error:
140         if (message != NULL)
141                 dbus_message_unref(message);
142         if (message_connect != NULL)
143                 dbus_message_unref(message_connect);
144         g_free(path);
145
146         return err_ret;
147 }
148
149 int disconnect_service(DBusConnection *connection, char *name)
150 {
151         DBusMessage *message, *message_disconnect = NULL;
152         struct service_data service;
153         char *path = NULL;
154         const char *path_name;
155         DBusError err;
156         int err_ret = 0;
157
158         message = get_message(connection, "GetServices");
159         if (message == NULL)
160                 return -ENOMEM;
161
162         path_name = find_service(connection, message, name, &service);
163         if (path_name == NULL) {
164                 err_ret = -ENXIO;
165                 goto error;
166         }
167
168         path = g_strdup_printf("/net/connman/service/%s", path_name);
169         printf("%s\n", path);
170         message_disconnect = dbus_message_new_method_call("net.connman", path,
171                                                           "net.connman.Service",
172                                                           "Disconnect");
173         if (message_disconnect == NULL) {
174                 err_ret = -ENOMEM;
175                 goto error;
176         }
177
178         dbus_error_init(&err);
179         dbus_connection_send_with_reply_and_block(connection,
180                                                   message_disconnect,
181                                                   -1, &err);
182
183         if (dbus_error_is_set(&err)) {
184                 printf("Connection failed; error: '%s'\n", err.message);
185                 err_ret = -EINVAL;
186                 goto error;
187         }
188
189         dbus_connection_send(connection, message_disconnect, NULL);
190         dbus_connection_flush(connection);
191
192 error:
193         if (message != NULL)
194                 dbus_message_unref(message);
195         if (message_disconnect != NULL)
196                 dbus_message_unref(message_disconnect);
197         g_free(path);
198
199         return err_ret;
200 }
201
202 int set_manager(DBusConnection *connection, char *key, dbus_bool_t value)
203 {
204         DBusMessage *message;
205         DBusMessageIter iter;
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         dbus_connection_send(connection, message, NULL);
217         dbus_connection_flush(connection);
218         dbus_message_unref(message);
219
220         return 0;
221 }
222
223 /* Call with any given function we want connman to respond to */
224 DBusMessage *get_message(DBusConnection *connection, char *function)
225 {
226         DBusMessage *message, *reply;
227         DBusError error;
228
229         message = dbus_message_new_method_call(CONNMAN_SERVICE,
230                                                 CONNMAN_MANAGER_PATH,
231                                                 CONNMAN_MANAGER_INTERFACE,
232                                                 function);
233         if (message == NULL)
234                 return NULL;
235
236         dbus_error_init(&error);
237
238         reply = dbus_connection_send_with_reply_and_block(connection,
239                                                            message, -1, &error);
240         if (dbus_error_is_set(&error) == TRUE) {
241                 fprintf(stderr, "%s\n", error.message);
242                 dbus_error_free(&error);
243         } else if (reply == NULL)
244                 fprintf(stderr, "Failed to receive message\n");
245
246         dbus_message_unref(message);
247
248         return reply;
249 }
250
251 int list_properties(DBusConnection *connection, char *function,
252                         char *service_name)
253 {
254         DBusMessage *message;
255
256         message = get_message(connection, function);
257         if (message == NULL)
258                 return -ENOMEM;
259
260         if (strcmp(function, "GetProperties") == 0)
261                 extract_manager_properties(message);
262
263         else if (strcmp(function, "GetServices") == 0 && service_name != NULL)
264                 extract_services(message, service_name);
265
266         else if (strcmp(function, "GetServices") == 0 && service_name == NULL)
267                 get_services(message);
268
269         else if (strcmp(function, "GetTechnologies") == 0)
270                 extract_tech(message);
271
272         dbus_message_unref(message);
273
274         return 0;
275 }