client: Fix various memory leaks in monitor and services parts
[platform/upstream/connman.git] / client / monitor.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2012  Intel Corporation. All rights reserved.
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 as
10  *  published by the Free Software Foundation.
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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <stdint.h>
28
29 #include <glib.h>
30
31 #include <dbus/dbus.h>
32
33 #include "client/monitor.h"
34 #include "client/services.h"
35 #include "client/technology.h"
36 #include "client/data_manager.h"
37 #include "src/connman.h"
38 #include "gdbus/gdbus.h"
39
40 static const char *get_service_name(DBusMessage *message, char *dbus_path)
41 {
42         DBusMessageIter iter, array;
43
44         dbus_message_iter_init(message, &iter);
45         dbus_message_iter_recurse(&iter, &array);
46
47         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
48                 DBusMessageIter entry, dict;
49                 struct service_data service;
50                 char *path;
51
52                 dbus_message_iter_recurse(&array, &entry);
53                 dbus_message_iter_get_basic(&entry, &path);
54
55                 if (g_strcmp0(path, dbus_path) == 0) {
56                         dbus_message_iter_next(&entry);
57                         dbus_message_iter_recurse(&entry, &dict);
58                         extract_service_name(&dict, &service);
59                         return service.name;
60                 } else {
61                         dbus_message_iter_next(&array);
62                 }
63         }
64         return NULL;
65 }
66
67 static void extract_tech_signal(DBusMessage *message)
68 {
69         DBusMessageIter iter, dict;
70         char *path;
71
72         dbus_message_iter_init(message, &iter);
73
74         if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_OBJECT_PATH) {
75                 dbus_message_iter_get_basic(&iter, &path);
76                 printf(" { %s }\n", path);
77         }
78         dbus_message_iter_next(&iter);
79
80         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
81                 dbus_message_iter_recurse(&iter, &dict);
82                 extract_properties(&dict);
83         }
84 }
85
86 static void extract_signal_args(DBusMessage *message)
87 {
88         DBusMessageIter iter, array, dict;
89         char *string, *value;
90         uint16_t key_int;
91         dbus_bool_t bvalue;
92
93         value = NULL;
94         key_int = 0;
95
96         dbus_message_iter_init(message, &iter);
97
98         while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
99                 if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
100                         dbus_message_iter_get_basic(&iter, &string);
101                         printf("\n[%s] = ",
102                         string);
103                 }
104                 dbus_message_iter_next(&iter);
105                 if (dbus_message_iter_get_arg_type(&iter) !=
106                                                         DBUS_TYPE_INVALID) {
107                         dbus_message_iter_recurse(&iter, &array);
108                         if (dbus_message_iter_get_arg_type(&array) ==
109                                                         DBUS_TYPE_STRING) {
110                                 dbus_message_iter_get_basic(&array, &value);
111                                 printf("%s\n", value);
112                                 continue;
113                         } else if (dbus_message_iter_get_arg_type(&array) ==
114                                                         DBUS_TYPE_BOOLEAN) {
115                                 dbus_message_iter_get_basic(&array, &bvalue);
116                                 printf("%s\n", bvalue == TRUE ?
117                                                         "True" : "False");
118                                 continue;
119                         } else if (dbus_message_iter_get_arg_type(&array) ==
120                                                         DBUS_TYPE_ARRAY)
121                                 dbus_message_iter_recurse(&array, &dict);
122                         if (dbus_message_iter_get_arg_type(&dict) ==
123                                                 DBUS_TYPE_DICT_ENTRY) {
124                                 iterate_dict(&dict, value, key_int);
125                                 printf("\n");
126                         } else {
127                                 iterate_array(&array);
128                                 printf("\n");
129                         }
130                         dbus_message_iter_next(&iter);
131                 }
132         }
133 }
134
135 int monitor_connman(DBusConnection *connection, char *interface,
136                                 char *signal_name)
137 {
138         char *rule = g_strdup_printf("type='signal',interface='net.connman.%s',"
139                                         "member='%s'", interface, signal_name);
140         DBusError err;
141
142         dbus_error_init(&err);
143         g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, &err);
144         if (dbus_error_is_set(&err)) {
145                 fprintf(stderr, "Bus setup error:%s\n", err.message);
146                 return -1;
147         }
148         dbus_bus_add_match(connection, rule, &err);
149
150         if (dbus_error_is_set(&err)) {
151                 fprintf(stderr, "Match Error: %s\n", err.message);
152                 return -1;
153         }
154         return 0;
155 }
156
157 DBusHandlerResult service_property_changed(DBusConnection *connection,
158                                                 DBusMessage *message,
159                                                 void *user_data)
160 {
161         DBusMessage *service_message;
162         struct service_data service;
163
164         if (dbus_message_is_signal(message, "net.connman.Service",
165                                             "PropertyChanged")) {
166                 service_message = get_message(connection, "GetServices");
167                 if (service_message == NULL)
168                         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
169
170                 service.name = get_service_name(service_message,
171                                 (char *) dbus_message_get_path(message));
172                 printf("\n");
173                 g_message("Path = %s, Interface = %s\nService = %s",
174                                 dbus_message_get_path(message),
175                                 dbus_message_get_interface(message),
176                                 service.name);
177                 extract_signal_args(message);
178
179                 dbus_message_unref(service_message);
180         }
181
182         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
183 }
184
185 DBusHandlerResult tech_property_changed(DBusConnection *connection,
186                                         DBusMessage *message, void *user_data)
187 {
188         if (dbus_message_is_signal(message, "net.connman.Technology",
189                                             "PropertyChanged")) {
190                 printf("\n");
191                 g_message("Path = %s, Interface = %s",
192                                 dbus_message_get_path(message),
193                                 dbus_message_get_interface(message));
194                 extract_signal_args(message);
195         }
196         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
197 }
198
199 DBusHandlerResult tech_added_removed(DBusConnection *connection,
200                                         DBusMessage *message, void *user_data)
201 {
202         if (dbus_message_is_signal(message, "net.connman.Manager",
203                                             "TechnologyAdded")) {
204                 printf("\n");
205                 g_message("Path = %s, Interface = %s",
206                                 dbus_message_get_path(message),
207                                 dbus_message_get_interface(message));
208                 printf("New technology added:\n");
209                 extract_tech_signal(message);
210         } else if (dbus_message_is_signal(message, "net.connman.Manager",
211                                                    "TechnologyRemoved")) {
212                 printf("\n");
213                 g_message("Path = %s, Interface = %s",
214                                 dbus_message_get_path(message),
215                                 dbus_message_get_interface(message));
216                 printf("Technology was removed:\n");
217                 extract_tech_signal(message);
218         }
219
220         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
221 }
222
223 DBusHandlerResult manager_services_changed(DBusConnection *connection,
224                                 DBusMessage *message, void *user_data)
225 {
226         if (dbus_message_is_signal(message, "net.connman.Manager",
227                                                 "ServicesChanged")) {
228                 printf("\n");
229                 g_message("Path = %s, Interface = %s",
230                                 dbus_message_get_path(message),
231                                 dbus_message_get_interface(message));
232                 printf("Services Changed, displaying updated "
233                                                         "list of services:\n");
234                 list_properties(connection, "GetServices", NULL);
235         }
236
237         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
238 }
239
240 DBusHandlerResult manager_property_changed(DBusConnection *connection,
241                                 DBusMessage *message, void *user_data)
242 {
243         if (dbus_message_is_signal(message, "net.connman.Manager",
244                                             "PropertyChanged")) {
245                 printf("\n");
246                 g_message("Path = %s, Interface = %s",
247                                 dbus_message_get_path(message),
248                                 dbus_message_get_interface(message));
249                 extract_signal_args(message);
250         }
251
252         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
253 }