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 #define VCONF_WIFI_OFF_STATE_BY_AIRPLANE "file/private/wifi/wifi_off_by_airplane"
50 #define VCONF_WIFI_OFF_STATE_BY_RESTRICTED "file/private/wifi/wifi_off_by_restricted"
51 #define VCONF_WIFI_OFF_STATE_BY_EMERGENCY "file/private/wifi/wifi_off_by_emergency"
52 #if !defined TIZEN_WEARABLE
53 #define VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT "db/setting/network_with_lcd_off_limit"
56 #define WLAN_MAC_ADDR_MAX 20
57 #define ETH_MAC_ADDR_SIZE 6
58 #define VCONF_ETH_MAC_ADDRESS "db/dnet/mac_address"
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 wifi_state_update_power_state(interface_name, TRUE);
108 } else if (g_strstr_len(error->message, strlen(error->message),
109 CONNMAN_ERROR_INTERFACE ".AlreadyDisabled") != NULL) {
110 wifi_state_update_power_state(interface_name, FALSE);
112 ERR("Fail to request status [%d: %s]", error->code, error->message);
113 wifi_state_update_power_state(interface_name, FALSE);
117 ERR("Fail to request status");
118 wifi_state_update_power_state(interface_name, FALSE);
121 DBG("Successfully requested");
122 g_variant_unref(reply);
125 netconfig_gdbus_pending_call_unref();
126 g_free(interface_name);
129 void __mark_supplicant_stopped(void)
131 is_supplicant_running = FALSE;
134 int __execute_supplicant(gboolean enable)
137 * TODO: [EAP on Ethernet] Temporary blocked wpa_supp.sh stop
138 * untill ConnMan adds logic to trigger/control wpa_supplicant interface.
141 const char *path = WLAN_SUPPLICANT_SCRIPT;
142 char *const args_enable[] = { "/usr/bin/wpa_supp.sh", "start", NULL };
144 char *const args_disable[] = { "/usr/bin/wpa_supp.sh", "stop", NULL };
146 char *const envs[] = { NULL };
148 if (is_supplicant_running == enable)
152 rv = netconfig_execute_file(path, args_enable, envs);
155 rv = netconfig_execute_file(path, args_disable, envs);
160 DBG("wpa_supplicant %s", enable == TRUE ? "started" : "stopped");
163 is_supplicant_running = enable;
168 static int _load_driver_and_supplicant(const char *interface_name)
171 wifi_tech_state_e tech_state;
173 tech_state = wifi_state_get_technology_state(interface_name);
174 if (tech_state > NETCONFIG_WIFI_TECH_OFF)
177 err = __execute_supplicant(TRUE);
178 if (err < 0 && err != -EALREADY)
181 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, interface_name, TRUE);
182 if (err < 0 && err != -EALREADY) {
183 __execute_supplicant(FALSE);
187 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_WPS_ONLY);
192 static int _remove_driver_and_supplicant(const char *interface_name)
196 DBG("remove driver and supplicant");
197 if (wifi_firmware_recovery_mode != TRUE &&
198 netconfig_wifi_bssidscan_get_mode(interface_name) == TRUE) {
199 DBG("Wi-Fi WPS mode");
203 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, interface_name, FALSE);
204 if (err < 0 && err != -EALREADY)
207 err = __execute_supplicant(FALSE);
208 if (err < 0 && err != -EALREADY)
211 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_OFF);
213 // reset service state
214 wifi_state_set_service_state(interface_name, NULL, NETCONFIG_WIFI_IDLE);
216 if (wifi_firmware_recovery_mode == TRUE) {
217 if (wifi_power_on(interface_name) < 0)
218 ERR("Failed to recover Wi-Fi firmware");
220 wifi_firmware_recovery_mode = FALSE;
226 static gboolean __check_and_set_technology_enable(gpointer data)
228 static int retry_count = NETCONFIG_TECH_WAITING_COUNT;
229 wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
230 gboolean value_enable = TRUE;
231 gboolean reply = FALSE;
232 GVariant *params = NULL;
233 char *interface_name = data;
235 tech_state = wifi_state_get_technology_state(interface_name);
236 if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN) {
242 params = g_variant_new("(sb)", interface_name, value_enable);
244 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
245 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
246 CONNMAN_TECHNOLOGY_INTERFACE,
247 "SetDevicePower", params,
249 g_strdup(interface_name));
252 ERR("Fail to set technology enable");
253 wifi_state_update_power_state(interface_name, FALSE);
255 retry_count = NETCONFIG_TECH_WAITING_COUNT;
256 g_free(interface_name);
260 retry_count = NETCONFIG_TECH_WAITING_COUNT;
261 g_free(interface_name);
265 static int _set_connman_technology_power(const char *interface_name, gboolean enable)
267 gboolean reply = FALSE;
268 GVariant *params = NULL;
269 gboolean value_enable = TRUE;
270 gboolean value_disable = FALSE;
271 gboolean powered = FALSE;
272 wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
274 DBG("Set %s technology [%s]", interface_name, enable == TRUE ? "enable" : "disable");
276 powered = wifi_state_get_powered(interface_name);
277 if (powered == enable) {
278 DBG("Already %s", enable ? "enabled" : "disabled");
282 if (enable == TRUE) {
283 tech_state = wifi_state_get_technology_state(interface_name);
284 if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN) {
285 netconfig_start_timer(NETCONFIG_TECH_WAITING_INTERVAL,
286 __check_and_set_technology_enable, g_strdup(interface_name), NULL);
287 wifi_state_set_powered(interface_name, enable);
292 params = g_variant_new("(sb)", interface_name, (enable == TRUE) ? value_enable : value_disable);
294 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
295 CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
296 "SetDevicePower", params, __technology_reply, g_strdup(interface_name));
299 ERR("Fail to set technology %s", enable == TRUE ? "enable" : "disable");
303 /* To be keep safe, early disable Wi-Fi tech state */
305 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_WPS_ONLY);
310 #if !defined TIZEN_WEARABLE
311 static void __netconfig_wifi_restrict_mode(keynode_t *node, void *user_data)
313 int wifi_state = 0, restricted = 0;
316 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
319 restricted = vconf_keynode_get_bool(node);
321 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted);
323 DBG("network restricted mode %s", restricted > 0 ? "ON" : "OFF");
324 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
326 if (restricted > 0) {
327 /* network restricted on */
328 GSList *device_list = NULL;
330 if (wifi_state == VCONFKEY_WIFI_OFF)
333 device_list = wifi_state_get_device_list();
334 for (list = device_list; list; list = list->next) {
335 wifi_device_data_s *device_data = list->data;
336 wifi_power_off(device_data->interface_name);
337 netconfig_setting_update_interface_off_for_restricted(device_data->interface_name, TRUE);
340 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 1, TRUE);
342 /* network restricted off */
343 GSList *ifname_list = NULL;
345 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 0, TRUE);
347 ifname_list = netconfig_setting_get_interfaces_off_by_restricted();
348 for (list = ifname_list; list; list = list->next) {
349 char *interface_name = list->data;
351 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
354 netconfig_setting_update_interface_off_for_restricted(interface_name, FALSE);
355 wifi_power_on(interface_name);
361 static void __netconfig_wifi_airplane_mode(keynode_t *node, void *user_data)
363 int wifi_state = 0, airplane_state = 0;
366 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
369 airplane_state = vconf_keynode_get_bool(node);
371 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_state);
373 DBG("airplane mode %s (prev:%d)", airplane_state > 0 ? "ON" : "OFF", airplane_mode);
374 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
376 if (airplane_mode == airplane_state)
379 airplane_mode = airplane_state;
381 if (airplane_state > 0) {
382 /* airplane mode on */
383 GSList *device_list = NULL;
385 if (wifi_state == VCONFKEY_WIFI_OFF)
388 device_list = wifi_state_get_device_list();
389 for (list = device_list; list; list = list->next) {
390 wifi_device_data_s *device_data = list->data;
391 if (device_data->tech_state > NETCONFIG_WIFI_TECH_OFF) {
392 wifi_power_off(device_data->interface_name);
393 netconfig_setting_update_interface_off_for_airplane(device_data->interface_name, TRUE);
397 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 1, TRUE);
399 /* airplane mode off */
400 GSList *ifname_list = NULL;
402 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
404 ifname_list = netconfig_setting_get_interfaces_off_by_airplane();
405 for (list = ifname_list; list; list = list->next) {
406 char *interface_name = list->data;
408 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
411 netconfig_setting_update_interface_off_for_airplane(interface_name, FALSE);
412 wifi_power_on(interface_name);
417 static void __emergency_mode_changed_cb(keynode_t *node, void *user_data)
419 int wifi_state = 0, emergency = 0;
421 #if !defined TIZEN_WEARABLE
422 int emergency_by_fmm = 0;
425 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
427 #if !defined TIZEN_WEARABLE
428 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT, &emergency_by_fmm);
429 DBG("emergency mode by Find My Mobile (%d)", emergency_by_fmm);
430 if (emergency_by_fmm == 1)
435 emergency = vconf_keynode_get_int(node);
437 netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &emergency);
439 DBG("emergency mode %s", emergency > SETTING_PSMODE_POWERFUL ? "ON" : "OFF");
440 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
442 #if defined TIZEN_WEARABLE
443 if (emergency == SETTING_PSMODE_WEARABLE) {
444 /* basic power saving mode on */
445 } else if (emergency == SETTING_PSMODE_WEARABLE_ENHANCED) {
446 /* enhanced power saving mode on */
447 GSList *device_list = NULL;
449 if (wifi_state == VCONFKEY_WIFI_OFF)
452 device_list = wifi_state_get_device_list();
453 for (list = device_list; list; list = list->next) {
454 wifi_device_data_s *device_data = list->data;
455 wifi_power_off(device_data->interface_name);
456 netconfig_setting_update_interface_off_for_emergency(device_data->interface_name, TRUE);
459 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1, TRUE);
461 /* power saving mode off */
462 GSList *ifname_list = NULL;
464 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0, TRUE);
465 ifname_list = netconfig_setting_get_interfaces_off_by_emergency();
466 for (list = ifname_list; list; list = list->next) {
467 char *interface_name = list->data;
469 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
472 netconfig_setting_update_interface_off_for_emergency(interface_name, FALSE);
473 wifi_power_on_wearable(interface_name, TRUE);
477 if (emergency > SETTING_PSMODE_POWERFUL) {
478 /* emergency mode on */
479 GSList *device_list = NULL;
481 if (wifi_state == VCONFKEY_WIFI_OFF)
484 device_list = wifi_state_get_device_list();
485 for (list = device_list; list; list = list->next) {
486 wifi_device_data_s *device_data = list->data;
487 wifi_power_off(device_data->interface_name);
488 netconfig_setting_update_interface_off_for_emergency(device_data->interface_name, TRUE);
491 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1, TRUE);
493 /* emergency mode off */
494 GSList *ifname_list = NULL;
496 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0, TRUE);
498 ifname_list = netconfig_setting_get_interfaces_off_by_emergency();
499 for (list = ifname_list; list; list = list->next) {
500 char *interface_name = list->data;
502 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
505 netconfig_setting_update_interface_off_for_emergency(interface_name, FALSE);
506 wifi_power_on(interface_name);
513 void wifi_set_early_suspend(const char *interface_name, gboolean value)
515 static gboolean old_state = FALSE;
517 char buf[MAX_DRV_CMD_SIZE];
518 netconfig_wifi_priv_cmd priv_cmd;
522 wifi_service_state_e wifi_state;
523 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
525 if (old_state == value) {
526 DBG("Old and new states are same");
530 if (netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
531 ERR("Fail to get VCONFKEY_PM_STATE");
533 wifi_state = wifi_state_get_service_state(interface_name);
536 (pm_state < VCONFKEY_PM_STATE_LCDOFF ||
537 wifi_state == NETCONFIG_WIFI_ASSOCIATION ||
538 wifi_state == NETCONFIG_WIFI_CONFIGURATION)){
543 memset(buf, 0, sizeof(buf));
544 snprintf(buf, sizeof(buf), "SETSUSPENDMODE %d", value);
546 memset(&ifr, 0, sizeof(struct ifreq));
547 g_strlcpy((char *)ifr.ifr_name, interface_name, IFNAMSIZ);
549 DBG("Early suspend command: [%s]", buf);
551 memset(&priv_cmd, 0, sizeof(priv_cmd));
553 priv_cmd.used_len = sizeof(buf);
554 priv_cmd.total_len = sizeof(buf);
555 ifr.ifr_data = (char *)&priv_cmd;
557 ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
558 if (ioctl_sock < 0) {
559 DBG("socket(PF_INET,SOCK_DGRAM) failed: %s",
560 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
564 ret = ioctl(ioctl_sock, WLAN_IOCTL_SUSPEND, &ifr);
566 ERR("Fail to issue private commands: %d. %s", ret,
567 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
575 static void __pm_state_changed_cb(keynode_t* node, void* user_data)
579 static int prev_state = VCONFKEY_PM_STATE_NORMAL;
580 GSList *list = NULL, *device_list = NULL;
582 if (netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) < 0) {
583 ERR("Fail to get VCONFKEY_WIFI_STATE");
588 * VCONFKEY_PM_STATE_NORMAL = 1,
589 * VCONFKEY_PM_STATE_LCDDIM,
590 * VCONFKEY_PM_STATE_LCDOFF,
591 * VCONFKEY_PM_STATE_SLEEP
594 new_state = vconf_keynode_get_int(node);
596 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &new_state);
598 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
599 DBG("Old PM state: %d, current: %d (1 normal / 2 lcddim / 3 lcdoff / 4 sleep)", prev_state, new_state);
601 if ((new_state == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) {
602 /* Send early suspend mode based on LCD state and disallow early suspend count */
603 device_list = wifi_state_get_device_list();
604 for (list = device_list; list; list = list->next) {
605 wifi_device_data_s *device_data = list->data;
606 if (device_data->powered == TRUE) {
607 wifi_set_early_suspend(device_data->interface_name, FALSE);
608 DBG("Unset early suspend [%s]", device_data->interface_name);
610 netconfig_wifi_bgscan_stop(device_data->interface_name);
611 netconfig_wifi_bgscan_set_interval(device_data->interface_name, SCAN_EXPONENTIAL_MIN);
612 netconfig_wifi_bgscan_start(device_data->interface_name, TRUE);
614 } else if ((new_state == VCONFKEY_PM_STATE_LCDOFF) && (prev_state < VCONFKEY_PM_STATE_LCDOFF) && (wifi_state != VCONFKEY_WIFI_OFF)) {
615 device_list = wifi_state_get_device_list();
616 for (list = device_list; list; list = list->next) {
617 wifi_device_data_s *device_data = list->data;
618 wifi_set_early_suspend(device_data->interface_name, TRUE);
619 DBG("Set early suspend [%s]", device_data->interface_name);
623 prev_state = new_state;
626 static void __netconfig_telephony_ready_changed_cb(keynode_t *node, void *data)
628 int telephony_ready = 0;
629 char *interface_name = data;
632 telephony_ready = vconf_keynode_get_bool(node);
634 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
636 if (telephony_ready != 0) {
637 if (netconfig_tapi_check_sim_state() == FALSE) {
638 DBG("Sim is not initialized yet.");
645 DBG("Turn Wi-Fi on automatically");
647 #if defined TIZEN_WEARABLE
648 wifi_power_on_wearable(interface_name, TRUE);
650 wifi_power_on(interface_name);
654 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __netconfig_telephony_ready_changed_cb);
655 g_free(interface_name);
658 int wifi_power_driver_and_supplicant(const char *interface_name, gboolean enable)
660 /* There are 3 thumb rules for Wi-Fi power management
661 * 1. Do not make exposed API to control wpa_supplicant and driver directly.
662 * It probably breaks ConnMan technology operation.
664 * 2. Do not remove driver and wpa_supplicant if ConnMan already enabled.
665 * It breaks ConnMan technology operation.
667 * 3. Final the best rule: make it as simple as possible.
668 * Simple code enables easy maintenance and reduces logical errors.
671 if (enable == TRUE) {
672 return _load_driver_and_supplicant(interface_name);
674 if (wifi_state_get_powered(interface_name) == TRUE)
677 return _remove_driver_and_supplicant(interface_name);
681 void wifi_power_recover_firmware(const char *interface_name)
683 wifi_firmware_recovery_mode = TRUE;
685 netconfig_wifi_bgscan_stop(interface_name);
687 wifi_power_off(interface_name);
690 int wifi_power_on(const char *interface_name)
693 wifi_tech_state_e tech_state;
695 tech_state = wifi_state_get_technology_state(interface_name);
696 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
697 INFO("Net-Config WiFi connman technology state %d", tech_state);
701 if (__is_wifi_restricted() == TRUE)
704 if (netconfig_is_wifi_tethering_on() == TRUE) {
705 /* TODO: Wi-Fi tethering turns off here */
707 ERR("Failed to turn tethering off");
711 err = wifi_power_driver_and_supplicant(interface_name, TRUE);
712 if (err < 0 && err != -EALREADY)
715 err = _set_connman_technology_power(interface_name, TRUE);
716 if (err < 0 && err != -EALREADY)
717 wifi_power_driver_and_supplicant(interface_name, FALSE);
722 int wifi_power_off(const char *interface_name)
726 err = _set_connman_technology_power(interface_name, FALSE);
727 if (err == -EALREADY)
728 wifi_state_update_power_state(interface_name, FALSE);
733 #if defined TIZEN_WEARABLE
734 int wifi_power_on_wearable(const char *interface_name, gboolean device_picker_test)
737 wifi_tech_state_e tech_state;
739 tech_state = wifi_state_get_technology_state(interface_name);
740 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED)
743 err = wifi_power_driver_and_supplicant(interface_name, TRUE);
744 if (err < 0 && err != -EALREADY)
747 err = _set_connman_technology_power(interface_name, TRUE);
748 if (err < 0 && err != -EALREADY) {
749 wifi_power_driver_and_supplicant(interface_name, FALSE);
753 if (device_picker_test == TRUE)
754 netconfig_wifi_enable_device_picker_test();
760 void wifi_power_initialize(void)
762 GSList *interface_list = NULL;
764 /* Initialize Airplane mode */
765 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_mode);
766 DBG("Airplane[%s]", airplane_mode > 0 ? "ON" : "OFF");
768 /* Update the last Wi-Fi power state */
769 interface_list = netconfig_setting_get_interfaces_for_last_powered();
770 for (; interface_list; interface_list = interface_list->next) {
771 const char *interface_name = interface_list->data;
773 if (TIZEN_TELEPHONY_ENABLE) {
774 int telephony_ready = 0;
775 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
776 if (telephony_ready == 0) {
777 DBG("Telephony API is not initialized yet");
778 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY,
779 __netconfig_telephony_ready_changed_cb,
780 g_strdup(interface_name));
782 if (netconfig_tapi_check_sim_state() == FALSE)
783 DBG("SIM is not initialized yet");
786 DBG("Turn Wi-Fi on automatically");
787 #if defined TIZEN_WEARABLE
788 wifi_power_on_wearable(interface_name, TRUE);
790 wifi_power_on(interface_name);
794 #if defined TIZEN_WEARABLE
795 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
796 __netconfig_wifi_airplane_mode, NULL);
798 vconf_notify_key_changed(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE,
799 __netconfig_wifi_restrict_mode, NULL);
800 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
801 __netconfig_wifi_airplane_mode, NULL);
804 vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
805 __emergency_mode_changed_cb, NULL);
806 vconf_notify_key_changed(VCONFKEY_PM_STATE, __pm_state_changed_cb, NULL);
809 void wifi_power_deinitialize(void)
813 gboolean handle_load_driver(Wifi *wifi,
814 GDBusMethodInvocation *context,
815 const gchar *ifname, gboolean device_picker_test)
819 DBG("Wi-Fi power on requested [%s]", ifname);
821 g_return_val_if_fail(wifi != NULL, TRUE);
823 if (!netconfig_dpm_update_from_wifi()) {
824 DBG("DPM policy restricts Wi-Fi");
825 netconfig_error_permission_denied(context);
829 if (TIZEN_WLAN_BOARD_SPRD)
830 wifi_firmware_download();
832 #if defined TIZEN_WEARABLE
833 err = wifi_power_on_wearable(ifname, device_picker_test);
835 err = wifi_power_on(ifname);
837 if (device_picker_test == TRUE)
838 netconfig_wifi_enable_device_picker_test();
841 if (err == -EALREADY)
842 netconfig_error_already_exists(context);
843 else if (err == -EPERM)
844 netconfig_error_permission_denied(context);
846 netconfig_error_wifi_driver_failed(context);
852 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
854 wifi_complete_load_driver(wifi, context);
858 gboolean handle_remove_driver(Wifi *wifi, GDBusMethodInvocation *context,
863 DBG("Wi-Fi power off requested [%s]", ifname);
865 g_return_val_if_fail(wifi != NULL, TRUE);
867 err = wifi_power_off(ifname);
869 if (err == -EALREADY)
870 netconfig_error_already_exists(context);
871 else if (err == -EPERM)
872 netconfig_error_permission_denied(context);
874 netconfig_error_wifi_driver_failed(context);
878 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
880 wifi_complete_remove_driver(wifi, context);
884 gboolean handle_load_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
888 wifi_complete_load_p2p_driver(wifi, context);
892 gboolean handle_remove_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
896 wifi_complete_remove_p2p_driver(wifi, context);
900 static int __netconfig_get_random_mac(unsigned char *mac_buf, int mac_len)
902 DBG("Generate Random Mac address of ethernet");
906 fp = fopen(OS_RANDOM_FILE, "rb");
909 ERR("Could not open /dev/urandom");
912 rc = fread(mac_buf, 1, mac_len, fp);
916 return rc != mac_len ? -1 : 0;
919 void __netconfig_set_ether_macaddr()
921 DBG("Set wired Mac address ");
922 char *mac_addr = NULL;
923 char rand_addr[WLAN_MAC_ADDR_MAX];
926 mac_addr = vconf_get_str(VCONF_ETH_MAC_ADDRESS);
927 if (mac_addr == NULL) {
928 DBG("vconf_get_str Failed\n");
931 /* Checking Invalid MAC Address */
932 if ((strlen(mac_addr) == 0)) {
933 ERR("Failed to get valid MAC Address from vconf");
934 /*Generate the Random Mac address*/
935 unsigned char rand_mac_add[ETH_MAC_ADDR_SIZE+1];
937 if (__netconfig_get_random_mac(rand_mac_add, ETH_MAC_ADDR_SIZE) == -1) {
939 ERR("Could not generate the Random Mac address");
944 rand_mac_add[0] &= 0xFE; /*Clear multicase bit*/
945 rand_mac_add[0] |= 0x02; /*set local assignment bit*/
947 /*Set the Mac address in Vconf*/
948 snprintf(rand_addr, WLAN_MAC_ADDR_MAX, "%x:%x:%x:%x:%x:%x",
949 rand_mac_add[0], rand_mac_add[1],
950 rand_mac_add[2], rand_mac_add[3],
951 rand_mac_add[4], rand_mac_add[5]);
953 netconfig_set_vconf_str(VCONF_ETH_MAC_ADDRESS, rand_addr, TRUE);
954 } else { /* Valid MAC address */
955 g_strlcpy(rand_addr, mac_addr, WLAN_MAC_ADDR_MAX);
958 DBG("MAC Address of eth0 [%s]", rand_addr);
959 const char *path = NET_EXEC_PATH;
960 char *const args[] = { "/sbin/ifconfig", "eth0", "hw",
961 "ether", rand_addr, "up", NULL};
962 char *const envs[] = { NULL };
963 rv = netconfig_execute_file(path, args, envs);
966 ERR("Unable to execute system command");