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.
24 #include <dbus/dbus-glib-lowlevel.h>
27 #include <vconf-keys.h>
32 #include "wifi-state.h"
33 #include "wifi-indicator.h"
34 #include "wifi-background-scan.h"
37 #define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged"
39 #define CONNMAN_MANAGER_SIGNAL_FILTER "type='signal',interface='net.connman.Manager'"
40 #define CONNMAN_TECHNOLOGY_SIGNAL_FILTER "type='signal',interface='net.connman.Technology'"
41 #define CONNMAN_SERVICE_SIGNAL_FILTER "type='signal',interface='net.connman.Service'"
43 static DBusConnection *signal_connection = NULL;
45 static int __netconfig_get_state(DBusMessage *msg, char *state)
47 char *key_name = NULL;
48 char *svc_state = NULL;
49 DBusMessageIter iter, sub_iter;
50 int Error = NETCONFIG_ERROR_INTERNAL;
53 dbus_message_iter_init(msg, &iter);
54 int ArgType = dbus_message_iter_get_arg_type(&iter);
56 if (ArgType != DBUS_TYPE_STRING)
59 dbus_message_iter_get_basic(&iter, &key_name);
60 if (strcmp(key_name, "State") != 0)
63 dbus_message_iter_next(&iter);
64 ArgType = dbus_message_iter_get_arg_type(&iter);
65 if (ArgType != DBUS_TYPE_VARIANT)
68 dbus_message_iter_recurse(&iter, &sub_iter);
69 ArgType = dbus_message_iter_get_arg_type(&sub_iter);
70 if (ArgType != DBUS_TYPE_STRING)
73 dbus_message_iter_get_basic(&sub_iter, &svc_state);
74 snprintf(state, strlen(svc_state) + 1, "%s", svc_state);
75 Error = NETCONFIG_NO_ERROR;
81 static char *__netconfig_get_property(DBusMessage * msg, char **property)
83 DBusMessageIter args, variant;
84 char *sigvalue = NULL;
86 /** read these parameters */
87 if (!dbus_message_iter_init(msg, &args))
88 ERR("Message does not have parameters");
89 else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING)
90 ERR("Argument is not string");
92 dbus_message_iter_get_basic(&args, &sigvalue);
93 dbus_message_iter_next(&args);
94 dbus_message_iter_recurse(&args, &variant);
95 if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_STRING)
96 dbus_message_iter_get_basic(&variant, property);
104 static void __netconfig_wifi_technology_state_signal_handler(
105 const char *sigvalue, const char *property)
107 static char previous_technology_state[DBUS_STATE_MAX_BUFLEN] = {0};
109 if (sigvalue == NULL || property == NULL)
112 if (g_str_equal(sigvalue, "State") != TRUE)
115 if (g_str_equal(property, "unknown") == TRUE)
118 if (g_str_equal(previous_technology_state, property) == TRUE)
121 g_strlcpy(previous_technology_state, property, sizeof(previous_technology_state));
123 INFO("Technology state value is %s, property %s", sigvalue, property);
125 if (g_str_equal(property, "offline") == TRUE) {
126 gchar *wifi_tech_state = NULL;
128 wifi_tech_state = netconfig_wifi_get_technology_state();
129 INFO("Wi-Fi technology state: %s", wifi_tech_state);
131 if (wifi_tech_state == NULL)
132 netconfig_wifi_update_power_state(FALSE);
134 g_free(wifi_tech_state);
135 } else if (g_str_equal(property, "enabled") == TRUE)
136 netconfig_wifi_update_power_state(TRUE);
139 static void netconfig_wifi_set_essid(const char *active_profile)
143 char *essid_name = NULL;
144 DBusConnection *connection = NULL;
145 DBusMessage *message = NULL;
148 if (active_profile == NULL) {
149 ERR("Can't get active_profile");
153 connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
154 if (connection == NULL) {
155 ERR("Failed to get system bus");
159 message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, connection, active_profile,
160 CONNMAN_SERVICE_INTERFACE, "GetProperties");
162 if (message == NULL) {
163 ERR("Failed to get service properties");
164 dbus_connection_unref(connection);
168 MessageType = dbus_message_get_type(message);
170 if (MessageType == DBUS_MESSAGE_TYPE_ERROR) {
171 const char *ptr = dbus_message_get_error_name(message);
172 ERR("Error!!! Error message received [%s]", ptr);
176 state = netconfig_extract_service_state(message, &essid_name);
179 ERR("state is not ready");
183 err = vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name);
185 ERR("Can't set essid [%d]", err);
192 dbus_message_unref(message);
194 dbus_connection_unref(connection);
197 static void netconfig_wifi_unset_essid(void)
199 vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, "");
202 static void __netconfig_wifi_service_state_signal_handler(DBusMessage *msg, const char *profile)
204 char state[DBUS_STATE_MAX_BUFLEN] = {0};
205 static char current_profile[DBUS_PATH_MAX_BUFLEN] = {0};
210 if (__netconfig_get_state(msg, state) == NETCONFIG_NO_ERROR) {
213 DBG("Signaled profile [%s] ==> state %s", profile, state);
215 vconf_get_int(VCONFKEY_WIFI_STATE, &value);
217 if (strcmp(state, "ready") == 0 || strcmp(state, "online") == 0) {
218 if (value > VCONFKEY_WIFI_OFF && value != VCONFKEY_WIFI_CONNECTED) {
220 INFO("Wifi connected");
222 if ((vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED)) < 0)
223 ERR("Error!!! vconf_set_int failed");
225 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTED);
227 netconfig_wifi_set_essid(profile);
229 netconfig_wifi_indicator_start();
231 g_strlcpy(current_profile, profile, sizeof(current_profile));
233 } else if (strcmp(state, "failure") == 0 || strcmp(state, "disconnect") == 0 || strcmp(state, "idle") == 0) {
234 if (value > VCONFKEY_WIFI_UNCONNECTED) {
236 INFO("Wifi [%s] Disconnected", profile);
237 DBG("Current profile is %s", current_profile);
239 if ((strcmp(profile, current_profile)) == 0) {
240 if ((vconf_set_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED)) < 0)
241 ERR("Error!!! vconf_set_int failed");
243 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
245 netconfig_wifi_unset_essid();
247 netconfig_wifi_indicator_stop();
249 memset(current_profile, 0, sizeof(current_profile));
252 } else if (strcmp(state, "association") == 0 || strcmp(state, "configuration") == 0) {
253 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING);
256 DBG("Signaled profile [%s] has error to get its state", profile);
259 static DBusHandlerResult __netconfig_signal_filter_handler(
260 DBusConnection *conn, DBusMessage *msg, void *user_data)
262 char *sigvalue = NULL;
265 INFO("Invalid Message. Ignore");
267 /* We have handled this message, don't pass it on */
268 return DBUS_HANDLER_RESULT_HANDLED;
271 if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE,
272 CONNMAN_SIGNAL_PROPERTY_CHANGED)) {
273 /* We have handled this message, don't pass it on */
274 return DBUS_HANDLER_RESULT_HANDLED;
275 } else if (dbus_message_is_signal(msg, CONNMAN_TECHNOLOGY_INTERFACE,
276 CONNMAN_SIGNAL_PROPERTY_CHANGED)) {
277 char *property = NULL;
278 char *tech_path = NULL;
280 sigvalue = __netconfig_get_property(msg, &property);
281 if (sigvalue == NULL)
282 return DBUS_HANDLER_RESULT_HANDLED;
284 tech_path = (char *)dbus_message_get_path(msg);
286 if (strstr(tech_path, "/wifi") != NULL) {
287 __netconfig_wifi_technology_state_signal_handler((const char *)sigvalue, (const char *)property);
288 return DBUS_HANDLER_RESULT_HANDLED;
291 /* We have handled this message, don't pass it on */
292 return DBUS_HANDLER_RESULT_HANDLED;
293 } else if (dbus_message_is_signal(msg, CONNMAN_SERVICE_INTERFACE, CONNMAN_SIGNAL_PROPERTY_CHANGED)) {
294 sigvalue = netconfig_dbus_get_string(msg);
296 if (sigvalue == NULL)
297 return DBUS_HANDLER_RESULT_HANDLED;
299 if (strcmp(sigvalue, "State") == 0) {
300 char *profile = NULL;
302 profile = (char *)dbus_message_get_path(msg);
304 if (strstr(profile, "wifi_") != NULL) {
305 __netconfig_wifi_service_state_signal_handler(msg, profile);
306 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
311 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
314 void netconfig_register_signal(void)
316 DBusConnection *conn = NULL;
319 DBG("Register DBus signal filters");
321 dbus_error_init(&err);
322 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
324 ERR("Error! Failed to connect to the D-BUS daemon: [%s]",
326 dbus_error_free(&err);
330 signal_connection = conn;
332 dbus_connection_setup_with_g_main(conn, NULL);
334 /* listening to messages from all objects as no path is specified */
335 /* see signals from the given interface */
336 dbus_bus_add_match(conn, CONNMAN_MANAGER_SIGNAL_FILTER, &err);
337 dbus_connection_flush(conn);
338 if (dbus_error_is_set(&err)) {
339 ERR("Error! Match Error (%s)", err.message);
340 dbus_error_free(&err);
344 dbus_bus_add_match(conn, CONNMAN_TECHNOLOGY_SIGNAL_FILTER, &err);
345 dbus_connection_flush(conn);
346 if (dbus_error_is_set(&err)) {
347 ERR("Error! Match Error (%s)", err.message);
348 dbus_error_free(&err);
352 dbus_bus_add_match(conn, CONNMAN_SERVICE_SIGNAL_FILTER, &err);
353 dbus_connection_flush(conn);
354 if (dbus_error_is_set(&err)) {
355 ERR("Error! Match Error (%s)", err.message);
356 dbus_error_free(&err);
360 if (dbus_connection_add_filter(conn, __netconfig_signal_filter_handler, NULL, NULL)
362 ERR("Error! dbus_connection_add_filter() failed");
366 INFO("Successfully register signal filters");
369 void netconfig_deregister_signal(void)
371 if (signal_connection == NULL) {
372 ERR("Error! Already de-registered. Nothing to be done");
376 dbus_connection_remove_filter(signal_connection, __netconfig_signal_filter_handler,
378 INFO("Successfully remove DBus signal filters");
380 dbus_connection_unref(signal_connection);
381 signal_connection = NULL;