Fixed memory related issues reported by valgrind.
[platform/core/connectivity/net-config.git] / src / dbus / netdbus.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23
24 #include "log.h"
25 #include "netdbus.h"
26
27 #define DBUS_PARAM_TYPE_STRING          "string"
28 #define DBUS_PARAM_TYPE_INT16           "int16"
29 #define DBUS_PARAM_TYPE_UINT16          "uint16"
30 #define DBUS_PARAM_TYPE_INT32           "int32"
31 #define DBUS_PARAM_TYPE_UINT32          "uint32"
32 #define DBUS_PARAM_TYPE_INT64           "int64"
33 #define DBUS_PARAM_TYPE_UINT64          "uint64"
34 #define DBUS_PARAM_TYPE_DOUBLE          "double"
35 #define DBUS_PARAM_TYPE_BYTE            "byte"
36 #define DBUS_PARAM_TYPE_BOOLEAN         "boolean"
37 #define DBUS_PARAM_TYPE_OBJECT_PATH     "objpath"
38 #define DBUS_PARAM_TYPE_VARIANT         "variant"
39 #define DBUS_PARAM_TYPE_ARRAY           "array"
40
41 static GDBusObjectManagerServer *manager_server_wifi = NULL;
42 static GDBusObjectManagerServer *manager_server_state = NULL;
43 static GDBusObjectManagerServer *manager_server_statistics = NULL;
44 static GDBusObjectManagerServer *manager_server_vpn = NULL;
45 static GDBusObjectManagerServer *manager_server_mptcp = NULL;
46 static guint owner_id = 0;
47 static got_name_cb g_callback = NULL;
48
49 struct gdbus_conn_data {
50         GDBusConnection *connection;
51         int conn_ref_count;
52         GCancellable *cancellable;
53 };
54
55 static struct gdbus_conn_data gconn_data = {NULL, 0, NULL};
56
57 GDBusObjectManagerServer *netdbus_get_wifi_manager(void)
58 {
59         return manager_server_wifi;
60 }
61
62 GDBusObjectManagerServer *netdbus_get_state_manager(void)
63 {
64         return manager_server_state;
65 }
66
67 GDBusObjectManagerServer *netdbus_get_statistics_manager(void)
68 {
69         return manager_server_statistics;
70 }
71
72 GDBusObjectManagerServer *netdbus_get_vpn_manager(void)
73 {
74         return manager_server_vpn;
75 }
76
77 GDBusObjectManagerServer *netdbus_get_mptcp_manager(void)
78 {
79         return manager_server_mptcp;
80 }
81
82 GDBusConnection *netdbus_get_connection(void)
83 {
84         return gconn_data.connection;
85 }
86
87 GCancellable *netdbus_get_cancellable(void)
88 {
89         return gconn_data.cancellable;
90 }
91
92 void netconfig_gdbus_pending_call_ref(void)
93 {
94         g_object_ref(gconn_data.connection);
95
96         __sync_fetch_and_add(&gconn_data.conn_ref_count, 1);
97 }
98
99 void netconfig_gdbus_pending_call_unref(void)
100 {
101         if (gconn_data.conn_ref_count < 1)
102                 return;
103
104         g_object_unref(gconn_data.connection);
105
106         if (__sync_sub_and_fetch(&gconn_data.conn_ref_count, 1) < 1) {
107                 /* TODO: Check this
108                  * gconn_data.connection = NULL;
109                  */
110         }
111 }
112
113 int _create_gdbus_call(GDBusConnection *conn)
114 {
115         if (gconn_data.connection != NULL) {
116                 ERR("Connection already set");
117                 return -1;
118         }
119
120         gconn_data.connection = conn;
121         if (gconn_data.connection == NULL) {
122                 ERR("Failed to connect to the D-BUS daemon");
123                 return -1;
124         }
125
126         gconn_data.cancellable = g_cancellable_new();
127
128         return 0;
129 }
130
131 gboolean netconfig_is_cellular_internet_profile(const char *profile)
132 {
133         const char internet_suffix[] = "_1";
134         char *suffix = NULL;
135
136         if (profile == NULL)
137                 return FALSE;
138
139         if (g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX)
140                         == TRUE) {
141                 suffix = strrchr(profile, '_');
142                 if (g_strcmp0(suffix, internet_suffix) == 0)
143                         return TRUE;
144         }
145
146         return FALSE;
147 }
148
149 gboolean netconfig_is_cellular_profile(const char *profile)
150 {
151         if (profile == NULL)
152                 return FALSE;
153
154         return g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX);
155 }
156
157 gboolean netconfig_is_wifi_profile(const char *profile)
158 {
159         if (profile == NULL)
160                 return FALSE;
161
162         return g_str_has_prefix(profile, CONNMAN_WIFI_SERVICE_PROFILE_PREFIX);
163 }
164
165 gboolean netconfig_is_ethernet_profile(const char *profile)
166 {
167         if (profile == NULL)
168                 return FALSE;
169
170         return g_str_has_prefix(profile, CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX);
171 }
172
173 gboolean netconfig_is_bluetooth_profile(const char *profile)
174 {
175         if (profile == NULL)
176                 return FALSE;
177
178         return g_str_has_prefix(profile, CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX);
179 }
180
181 gboolean netconfig_invoke_dbus_method_nonblock(const char *dest, const char *path,
182                 const char *interface_name, const char *method, GVariant *params,
183                 GAsyncReadyCallback notify_func)
184 {
185         GDBusConnection *connection = NULL;
186
187         DBG("[GDBUS Async] %s %s %s", interface_name, method, path);
188
189         connection = netdbus_get_connection();
190         if (connection == NULL) {
191                 ERR("Failed to get gdbus connection");
192                 return FALSE;
193         }
194
195         g_dbus_connection_call(connection,
196                         dest,
197                         path,
198                         interface_name,
199                         method,
200                         params,
201                         NULL,
202                         G_DBUS_CALL_FLAGS_NONE,
203                         NETCONFIG_DBUS_REPLY_TIMEOUT,
204                         netdbus_get_cancellable(),
205                         (GAsyncReadyCallback) notify_func,
206                         NULL);
207         if (notify_func)
208                 netconfig_gdbus_pending_call_ref();
209
210         return TRUE;
211 }
212
213 GVariant *netconfig_invoke_dbus_method(const char *dest, const char *path,
214                 const char *interface_name, const char *method, GVariant *params)
215 {
216
217         GError *error = NULL;
218         GVariant *reply = NULL;
219         GDBusConnection *connection;
220
221         connection = netdbus_get_connection();
222         if (connection == NULL) {
223                 ERR("Failed to get GDBusconnection");
224                 return reply;
225         }
226
227         reply = g_dbus_connection_call_sync(
228                         connection,
229                         dest,
230                         path,
231                         interface_name,
232                         method,
233                         params,
234                         NULL,
235                         G_DBUS_CALL_FLAGS_NONE,
236                         NETCONFIG_DBUS_REPLY_TIMEOUT,
237                         netdbus_get_cancellable(),
238                         &error);
239
240         if (reply == NULL) {
241                 if (error != NULL) {
242                         ERR("g_dbus_connection_call_sync() failed"
243                                                 "error [%d: %s]", error->code, error->message);
244                         g_error_free(error);
245                 } else {
246                         ERR("g_dbus_connection_call_sync() failed");
247                 }
248
249                 return NULL;
250         }
251
252         return reply;
253 }
254
255 gboolean netconfig_dbus_emit_signal(const gchar *destination_bus_name,
256                                                                         const gchar *object_path,
257                                                                         const gchar *interface_name,
258                                                                         const gchar *signal_name,
259                                                                         GVariant *params)
260 {
261         gboolean rv = FALSE;
262         GError *Error = NULL;
263         GDBusConnection *connection;
264
265         connection = netdbus_get_connection();
266         if (connection == NULL) {
267                 ERR("[NET_DBUS] GDBusconnection is NULL");
268                 return 0;
269         }
270
271         rv = g_dbus_connection_emit_signal(connection, destination_bus_name,
272                 object_path, interface_name, signal_name, params, &Error);
273         if (rv != TRUE) {
274                 ERR("[NET_DBUS] Failed to emit signal, Error: %s", Error->message);
275                 g_clear_error(&Error);
276                 return rv;
277         }
278
279         INFO("Sent signal (%s), Interface (%s)", signal_name, interface_name);
280
281         return rv;
282 }
283
284 static void _got_bus_cb(GDBusConnection *conn, const gchar *name,
285                 gpointer user_data)
286 {
287         _create_gdbus_call(conn);
288 }
289
290 static void _got_name_cb(GDBusConnection *conn, const gchar *name,
291                 gpointer user_data)
292 {
293         INFO("Got gdbus name: [%s] and gdbus connection: [%p]", name, conn);
294
295         if (g_callback != NULL)
296                 g_callback();
297 }
298
299 static void _lost_name_cb(GDBusConnection *conn, const gchar *name,
300                 gpointer user_data)
301 {
302         /* May service name is already in use */
303         ERR("_lost_name_cb [%s]", name);
304
305         /* The result of DBus name request is only permitted,
306          *  such as DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER.
307          */
308         exit(2);
309 }
310
311 int setup_gdbus(got_name_cb cb)
312 {
313         g_callback = cb;
314
315         manager_server_wifi = g_dbus_object_manager_server_new(NETCONFIG_WIFI_PATH);
316         if (manager_server_wifi == NULL) {
317                 ERR("Manager server for WIFI_PATH not created.");
318                 exit(1);
319         }
320
321         manager_server_state = g_dbus_object_manager_server_new(NETCONFIG_NETWORK_STATE_PATH);
322         if (manager_server_state == NULL) {
323                 ERR("Manager server for STATE_PATH not created.");
324                 exit(1);
325         }
326
327         manager_server_statistics = g_dbus_object_manager_server_new(NETCONFIG_NETWORK_STATISTICS_PATH);
328         if (manager_server_statistics == NULL) {
329                 ERR("Manager server for STATISTICS_PATH not created.");
330                 exit(1);
331         }
332
333         manager_server_vpn = g_dbus_object_manager_server_new(NETCONFIG_VPNSVC_PATH);
334         if (manager_server_vpn == NULL) {
335                 ERR("Manager server for VPNSVC_PATH not created.");
336                 exit(1);
337         }
338
339         manager_server_mptcp = g_dbus_object_manager_server_new(NETCONFIG_MPTCP_PATH);
340         if (manager_server_mptcp == NULL) {
341                 ERR("Manager server for MPTCP_PATH not created.");
342                 exit(1);
343         }
344
345         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, NETCONFIG_SERVICE,
346                                                           G_BUS_NAME_OWNER_FLAGS_NONE,
347                                                           _got_bus_cb, _got_name_cb, _lost_name_cb,
348                                                           NULL, NULL);
349         if (!owner_id) {
350                 ERR("Could not get system bus!");
351                 return -EIO;
352         }
353
354         INFO("Got system bus!");
355         return 0;
356 }
357
358 void cleanup_gdbus(void)
359 {
360         g_bus_unown_name(owner_id);
361         g_object_unref(manager_server_wifi);
362         g_object_unref(manager_server_state);
363         g_object_unref(manager_server_statistics);
364 }