2 * Network Client Library
4 * Copyright 2012 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.1 (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
10 * http://www.tizenopensource.org/license
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.
22 #include "network-internal.h"
23 #include "network-dbus-request.h"
25 struct gdbus_connection_data {
26 GDBusConnection *connection;
28 GCancellable *cancellable;
29 void *handle_libnetwork;
32 /*****************************************************************************
33 * Extern Global Variables
34 *****************************************************************************/
36 /*****************************************************************************
38 *****************************************************************************/
40 static pthread_mutex_t managed_idler_list_mutex = PTHREAD_MUTEX_INITIALIZER;
41 static GSList *managed_idler_list;
43 /*****************************************************************************
44 * Global Functions Definition
45 *****************************************************************************/
47 static void __net_managed_idler_list_lock(void)
49 pthread_mutex_lock(&managed_idler_list_mutex);
52 static void __net_managed_idler_list_unlock(void)
54 pthread_mutex_unlock(&managed_idler_list_mutex);
57 static void __net_remove_idler(gpointer data)
59 managed_idler_data_t *idler = (managed_idler_data_t *) data;
61 NETWORK_LOG(NETWORK_HIGH, "Remove idler [%d]", idler->id);
63 g_source_remove(idler->id);
64 _network_info_unref(idler->network_info);
69 * NOTE: When API user is a dynamically loadable module,
70 * the API user module may get unloaded post net_deregister_client() call.
71 * To clean residual memory, this destructor is called before unloading.
73 void __attribute__ ((destructor)) _net_destructor(void)
75 __net_managed_idler_list_lock();
77 g_slist_free_full(managed_idler_list, __net_remove_idler);
79 __net_managed_idler_list_unlock();
81 NETWORK_LOG(NETWORK_HIGH, "net-client destructed");
84 gboolean _net_add_idler_to_list(managed_idler_data_t *idler_data)
86 __net_managed_idler_list_lock();
88 GSList *found = g_slist_find(managed_idler_list, idler_data);
90 __net_managed_idler_list_unlock();
94 managed_idler_list = g_slist_prepend(managed_idler_list, idler_data);
96 __net_managed_idler_list_unlock();
100 gboolean _net_remove_idler_from_list(managed_idler_data_t *idler_data)
102 __net_managed_idler_list_lock();
104 GSList *found = g_slist_find(managed_idler_list, idler_data);
106 __net_managed_idler_list_unlock();
111 * Just remove the entry, no need to free idler_data here,
112 * it freed in __net_dbus_idler_cb
114 managed_idler_list = g_slist_delete_link(managed_idler_list, found);
116 __net_managed_idler_list_unlock();
120 void _network_info_ref(network_info_t *network_info)
122 __atomic_add_fetch(&network_info->refcount, 1, __ATOMIC_ACQ_REL);
124 NETWORK_LOG(NETWORK_HIGH, "%p ref %d", network_info,
125 __atomic_load_n(&network_info->refcount, __ATOMIC_ACQUIRE));
128 void _network_info_unref(network_info_t *network_info)
130 if (__atomic_load_n(&network_info->refcount, __ATOMIC_ACQUIRE) == 0) {
131 NETWORK_LOG(NETWORK_ERROR, "This should not happen, some error scenario!!!");
135 NETWORK_LOG(NETWORK_HIGH, "%p ref %d", network_info,
136 __atomic_load_n(&network_info->refcount, __ATOMIC_ACQUIRE) - 1);
138 if (__atomic_sub_fetch(&network_info->refcount, 1, __ATOMIC_ACQ_REL) > 0)
141 g_free(network_info);
144 char* _net_print_error(net_err_t error)
146 /* LCOV_EXCL_START */
150 return "NET_ERR_NONE";
152 /* Common Error value */
155 case NET_ERR_UNKNOWN:
156 return "NET_ERR_UNKNOWN";
158 /* Client Register related Errors used in API return */
160 /** Application is already registered */
161 case NET_ERR_APP_ALREADY_REGISTERED:
162 return "NET_ERR_APP_ALREADY_REGISTERED";
163 /** Application is not registered */
164 case NET_ERR_APP_NOT_REGISTERED:
165 return "NET_ERR_APP_NOT_REGISTERED";
167 /* Connection Related Error */
169 /** No active connection exists for the given profile name */
170 case NET_ERR_NO_ACTIVE_CONNECTIONS:
171 return "NET_ERR_NO_ACTIVE_CONNECTIONS";
172 /** Active connection already exists for the given profile name */
173 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
174 return "NET_ERR_ACTIVE_CONNECTION_EXISTS";
176 /** Connection failure : out of range */
177 case NET_ERR_CONNECTION_OUT_OF_RANGE:
178 return "NET_ERR_CONNECTION_OUT_OF_RANGE";
179 /** Connection failure : pin missing */
180 case NET_ERR_CONNECTION_PIN_MISSING:
181 return "NET_ERR_CONNECTION_PIN_MISSING";
182 /** Connection failure : dhcp failed */
183 case NET_ERR_CONNECTION_DHCP_FAILED:
184 return "NET_ERR_CONNECTION_DHCP_FAILED";
185 /** Connection failure */
186 case NET_ERR_CONNECTION_CONNECT_FAILED:
187 return "NET_ERR_CONNECTION_CONNECT_FAILED";
188 /** Connection failure : login failed */
189 case NET_ERR_CONNECTION_LOGIN_FAILED:
190 return "NET_ERR_CONNECTION_LOGIN_FAILED";
191 /** Connection failure : authentication failed */
192 case NET_ERR_CONNECTION_AUTH_FAILED:
193 return "NET_ERR_CONNECTION_AUTH_FAILED";
194 /** Connection failure : invalid key */
195 case NET_ERR_CONNECTION_INVALID_KEY:
196 return "NET_ERR_CONNECTION_INVALID_KEY";
200 /** Access is denied */
201 case NET_ERR_ACCESS_DENIED:
202 return "NET_ERR_ACCESS_DENIED";
203 /** Operation is in progress */
204 case NET_ERR_IN_PROGRESS:
205 return "NET_ERR_IN_PROGRESS";
206 /** Operation was aborted by client or network*/
207 case NET_ERR_OPERATION_ABORTED:
208 return "NET_ERR_OPERATION_ABORTED";
209 /** Invalid value of API parameter */
210 case NET_ERR_INVALID_PARAM:
211 return "NET_ERR_INVALID_PARAM";
212 /** invalid operation depending on current state */
213 case NET_ERR_INVALID_OPERATION:
214 return "NET_ERR_INVALID_OPERATION";
216 /** Feature not supported */
217 case NET_ERR_NOT_SUPPORTED:
218 return "NET_ERR_NOT_SUPPORTED";
220 case NET_ERR_TIME_OUT:
221 return "NET_ERR_TIME_OUT";
222 /** Network service is not available*/
223 case NET_ERR_NO_SERVICE:
224 return "NET_ERR_NO_SERVICE";
225 /** DBus can't find appropriate method */
226 case NET_ERR_UNKNOWN_METHOD:
227 return "NET_ERR_UNKNOWN_METHOD";
228 /** Operation is restricted */
229 case NET_ERR_SECURITY_RESTRICTED:
230 return "NET_ERR_SECURITY_RESTRICTED";
231 /** WiFi driver on/off failed */
232 case NET_ERR_WIFI_DRIVER_FAILURE:
233 return "NET_ERR_WIFI_DRIVER_FAILURE";
240 int _net_is_valid_service_type(net_service_type_t service_type)
242 switch (service_type) {
243 case NET_SERVICE_INTERNET:
244 case NET_SERVICE_MMS:
245 case NET_SERVICE_PREPAID_INTERNET:
246 case NET_SERVICE_PREPAID_MMS:
247 case NET_SERVICE_TETHERING:
248 case NET_SERVICE_APPLICATION:
254 return TRUE; //LCOV_EXCL_LINE
257 net_device_t _net_get_tech_type_from_path(const char *profile_name)
259 __NETWORK_FUNC_ENTER__;
261 net_device_t device_type = NET_DEVICE_UNKNOWN;
263 /* LCOV_EXCL_START */
264 if (g_str_has_prefix(profile_name,
265 CONNMAN_WIFI_SERVICE_PROFILE_PREFIX) == TRUE)
266 device_type = NET_DEVICE_WIFI;
267 else if (g_str_has_prefix(profile_name,
268 CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX) == TRUE)
269 device_type = NET_DEVICE_CELLULAR;
270 else if (g_str_has_prefix(profile_name,
271 CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX) == TRUE)
272 device_type = NET_DEVICE_ETHERNET;
273 else if (g_str_has_prefix(profile_name,
274 CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX) == TRUE)
275 device_type = NET_DEVICE_BLUETOOTH;
276 else if (g_str_has_prefix(profile_name,
277 CONNMAN_MESH_PROFILE_PREFIX) == TRUE)
278 device_type = NET_DEVICE_MESH;
281 __NETWORK_FUNC_EXIT__;
285 int _net_get_tech_state(GVariant *msg, network_tech_state_info_t* tech_state)
287 __NETWORK_FUNC_ENTER__;
289 net_err_t Error = NET_ERR_NONE;
290 GVariantIter *iter_main = NULL;
291 GVariantIter *var = NULL;
292 GVariant *value = NULL;
298 /* LCOV_EXCL_START */
299 if (g_strcmp0(tech_state->technology, "wifi") == 0)
300 tech_prefix = CONNMAN_WIFI_TECHNOLOGY_PREFIX;
301 else if (g_strcmp0(tech_state->technology, "cellular") == 0)
302 tech_prefix = CONNMAN_CELLULAR_TECHNOLOGY_PREFIX;
303 else if (g_strcmp0(tech_state->technology, "ethernet") == 0)
304 tech_prefix = CONNMAN_ETHERNET_TECHNOLOGY_PREFIX;
305 else if (g_strcmp0(tech_state->technology, "bluetooth") == 0)
306 tech_prefix = CONNMAN_BLUETOOTH_TECHNOLOGY_PREFIX;
307 else if (g_strcmp0(tech_state->technology, "mesh") == 0)
308 tech_prefix = CONNMAN_MESH_TECHNOLOGY_PREFIX;
310 NETWORK_LOG(NETWORK_ERROR, "Invalid technology type");
311 Error = NET_ERR_INVALID_PARAM;
316 g_variant_get(msg, "(a(oa{sv}))", &iter_main);
317 while (g_variant_iter_loop(iter_main, "(oa{sv})", &path, &var)) {
319 if (path == NULL || g_strcmp0(path, tech_prefix) != 0)
322 while (g_variant_iter_loop(var, "{sv}", &key, &value)) {
323 if (g_strcmp0(key, "Powered") == 0) {
324 data = g_variant_get_boolean(value);
327 tech_state->Powered = TRUE;
329 tech_state->Powered = FALSE; //LCOV_EXCL_LINE
330 } else if (g_strcmp0(key, "Connected") == 0) {
331 data = g_variant_get_boolean(value);
334 tech_state->Connected = TRUE;
336 tech_state->Connected = FALSE; //LCOV_EXCL_LINE
337 } else if (g_strcmp0(key, "Tethering") == 0) {
338 /* For further use */
342 g_variant_iter_free(iter_main);
345 __NETWORK_FUNC_EXIT__;
349 void _net_clear_request_table(network_info_t *network_info)
351 __NETWORK_FUNC_ENTER__;
356 for (i = 0; i < NETWORK_REQUEST_TYPE_MAX; i++)
357 memset(&(network_info->request_table[i]), 0, sizeof(network_request_table_t));
360 __NETWORK_FUNC_EXIT__;
363 int _net_dbus_create_gdbus_call(network_info_t *network_info)
365 GError *error = NULL;
367 #if !GLIB_CHECK_VERSION(2, 36, 0)
372 network_info->connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
373 if (network_info->connection == NULL) {
374 /* LCOV_EXCL_START */
376 NETWORK_LOG(NETWORK_ERROR,
377 "Failed to connect to the D-BUS daemon [%s]", error->message);
381 return NET_ERR_UNKNOWN;
384 network_info->cancellable = g_cancellable_new();
390 void _net_dbus_close_gdbus_call(network_info_t *network_info)
393 g_cancellable_cancel(network_info->cancellable);
394 g_object_unref(network_info->cancellable);
395 network_info->cancellable = NULL;
397 g_object_unref(network_info->connection);
398 network_info->connection = NULL;