2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 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>
31 #include "netconfig.h"
33 #include "network-statistics.h"
34 #include "wifi-state.h"
35 #include "wifi-ssid-scan.h"
36 #include "wifi-background-scan.h"
37 #include "mdm-private.h"
39 gboolean netconfig_iface_wifi_load_driver(NetconfigWifi *wifi, GError **error);
40 gboolean netconfig_iface_wifi_remove_driver(NetconfigWifi *wifi, GError **error);
42 #include "netconfig-iface-wifi-glue.h"
44 #define WLAN_DRIVER_SCRIPT "/usr/bin/wlan.sh"
46 #define PROP_DEFAULT FALSE
47 #define PROP_DEFAULT_STR NULL
60 struct NetconfigWifiClass {
63 /* method and signals */
64 void (*driver_loaded) (NetconfigWifi *wifi, gchar *mac);
67 struct NetconfigWifi {
71 DBusGConnection *conn;
75 static guint32 signals[SIG_LAST] = { 0, };
77 G_DEFINE_TYPE(NetconfigWifi, netconfig_wifi, G_TYPE_OBJECT);
80 static void __netconfig_wifi_gobject_get_property(GObject *object, guint prop_id,
81 GValue *value, GParamSpec *pspec)
86 static void __netconfig_wifi_gobject_set_property(GObject *object, guint prop_id,
87 const GValue *value, GParamSpec *pspec)
89 NetconfigWifi *wifi = NETCONFIG_WIFI(object);
94 wifi->conn = g_value_get_boxed(value);
95 INFO("wifi(%p) set conn(%p)", wifi, wifi->conn);
104 wifi->path = g_value_dup_string(value);
105 INFO("wifi(%p) path(%s)", wifi, wifi->path);
111 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
115 static void netconfig_wifi_init(NetconfigWifi *wifi)
117 DBG("wifi initialize");
120 wifi->path = g_strdup(PROP_DEFAULT_STR);
123 static void netconfig_wifi_class_init(NetconfigWifiClass *klass)
125 GObjectClass *object_class = G_OBJECT_CLASS(klass);
127 DBG("class initialize");
129 object_class->get_property = __netconfig_wifi_gobject_get_property;
130 object_class->set_property = __netconfig_wifi_gobject_set_property;
133 dbus_g_object_type_install_info(NETCONFIG_TYPE_WIFI,
134 &dbus_glib_netconfig_iface_wifi_object_info);
137 g_object_class_install_property(object_class, PROP_WIFI_CONN,
138 g_param_spec_boxed("conn", "CONNECTION", "DBus connection",
139 DBUS_TYPE_G_CONNECTION,
140 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
142 g_object_class_install_property(object_class, PROP_WIFI_PATH,
143 g_param_spec_string("path", "PATH", "Object Path",
145 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
148 signals[SIG_WIFI_DRIVER] = g_signal_new("driver-loaded",
149 G_OBJECT_CLASS_TYPE(klass),
151 G_STRUCT_OFFSET(NetconfigWifiClass,
154 g_cclosure_marshal_VOID__STRING,
155 G_TYPE_NONE, 1, G_TYPE_STRING);
159 static gboolean __netconfig_wifi_enable_technology(void)
161 DBusMessage *reply = NULL;
162 char path[DBUS_PATH_MAX_BUFLEN] = "/";
163 char param1[] = "string:wifi";
164 char *param_array[] = {NULL, NULL};
166 param_array[0] = param1;
168 reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, path,
169 CONNMAN_MANAGER_INTERFACE, "EnableTechnology", param_array);
172 ERR("Error! Request failed");
176 dbus_message_unref(reply);
181 static gboolean __netconfig_wifi_disable_technology(void)
183 DBusMessage *reply = NULL;
184 char path[DBUS_PATH_MAX_BUFLEN] = "/";
185 char param1[] = "string:wifi";
186 char *param_array[] = {NULL, NULL};
188 param_array[0] = param1;
190 reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, path,
191 CONNMAN_MANAGER_INTERFACE, "DisableTechnology", param_array);
194 ERR("Error! Request failed");
198 dbus_message_unref(reply);
203 static gboolean __netconfig_wifi_load_driver(void)
206 const char *path = WLAN_DRIVER_SCRIPT;
207 char *const args[] = { "wlan.sh", "start" };
208 char *const envs[] = { NULL };
210 if (netconfig_emulator_is_emulated() == TRUE)
213 rv = netconfig_execute_file(path, args, envs);
215 DBG("Failed to load wireless device driver");
219 DBG("Successfully loaded wireless device drivers");
223 static gboolean __netconfig_wifi_remove_driver(void)
226 const char *path = WLAN_DRIVER_SCRIPT;
227 char *const args[] = { "wlan.sh", "stop" };
228 char *const env[] = { NULL };
230 if (netconfig_emulator_is_emulated() == TRUE)
233 rv = netconfig_execute_file(path, args, env);
235 DBG("Failed to remove(unload) driver for wireless device");
239 DBG("Successfully removed(unloaded) wireless driver");
243 static gboolean __netconfig_wifi_try_to_load_driver(void);
244 static gboolean __netconfig_wifi_try_to_remove_driver(void);
246 static void __netconfig_wifi_direct_state_cb(int error_code,
247 wifi_direct_device_state_e device_state, void *user_data)
249 wifi_direct_unset_device_state_changed_cb();
250 wifi_direct_deinitialize();
252 if (device_state == WIFI_DIRECT_DEVICE_STATE_DEACTIVATED) {
253 __netconfig_wifi_try_to_load_driver();
258 /* TODO: error report */
261 static gboolean __netconfig_wifi_direct_power_off(void)
263 DBG("Wi-Fi direct is turning off");
265 if (wifi_direct_initialize() < 0)
268 if (wifi_direct_set_device_state_changed_cb(
269 __netconfig_wifi_direct_state_cb, NULL) < 0)
272 if (wifi_direct_deactivate() < 0)
278 static gboolean __netconfig_wifi_try_to_load_driver(void)
281 gchar *wifi_tech_state = NULL;
283 if (netconfig_is_wifi_allowed() != TRUE)
286 if (netconfig_is_wifi_tethering_on() == TRUE) {
287 /* TODO: Wi-Fi tethering turns off here */
292 if (netconfig_is_wifi_direct_on() == TRUE) {
293 if (__netconfig_wifi_direct_power_off() == TRUE)
299 if (__netconfig_wifi_load_driver() != TRUE) {
300 __netconfig_wifi_remove_driver();
305 for (count = 0; count < 3; count++) {
306 __netconfig_wifi_enable_technology();
308 wifi_tech_state = netconfig_wifi_get_technology_state();
310 if (wifi_tech_state == NULL) {
311 DBG("Failed to get Wi-Fi technology state");
315 if (g_str_equal(wifi_tech_state, "EnabledTechnologies") == TRUE) {
316 netconfig_wifi_update_power_state(TRUE);
318 netconfig_wifi_device_picker_service_start();
320 g_free(wifi_tech_state);
321 wifi_tech_state = NULL;
326 g_free(wifi_tech_state);
327 wifi_tech_state = NULL;
330 __netconfig_wifi_try_to_remove_driver();
335 static gboolean __netconfig_wifi_try_to_remove_driver(void)
338 gchar *wifi_tech_state = NULL;
340 netconfig_wifi_device_picker_service_stop();
342 netconfig_wifi_statistics_update_powered_off();
344 for (count = 0; count < 3; count++) {
345 __netconfig_wifi_disable_technology();
347 wifi_tech_state = netconfig_wifi_get_technology_state();
349 if (wifi_tech_state == NULL) {
350 DBG("Failed to get Wi-Fi technology state");
354 if (g_str_equal(wifi_tech_state, "EnabledTechnologies") != TRUE) {
355 g_free(wifi_tech_state);
356 wifi_tech_state = NULL;
361 g_free(wifi_tech_state);
362 wifi_tech_state = NULL;
365 if (__netconfig_wifi_remove_driver() == TRUE) {
366 netconfig_wifi_update_power_state(FALSE);
373 static void __netconfig_wifi_airplane_mode(keynode_t* node,
378 static gboolean powered_off_by_flightmode = FALSE;
380 vconf_get_bool(VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL, &value);
381 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
383 DBG("flight mode %s", value > 0 ? "ON" : "OFF");
384 DBG("Wi-Fi state %d, Wi-Fi was off by flight mode %s",
385 wifi_state, powered_off_by_flightmode == TRUE ? "Yes" : "No");
388 /* flight mode enabled */
389 if (wifi_state == VCONFKEY_WIFI_OFF)
392 DBG("Turning Wi-Fi off");
394 __netconfig_wifi_try_to_remove_driver();
396 powered_off_by_flightmode = TRUE;
397 } else if (value == 0) {
398 /* flight mode disabled */
399 if (wifi_state > VCONFKEY_WIFI_OFF)
402 if (powered_off_by_flightmode != TRUE)
405 __netconfig_wifi_try_to_load_driver();
407 powered_off_by_flightmode = FALSE;
409 DBG("Invalid value (%d)", value);
412 static void __netconfig_wifi_pm_state_mode(keynode_t* node,
417 static int prev_state = VCONFKEY_PM_STATE_NORMAL;
419 /*** vconf-keys.h ***
420 * VCONFKEY_PM_STATE_NORMAL = 1,
421 * VCONFKEY_PM_STATE_LCDDIM,
422 * VCONFKEY_PM_STATE_LCDOFF,
423 * VCONFKEY_PM_STATE_SLEEP
426 if(vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) == 0) {
427 DBG("wifi state : %d (0 off / 1 on / 2 connected)", wifi_state);
428 if(wifi_state <= VCONFKEY_WIFI_OFF)
432 if(vconf_get_int(VCONFKEY_PM_STATE, &value) < 0) {
433 ERR("VCONFKEY_PM_STATE get failed");
437 DBG("Old state: %d, current: %d", prev_state, value);
439 if((value == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) {
440 DBG("PM state : Wake UP!");
442 netconfig_wifi_bgscan_stop();
443 netconfig_wifi_bgscan_start();
449 static void __netconfig_wifi_power_configuration(void)
451 int wifi_last_power_state = 0;
453 vconf_notify_key_changed(VCONFKEY_SETAPPL_FLIGHT_MODE_BOOL,
454 __netconfig_wifi_airplane_mode, NULL);
456 vconf_notify_key_changed(VCONFKEY_PM_STATE,
457 __netconfig_wifi_pm_state_mode, NULL);
459 vconf_get_int(VCONF_WIFI_LAST_POWER_STATE, &wifi_last_power_state);
461 if (wifi_last_power_state == WIFI_POWER_ON) {
462 DBG("Turn Wi-Fi on automatically");
464 __netconfig_wifi_try_to_load_driver();
468 static void __netconfig_wifi_notify_power_completed(gboolean power_on)
471 DBusConnection *connection = NULL;
473 char *sig_name = NULL;
476 sig_name = "PowerOnCompleted";
478 sig_name = "PowerOffCompleted";
480 dbus_error_init(&error);
482 connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
483 if (connection == NULL) {
484 ERR("Error!!! Failed to get system DBus, error [%s]", error.message);
485 dbus_error_free(&error);
489 signal = dbus_message_new_signal(NETCONFIG_WIFI_PATH,
490 NETCONFIG_WIFI_INTERFACE, sig_name);
494 dbus_connection_send(connection, signal, NULL);
496 dbus_message_unref(signal);
497 dbus_connection_unref(connection);
499 INFO("(%s)", sig_name);
502 gpointer netconfig_wifi_create_and_init(DBusGConnection *conn)
506 g_return_val_if_fail(conn != NULL, NULL);
508 object = g_object_new(NETCONFIG_TYPE_WIFI, "conn", conn, "path",
509 NETCONFIG_WIFI_PATH, NULL);
511 INFO("create wifi(%p)", object);
513 dbus_g_connection_register_g_object(conn, NETCONFIG_WIFI_PATH, object);
515 INFO("wifi(%p) register DBus path(%s)", object, NETCONFIG_WIFI_PATH);
517 __netconfig_wifi_power_configuration();
522 gboolean netconfig_iface_wifi_load_driver(NetconfigWifi *wifi, GError **error)
524 DBG("Wi-Fi turned on");
526 g_return_val_if_fail(wifi != NULL, FALSE);
528 if (netconfig_is_wifi_allowed() != TRUE) {
529 netconfig_error_security_restricted(error);
534 if (__netconfig_wifi_try_to_load_driver() != TRUE) {
535 netconfig_error_wifi_driver_failed(error);
540 __netconfig_wifi_notify_power_completed(TRUE);
544 gboolean netconfig_iface_wifi_remove_driver(NetconfigWifi *wifi, GError **error)
546 DBG("Wi-Fi turned off");
548 g_return_val_if_fail(wifi != NULL, FALSE);
550 if (__netconfig_wifi_try_to_remove_driver() != TRUE) {
551 netconfig_error_wifi_driver_failed(error);
556 __netconfig_wifi_notify_power_completed(FALSE);