2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Danny JS Seo <S.Seo@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
28 #include "netconfig.h"
30 #define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
32 #define DBUS_PARAM_TYPE_STRING "string"
33 #define DBUS_PARAM_TYPE_INT16 "int16"
34 #define DBUS_PARAM_TYPE_UINT16 "uint16"
35 #define DBUS_PARAM_TYPE_INT32 "int32"
36 #define DBUS_PARAM_TYPE_UINT32 "uint32"
37 #define DBUS_PARAM_TYPE_INT64 "int64"
38 #define DBUS_PARAM_TYPE_UINT64 "uint64"
39 #define DBUS_PARAM_TYPE_DOUBLE "double"
40 #define DBUS_PARAM_TYPE_BYTE "byte"
41 #define DBUS_PARAM_TYPE_BOOLEAN "boolean"
42 #define DBUS_PARAM_TYPE_OBJECT_PATH "objpath"
44 static int __neconfig_dbus_datatype_from_stringname(const char *Args)
48 if (!strcmp(Args, DBUS_PARAM_TYPE_STRING))
49 ArgType = DBUS_TYPE_STRING;
50 else if (!strcmp(Args, DBUS_PARAM_TYPE_INT16))
51 ArgType = DBUS_TYPE_INT16;
52 else if (!strcmp(Args, DBUS_PARAM_TYPE_UINT16))
53 ArgType = DBUS_TYPE_UINT16;
54 else if (!strcmp(Args, DBUS_PARAM_TYPE_INT32))
55 ArgType = DBUS_TYPE_INT32;
56 else if (!strcmp(Args, DBUS_PARAM_TYPE_UINT32))
57 ArgType = DBUS_TYPE_UINT32;
58 else if (!strcmp(Args, DBUS_PARAM_TYPE_INT64))
59 ArgType = DBUS_TYPE_INT64;
60 else if (!strcmp(Args, DBUS_PARAM_TYPE_UINT64))
61 ArgType = DBUS_TYPE_UINT64;
62 else if (!strcmp(Args, DBUS_PARAM_TYPE_DOUBLE))
63 ArgType = DBUS_TYPE_DOUBLE;
64 else if (!strcmp(Args, DBUS_PARAM_TYPE_BYTE))
65 ArgType = DBUS_TYPE_BYTE;
66 else if (!strcmp(Args, DBUS_PARAM_TYPE_BOOLEAN))
67 ArgType = DBUS_TYPE_BOOLEAN;
68 else if (!strcmp(Args, DBUS_PARAM_TYPE_OBJECT_PATH))
69 ArgType = DBUS_TYPE_OBJECT_PATH;
71 ERR("Error!!! Unknown Argument Type \"%s\"", Args);
79 static int __netconfig_dbus_append_argument(DBusMessageIter *iter, int ArgType,
83 unsigned char ByteValue = 0;
84 dbus_bool_t booleanvalue = 0;
85 dbus_uint16_t Uint16 = 0;
86 dbus_int16_t Int16 = 0;
87 dbus_uint32_t Uint32 = 0;
88 dbus_int32_t Int32 = 0;
92 ByteValue = strtoul(Value, NULL, 0);
93 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &ByteValue);
96 case DBUS_TYPE_DOUBLE:
97 Double = strtod(Value, NULL);
98 dbus_message_iter_append_basic(iter, DBUS_TYPE_DOUBLE, &Double);
101 case DBUS_TYPE_INT16:
102 Int16 = strtol(Value, NULL, 0);
103 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &Int16);
106 case DBUS_TYPE_UINT16:
107 Uint16 = strtoul(Value, NULL, 0);
108 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &Uint16);
111 case DBUS_TYPE_INT32:
112 Int32 = strtol(Value, NULL, 0);
113 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &Int32);
116 case DBUS_TYPE_UINT32:
117 Uint32 = strtoul(Value, NULL, 0);
118 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &Uint32);
121 case DBUS_TYPE_STRING:
122 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &Value);
125 case DBUS_TYPE_OBJECT_PATH:
126 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &Value);
129 case DBUS_TYPE_BOOLEAN:
130 if (strcmp(Value, "true") == 0) {
132 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &booleanvalue);
133 } else if (strcmp(Value, "false") == 0) {
134 booleanvalue = FALSE;
135 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &booleanvalue);
137 ERR("Error!!! Expected \"true\" or \"false\" instead of \"%s\"", Value);
144 ERR("Error!!! Unsupported data ArgType %c", (char)ArgType);
152 static int __netconfig_dbus_append_array(DBusMessageIter *iter, int ArgType,
155 const char *Val = NULL;
156 char *DupValue = strdup(Value);
157 Val = strtok(DupValue, ",");
159 while (Val != NULL) {
160 if (__netconfig_dbus_append_argument(iter, ArgType, Val) != 0) {
167 Val = strtok(NULL, ",");
175 static int __netconfig_dbus_append_dict(DBusMessageIter *iter, int KeyType,
176 int ValueType, const char *Value)
178 const char *Val = NULL;
179 char *DupValue = strdup(Value);
180 Val = strtok(DupValue, ",");
182 while (Val != NULL) {
183 DBusMessageIter SubIter;
184 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
187 if (__netconfig_dbus_append_argument(&SubIter, KeyType, Val) != 0) {
188 ERR("Error!!! network_append_argument() failed");
194 Val = strtok(NULL, ",");
196 ERR("Error!!! Mal-formed dictionary data");
202 if (__netconfig_dbus_append_argument(&SubIter, ValueType, Val) != 0) {
203 ERR("Error!!! network_append_argument() failed");
209 dbus_message_iter_close_container(iter, &SubIter);
211 Val = strtok(NULL, ",");
219 char *netconfig_dbus_get_string(DBusMessage * msg)
221 DBusMessageIter args;
222 char *sigvalue = NULL;
224 /** read these parameters */
225 if (!dbus_message_iter_init(msg, &args))
226 DBG("Message does not have parameters");
227 else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args))
228 DBG("Argument is not string");
230 dbus_message_iter_get_basic(&args, &sigvalue);
235 DBusMessage *netconfig_dbus_send_request(const char *destination, char *param_array[])
237 DBusConnection *connection = NULL;
239 DBusMessage *message = NULL;
240 char *RequestMethod = NULL;
242 const char *path = NULL;
243 const char *name = NULL;
245 DBusMessageIter iter;
246 DBusMessage *reply = NULL;
248 DBG("Send DBus request to %s", destination);
250 for (param_count = 0; param_array[param_count] != NULL;
252 DBG("[%s]", param_array[param_count]);
254 DBG("Total Arguments [%d]", param_count);
255 path = param_array[i++];
258 name = param_array[i++];/** 1st is request name */
259 if ((strlen(path) == 0) || (strlen(name) == 0)) {
260 ERR("Error!!! Invalid parameters passed path [%s], request name [%s]",
266 dbus_error_init(&error);
268 connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
269 if (connection == NULL) {
270 ERR("Error!!! Failed to get system DBus, error [%s]",
272 dbus_error_free(&error);
277 RequestMethod = strrchr(name, '.');
278 if (RequestMethod == NULL) {
279 ERR("Error!!! Invalid method in \"%s\"", name);
284 *RequestMethod = '\0';
285 message = dbus_message_new_method_call(NULL, path, name,
287 if (message == NULL) {
288 ERR("Error!!! dbus_message_new_method_call() failed");
293 if (destination && !dbus_message_set_destination(message, destination)) {
294 ERR("Error!!! dbus_message_set_destination() failed");
299 dbus_message_iter_init_append(message, &iter);
301 /** Two args name and path already extracted, so i == 2 */
302 while (i < param_count) {
306 int SecondaryType = 0;
307 int ContainerType = 0;
308 DBusMessageIter *TargetIter = NULL;
309 DBusMessageIter ContainerIter;
310 ArgType = DBUS_TYPE_INVALID;
312 Args = param_array[i++];
313 Ch = strchr(Args, ':');
315 ERR("Error!!! Invalid data format[\"%s\"]", Args);
321 if (strcmp(Args, "variant") == 0)
322 ContainerType = DBUS_TYPE_VARIANT;
323 else if (strcmp(Args, "array") == 0)
324 ContainerType = DBUS_TYPE_ARRAY;
325 else if (strcmp(Args, "dict") == 0)
326 ContainerType = DBUS_TYPE_DICT_ENTRY;
328 ContainerType = DBUS_TYPE_INVALID;
330 if (ContainerType != DBUS_TYPE_INVALID) {
332 Ch = strchr(Args, ':');
334 ERR("Error!!! Invalid data format[\"%s\"]", Args);
343 ArgType = DBUS_TYPE_STRING;
345 ArgType = __neconfig_dbus_datatype_from_stringname(Args);
348 ERR("Error!!! Unknown data type");
354 if (ContainerType == DBUS_TYPE_DICT_ENTRY) {
355 char Signature[5] = "";
357 Ch = strchr(Ch, ':');
359 ERR("Error!!! Invalid data format[\"%s\"]", Args);
365 SecondaryType = __neconfig_dbus_datatype_from_stringname(Args);
366 if (SecondaryType == -1) {
367 ERR("Error!!! Unknown data type");
372 Signature[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
373 Signature[1] = ArgType;
374 Signature[2] = SecondaryType;
375 Signature[3] = DBUS_DICT_ENTRY_END_CHAR;
378 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
379 Signature, &ContainerIter);
381 TargetIter = &ContainerIter;
382 } else if (ContainerType != DBUS_TYPE_INVALID) {
383 char Signature[2] = "";
384 Signature[0] = ArgType;
387 dbus_message_iter_open_container(&iter, ContainerType,
388 Signature, &ContainerIter);
390 TargetIter = &ContainerIter;
394 if (ContainerType == DBUS_TYPE_ARRAY) {
395 if (__netconfig_dbus_append_array(TargetIter, ArgType, Ch) != 0) {
396 ERR("Error!!! network_append_array() failed");
400 } else if (ContainerType == DBUS_TYPE_DICT_ENTRY) {
401 if (__netconfig_dbus_append_dict(TargetIter, ArgType, SecondaryType, Ch) != 0) {
402 ERR("Error!!! network_append_dict() failed");
407 if (__netconfig_dbus_append_argument(TargetIter, ArgType, Ch) != 0) {
408 ERR("Error!!! network_append_array() failed");
414 if (ContainerType != DBUS_TYPE_INVALID) {
415 dbus_message_iter_close_container(&iter, &ContainerIter);
419 dbus_error_init(&error);
421 reply = dbus_connection_send_with_reply_and_block(connection, message,
422 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
425 if (dbus_error_is_set(&error) == TRUE) {
426 ERR("Error!!! dbus_connection_send_with_reply_and_block() failed, Error[%s: %s]",
427 error.name, error.message);
429 dbus_error_free(&error);
435 dbus_message_unref(message);
436 dbus_connection_unref(connection);
443 dbus_message_unref(message);
444 if (connection != NULL)
445 dbus_connection_unref(connection);
450 DBusMessage *netconfig_invoke_dbus_method(const char *dest, DBusConnection *connection,
451 const char *path, const char *interface_name, const char *method)
454 DBusMessage *reply = NULL;
455 DBusMessage *message = NULL;
457 message = dbus_message_new_method_call(dest, path, interface_name, method);
458 if (message == NULL) {
459 ERR("Error!!! Failed to GetProperties");
463 dbus_error_init(&error);
465 reply = dbus_connection_send_with_reply_and_block(connection, message,
466 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
469 if (dbus_error_is_set(&error) == TRUE) {
470 ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. DBus error [%s: %s]",
471 error.name, error.message);
473 dbus_error_free(&error);
475 ERR("Error!!! Failed to get properties");
477 dbus_message_unref(message);
482 dbus_message_unref(message);
487 void setup_dbus(gpointer data, gpointer user_data)
489 struct dbus_input_arguments *args;
490 DBusMessageIter *iter;
492 if (data != NULL && user_data != NULL) {
493 args = (struct dbus_input_arguments *)data;
494 iter = (DBusMessageIter *) user_data;
496 dbus_message_iter_append_basic(iter, args->type,
501 DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest,
502 DBusConnection *connection,
503 const char *path, const char *interface_name,
504 const char *method, GList *args)
507 DBusMessageIter iter;
508 DBusMessage *reply = NULL;
509 DBusMessage *message = NULL;
511 message = dbus_message_new_method_call(dest, path, interface_name, method);
512 if (message == NULL) {
513 ERR("Error!!! DBus method call fail");
517 dbus_message_iter_init_append(message, &iter);
520 g_list_foreach(args, setup_dbus, (gpointer) &iter);
522 dbus_error_init(&error);
524 reply = dbus_connection_send_with_reply_and_block(connection, message,
525 NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
528 if (dbus_error_is_set(&error) == TRUE) {
529 ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. DBus error [%s: %s]",
530 error.name, error.message);
532 dbus_error_free(&error);
534 ERR("Error!!! Failed to get properties");
536 dbus_message_unref(message);
541 dbus_message_unref(message);
546 char *netconfig_wifi_get_connected_service_name(DBusMessage *message)
548 int is_connected = 0;
549 char *essid_name = NULL;
550 DBusMessageIter iter, array;
552 dbus_message_iter_init(message, &iter);
553 dbus_message_iter_recurse(&iter, &array);
555 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
556 DBusMessageIter entry, string;
557 const char *key = NULL;
559 dbus_message_iter_recurse(&array, &entry);
560 dbus_message_iter_get_basic(&entry, &key);
562 if (g_str_equal(key, "State") == TRUE && is_connected == 0) {
563 dbus_message_iter_next(&entry);
564 dbus_message_iter_recurse(&entry, &string);
566 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
567 dbus_message_iter_get_basic(&string, &key);
569 if (g_str_equal(key, "ready") == TRUE || g_str_equal(key, "online") == TRUE)
572 } else if (g_str_equal(key, "Name") == TRUE) {
573 dbus_message_iter_next(&entry);
574 dbus_message_iter_recurse(&entry, &string);
576 if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) {
577 dbus_message_iter_get_basic(&string, &key);
579 essid_name = (char *)g_strdup(key);
583 dbus_message_iter_next(&array);
586 if (is_connected == 1 && essid_name != NULL)
589 if (essid_name != NULL)
595 void netconfig_dbus_parse_recursive(DBusMessageIter *iter,
596 netconfig_dbus_result_type result_type, void *data)
598 unsigned char *bgscan_mode = NULL;
599 static dbus_bool_t default_tech_flag = FALSE;
600 char *default_tech = NULL;
602 if (result_type == NETCONFIG_DBUS_RESULT_GET_BGSCAN_MODE)
603 bgscan_mode = (unsigned char *)data;
604 else if (result_type == NETCONFIG_DBUS_RESULT_DEFAULT_TECHNOLOGY)
605 default_tech = (char *)data;
608 int ArgType = dbus_message_iter_get_arg_type(iter);
610 if (ArgType == DBUS_TYPE_INVALID)
616 unsigned char Value = 0;
618 dbus_message_iter_get_basic(iter, &Value);
620 *bgscan_mode = Value;
621 INFO("BG scan mode: %d, %d", *bgscan_mode, Value);
625 case DBUS_TYPE_STRING:
629 dbus_message_iter_get_basic(iter, &Value);
631 INFO("result type: %d, string: %s", result_type, Value);
632 if (result_type == NETCONFIG_DBUS_RESULT_DEFAULT_TECHNOLOGY) {
633 if (strcmp(Value, "DefaultTechnology") == 0) {
634 default_tech_flag = TRUE;
636 if (default_tech_flag == TRUE) {
637 sprintf(default_tech, "%s", Value);
638 INFO("default technology: %s", default_tech);
639 default_tech_flag = FALSE;
646 case DBUS_TYPE_SIGNATURE:
650 dbus_message_iter_get_basic(iter, &Value);
654 case DBUS_TYPE_OBJECT_PATH:
658 dbus_message_iter_get_basic(iter, &Value);
662 case DBUS_TYPE_INT16:
664 dbus_int16_t Value = 0;
666 dbus_message_iter_get_basic(iter, &Value);
670 case DBUS_TYPE_UINT16:
672 dbus_uint16_t Value = 0;
674 dbus_message_iter_get_basic(iter, &Value);
678 case DBUS_TYPE_INT32:
680 dbus_int32_t Value = 0;
682 dbus_message_iter_get_basic(iter, &Value);
686 case DBUS_TYPE_UINT32:
688 dbus_uint32_t Value = 0;
690 dbus_message_iter_get_basic(iter, &Value);
694 case DBUS_TYPE_INT64:
696 dbus_int64_t Value = 0;
698 dbus_message_iter_get_basic(iter, &Value);
702 case DBUS_TYPE_UINT64:
704 dbus_uint64_t Value = 0;
706 dbus_message_iter_get_basic(iter, &Value);
710 case DBUS_TYPE_DOUBLE:
714 dbus_message_iter_get_basic(iter, &Value);
718 case DBUS_TYPE_BOOLEAN:
720 dbus_bool_t Value = 0;
722 dbus_message_iter_get_basic(iter, &Value);
726 case DBUS_TYPE_VARIANT:
728 DBusMessageIter SubIter;
730 dbus_message_iter_recurse(iter, &SubIter);
731 netconfig_dbus_parse_recursive(&SubIter,
736 case DBUS_TYPE_ARRAY:
739 DBusMessageIter SubIter;
741 dbus_message_iter_recurse(iter, &SubIter);
742 CurrentType = dbus_message_iter_get_arg_type(&SubIter);
744 while (CurrentType != DBUS_TYPE_INVALID) {
745 netconfig_dbus_parse_recursive(&SubIter,
748 dbus_message_iter_next(&SubIter);
749 CurrentType = dbus_message_iter_get_arg_type(&SubIter);
754 case DBUS_TYPE_DICT_ENTRY:
756 DBusMessageIter SubIter;
758 dbus_message_iter_recurse(iter, &SubIter);
759 netconfig_dbus_parse_recursive(&SubIter, result_type, data);
761 dbus_message_iter_next(&SubIter);
762 netconfig_dbus_parse_recursive(&SubIter, result_type, data);
766 case DBUS_TYPE_STRUCT:
769 DBusMessageIter SubIter;
771 dbus_message_iter_recurse(iter, &SubIter);
773 while ((CurrentType = dbus_message_iter_get_arg_type(&SubIter))
774 != DBUS_TYPE_INVALID) {
775 netconfig_dbus_parse_recursive(&SubIter, result_type, data);
777 dbus_message_iter_next(&SubIter);
783 ERR("Error!!! Invalid Argument Type [%c]", ArgType);
785 } while (dbus_message_iter_next(iter));
788 DBusGConnection *netconfig_setup_dbus(void)
790 DBusGConnection* connection = NULL;
791 GError *error = NULL;
795 connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
796 if (connection == NULL) {
797 ERR("Fail to get DBus(%s)", error->message);
801 INFO("Successfully get system DBus connection(%p)", connection);
803 proxy = dbus_g_proxy_new_for_name(connection, "org.freedesktop.DBus",
804 "/org/freedesktop/DBus",
805 "org.freedesktop.DBus");
807 if (!dbus_g_proxy_call(proxy, "RequestName", &error,
808 G_TYPE_STRING, NETCONFIG_SERVICE, G_TYPE_UINT, 0,
809 G_TYPE_INVALID, G_TYPE_UINT, &rv,
811 ERR("Failed to acquire service(%s) error(%s)",
812 NETCONFIG_SERVICE, error->message);
814 dbus_g_connection_unref(connection);
819 if (rv != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
820 ERR("Service name is already in use");
822 dbus_g_connection_unref(connection);