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.
22 #include <vconf-keys.h>
26 #include <tzplatform_config.h>
28 #include <sys/ioctl.h>
36 #include "wifi-scan.h"
37 #include "wifi-bssid-scan.h"
38 #include "wifi-power.h"
39 #include "wifi-state.h"
40 #include "netsupplicant.h"
41 #include "network-state.h"
42 #include "network-dpm.h"
43 #include "wifi-firmware.h"
44 #include "wifi-background-scan.h"
46 #define WLAN_SUPPLICANT_SCRIPT "/usr/bin/wpa_supp.sh"
47 #define P2P_SUPPLICANT_SCRIPT "/usr/bin/p2p_supp.sh"
49 #if !defined TIZEN_WEARABLE
50 #define VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT "db/setting/network_with_lcd_off_limit"
53 #define NETCONFIG_SIGNAL_MODULE_STATE_CHANGED "ModuleStateChanged"
54 #define VCONFKEY_WIFI_DEVICE_STATUS_UEVENT "memory/wifi/device/status_uevent"
55 #define VCONFKEY_WIFI_INTERFACE_NAME "memory/wifi/device/ifname"
57 #define WLAN_MAC_ADDR_MAX 20
58 #define ETH_MAC_ADDR_SIZE 6
59 #define NET_EXEC_PATH "/sbin/ifconfig"
60 #define OS_RANDOM_FILE "/dev/urandom"
62 #define NETCONFIG_TECH_WAITING_INTERVAL 500
63 #define NETCONFIG_TECH_WAITING_COUNT 6
64 #define MAX_DRV_CMD_SIZE 248
65 #define WLAN_IOCTL_SUSPEND (SIOCDEVPRIVATE + 1)
71 } netconfig_wifi_priv_cmd;
73 static gboolean wifi_firmware_recovery_mode = FALSE;
74 static int airplane_mode = 0;
75 gboolean is_supplicant_running = FALSE;
77 static gboolean __is_wifi_restricted(void)
79 #if defined TIZEN_WEARABLE
82 int restricted_mode = 0;
84 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted_mode);
85 if (restricted_mode != 0) {
86 DBG("network restricted mode[%d]", restricted_mode);
93 static void __technology_reply(GObject *source_object, GAsyncResult *res, gpointer user_data)
96 GDBusConnection *conn = NULL;
98 char *interface_name = user_data;
100 conn = G_DBUS_CONNECTION(source_object);
101 reply = g_dbus_connection_call_finish(conn, res, &error);
105 if (g_strstr_len(error->message, strlen(error->message),
106 CONNMAN_ERROR_INTERFACE ".AlreadyEnabled") != NULL) {
107 DBG(".AlreadyEnabled");
108 wifi_state_update_power_state(interface_name, TRUE);
109 } else if (g_strstr_len(error->message, strlen(error->message),
110 CONNMAN_ERROR_INTERFACE ".AlreadyDisabled") != NULL) {
111 DBG(".AlreadyDisabled");
112 wifi_state_update_power_state(interface_name, FALSE);
114 ERR("Fail to request status [%d: %s]", error->code, error->message);
115 wifi_state_update_power_state(interface_name, FALSE);
119 ERR("Fail to request status");
120 wifi_state_update_power_state(interface_name, FALSE);
123 DBG("Successfully requested");
124 g_variant_unref(reply);
127 netconfig_gdbus_pending_call_unref();
128 g_free(interface_name);
131 void __mark_supplicant_stopped(void)
133 is_supplicant_running = FALSE;
136 int __execute_supplicant(gboolean enable)
139 * TODO: [EAP on Ethernet] Temporary blocked wpa_supp.sh stop
140 * untill ConnMan adds logic to trigger/control wpa_supplicant interface.
143 const char *path = WLAN_SUPPLICANT_SCRIPT;
144 char *const args_enable[] = { "/usr/bin/wpa_supp.sh", "start", NULL };
146 char *const args_disable[] = { "/usr/bin/wpa_supp.sh", "stop", NULL };
148 char *const envs[] = { NULL };
150 if (is_supplicant_running == enable)
154 rv = netconfig_execute_file(path, args_enable, envs);
157 rv = netconfig_execute_file(path, args_disable, envs);
162 DBG("wpa_supplicant %s", enable == TRUE ? "started" : "stopped");
165 is_supplicant_running = enable;
170 static int _load_driver_and_supplicant(const char *interface_name)
173 wifi_tech_state_e tech_state;
175 tech_state = wifi_state_get_technology_state(interface_name);
176 if (tech_state > NETCONFIG_WIFI_TECH_OFF)
179 err = __execute_supplicant(TRUE);
180 if (err < 0 && err != -EALREADY)
183 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, interface_name, TRUE);
184 if (err < 0 && err != -EALREADY) {
185 __execute_supplicant(FALSE);
189 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_WPS_ONLY);
194 static int _remove_driver_and_supplicant(const char *interface_name)
198 DBG("remove driver and supplicant");
199 if (wifi_firmware_recovery_mode != TRUE &&
200 netconfig_wifi_bssidscan_get_mode(interface_name) == TRUE) {
201 DBG("Wi-Fi WPS mode");
205 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, interface_name, FALSE);
206 if (err < 0 && err != -EALREADY)
209 err = __execute_supplicant(FALSE);
210 if (err < 0 && err != -EALREADY)
213 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_OFF);
215 // reset service state
216 wifi_state_set_service_state(interface_name, NULL, NETCONFIG_WIFI_IDLE);
218 if (wifi_firmware_recovery_mode == TRUE) {
219 if (wifi_power_on(interface_name) < 0)
220 ERR("Failed to recover Wi-Fi firmware");
222 wifi_firmware_recovery_mode = FALSE;
228 static gboolean __check_and_set_technology_enable(gpointer data)
230 static int retry_count = NETCONFIG_TECH_WAITING_COUNT;
231 wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
232 gboolean value_enable = TRUE;
233 gboolean reply = FALSE;
234 GVariant *params = NULL;
235 char *interface_name = data;
237 tech_state = wifi_state_get_technology_state(interface_name);
238 if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN) {
244 params = g_variant_new("(sb)", interface_name, value_enable);
246 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
247 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
248 CONNMAN_TECHNOLOGY_INTERFACE,
249 "SetDevicePower", params,
251 g_strdup(interface_name));
254 ERR("Fail to set technology enable");
255 wifi_state_update_power_state(interface_name, FALSE);
257 retry_count = NETCONFIG_TECH_WAITING_COUNT;
258 g_free(interface_name);
262 retry_count = NETCONFIG_TECH_WAITING_COUNT;
263 g_free(interface_name);
267 static int _set_connman_technology_power(const char *interface_name, gboolean enable)
269 gboolean reply = FALSE;
270 GVariant *params = NULL;
271 gboolean value_enable = TRUE;
272 gboolean value_disable = FALSE;
273 gboolean powered = FALSE;
274 wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
276 DBG("Set %s technology [%s]", interface_name, enable == TRUE ? "enable" : "disable");
278 powered = wifi_state_get_powered(interface_name);
279 if (powered == enable) {
280 DBG("Already %s", enable ? "enabled" : "disabled");
284 if (enable == TRUE) {
285 tech_state = wifi_state_get_technology_state(interface_name);
286 if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN) {
287 netconfig_start_timer(NETCONFIG_TECH_WAITING_INTERVAL,
288 __check_and_set_technology_enable, g_strdup(interface_name), NULL);
289 wifi_state_set_powered(interface_name, enable);
294 params = g_variant_new("(sb)", interface_name, (enable == TRUE) ? value_enable : value_disable);
296 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
297 CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
298 "SetDevicePower", params, __technology_reply, g_strdup(interface_name));
301 ERR("Fail to set technology %s", enable == TRUE ? "enable" : "disable");
305 /* To be keep safe, early disable Wi-Fi tech state */
307 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_WPS_ONLY);
312 #if !defined TIZEN_WEARABLE
313 static void __netconfig_wifi_restrict_mode(keynode_t *node, void *user_data)
315 int wifi_state = 0, restricted = 0;
318 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
321 restricted = vconf_keynode_get_bool(node);
323 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted);
325 DBG("network restricted mode %s", restricted > 0 ? "ON" : "OFF");
326 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
328 if (restricted > 0) {
329 /* network restricted on */
330 GSList *device_list = NULL;
332 if (wifi_state == VCONFKEY_WIFI_OFF)
335 device_list = wifi_state_get_device_list();
336 for (list = device_list; list; list = list->next) {
337 wifi_device_data_s *device_data = list->data;
338 wifi_power_off(device_data->interface_name);
339 netconfig_setting_update_interface_off_for_restricted(device_data->interface_name, TRUE);
342 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 1, TRUE);
344 /* network restricted off */
345 GSList *ifname_list = NULL;
347 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 0, TRUE);
349 ifname_list = netconfig_setting_get_interfaces_off_by_restricted();
350 for (list = ifname_list; list; list = list->next) {
351 char *interface_name = list->data;
353 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
356 netconfig_setting_update_interface_off_for_restricted(interface_name, FALSE);
357 wifi_power_on(interface_name);
363 static void __netconfig_emit_wifi_module_state_signal(int wifi_module_state)
365 GVariant *sig_params;
366 char *interface_name = NULL;
368 interface_name = vconf_get_str(VCONFKEY_WIFI_INTERFACE_NAME);
370 DBG("wifi module state [%d]", wifi_module_state);
372 GVariantBuilder *module_state_info = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
373 g_variant_builder_add(module_state_info, "{sv}", "ifname", g_variant_new_string(interface_name));
374 g_variant_builder_add(module_state_info, "{sv}", "status_uevent", g_variant_new_uint32(wifi_module_state));
375 sig_params = g_variant_new("(@a{sv})", g_variant_builder_end(module_state_info));
376 g_variant_builder_unref(module_state_info);
377 netconfig_dbus_emit_signal(NULL, NETCONFIG_WIFI_PATH,
378 NETCONFIG_WIFI_INTERFACE, NETCONFIG_SIGNAL_MODULE_STATE_CHANGED, sig_params);
380 g_free(interface_name);
383 static void __netconfig_wifi_module_state_changed_cb(keynode_t *node, void *data)
385 int wifi_module_state = 0;
388 wifi_module_state = vconf_keynode_get_int(node);
390 netconfig_vconf_get_int(VCONFKEY_WIFI_DEVICE_STATUS_UEVENT, &wifi_module_state);
392 __netconfig_emit_wifi_module_state_signal(wifi_module_state);
395 static void __netconfig_wifi_airplane_mode(keynode_t *node, void *user_data)
397 int wifi_state = 0, airplane_state = 0;
400 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
403 airplane_state = vconf_keynode_get_bool(node);
405 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_state);
407 DBG("airplane mode %s (prev:%d)", airplane_state > 0 ? "ON" : "OFF", airplane_mode);
408 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
410 if (airplane_mode == airplane_state)
413 airplane_mode = airplane_state;
415 if (airplane_state > 0) {
416 /* airplane mode on */
417 GSList *device_list = NULL;
419 if (wifi_state == VCONFKEY_WIFI_OFF)
422 device_list = wifi_state_get_device_list();
423 for (list = device_list; list; list = list->next) {
424 wifi_device_data_s *device_data = list->data;
425 if (device_data->tech_state > NETCONFIG_WIFI_TECH_OFF) {
426 wifi_power_off(device_data->interface_name);
427 netconfig_setting_update_interface_off_for_airplane(device_data->interface_name, TRUE);
431 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 1, TRUE);
433 /* airplane mode off */
434 GSList *ifname_list = NULL;
436 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
438 ifname_list = netconfig_setting_get_interfaces_off_by_airplane();
439 for (list = ifname_list; list; list = list->next) {
440 char *interface_name = list->data;
442 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
445 netconfig_setting_update_interface_off_for_airplane(interface_name, FALSE);
446 wifi_power_on(interface_name);
451 static void __emergency_mode_changed_cb(keynode_t *node, void *user_data)
453 int wifi_state = 0, emergency = 0;
455 #if !defined TIZEN_WEARABLE
456 int emergency_by_fmm = 0;
459 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
461 #if !defined TIZEN_WEARABLE
462 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT, &emergency_by_fmm);
463 DBG("emergency mode by Find My Mobile (%d)", emergency_by_fmm);
464 if (emergency_by_fmm == 1)
469 emergency = vconf_keynode_get_int(node);
471 netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &emergency);
473 DBG("emergency mode %s", emergency > SETTING_PSMODE_POWERFUL ? "ON" : "OFF");
474 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
476 #if defined TIZEN_WEARABLE
477 if (emergency == SETTING_PSMODE_WEARABLE) {
478 /* basic power saving mode on */
479 } else if (emergency == SETTING_PSMODE_WEARABLE_ENHANCED) {
480 /* enhanced power saving mode on */
481 GSList *device_list = NULL;
483 if (wifi_state == VCONFKEY_WIFI_OFF)
486 device_list = wifi_state_get_device_list();
487 for (list = device_list; list; list = list->next) {
488 wifi_device_data_s *device_data = list->data;
489 wifi_power_off(device_data->interface_name);
490 netconfig_setting_update_interface_off_for_emergency(device_data->interface_name, TRUE);
493 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1, TRUE);
495 /* power saving mode off */
496 GSList *ifname_list = NULL;
498 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0, TRUE);
499 ifname_list = netconfig_setting_get_interfaces_off_by_emergency();
500 for (list = ifname_list; list; list = list->next) {
501 char *interface_name = list->data;
503 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
506 netconfig_setting_update_interface_off_for_emergency(interface_name, FALSE);
507 wifi_power_on_wearable(interface_name, TRUE);
511 if (emergency > SETTING_PSMODE_POWERFUL) {
512 /* emergency mode on */
513 GSList *device_list = NULL;
515 if (wifi_state == VCONFKEY_WIFI_OFF)
518 device_list = wifi_state_get_device_list();
519 for (list = device_list; list; list = list->next) {
520 wifi_device_data_s *device_data = list->data;
521 wifi_power_off(device_data->interface_name);
522 netconfig_setting_update_interface_off_for_emergency(device_data->interface_name, TRUE);
525 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1, TRUE);
527 /* emergency mode off */
528 GSList *ifname_list = NULL;
530 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0, TRUE);
532 ifname_list = netconfig_setting_get_interfaces_off_by_emergency();
533 for (list = ifname_list; list; list = list->next) {
534 char *interface_name = list->data;
536 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
539 netconfig_setting_update_interface_off_for_emergency(interface_name, FALSE);
540 wifi_power_on(interface_name);
547 void wifi_set_early_suspend(const char *interface_name, gboolean value)
549 static gboolean old_state = FALSE;
551 char buf[MAX_DRV_CMD_SIZE];
552 netconfig_wifi_priv_cmd priv_cmd;
556 wifi_service_state_e wifi_state;
557 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
559 if (old_state == value) {
560 DBG("Old and new states are same");
564 if (netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
565 ERR("Fail to get VCONFKEY_PM_STATE");
567 wifi_state = wifi_state_get_service_state(interface_name);
570 (pm_state < VCONFKEY_PM_STATE_LCDOFF ||
571 wifi_state == NETCONFIG_WIFI_ASSOCIATION ||
572 wifi_state == NETCONFIG_WIFI_CONFIGURATION)){
577 memset(buf, 0, sizeof(buf));
578 snprintf(buf, sizeof(buf), "SETSUSPENDMODE %d", value);
580 memset(&ifr, 0, sizeof(struct ifreq));
581 g_strlcpy((char *)ifr.ifr_name, interface_name, IFNAMSIZ);
583 DBG("Early suspend command: [%s]", buf);
585 memset(&priv_cmd, 0, sizeof(priv_cmd));
587 priv_cmd.used_len = sizeof(buf);
588 priv_cmd.total_len = sizeof(buf);
589 ifr.ifr_data = (char *)&priv_cmd;
591 ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
592 if (ioctl_sock < 0) {
593 DBG("socket(PF_INET,SOCK_DGRAM) failed: %s",
594 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
598 ret = ioctl(ioctl_sock, WLAN_IOCTL_SUSPEND, &ifr);
600 ERR("Fail to issue private commands: %d. %s", ret,
601 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
609 static void __pm_state_changed_cb(keynode_t* node, void* user_data)
613 static int prev_state = VCONFKEY_PM_STATE_NORMAL;
614 GSList *list = NULL, *device_list = NULL;
616 if (netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) < 0) {
617 ERR("Fail to get VCONFKEY_WIFI_STATE");
622 * VCONFKEY_PM_STATE_NORMAL = 1,
623 * VCONFKEY_PM_STATE_LCDDIM,
624 * VCONFKEY_PM_STATE_LCDOFF,
625 * VCONFKEY_PM_STATE_SLEEP
628 new_state = vconf_keynode_get_int(node);
630 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &new_state);
632 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
633 DBG("Old PM state: %d, current: %d (1 normal / 2 lcddim / 3 lcdoff / 4 sleep)", prev_state, new_state);
635 if ((new_state == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) {
636 /* Send early suspend mode based on LCD state and disallow early suspend count */
637 device_list = wifi_state_get_device_list();
638 for (list = device_list; list; list = list->next) {
639 wifi_device_data_s *device_data = list->data;
640 if (device_data->powered == TRUE) {
641 wifi_set_early_suspend(device_data->interface_name, FALSE);
642 DBG("Unset early suspend [%s]", device_data->interface_name);
644 netconfig_wifi_bgscan_stop(device_data->interface_name);
645 netconfig_wifi_bgscan_set_exp_interval(device_data->interface_name, SCAN_EXPONENTIAL_MIN);
646 netconfig_wifi_bgscan_start(device_data->interface_name, TRUE);
648 } else if ((new_state == VCONFKEY_PM_STATE_LCDOFF) && (prev_state < VCONFKEY_PM_STATE_LCDOFF) && (wifi_state != VCONFKEY_WIFI_OFF)) {
649 device_list = wifi_state_get_device_list();
650 for (list = device_list; list; list = list->next) {
651 wifi_device_data_s *device_data = list->data;
652 wifi_set_early_suspend(device_data->interface_name, TRUE);
653 DBG("Set early suspend [%s]", device_data->interface_name);
657 prev_state = new_state;
660 static void __netconfig_telephony_ready_changed_cb(keynode_t *node, void *data)
662 int telephony_ready = 0;
663 char *interface_name = data;
666 telephony_ready = vconf_keynode_get_bool(node);
668 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
670 if (telephony_ready != 0) {
671 if (netconfig_tapi_check_sim_state() == FALSE) {
672 DBG("Sim is not initialized yet.");
679 DBG("Turn Wi-Fi on automatically");
681 #if defined TIZEN_WEARABLE
682 wifi_power_on_wearable(interface_name, TRUE);
684 wifi_power_on(interface_name);
688 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __netconfig_telephony_ready_changed_cb);
689 g_free(interface_name);
692 int wifi_power_driver_and_supplicant(const char *interface_name, gboolean enable)
694 /* There are 3 thumb rules for Wi-Fi power management
695 * 1. Do not make exposed API to control wpa_supplicant and driver directly.
696 * It probably breaks ConnMan technology operation.
698 * 2. Do not remove driver and wpa_supplicant if ConnMan already enabled.
699 * It breaks ConnMan technology operation.
701 * 3. Final the best rule: make it as simple as possible.
702 * Simple code enables easy maintenance and reduces logical errors.
705 if (enable == TRUE) {
706 return _load_driver_and_supplicant(interface_name);
708 if (wifi_state_get_powered(interface_name) == TRUE)
711 return _remove_driver_and_supplicant(interface_name);
715 void wifi_power_recover_firmware(const char *interface_name)
717 wifi_firmware_recovery_mode = TRUE;
719 netconfig_wifi_bgscan_stop(interface_name);
721 wifi_power_off(interface_name);
724 int wifi_power_on(const char *interface_name)
727 wifi_tech_state_e tech_state;
729 tech_state = wifi_state_get_technology_state(interface_name);
730 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
731 INFO("Net-Config WiFi connman technology state %d", tech_state);
735 if (__is_wifi_restricted() == TRUE)
738 if (netconfig_is_wifi_tethering_on() == TRUE) {
739 /* TODO: Wi-Fi tethering turns off here */
741 ERR("Failed to turn tethering off");
745 err = wifi_power_driver_and_supplicant(interface_name, TRUE);
746 if (err < 0 && err != -EALREADY)
749 err = _set_connman_technology_power(interface_name, TRUE);
750 if (err < 0 && err != -EALREADY)
751 wifi_power_driver_and_supplicant(interface_name, FALSE);
756 int wifi_power_off(const char *interface_name)
760 err = _set_connman_technology_power(interface_name, FALSE);
761 if (err == -EALREADY)
762 wifi_state_update_power_state(interface_name, FALSE);
767 #if defined TIZEN_WEARABLE
768 int wifi_power_on_wearable(const char *interface_name, gboolean device_picker_test)
771 wifi_tech_state_e tech_state;
773 tech_state = wifi_state_get_technology_state(interface_name);
774 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED)
777 err = wifi_power_driver_and_supplicant(interface_name, TRUE);
778 if (err < 0 && err != -EALREADY)
781 err = _set_connman_technology_power(interface_name, TRUE);
782 if (err < 0 && err != -EALREADY) {
783 wifi_power_driver_and_supplicant(interface_name, FALSE);
787 if (device_picker_test == TRUE)
788 netconfig_wifi_enable_device_picker_test();
794 void wifi_power_initialize(void)
796 GSList *interface_list = NULL;
798 /* Initialize Airplane mode */
799 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_mode);
800 DBG("Airplane[%s]", airplane_mode > 0 ? "ON" : "OFF");
802 /* Update the last Wi-Fi power state */
803 interface_list = netconfig_setting_get_interfaces_for_last_powered();
804 for (; interface_list; interface_list = interface_list->next) {
805 const char *interface_name = interface_list->data;
807 if (TIZEN_TELEPHONY_ENABLE) {
808 int telephony_ready = 0;
809 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
810 if (telephony_ready == 0) {
811 DBG("Telephony API is not initialized yet");
812 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY,
813 __netconfig_telephony_ready_changed_cb,
814 g_strdup(interface_name));
816 if (netconfig_tapi_check_sim_state() == FALSE)
817 DBG("SIM is not initialized yet");
820 DBG("Turn Wi-Fi on automatically");
821 #if defined TIZEN_WEARABLE
822 wifi_power_on_wearable(interface_name, TRUE);
824 wifi_power_on(interface_name);
828 #if defined TIZEN_WEARABLE
829 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
830 __netconfig_wifi_airplane_mode, NULL);
832 vconf_notify_key_changed(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE,
833 __netconfig_wifi_restrict_mode, NULL);
834 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
835 __netconfig_wifi_airplane_mode, NULL);
838 vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
839 __emergency_mode_changed_cb, NULL);
840 vconf_notify_key_changed(VCONFKEY_PM_STATE, __pm_state_changed_cb, NULL);
841 vconf_notify_key_changed(VCONFKEY_WIFI_DEVICE_STATUS_UEVENT, __netconfig_wifi_module_state_changed_cb, NULL);
844 void wifi_power_deinitialize(void)
848 gboolean handle_load_driver(Wifi *wifi,
849 GDBusMethodInvocation *context,
850 const gchar *ifname, gboolean device_picker_test)
854 DBG("Wi-Fi power on requested [%s]", ifname);
856 g_return_val_if_fail(wifi != NULL, TRUE);
858 if (!netconfig_dpm_update_from_wifi()) {
859 DBG("DPM policy restricts Wi-Fi");
860 netconfig_error_permission_denied(context);
864 if (TIZEN_WLAN_BOARD_SPRD)
865 wifi_firmware_download();
867 #if defined TIZEN_WEARABLE
868 err = wifi_power_on_wearable(ifname, device_picker_test);
870 err = wifi_power_on(ifname);
872 if (device_picker_test == TRUE)
873 netconfig_wifi_enable_device_picker_test();
876 if (err == -EALREADY)
877 netconfig_error_already_exists(context);
878 else if (err == -EPERM)
879 netconfig_error_permission_denied(context);
881 netconfig_error_wifi_driver_failed(context);
887 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
889 wifi_complete_load_driver(wifi, context);
893 gboolean handle_remove_driver(Wifi *wifi, GDBusMethodInvocation *context,
898 DBG("Wi-Fi power off requested [%s]", ifname);
900 g_return_val_if_fail(wifi != NULL, TRUE);
902 err = wifi_power_off(ifname);
904 if (err == -EALREADY)
905 netconfig_error_already_exists(context);
906 else if (err == -EPERM)
907 netconfig_error_permission_denied(context);
909 netconfig_error_wifi_driver_failed(context);
913 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
915 wifi_complete_remove_driver(wifi, context);
919 gboolean handle_load_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
923 wifi_complete_load_p2p_driver(wifi, context);
927 gboolean handle_remove_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
931 wifi_complete_remove_p2p_driver(wifi, context);
935 static int __netconfig_get_random_mac(unsigned char *mac_buf, int mac_len)
937 DBG("Generate Random Mac address of ethernet");
941 fp = fopen(OS_RANDOM_FILE, "rb");
944 ERR("Could not open /dev/urandom");
947 rc = fread(mac_buf, 1, mac_len, fp);
951 return rc != mac_len ? -1 : 0;
954 void __netconfig_set_ether_macaddr()
956 DBG("Set wired Mac address ");
957 char *mac_addr = NULL;
958 char rand_addr[WLAN_MAC_ADDR_MAX];
961 mac_addr = vconf_get_str(VCONF_ETH_MAC_ADDRESS);
962 if (mac_addr == NULL) {
963 DBG("vconf_get_str Failed\n");
966 /* Checking Invalid MAC Address */
967 if ((strlen(mac_addr) == 0)) {
968 ERR("Failed to get valid MAC Address from vconf");
969 /*Generate the Random Mac address*/
970 unsigned char rand_mac_add[ETH_MAC_ADDR_SIZE+1];
972 if (__netconfig_get_random_mac(rand_mac_add, ETH_MAC_ADDR_SIZE) == -1) {
974 ERR("Could not generate the Random Mac address");
979 rand_mac_add[0] &= 0xFE; /*Clear multicase bit*/
980 rand_mac_add[0] |= 0x02; /*set local assignment bit*/
982 /*Set the Mac address in Vconf*/
983 snprintf(rand_addr, WLAN_MAC_ADDR_MAX, "%x:%x:%x:%x:%x:%x",
984 rand_mac_add[0], rand_mac_add[1],
985 rand_mac_add[2], rand_mac_add[3],
986 rand_mac_add[4], rand_mac_add[5]);
988 netconfig_set_vconf_str(VCONF_ETH_MAC_ADDRESS, rand_addr, TRUE);
989 } else { /* Valid MAC address */
990 g_strlcpy(rand_addr, mac_addr, WLAN_MAC_ADDR_MAX);
993 DBG("MAC Address of eth0 [%s]", rand_addr);
994 const char *path = NET_EXEC_PATH;
995 char *const args[] = { "/sbin/ifconfig", "eth0", "hw",
996 "ether", rand_addr, "up", NULL};
997 char *const envs[] = { NULL };
998 rv = netconfig_execute_file(path, args, envs);
1001 ERR("Unable to execute system command");