2 * Network Configuration Module
4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include "netconfig.h"
28 #define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
30 #define DBUS_PARAM_TYPE_STRING "string"
31 #define DBUS_PARAM_TYPE_INT16 "int16"
32 #define DBUS_PARAM_TYPE_UINT16 "uint16"
33 #define DBUS_PARAM_TYPE_INT32 "int32"
34 #define DBUS_PARAM_TYPE_UINT32 "uint32"
35 #define DBUS_PARAM_TYPE_INT64 "int64"
36 #define DBUS_PARAM_TYPE_UINT64 "uint64"
37 #define DBUS_PARAM_TYPE_DOUBLE "double"
38 #define DBUS_PARAM_TYPE_BYTE "byte"
39 #define DBUS_PARAM_TYPE_BOOLEAN "boolean"
40 #define DBUS_PARAM_TYPE_OBJECT_PATH "objpath"
41 #define DBUS_PARAM_TYPE_VARIANT "variant"
42 #define DBUS_PARAM_TYPE_ARRAY "array"
45 static gboolean __netconfig_dbus_append_param_variant(
46 DBusMessageIter *iter, char *type, char *param)
48 DBusMessageIter value, array;
49 char *args = NULL, *ch = NULL;
50 dbus_bool_t b_value = FALSE;
52 if (strcmp(type, DBUS_PARAM_TYPE_STRING) == 0) {
53 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
54 DBUS_TYPE_STRING_AS_STRING, &value);
56 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, ¶m);
58 dbus_message_iter_close_container(iter, &value);
59 } else if (strcmp(type, DBUS_PARAM_TYPE_BOOLEAN) == 0) {
60 if (strcmp(param, "true") == 0) {
62 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
63 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
64 dbus_message_iter_append_basic(&value,
65 DBUS_TYPE_BOOLEAN, &b_value);
66 dbus_message_iter_close_container(iter, &value);
67 } else if (strcmp(param, "false") == 0) {
69 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
70 DBUS_TYPE_BOOLEAN_AS_STRING, &value);
71 dbus_message_iter_append_basic(&value,
72 DBUS_TYPE_BOOLEAN, &b_value);
73 dbus_message_iter_close_container(iter, &value);
75 ERR("Error!!! Expected \"true\" or"
76 "\"false\" instead of \"%s\"", ch);
79 } else if (strcmp(type, DBUS_PARAM_TYPE_OBJECT_PATH) == 0) {
80 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
81 DBUS_TYPE_OBJECT_PATH_AS_STRING, &value);
83 dbus_message_iter_append_basic(&value, DBUS_TYPE_OBJECT_PATH, ¶m);
85 dbus_message_iter_close_container(iter, &value);
86 } else if (strcmp(type, DBUS_PARAM_TYPE_ARRAY) == 0) {
88 ch = strchr(args, ':');
90 ERR("Error!!! Invalid data format[\"%s\"]", args);
95 if (strcmp(args, DBUS_PARAM_TYPE_STRING) == 0) {
96 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
97 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING,
100 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
101 DBUS_TYPE_STRING_AS_STRING, &array);
103 dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &ch);
105 dbus_message_iter_close_container(&value, &array);
107 dbus_message_iter_close_container(iter, &value);
108 } else if (strcmp(args, DBUS_PARAM_TYPE_OBJECT_PATH) == 0) {
109 dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
110 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING,
113 dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
114 DBUS_TYPE_OBJECT_PATH_AS_STRING, &array);
116 dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH, &ch);
118 dbus_message_iter_close_container(&value, &array);
120 dbus_message_iter_close_container(iter, &value);
122 ERR("Error!!! Not supported data format[\"%s\"]", args);
126 ERR("Error!!! Not supported data format[\"%s\"]", args);
133 static gboolean __netconfig_dbus_append_param(
134 DBusMessage *message, char *param_array[])
137 dbus_uint32_t uint32 = 0;
138 DBusMessageIter iter;
139 char *args = NULL, *ch = NULL;
141 if (param_array == NULL)
144 dbus_message_iter_init_append(message, &iter);
146 while (param_array[count] != NULL) {
147 args = param_array[count];
148 DBG("parameter %d - [%s]", count, param_array[count]);
150 ch = strchr(args, ':');
152 ERR("Error!!! Invalid parameter[\"%s\"]\n", args);
157 if (strcmp(args, DBUS_PARAM_TYPE_STRING) == 0) {
158 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ch);
159 } else if (strcmp(args, DBUS_PARAM_TYPE_UINT32) == 0) {
160 uint32 = strtoul(ch, NULL, 0);
161 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &uint32);
162 } else if (strcmp(args, DBUS_PARAM_TYPE_VARIANT) == 0) {
164 ch = strchr(args, ':');
166 ERR("Error!!! Invalid data format[\"%s\"]\n", args);
171 if (__netconfig_dbus_append_param_variant(&iter, args, ch) != TRUE)
174 } else if (strcmp(args, DBUS_PARAM_TYPE_OBJECT_PATH) == 0) {
175 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &ch);
177 ERR("Error!!! Not supported data format[\"%s\"]", args);
187 gboolean netconfig_dbus_get_basic_params_string(DBusMessage *message,
188 char **key, int type, void *value)
190 DBusMessageIter iter, iter_variant;
192 dbus_message_iter_init(message, &iter);
193 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
194 DBG("Argument type %d", dbus_message_iter_get_arg_type(&iter));
198 dbus_message_iter_get_basic(&iter, key);
203 dbus_message_iter_next(&iter);
204 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
205 DBG("Argument type %d", dbus_message_iter_get_arg_type(&iter));
209 dbus_message_iter_recurse(&iter, &iter_variant);
210 if (dbus_message_iter_get_arg_type(&iter_variant) != type)
213 dbus_message_iter_get_basic(&iter_variant, value);
218 gboolean netconfig_dbus_get_basic_params_array(DBusMessage *message,
219 char **key, void **value)
221 DBusMessageIter args, dict, entry, variant;
227 /* read parameters */
228 if (dbus_message_iter_init(message, &args) == FALSE) {
229 DBG("Message does not have parameters");
233 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) {
234 DBG("Argument type %d", dbus_message_iter_get_arg_type(&args));
238 dbus_message_iter_recurse(&args, &dict);
240 if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY) {
241 DBG("Argument type %d", dbus_message_iter_get_arg_type(&dict));
245 dbus_message_iter_recurse(&dict, &entry);
247 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
248 DBG("Argument type %d", dbus_message_iter_get_arg_type(&entry));
252 dbus_message_iter_get_basic(&entry, key);
257 dbus_message_iter_next(&entry);
259 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) {
260 DBG("Argument type %d", dbus_message_iter_get_arg_type(&entry));
264 dbus_message_iter_recurse(&entry, &variant);
266 type = dbus_message_iter_get_arg_type(&variant);
267 if (type == DBUS_TYPE_STRING)
268 dbus_message_iter_get_basic(&variant, value);
269 else if (type == DBUS_TYPE_BYTE || type == DBUS_TYPE_BOOLEAN ||
270 type == DBUS_TYPE_INT16 || type == DBUS_TYPE_UINT16 ||
271 type == DBUS_TYPE_INT32 || type == DBUS_TYPE_UINT32 ||
272 type == DBUS_TYPE_DOUBLE)
273 dbus_message_iter_get_basic(&variant, *value);
275 DBG("Argument type %d", type);
280 gboolean netconfig_is_cellular_profile(const char *profile)
285 return g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX);
288 gboolean netconfig_is_wifi_profile(const char *profile)
293 return g_str_has_prefix(profile, CONNMAN_WIFI_SERVICE_PROFILE_PREFIX);
296 gboolean netconfig_is_ethernet_profile(const char *profile)
301 return g_str_has_prefix(profile, CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX);
304 gboolean netconfig_is_bluetooth_profile(const char *profile)
309 return g_str_has_prefix(profile, CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX);
312 gboolean netconfig_invoke_dbus_method_nonblock(
313 const char *dest, const char *path,
314 const char *interface_name, const char *method, char *param_array[],
315 DBusPendingCallNotifyFunction notify_func)
318 DBusPendingCall *call;
319 DBusMessage *message = NULL;
320 DBusConnection *connection = NULL;
322 DBG("[DBUS Async] %s %s %s", interface_name, method, path);
324 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
325 if (connection == NULL) {
326 ERR("Failed to get system bus");
331 message = dbus_message_new_method_call(dest, path, interface_name, method);
332 if (message == NULL) {
333 ERR("Failed DBus method call");
335 dbus_connection_unref(connection);
340 if (__netconfig_dbus_append_param(message, param_array) == FALSE) {
341 ERR("Failed to append DBus params");
343 dbus_message_unref(message);
344 dbus_connection_unref(connection);
349 result = dbus_connection_send_with_reply(connection, message, &call,
350 NETCONFIG_DBUS_REPLY_TIMEOUT);
352 if (result != TRUE || call == NULL) {
353 ERR("dbus_connection_send_with_reply() failed.");
355 dbus_message_unref(message);
356 dbus_connection_unref(connection);
361 if (notify_func == NULL)
362 dbus_pending_call_cancel(call);
364 dbus_pending_call_set_notify(call, notify_func, NULL, NULL);
366 dbus_message_unref(message);
367 dbus_connection_unref(connection);
372 DBusMessage *netconfig_invoke_dbus_method(const char *dest, const char *path,
373 const char *interface_name, const char *method, char *param_array[])
376 DBusConnection *conn = NULL;
377 DBusMessage *reply = NULL;
378 DBusMessage *message = NULL;
380 DBG("[DBUS Sync] %s %s %s", interface_name, method, path);
382 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
384 ERR("Failed to get system bus");
389 message = dbus_message_new_method_call(dest, path, interface_name, method);
390 if (message == NULL) {
391 ERR("Error!!! Failed to GetProperties");
393 dbus_connection_unref(conn);
398 if (__netconfig_dbus_append_param(message, param_array) == FALSE) {
399 ERR("Error!!! __netconfig_dbus_append_param() failed");
401 dbus_message_unref(message);
402 dbus_connection_unref(conn);
407 dbus_error_init(&error);
409 reply = dbus_connection_send_with_reply_and_block(conn, message,
410 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
413 if (dbus_error_is_set(&error) == TRUE) {
414 ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. "
415 "DBus error [%s: %s]", error.name, error.message);
417 dbus_error_free(&error);
419 ERR("Error!!! Failed to get properties");
421 dbus_message_unref(message);
422 dbus_connection_unref(conn);
427 dbus_message_unref(message);
428 dbus_connection_unref(conn);
433 char *netconfig_wifi_get_connected_service_name(DBusMessage *message)
435 int is_connected = 0;
436 char *essid_name = NULL;
437 DBusMessageIter iter, array;
439 dbus_message_iter_init(message, &iter);
440 dbus_message_iter_recurse(&iter, &array);
442 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
443 DBusMessageIter entry, string;
444 const char *key = NULL;
446 dbus_message_iter_recurse(&array, &entry);
447 dbus_message_iter_get_basic(&entry, &key);
449 if (g_str_equal(key, "State") == TRUE && is_connected == 0) {
450 dbus_message_iter_next(&entry);
451 dbus_message_iter_recurse(&entry, &string);
453 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
454 dbus_message_iter_get_basic(&string, &key);
456 if (g_str_equal(key, "ready") == TRUE ||
457 g_str_equal(key, "online") == TRUE)
460 } else if (g_str_equal(key, "Name") == TRUE) {
461 dbus_message_iter_next(&entry);
462 dbus_message_iter_recurse(&entry, &string);
464 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
465 dbus_message_iter_get_basic(&string, &key);
467 essid_name = (char *)g_strdup(key);
471 dbus_message_iter_next(&array);
474 if (is_connected == 1 && essid_name != NULL)
477 if (essid_name != NULL)
483 DBusGConnection *netconfig_setup_dbus(void)
485 DBusGConnection* connection = NULL;
486 GError *error = NULL;
490 connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
491 if (connection == NULL) {
492 ERR("Fail to get DBus(%s)", error->message);
498 INFO("Successfully get system DBus connection(%p)", connection);
500 proxy = dbus_g_proxy_new_for_name(connection, "org.freedesktop.DBus",
501 "/org/freedesktop/DBus",
502 "org.freedesktop.DBus");
504 if (!dbus_g_proxy_call(proxy, "RequestName", &error,
505 G_TYPE_STRING, NETCONFIG_SERVICE, G_TYPE_UINT, 0,
506 G_TYPE_INVALID, G_TYPE_UINT, &rv,
508 ERR("Failed to acquire service(%s) error(%s)",
509 NETCONFIG_SERVICE, error->message);
512 dbus_g_connection_unref(connection);
517 if (rv != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
518 ERR("Service name is already in use");
520 dbus_g_connection_unref(connection);