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.
23 #include <vconf-keys.h>
24 #include <wifi-direct.h>
32 #include "netconfig.h"
34 #include "network-statistics.h"
35 #include "wifi-background-scan.h"
36 #include "wifi-power.h"
37 #include "wifi-state.h"
38 #include "mdm-private.h"
39 #include "wifi-agent.h"
40 #include "wifi-eap-config.h"
41 #include "wifi-firmware.h"
44 #define WLAN_DRIVER_SCRIPT "/usr/bin/wlan.sh"
46 static gboolean power_in_progress = FALSE;
47 static gboolean fm_waiting = FALSE;
49 static void __netconfig_wifi_technology_reply(DBusPendingCall *call, void *data)
53 message = dbus_pending_call_steal_reply(call);
55 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
56 ERR("%s", dbus_message_get_error_name(message));
58 if (dbus_message_is_error(message,
59 CONNMAN_ERROR_INTERFACE ".AlreadyEnabled") == TRUE) {
60 netconfig_wifi_update_power_state(TRUE);
61 power_in_progress = FALSE;
62 } else if (dbus_message_is_error(message,
63 CONNMAN_ERROR_INTERFACE ".AlreadyDisabled") == TRUE) {
64 netconfig_wifi_update_power_state(FALSE);
65 power_in_progress = FALSE;
68 DBG("Successfully requested");
71 dbus_message_unref(message);
72 dbus_pending_call_unref(call);
75 static gboolean __netconfig_wifi_enable_technology(void)
77 gboolean reply = FALSE;
78 char param0[] = "string:Powered";
79 char param1[] = "variant:boolean:true";
80 char *param_array[] = { NULL, NULL, NULL };
82 param_array[0] = param0;
83 param_array[1] = param1;
85 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
86 CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
87 "SetProperty", param_array, __netconfig_wifi_technology_reply);
90 ERR("Fail to enable Wi-Fi");
95 static gboolean __netconfig_wifi_disable_technology(void)
97 gboolean reply = FALSE;
98 char param0[] = "string:Powered";
99 char param1[] = "variant:boolean:false";
100 char *param_array[] = { NULL, NULL, NULL };
102 param_array[0] = param0;
103 param_array[1] = param1;
105 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
106 CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
107 "SetProperty", param_array, __netconfig_wifi_technology_reply);
110 ERR("Fail to disable Wi-Fi");
115 static gboolean __netconfig_wifi_load_driver(void)
118 const char *path = WLAN_DRIVER_SCRIPT;
119 char *const args[] = { "wlan.sh", "start", NULL };
120 char *const envs[] = { NULL };
122 if (netconfig_emulator_is_emulated() == TRUE)
125 #if defined EMBEDDED_TARGET
126 rv = netconfig_execute_file(path, args, envs);
128 DBG("Failed to load wireless device driver");
133 DBG("Successfully loaded wireless device driver");
137 gboolean netconfig_wifi_remove_driver(void)
140 const char *path = WLAN_DRIVER_SCRIPT;
141 char *const args[] = { "wlan.sh", "stop", NULL };
142 char *const env[] = { NULL };
144 if (netconfig_emulator_is_emulated() == TRUE)
147 #if defined EMBEDDED_TARGET
148 rv = netconfig_execute_file(path, args, env);
150 DBG("Failed to remove wireless device driver");
155 DBG("Successfully removed wireless device driver");
159 static int __netconfig_wifi_try_to_load_driver(void);
160 static gboolean __netconfig_wifi_try_to_remove_driver(void);
162 void netconfig_wifi_notify_power_completed(gboolean power_on)
165 DBusConnection *connection;
170 sig_name = "PowerOnCompleted";
172 sig_name = "PowerOffCompleted";
174 dbus_error_init(&error);
176 connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
177 if (connection == NULL) {
178 ERR("Error!!! Failed to get system DBus, error [%s]", error.message);
179 dbus_error_free(&error);
183 signal = dbus_message_new_signal(NETCONFIG_WIFI_PATH,
184 NETCONFIG_WIFI_INTERFACE, sig_name);
188 dbus_connection_send(connection, signal, NULL);
190 dbus_message_unref(signal);
191 dbus_connection_unref(connection);
193 INFO("(%s)", sig_name);
196 static void __netconfig_wifi_direct_state_cb(int error_code,
197 wifi_direct_device_state_e device_state, void *user_data)
199 wifi_direct_unset_device_state_changed_cb();
200 wifi_direct_deinitialize();
202 if (device_state == WIFI_DIRECT_DEVICE_STATE_DEACTIVATED) {
203 if (__netconfig_wifi_try_to_load_driver() < 0) {
204 power_in_progress = FALSE;
206 /* TODO: error report */
213 static gboolean __netconfig_wifi_direct_power_off(void)
215 DBG("Wi-Fi direct is turning off");
217 if (wifi_direct_initialize() < 0)
220 if (wifi_direct_set_device_state_changed_cb(
221 __netconfig_wifi_direct_state_cb, NULL) < 0)
224 if (wifi_direct_deactivate() < 0)
230 static int __netconfig_wifi_try_to_load_driver(void)
232 if (netconfig_is_wifi_allowed() != TRUE)
235 if (netconfig_is_wifi_tethering_on() == TRUE) {
236 /* TODO: Wi-Fi tethering turns off here */
241 if (netconfig_is_wifi_direct_on() == TRUE) {
242 if (__netconfig_wifi_direct_power_off() == TRUE) {
243 power_in_progress = TRUE;
249 if (__netconfig_wifi_load_driver() != TRUE) {
250 netconfig_wifi_remove_driver();
255 if (__netconfig_wifi_enable_technology() != TRUE) {
256 netconfig_wifi_remove_driver();
260 power_in_progress = TRUE;
265 static gboolean __netconfig_wifi_try_to_remove_driver(void)
267 netconfig_wifi_device_picker_service_stop();
269 netconfig_wifi_statistics_update_powered_off();
271 if (__netconfig_wifi_disable_technology() != TRUE)
274 power_in_progress = TRUE;
279 static void __netconfig_wifi_airplane_mode(keynode_t* node,
284 static gboolean powered_off_by_flightmode = FALSE;
286 if (power_in_progress) {
293 vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &value);
294 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
296 DBG("flight mode %s", value > 0 ? "ON" : "OFF");
297 DBG("Wi-Fi state %d, Wi-Fi was off by flight mode %s",
298 wifi_state, powered_off_by_flightmode == TRUE ? "Yes" : "No");
301 /* flight mode enabled */
302 if (wifi_state == VCONFKEY_WIFI_OFF)
305 DBG("Turning Wi-Fi off");
307 __netconfig_wifi_try_to_remove_driver();
309 powered_off_by_flightmode = TRUE;
310 } else if (value == 0) {
311 /* flight mode disabled */
312 if (wifi_state > VCONFKEY_WIFI_OFF)
315 if (powered_off_by_flightmode != TRUE)
318 __netconfig_wifi_try_to_load_driver();
320 powered_off_by_flightmode = FALSE;
322 DBG("Invalid value (%d)", value);
325 static void __netconfig_wifi_pm_state_mode(keynode_t* node,
330 static int prev_state = VCONFKEY_PM_STATE_NORMAL;
332 /*** vconf-keys.h ***
333 * VCONFKEY_PM_STATE_NORMAL = 1,
334 * VCONFKEY_PM_STATE_LCDDIM,
335 * VCONFKEY_PM_STATE_LCDOFF,
336 * VCONFKEY_PM_STATE_SLEEP
339 if(vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) == 0) {
340 DBG("wifi state : %d (0 off / 1 on / 2 connected)", wifi_state);
341 if(wifi_state <= VCONFKEY_WIFI_OFF)
345 if(vconf_get_int(VCONFKEY_PM_STATE, &value) < 0) {
346 ERR("VCONFKEY_PM_STATE get failed");
350 DBG("Old state: %d, current: %d", prev_state, value);
352 if((value == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) {
353 DBG("PM state : Wake UP!");
355 netconfig_wifi_bgscan_stop();
356 netconfig_wifi_bgscan_start();
362 void netconfig_set_power_in_progress(gboolean in_progress)
364 power_in_progress = in_progress;
367 void netconfig_check_fm_waiting(void)
370 __netconfig_wifi_airplane_mode(NULL, NULL);
373 void netconfig_wifi_power_configuration(void)
375 int wifi_last_power_state = 0;
377 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
378 __netconfig_wifi_airplane_mode, NULL);
380 vconf_notify_key_changed(VCONFKEY_PM_STATE,
381 __netconfig_wifi_pm_state_mode, NULL);
383 vconf_get_int(VCONF_WIFI_LAST_POWER_STATE, &wifi_last_power_state);
385 if (wifi_last_power_state == WIFI_POWER_ON) {
386 DBG("Turn Wi-Fi on automatically");
388 __netconfig_wifi_try_to_load_driver();
392 gboolean netconfig_iface_wifi_load_driver(NetconfigWifi *wifi, GError **error)
394 DBG("Wi-Fi power on requested");
396 g_return_val_if_fail(wifi != NULL, FALSE);
400 if (netconfig_is_wifi_allowed() != TRUE) {
401 netconfig_error_security_restricted(error);
406 if (power_in_progress) {
407 netconfig_error_wifi_driver_failed(error);
411 err = __netconfig_wifi_try_to_load_driver();
413 if (err == -EINPROGRESS)
414 netconfig_error_wifi_load_inprogress(error);
416 netconfig_error_wifi_driver_failed(error);
424 gboolean netconfig_iface_wifi_remove_driver(NetconfigWifi *wifi, GError **error)
426 DBG("Wi-Fi power off requested");
428 g_return_val_if_fail(wifi != NULL, FALSE);
430 if (power_in_progress) {
431 netconfig_error_wifi_driver_failed(error);
435 if (__netconfig_wifi_try_to_remove_driver() != TRUE) {
436 netconfig_error_wifi_driver_failed(error);