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>
35 #include "wifi-bssid-scan.h"
36 #include "wifi-power.h"
37 #include "wifi-state.h"
38 #include "netsupplicant.h"
39 #include "network-state.h"
40 #include "network-dpm.h"
41 #include "wifi-firmware.h"
42 #include "wifi-background-scan.h"
45 #define WLAN_SUPPLICANT_SCRIPT "/usr/bin/wpa_supp.sh"
46 #define P2P_SUPPLICANT_SCRIPT "/usr/bin/p2p_supp.sh"
48 #define VCONF_WIFI_OFF_STATE_BY_AIRPLANE "file/private/wifi/wifi_off_by_airplane"
49 #define VCONF_WIFI_OFF_STATE_BY_RESTRICTED "file/private/wifi/wifi_off_by_restricted"
50 #define VCONF_WIFI_OFF_STATE_BY_EMERGENCY "file/private/wifi/wifi_off_by_emergency"
51 #if !defined TIZEN_WEARABLE
52 #define VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT "db/setting/network_with_lcd_off_limit"
55 #define WLAN_MAC_ADDRESS_FILEPATH "/sys/class/net/wlan0/address"
56 #define WLAN_MAC_ADDR_MAX 20
57 #define VCONF_WIFI_BSSID_ADDRESS "db/wifi/bssid_address"
59 #define ETH_MAC_ADDR_SIZE 6
60 #define VCONF_ETH_MAC_ADDRESS "db/dnet/mac_address"
61 #define NET_EXEC_PATH "/sbin/ifconfig"
62 #define OS_RANDOM_FILE "/dev/urandom"
64 #define NETCONFIG_TECH_WAITING_INTERVAL 500
65 #define NETCONFIG_TECH_WAITING_COUNT 6
66 #define MAX_DRV_CMD_SIZE 248
67 #define WLAN_IOCTL_SUSPEND (SIOCDEVPRIVATE + 1)
69 static gboolean connman_wifi_technology_state = FALSE;
70 static gboolean wifi_firmware_recovery_mode = FALSE;
71 static int airplane_mode = 0;
77 } netconfig_wifi_priv_cmd;
79 static gboolean __is_wifi_restricted(void)
81 #if defined TIZEN_WEARABLE
84 int restricted_mode = 0;
86 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted_mode);
87 if (restricted_mode != 0) {
88 DBG("network restricted mode[%d]", restricted_mode);
95 static void __technology_reply(GObject *source_object, GAsyncResult *res, gpointer user_data)
98 GDBusConnection *conn = NULL;
101 conn = G_DBUS_CONNECTION(source_object);
102 reply = g_dbus_connection_call_finish(conn, res, &error);
106 if (g_strstr_len(error->message, strlen(error->message),
107 CONNMAN_ERROR_INTERFACE ".AlreadyEnabled") != NULL) {
108 wifi_state_update_power_state(TRUE);
109 } else if (g_strstr_len(error->message, strlen(error->message),
110 CONNMAN_ERROR_INTERFACE ".AlreadyDisabled") != NULL) {
111 wifi_state_update_power_state(FALSE);
113 ERR("Fail to request status [%d: %s]", error->code, error->message);
114 wifi_state_update_power_state(FALSE);
118 ERR("Fail to request status");
119 wifi_state_update_power_state(FALSE);
122 DBG("Successfully requested");
123 g_variant_unref(reply);
126 netconfig_gdbus_pending_call_unref();
129 static int __execute_supplicant(gboolean enable)
132 const char *path = WLAN_SUPPLICANT_SCRIPT;
133 char *const args_enable[] = { "/usr/bin/wpa_supp.sh", "start", NULL };
134 char *const args_disable[] = { "/usr/bin/wpa_supp.sh", "stop", NULL };
135 char *const envs[] = { NULL };
136 static gboolean enabled = FALSE;
138 if (enabled == enable)
142 rv = netconfig_execute_file(path, args_enable, envs);
144 rv = netconfig_execute_file(path, args_disable, envs);
148 DBG("wpa_supplicant %s", enable == TRUE ? "started" : "stopped");
155 void netconfig_wifi_recover_firmware(void)
157 wifi_firmware_recovery_mode = TRUE;
159 netconfig_wifi_bgscan_stop();
164 static int _load_driver_and_supplicant(void)
167 wifi_tech_state_e tech_state;
169 tech_state = wifi_state_get_technology_state();
170 if (tech_state > NETCONFIG_WIFI_TECH_OFF)
173 err = __execute_supplicant(TRUE);
174 if (err < 0 && err != -EALREADY)
177 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, TRUE);
178 if (err < 0 && err != -EALREADY) {
179 __execute_supplicant(FALSE);
183 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_WPS_ONLY);
188 static int _remove_driver_and_supplicant(void)
192 DBG("remove driver and supplicant");
193 if (wifi_firmware_recovery_mode != TRUE &&
194 netconfig_wifi_is_bssid_scan_started() == TRUE) {
195 DBG("Wi-Fi WPS mode");
199 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, FALSE);
200 if (err < 0 && err != -EALREADY)
203 err = __execute_supplicant(FALSE);
204 if (err < 0 && err != -EALREADY)
207 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_OFF);
209 // reset service state
210 wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
212 if (wifi_firmware_recovery_mode == TRUE) {
213 if (wifi_power_on() < 0)
214 ERR("Failed to recover Wi-Fi firmware");
216 wifi_firmware_recovery_mode = FALSE;
222 static gboolean __check_and_set_technology_enable(gpointer data)
224 static int retry_count = NETCONFIG_TECH_WAITING_COUNT;
225 gboolean value_enable = TRUE;
226 gboolean reply = FALSE;
227 GVariant *params = NULL;
228 char key[] = "Powered";
230 if (wifi_state_is_technology_available() == FALSE) {
236 params = g_variant_new("(sv)", key, g_variant_new_boolean(value_enable));
238 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
239 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
240 CONNMAN_TECHNOLOGY_INTERFACE,
241 "SetProperty", params, __technology_reply);
244 ERR("Fail to set technology enable");
245 wifi_state_update_power_state(FALSE);
247 retry_count = NETCONFIG_TECH_WAITING_COUNT;
251 retry_count = NETCONFIG_TECH_WAITING_COUNT;
255 static int _set_connman_technology_power(gboolean enable)
257 gboolean reply = FALSE;
258 GVariant *params = NULL;
259 char key[] = "Powered";
260 gboolean value_enable = TRUE;
261 gboolean value_disable = FALSE;
263 if (connman_wifi_technology_state == enable)
266 if (enable && wifi_state_is_technology_available() == FALSE) {
267 netconfig_start_timer(NETCONFIG_TECH_WAITING_INTERVAL,
268 __check_and_set_technology_enable, NULL, NULL);
269 connman_wifi_technology_state = enable;
273 params = g_variant_new("(sv)", key, (enable == TRUE) ?
274 g_variant_new_boolean(value_enable) : g_variant_new_boolean(value_disable));
276 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
277 CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
278 "SetProperty", params, __technology_reply);
281 ERR("Fail to set technology %s", enable == TRUE ? "enable" : "disable");
285 /* If Wi-Fi powered off,
286 * Do not remove Wi-Fi driver until ConnMan technology state updated
289 connman_wifi_technology_state = enable;
291 /* To be keep safe, early disable Wi-Fi tech state */
293 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_WPS_ONLY);
298 static void __netconfig_set_wifi_bssid(void)
301 char bssid[WLAN_MAC_ADDR_MAX];
303 FILE *fp = fopen(WLAN_MAC_ADDRESS_FILEPATH, "r");
306 ERR("Fail to open %s", WLAN_MAC_ADDRESS_FILEPATH);
310 fseek(fp, 0L, SEEK_SET);
311 rv = fscanf(fp, "%17s", bssid);
314 ERR("Fail to read bssid");
316 netconfig_set_vconf_str(VCONF_WIFI_BSSID_ADDRESS, bssid);
321 void netconfig_wifi_disable_technology_state_by_only_connman_signal(void)
323 /* Important: it's only done by ConnMan technology signal update */
324 connman_wifi_technology_state = FALSE;
327 #if defined TIZEN_WEARABLE
328 int netconfig_wifi_on_wearable(gboolean device_picker_test)
333 if (netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ps_mode) < 0) {
334 ERR("Fail to get VCONFKEY_SETAPPL_PSMODE");
338 if (ps_mode > SETTING_PSMODE_NORMAL) {
339 WARN("ps mode is on(%d), Not turn on Wi-Fi", ps_mode);
343 err = wifi_power_driver_and_supplicant(TRUE);
344 if (err < 0 && err != -EALREADY)
347 err = _set_connman_technology_power(TRUE);
349 if (device_picker_test == TRUE)
350 netconfig_wifi_enable_device_picker_test();
355 static void __netconfig_wifi_restrict_mode(keynode_t *node, void *user_data)
357 int wifi_state = 0, restricted = 0;
358 int wifi_off_by_restricted = 0;
360 netconfig_vconf_get_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, &wifi_off_by_restricted);
362 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
365 restricted = vconf_keynode_get_bool(node);
367 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted);
369 DBG("network restricted mode %s", restricted > 0 ? "ON" : "OFF");
370 DBG("Wi-Fi state %d, Wi-Fi was off by restricted mode %s", wifi_state,
371 wifi_off_by_restricted ? "Yes" : "No");
373 if (restricted > 0) {
374 /* network restricted on */
375 if (wifi_state == VCONFKEY_WIFI_OFF)
380 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 1);
382 /* network restricted off */
383 if (!wifi_off_by_restricted)
386 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 0);
388 if (wifi_state > VCONFKEY_WIFI_OFF)
396 static void __netconfig_wifi_airplane_mode(keynode_t *node, void *user_data)
398 int wifi_state = 0, airplane_state = 0;
399 int wifi_off_by_airplane = 0;
401 netconfig_vconf_get_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, &wifi_off_by_airplane);
402 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
405 airplane_state = vconf_keynode_get_bool(node);
407 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_state);
409 DBG("airplane mode %s (prev:%d)", airplane_state > 0 ? "ON" : "OFF", airplane_mode);
410 DBG("Wi-Fi state(or use) %d, Wi-Fi was off by flight mode %s", wifi_state,
411 wifi_off_by_airplane ? "Yes" : "No");
413 if (airplane_mode == airplane_state)
416 airplane_mode = airplane_state;
418 if (airplane_state > 0) {
419 /* airplane mode on */
420 if (wifi_state == VCONFKEY_WIFI_OFF)
425 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 1);
427 /* airplane mode off */
428 if (!wifi_off_by_airplane)
431 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0);
432 if (wifi_state > VCONFKEY_WIFI_OFF)
439 static void __emergency_mode_changed_cb(keynode_t *node, void *user_data)
441 int wifi_state = 0, emergency = 0;
442 int wifi_off_by_emergency = 0;
443 #if !defined TIZEN_WEARABLE
444 int emergency_by_fmm = 0;
446 netconfig_vconf_get_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, &wifi_off_by_emergency);
447 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
449 #if !defined TIZEN_WEARABLE
450 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT, &emergency_by_fmm);
451 DBG("emergency mode by Find My Mobile (%d)", emergency_by_fmm);
452 if (emergency_by_fmm == 1)
457 emergency = vconf_keynode_get_int(node);
459 netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &emergency);
461 DBG("emergency mode %s", emergency > SETTING_PSMODE_POWERFUL ? "ON" : "OFF");
462 DBG("Wi-Fi state %d, Wi-Fi was off by emergency mode %s", wifi_state, wifi_off_by_emergency ? "Yes" : "No");
464 #if defined TIZEN_WEARABLE
465 if (emergency == SETTING_PSMODE_WEARABLE) {
466 /* basic power saving mode on */
467 } else if (emergency == SETTING_PSMODE_WEARABLE_ENHANCED) {
468 /* enhanced power saving mode on */
469 if (wifi_state == VCONFKEY_WIFI_OFF)
473 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1);
475 /* power saving mode off */
476 if (!wifi_off_by_emergency)
479 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0);
480 if (wifi_state > VCONFKEY_WIFI_OFF)
483 wifi_power_on_wearable(TRUE);
486 if (emergency > SETTING_PSMODE_POWERFUL) {
487 /* emergency mode on */
488 if (wifi_state == VCONFKEY_WIFI_OFF)
493 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1);
495 /* emergency mode off */
496 if (!wifi_off_by_emergency)
499 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0);
501 if (wifi_state > VCONFKEY_WIFI_OFF)
510 void wifi_set_early_suspend(gboolean value)
512 static gboolean old_state = FALSE;
514 char buf[MAX_DRV_CMD_SIZE];
515 netconfig_wifi_priv_cmd priv_cmd;
519 wifi_service_state_e wifi_state;
520 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
522 if (old_state == value) {
523 DBG("Old and new states are same");
527 if (netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
528 ERR("Fail to get VCONFKEY_PM_STATE");
530 wifi_state = wifi_state_get_service_state();
533 (pm_state < VCONFKEY_PM_STATE_LCDOFF ||
534 wifi_state == NETCONFIG_WIFI_ASSOCIATION ||
535 wifi_state == NETCONFIG_WIFI_CONFIGURATION)){
540 memset(buf, 0, sizeof(buf));
541 snprintf(buf, sizeof(buf), "SETSUSPENDMODE %d", value);
543 memset(&ifr, 0, sizeof(struct ifreq));
544 g_strlcpy((char *)ifr.ifr_name, WIFI_IFNAME, IFNAMSIZ);
546 DBG("Early suspend command: [%s]", buf);
548 memset(&priv_cmd, 0, sizeof(priv_cmd));
550 priv_cmd.used_len = sizeof(buf);
551 priv_cmd.total_len = sizeof(buf);
552 ifr.ifr_data = (char *)&priv_cmd;
554 ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
555 if (ioctl_sock < 0) {
556 DBG("socket(PF_INET,SOCK_DGRAM) failed: %s",
557 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
561 ret = ioctl(ioctl_sock, WLAN_IOCTL_SUSPEND, &ifr);
563 ERR("Fail to issue private commands: %d. %s", ret,
564 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
572 static void __pm_state_changed_cb(keynode_t* node, void* user_data)
576 static int prev_state = VCONFKEY_PM_STATE_NORMAL;
578 if (netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) < 0) {
579 ERR("Fail to get VCONFKEY_WIFI_STATE");
584 * VCONFKEY_PM_STATE_NORMAL = 1,
585 * VCONFKEY_PM_STATE_LCDDIM,
586 * VCONFKEY_PM_STATE_LCDOFF,
587 * VCONFKEY_PM_STATE_SLEEP
590 new_state = vconf_keynode_get_int(node);
592 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &new_state);
594 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
595 DBG("Old PM state: %d, current: %d (1 normal / 2 lcddim / 3 lcdoff / 4 sleep)", prev_state, new_state);
597 if ((new_state == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) {
598 /* Send early suspend mode based on LCD state and disallow early suspend count */
599 if (wifi_state != VCONFKEY_WIFI_OFF) {
600 wifi_set_early_suspend(FALSE);
601 DBG("Unset early suspend");
604 netconfig_wifi_bgscan_stop();
605 netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
606 netconfig_wifi_bgscan_start(TRUE);
607 } else if ((new_state == VCONFKEY_PM_STATE_LCDOFF) && (prev_state < VCONFKEY_PM_STATE_LCDOFF) && (wifi_state != VCONFKEY_WIFI_OFF)) {
608 wifi_set_early_suspend(TRUE);
609 DBG("Set early suspend");
612 prev_state = new_state;
615 static void __netconfig_telephony_ready_changed_cb(keynode_t * node, void *data)
617 int telephony_ready = 0;
620 telephony_ready = vconf_keynode_get_bool(node);
622 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
624 if (telephony_ready != 0) {
625 if (netconfig_tapi_check_sim_state() == FALSE) {
626 DBG("Sim is not initialized yet.");
633 DBG("Turn Wi-Fi on automatically");
635 #if defined TIZEN_WEARABLE
636 wifi_power_on_wearable(TRUE);
642 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __netconfig_telephony_ready_changed_cb);
645 int wifi_power_driver_and_supplicant(gboolean enable)
647 /* There are 3 thumb rules for Wi-Fi power management
648 * 1. Do not make exposed API to control wpa_supplicant and driver directly.
649 * It probably breaks ConnMan technology operation.
651 * 2. Do not remove driver and wpa_supplicant if ConnMan already enabled.
652 * It breaks ConnMan technology operation.
654 * 3. Final the best rule: make it as simple as possible.
655 * Simple code enables easy maintenance and reduces logical errors.
657 if (enable == TRUE) {
658 return _load_driver_and_supplicant();
660 if (connman_wifi_technology_state == TRUE)
663 return _remove_driver_and_supplicant();
667 void wifi_power_disable_technology_state_by_only_connman_signal(void)
669 /* Important: it's only done by ConnMan technology signal update */
670 connman_wifi_technology_state = FALSE;
673 void wifi_power_recover_firmware(void)
675 wifi_firmware_recovery_mode = TRUE;
677 netconfig_wifi_bgscan_stop();
682 int wifi_power_on(void)
685 wifi_tech_state_e tech_state;
687 tech_state = wifi_state_get_technology_state();
688 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
689 /* There can be a scenario where wifi is automatically *
690 * activated by connman if wifi was powered in last boot. *
691 * So we should update connman_wifi_technology_state variable *
692 * if it is found that wifi_tech_state variable is *
693 * NETCONFIG_WIFI_TECH_POWERED and connman_wifi_technology_state *
694 * variable is FALSE. Earlier connman_wifi_technology_state *
695 * variable was only updated when wifi was Powered on from *
696 * net-config resulting in variable not getting updated. *
697 * This caused wifi to not get deactivated after reboot if *
698 * last power state was activated */
699 ERR("Net-Config WiFi connman technology state %d",
700 connman_wifi_technology_state);
701 if (connman_wifi_technology_state == FALSE)
702 connman_wifi_technology_state = TRUE;
706 if (__is_wifi_restricted() == TRUE)
709 if (netconfig_is_wifi_tethering_on() == TRUE) {
710 /* TODO: Wi-Fi tethering turns off here */
712 ERR("Failed to turn tethering off");
716 err = wifi_power_driver_and_supplicant(TRUE);
717 if (err < 0 && err != -EALREADY)
720 err = _set_connman_technology_power(TRUE);
725 int wifi_power_off(void)
729 err = _set_connman_technology_power(FALSE);
730 if (err == -EALREADY)
731 wifi_state_update_power_state(FALSE);
736 #if defined TIZEN_WEARABLE
737 int wifi_power_on_wearable(gboolean device_picker_test)
740 wifi_tech_state_e tech_state;
742 tech_state = wifi_state_get_technology_state();
743 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED)
746 err = wifi_power_driver_and_supplicant(TRUE);
747 if (err < 0 && err != -EALREADY)
750 err = _set_connman_technology_power(TRUE);
752 if (device_picker_test == TRUE)
753 netconfig_wifi_enable_device_picker_test();
759 void wifi_power_initialize(void)
761 int wifi_last_power_state = 0;
763 /* Initialize Airplane mode */
764 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_mode);
765 DBG("Airplane[%s]", airplane_mode > 0 ? "ON" : "OFF");
767 /* Update the last Wi-Fi power state */
768 netconfig_vconf_get_int(VCONF_WIFI_LAST_POWER_STATE, &wifi_last_power_state);
769 if (wifi_last_power_state > VCONFKEY_WIFI_OFF) {
770 if (TIZEN_TELEPHONY_ENABLE) {
771 int telephony_ready = 0;
772 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
773 if (telephony_ready == 0) {
774 DBG("Telephony API is not initialized yet");
775 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY,
776 __netconfig_telephony_ready_changed_cb, NULL);
778 if (netconfig_tapi_check_sim_state() == FALSE)
779 DBG("SIM is not initialized yet");
782 DBG("Turn Wi-Fi on automatically");
783 #if defined TIZEN_WEARABLE
784 wifi_power_on_wearable(TRUE);
790 #if defined TIZEN_WEARABLE
791 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
792 __netconfig_wifi_airplane_mode, NULL);
794 vconf_notify_key_changed(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE,
795 __netconfig_wifi_restrict_mode, NULL);
796 vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
797 __netconfig_wifi_airplane_mode, NULL);
800 vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, __emergency_mode_changed_cb, NULL);
801 vconf_notify_key_changed(VCONFKEY_PM_STATE, __pm_state_changed_cb, NULL);
804 void wifi_power_deinitialize(void)
808 gboolean handle_load_driver(Wifi *wifi,
809 GDBusMethodInvocation *context, gboolean device_picker_test)
813 DBG("Wi-Fi power on requested");
815 g_return_val_if_fail(wifi != NULL, TRUE);
817 if (!netconfig_dpm_update_from_wifi()) {
818 DBG("DPM policy restricts Wi-Fi");
819 netconfig_error_permission_denied(context);
823 if (TIZEN_WLAN_BOARD_SPRD)
824 wifi_firmware_download();
826 #if defined TIZEN_WEARABLE
827 err = wifi_power_on_wearable(device_picker_test);
829 err = wifi_power_on();
831 if (device_picker_test == TRUE)
832 netconfig_wifi_enable_device_picker_test();
835 if (err == -EALREADY)
836 netconfig_error_already_exists(context);
837 else if (err == -EPERM)
838 netconfig_error_permission_denied(context);
840 netconfig_error_wifi_driver_failed(context);
846 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0);
847 __netconfig_set_wifi_bssid();
849 wifi_complete_load_driver(wifi, context);
853 gboolean handle_remove_driver(Wifi *wifi, GDBusMethodInvocation *context)
857 DBG("Wi-Fi power off requested");
859 g_return_val_if_fail(wifi != NULL, TRUE);
861 err = wifi_power_off();
863 if (err == -EINPROGRESS)
864 netconfig_error_inprogress(context);
865 else if (err == -EALREADY)
866 netconfig_error_already_exists(context);
867 else if (err == -EPERM)
868 netconfig_error_permission_denied(context);
870 netconfig_error_wifi_driver_failed(context);
874 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0);
876 wifi_complete_remove_driver(wifi, context);
880 gboolean handle_load_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
884 wifi_complete_load_p2p_driver(wifi, context);
888 gboolean handle_remove_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
892 wifi_complete_remove_p2p_driver(wifi, context);
896 static int __netconfig_get_random_mac(unsigned char *mac_buf, int mac_len)
898 DBG("Generate Random Mac address of ethernet");
902 fp = fopen(OS_RANDOM_FILE, "rb");
905 ERR("Could not open /dev/urandom");
908 rc = fread(mac_buf, 1, mac_len, fp);
912 return rc != mac_len ? -1 : 0;
915 void __netconfig_set_ether_macaddr()
917 DBG("Set wired Mac address ");
918 char *mac_addr = NULL;
919 char rand_addr[WLAN_MAC_ADDR_MAX];
922 mac_addr = vconf_get_str(VCONF_ETH_MAC_ADDRESS);
923 if (mac_addr == NULL) {
924 DBG("vconf_get_str Failed\n");
927 /* Checking Invalid MAC Address */
928 if ((strlen(mac_addr) == 0)) {
929 ERR("Failed to get valid MAC Address from vconf");
930 /*Generate the Random Mac address*/
931 unsigned char rand_mac_add[ETH_MAC_ADDR_SIZE+1];
933 if (__netconfig_get_random_mac(rand_mac_add, ETH_MAC_ADDR_SIZE) == -1) {
935 ERR("Could not generate the Random Mac address");
940 rand_mac_add[0] &= 0xFE; /*Clear multicase bit*/
941 rand_mac_add[0] |= 0x02; /*set local assignment bit*/
943 /*Set the Mac address in Vconf*/
944 snprintf(rand_addr, WLAN_MAC_ADDR_MAX, "%x:%x:%x:%x:%x:%x",
945 rand_mac_add[0], rand_mac_add[1],
946 rand_mac_add[2], rand_mac_add[3],
947 rand_mac_add[4], rand_mac_add[5]);
949 netconfig_set_vconf_str(VCONF_ETH_MAC_ADDRESS, rand_addr);
950 } else { /* Valid MAC address */
951 g_strlcpy(rand_addr, mac_addr, WLAN_MAC_ADDR_MAX);
954 DBG("MAC Address of eth0 [%s]", rand_addr);
955 const char *path = NET_EXEC_PATH;
956 char *const args[] = { "/sbin/ifconfig", "eth0", "hw",
957 "ether", rand_addr, "up", NULL};
958 char *const envs[] = { NULL };
959 rv = netconfig_execute_file(path, args, envs);
962 ERR("Unable to execute system command");