[net-config] Add reference to gdbus connection
[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 guint owner_id = 0;
45 static got_name_cb g_callback = NULL;
46
47 struct gdbus_conn_data {
48         GDBusConnection *connection;
49         int conn_ref_count;
50         GCancellable *cancellable;
51 };
52
53 static struct gdbus_conn_data gconn_data = {NULL, 0, NULL};
54
55 GDBusObjectManagerServer *netdbus_get_wifi_manager(void)
56 {
57         return manager_server_wifi;
58 }
59
60 GDBusObjectManagerServer *netdbus_get_state_manager(void)
61 {
62         return manager_server_state;
63 }
64
65 GDBusObjectManagerServer *netdbus_get_statistics_manager(void)
66 {
67         return manager_server_statistics;
68 }
69
70 GDBusConnection *netdbus_get_connection(void)
71 {
72         return gconn_data.connection;
73 }
74
75 GCancellable *netdbus_get_cancellable(void)
76 {
77         return gconn_data.cancellable;
78 }
79
80 void netconfig_gdbus_pending_call_ref(void)
81 {
82         g_object_ref(gconn_data.connection);
83
84         __sync_fetch_and_add(&gconn_data.conn_ref_count, 1);
85 }
86
87 void netconfig_gdbus_pending_call_unref(void)
88 {
89         if (gconn_data.conn_ref_count < 1)
90                 return;
91
92         g_object_unref(gconn_data.connection);
93
94         if (__sync_sub_and_fetch(&gconn_data.conn_ref_count, 1) < 1) {
95                 /* TODO: Check this
96                  * gconn_data.connection = NULL;
97                  */
98         }
99 }
100
101 int _create_gdbus_call(GDBusConnection *conn)
102 {
103         if (gconn_data.connection != NULL) {
104                 ERR("Connection already set");
105                 return -1;
106         }
107
108         gconn_data.connection = conn;
109         if (gconn_data.connection == NULL) {
110                 ERR("Failed to connect to the D-BUS daemon");
111                 return -1;
112         }
113
114         gconn_data.cancellable = g_cancellable_new();
115
116         return 0;
117 }
118
119 gboolean netconfig_is_cellular_internet_profile(const char *profile)
120 {
121         const char internet_suffix[] = "_1";
122         char *suffix = NULL;
123
124         if (profile == NULL)
125                 return FALSE;
126
127         if (g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX)
128                         == TRUE) {
129                 suffix = strrchr(profile, '_');
130                 if (g_strcmp0(suffix, internet_suffix) == 0)
131                         return TRUE;
132         }
133
134         return FALSE;
135 }
136
137 gboolean netconfig_is_cellular_profile(const char *profile)
138 {
139         if (profile == NULL)
140                 return FALSE;
141
142         return g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX);
143 }
144
145 gboolean netconfig_is_wifi_profile(const char *profile)
146 {
147         if (profile == NULL)
148                 return FALSE;
149
150         return g_str_has_prefix(profile, CONNMAN_WIFI_SERVICE_PROFILE_PREFIX);
151 }
152
153 gboolean netconfig_is_ethernet_profile(const char *profile)
154 {
155         if (profile == NULL)
156                 return FALSE;
157
158         return g_str_has_prefix(profile, CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX);
159 }
160
161 gboolean netconfig_is_bluetooth_profile(const char *profile)
162 {
163         if (profile == NULL)
164                 return FALSE;
165
166         return g_str_has_prefix(profile, CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX);
167 }
168
169 gboolean netconfig_invoke_dbus_method_nonblock(const char *dest, const char *path,
170                 const char *interface_name, const char *method, GVariant *params,
171                 GAsyncReadyCallback notify_func)
172 {
173         GDBusConnection *connection = NULL;
174
175         DBG("[GDBUS Async] %s %s %s", interface_name, method, path);
176
177         connection = netdbus_get_connection();
178         if (connection == NULL) {
179                 ERR("Failed to get gdbus connection");
180                 return FALSE;
181         }
182
183         g_dbus_connection_call(connection,
184                         dest,
185                         path,
186                         interface_name,
187                         method,
188                         params,
189                         NULL,
190                         G_DBUS_CALL_FLAGS_NONE,
191                         NETCONFIG_DBUS_REPLY_TIMEOUT,
192                         netdbus_get_cancellable(),
193                         (GAsyncReadyCallback) notify_func,
194                         NULL);
195         if (notify_func)
196                 netconfig_gdbus_pending_call_ref();
197
198         return TRUE;
199 }
200
201 GVariant *netconfig_invoke_dbus_method(const char *dest, const char *path,
202                 const char *interface_name, const char *method, GVariant *params)
203 {
204
205         GError *error = NULL;
206         GVariant *reply = NULL;
207         GDBusConnection *connection;
208
209         connection = netdbus_get_connection();
210         if (connection == NULL) {
211                 ERR("Failed to get GDBusconnection");
212                 return reply;
213         }
214
215         reply = g_dbus_connection_call_sync(
216                         connection,
217                         dest,
218                         path,
219                         interface_name,
220                         method,
221                         params,
222                         NULL,
223                         G_DBUS_CALL_FLAGS_NONE,
224                         NETCONFIG_DBUS_REPLY_TIMEOUT,
225                         netdbus_get_cancellable(),
226                         &error);
227
228         if (reply == NULL) {
229                 if (error != NULL) {
230                         ERR("g_dbus_connection_call_sync() failed"
231                                                 "error [%d: %s]", error->code, error->message);
232                         g_error_free(error);
233                 } else {
234                         ERR("g_dbus_connection_call_sync() failed");
235                 }
236
237                 return NULL;
238         }
239
240         return reply;
241 }
242
243 gboolean netconfig_dbus_emit_signal(const gchar *destination_bus_name,
244                                                                         const gchar *object_path,
245                                                                         const gchar *interface_name,
246                                                                         const gchar *signal_name,
247                                                                         GVariant *params)
248 {
249         gboolean rv = FALSE;
250         GError *Error = NULL;
251         GDBusConnection *connection;
252
253         connection = netdbus_get_connection();
254         if (connection == NULL) {
255                 ERR("[NET_DBUS] GDBusconnection is NULL");
256                 return 0;
257         }
258
259         rv = g_dbus_connection_emit_signal(connection, destination_bus_name,
260                 object_path, interface_name, signal_name, params, &Error);
261         if (rv != TRUE) {
262                 ERR("[NET_DBUS] Failed to emit signal, Error: %s", Error->message);
263                 g_clear_error(&Error);
264                 return rv;
265         }
266
267         INFO("Sent signal (%s), Interface (%s)", signal_name, interface_name);
268
269         return rv;
270 }
271
272 static void _got_bus_cb(GDBusConnection *conn, const gchar *name,
273                 gpointer user_data)
274 {
275         _create_gdbus_call(conn);
276 }
277
278 static void _got_name_cb(GDBusConnection *conn, const gchar *name,
279                 gpointer user_data)
280 {
281         INFO("Got gdbus name: [%s] and gdbus connection: [%p]", name, conn);
282
283         if (g_callback != NULL) {
284                 g_callback();
285         }
286 }
287
288 static void _lost_name_cb(GDBusConnection *conn, const gchar *name,
289                 gpointer user_data)
290 {
291         /* May service name is already in use */
292         ERR("_lost_name_cb [%s]", name);
293
294         /* The result of DBus name request is only permitted,
295          *  such as DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER.
296          */
297         exit(2);
298 }
299
300 int setup_gdbus(got_name_cb cb)
301 {
302         g_callback = cb;
303
304         manager_server_wifi = g_dbus_object_manager_server_new(NETCONFIG_WIFI_PATH);
305         if (manager_server_wifi == NULL) {
306                 ERR("Manager server for WIFI_PATH not created.");
307                 exit(1);
308         }
309
310         manager_server_state = g_dbus_object_manager_server_new(NETCONFIG_NETWORK_STATE_PATH);
311         if (manager_server_state == NULL) {
312                 ERR("Manager server for STATE_PATH not created.");
313                 exit(1);
314         }
315
316         manager_server_statistics = g_dbus_object_manager_server_new(NETCONFIG_NETWORK_STATISTICS_PATH);
317         if (manager_server_statistics == NULL) {
318                 ERR("Manager server for STATISTICS_PATH not created.");
319                 exit(1);
320         }
321
322         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, NETCONFIG_SERVICE,
323                                                           G_BUS_NAME_OWNER_FLAGS_NONE,
324                                                           _got_bus_cb, _got_name_cb, _lost_name_cb,
325                                                           NULL, NULL);
326         if (!owner_id) {
327                 ERR("Could not get system bus!");
328                 return -EIO;
329         }
330
331         INFO("Got system bus!");
332         return 0;
333 }
334
335 void cleanup_gdbus(void)
336 {
337         g_bus_unown_name(owner_id);
338         g_object_unref(manager_server_wifi);
339         g_object_unref(manager_server_state);
340         g_object_unref(manager_server_statistics);
341 }