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 WLAN_MAC_ADDR_MAX 20
54 #define ETH_MAC_ADDR_SIZE 6
55 #define NET_EXEC_PATH "/sbin/ifconfig"
56 #define OS_RANDOM_FILE "/dev/urandom"
58 #define NETCONFIG_TECH_WAITING_INTERVAL 500
59 #define NETCONFIG_TECH_WAITING_COUNT 6
60 #define MAX_DRV_CMD_SIZE 248
61 #define WLAN_IOCTL_SUSPEND (SIOCDEVPRIVATE + 1)
67 } netconfig_wifi_priv_cmd;
69 static gboolean wifi_firmware_recovery_mode = FALSE;
70 static int airplane_mode = 0;
71 gboolean is_supplicant_running = FALSE;
73 static gboolean __is_wifi_restricted(void)
75 #if defined TIZEN_WEARABLE
78 int restricted_mode = 0;
80 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted_mode);
81 if (restricted_mode != 0) {
82 DBG("network restricted mode[%d]", restricted_mode);
89 static void __technology_reply(GObject *source_object, GAsyncResult *res, gpointer user_data)
92 GDBusConnection *conn = NULL;
94 char *interface_name = user_data;
96 conn = G_DBUS_CONNECTION(source_object);
97 reply = g_dbus_connection_call_finish(conn, res, &error);
101 if (g_strstr_len(error->message, strlen(error->message),
102 CONNMAN_ERROR_INTERFACE ".AlreadyEnabled") != NULL) {
103 wifi_state_update_power_state(interface_name, TRUE);
104 } else if (g_strstr_len(error->message, strlen(error->message),
105 CONNMAN_ERROR_INTERFACE ".AlreadyDisabled") != NULL) {
106 wifi_state_update_power_state(interface_name, FALSE);
108 ERR("Fail to request status [%d: %s]", error->code, error->message);
109 wifi_state_update_power_state(interface_name, FALSE);
113 ERR("Fail to request status");
114 wifi_state_update_power_state(interface_name, FALSE);
117 DBG("Successfully requested");
118 g_variant_unref(reply);
121 netconfig_gdbus_pending_call_unref();
122 g_free(interface_name);
125 void __mark_supplicant_stopped(void)
127 is_supplicant_running = FALSE;
130 int __execute_supplicant(gboolean enable)
133 * TODO: [EAP on Ethernet] Temporary blocked wpa_supp.sh stop
134 * untill ConnMan adds logic to trigger/control wpa_supplicant interface.
137 const char *path = WLAN_SUPPLICANT_SCRIPT;
138 char *const args_enable[] = { "/usr/bin/wpa_supp.sh", "start", NULL };
140 char *const args_disable[] = { "/usr/bin/wpa_supp.sh", "stop", NULL };
142 char *const envs[] = { NULL };
144 if (is_supplicant_running == enable)
148 rv = netconfig_execute_file(path, args_enable, envs);
151 rv = netconfig_execute_file(path, args_disable, envs);
156 DBG("wpa_supplicant %s", enable == TRUE ? "started" : "stopped");
159 is_supplicant_running = enable;
164 static int _load_driver_and_supplicant(const char *interface_name)
167 wifi_tech_state_e tech_state;
169 tech_state = wifi_state_get_technology_state(interface_name);
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, interface_name, TRUE);
178 if (err < 0 && err != -EALREADY) {
179 __execute_supplicant(FALSE);
183 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_WPS_ONLY);
188 static int _remove_driver_and_supplicant(const char *interface_name)
192 DBG("remove driver and supplicant");
193 if (wifi_firmware_recovery_mode != TRUE &&
194 netconfig_wifi_bssidscan_get_mode(interface_name) == TRUE) {
195 DBG("Wi-Fi WPS mode");
199 err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, interface_name, FALSE);
200 if (err < 0 && err != -EALREADY)
203 err = __execute_supplicant(FALSE);
204 if (err < 0 && err != -EALREADY)
207 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_OFF);
209 // reset service state
210 wifi_state_set_service_state(interface_name, NULL, NETCONFIG_WIFI_IDLE);
212 if (wifi_firmware_recovery_mode == TRUE) {
213 if (wifi_power_on(interface_name) < 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 wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
226 gboolean value_enable = TRUE;
227 gboolean reply = FALSE;
228 GVariant *params = NULL;
229 char *interface_name = data;
231 tech_state = wifi_state_get_technology_state(interface_name);
232 if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN) {
238 params = g_variant_new("(sb)", interface_name, value_enable);
240 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
241 CONNMAN_WIFI_TECHNOLOGY_PREFIX,
242 CONNMAN_TECHNOLOGY_INTERFACE,
243 "SetDevicePower", params,
245 g_strdup(interface_name));
248 ERR("Fail to set technology enable");
249 wifi_state_update_power_state(interface_name, FALSE);
251 retry_count = NETCONFIG_TECH_WAITING_COUNT;
252 g_free(interface_name);
256 retry_count = NETCONFIG_TECH_WAITING_COUNT;
257 g_free(interface_name);
261 static int _set_connman_technology_power(const char *interface_name, gboolean enable)
263 gboolean reply = FALSE;
264 GVariant *params = NULL;
265 gboolean value_enable = TRUE;
266 gboolean value_disable = FALSE;
267 gboolean powered = FALSE;
268 wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
270 DBG("Set %s technology [%s]", interface_name, enable == TRUE ? "enable" : "disable");
272 powered = wifi_state_get_powered(interface_name);
273 if (powered == enable) {
274 DBG("Already %s", enable ? "enabled" : "disabled");
278 if (enable == TRUE) {
279 tech_state = wifi_state_get_technology_state(interface_name);
280 if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN) {
281 netconfig_start_timer(NETCONFIG_TECH_WAITING_INTERVAL,
282 __check_and_set_technology_enable, g_strdup(interface_name), NULL);
283 wifi_state_set_powered(interface_name, enable);
288 params = g_variant_new("(sb)", interface_name, (enable == TRUE) ? value_enable : value_disable);
290 reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
291 CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
292 "SetDevicePower", params, __technology_reply, g_strdup(interface_name));
295 ERR("Fail to set technology %s", enable == TRUE ? "enable" : "disable");
299 /* To be keep safe, early disable Wi-Fi tech state */
301 wifi_state_set_technology_state(interface_name, NETCONFIG_WIFI_TECH_WPS_ONLY);
306 #if !defined TIZEN_WEARABLE
307 static void __netconfig_wifi_restrict_mode(keynode_t *node, void *user_data)
309 int wifi_state = 0, restricted = 0;
312 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
315 restricted = vconf_keynode_get_bool(node);
317 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted);
319 DBG("network restricted mode %s", restricted > 0 ? "ON" : "OFF");
320 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
322 if (restricted > 0) {
323 /* network restricted on */
324 GSList *device_list = NULL;
326 if (wifi_state == VCONFKEY_WIFI_OFF)
329 device_list = wifi_state_get_device_list();
330 for (list = device_list; list; list = list->next) {
331 wifi_device_data_s *device_data = list->data;
332 wifi_power_off(device_data->interface_name);
333 netconfig_setting_update_interface_off_for_restricted(device_data->interface_name, TRUE);
336 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 1, TRUE);
338 /* network restricted off */
339 GSList *ifname_list = NULL;
341 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 0, TRUE);
343 ifname_list = netconfig_setting_get_interfaces_off_by_restricted();
344 for (list = ifname_list; list; list = list->next) {
345 char *interface_name = list->data;
347 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
350 netconfig_setting_update_interface_off_for_restricted(interface_name, FALSE);
351 wifi_power_on(interface_name);
357 static void __netconfig_wifi_airplane_mode(keynode_t *node, void *user_data)
359 int wifi_state = 0, airplane_state = 0;
362 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
365 airplane_state = vconf_keynode_get_bool(node);
367 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_state);
369 DBG("airplane mode %s (prev:%d)", airplane_state > 0 ? "ON" : "OFF", airplane_mode);
370 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
372 if (airplane_mode == airplane_state)
375 airplane_mode = airplane_state;
377 if (airplane_state > 0) {
378 /* airplane mode on */
379 GSList *device_list = NULL;
381 if (wifi_state == VCONFKEY_WIFI_OFF)
384 device_list = wifi_state_get_device_list();
385 for (list = device_list; list; list = list->next) {
386 wifi_device_data_s *device_data = list->data;
387 if (device_data->tech_state > NETCONFIG_WIFI_TECH_OFF) {
388 wifi_power_off(device_data->interface_name);
389 netconfig_setting_update_interface_off_for_airplane(device_data->interface_name, TRUE);
393 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 1, TRUE);
395 /* airplane mode off */
396 GSList *ifname_list = NULL;
398 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
400 ifname_list = netconfig_setting_get_interfaces_off_by_airplane();
401 for (list = ifname_list; list; list = list->next) {
402 char *interface_name = list->data;
404 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
407 netconfig_setting_update_interface_off_for_airplane(interface_name, FALSE);
408 wifi_power_on(interface_name);
413 static void __emergency_mode_changed_cb(keynode_t *node, void *user_data)
415 int wifi_state = 0, emergency = 0;
417 #if !defined TIZEN_WEARABLE
418 int emergency_by_fmm = 0;
421 netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
423 #if !defined TIZEN_WEARABLE
424 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT, &emergency_by_fmm);
425 DBG("emergency mode by Find My Mobile (%d)", emergency_by_fmm);
426 if (emergency_by_fmm == 1)
431 emergency = vconf_keynode_get_int(node);
433 netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &emergency);
435 DBG("emergency mode %s", emergency > SETTING_PSMODE_POWERFUL ? "ON" : "OFF");
436 DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
438 #if defined TIZEN_WEARABLE
439 if (emergency == SETTING_PSMODE_WEARABLE) {
440 /* basic power saving mode on */
441 } else if (emergency == SETTING_PSMODE_WEARABLE_ENHANCED) {
442 /* enhanced power saving mode on */
443 GSList *device_list = NULL;
445 if (wifi_state == VCONFKEY_WIFI_OFF)
448 device_list = wifi_state_get_device_list();
449 for (list = device_list; list; list = list->next) {
450 wifi_device_data_s *device_data = list->data;
451 wifi_power_off(device_data->interface_name);
452 netconfig_setting_update_interface_off_for_emergency(device_data->interface_name, TRUE);
455 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1, TRUE);
457 /* power saving mode off */
458 GSList *ifname_list = NULL;
460 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0, TRUE);
461 ifname_list = netconfig_setting_get_interfaces_off_by_emergency();
462 for (list = ifname_list; list; list = list->next) {
463 char *interface_name = list->data;
465 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
468 netconfig_setting_update_interface_off_for_emergency(interface_name, FALSE);
469 wifi_power_on_wearable(interface_name, TRUE);
473 if (emergency > SETTING_PSMODE_POWERFUL) {
474 /* emergency mode on */
475 GSList *device_list = NULL;
477 if (wifi_state == VCONFKEY_WIFI_OFF)
480 device_list = wifi_state_get_device_list();
481 for (list = device_list; list; list = list->next) {
482 wifi_device_data_s *device_data = list->data;
483 wifi_power_off(device_data->interface_name);
484 netconfig_setting_update_interface_off_for_emergency(device_data->interface_name, TRUE);
487 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1, TRUE);
489 /* emergency mode off */
490 GSList *ifname_list = NULL;
492 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0, TRUE);
494 ifname_list = netconfig_setting_get_interfaces_off_by_emergency();
495 for (list = ifname_list; list; list = list->next) {
496 char *interface_name = list->data;
498 if (wifi_state_get_technology_state(interface_name) > NETCONFIG_WIFI_TECH_OFF)
501 netconfig_setting_update_interface_off_for_emergency(interface_name, FALSE);
502 wifi_power_on(interface_name);
509 void wifi_set_early_suspend(const char *interface_name, gboolean value)
511 static gboolean old_state = FALSE;
513 char buf[MAX_DRV_CMD_SIZE];
514 netconfig_wifi_priv_cmd priv_cmd;
518 wifi_service_state_e wifi_state;
519 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
521 if (old_state == value) {
522 DBG("Old and new states are same");
526 if (netconfig_vconf_get_int(VCONFKEY_PM_STATE, &pm_state) < 0)
527 ERR("Fail to get VCONFKEY_PM_STATE");
529 wifi_state = wifi_state_get_service_state(interface_name);
532 (pm_state < VCONFKEY_PM_STATE_LCDOFF ||
533 wifi_state == NETCONFIG_WIFI_ASSOCIATION ||
534 wifi_state == NETCONFIG_WIFI_CONFIGURATION)){
539 memset(buf, 0, sizeof(buf));
540 snprintf(buf, sizeof(buf), "SETSUSPENDMODE %d", value);
542 memset(&ifr, 0, sizeof(struct ifreq));
543 g_strlcpy((char *)ifr.ifr_name, interface_name, IFNAMSIZ);
545 DBG("Early suspend command: [%s]", buf);
547 memset(&priv_cmd, 0, sizeof(priv_cmd));
549 priv_cmd.used_len = sizeof(buf);
550 priv_cmd.total_len = sizeof(buf);
551 ifr.ifr_data = (char *)&priv_cmd;
553 ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
554 if (ioctl_sock < 0) {
555 DBG("socket(PF_INET,SOCK_DGRAM) failed: %s",
556 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
560 ret = ioctl(ioctl_sock, WLAN_IOCTL_SUSPEND, &ifr);
562 ERR("Fail to issue private commands: %d. %s", ret,
563 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
571 static void __pm_state_changed_cb(keynode_t* node, void* user_data)
575 static int prev_state = VCONFKEY_PM_STATE_NORMAL;
576 GSList *list = NULL, *device_list = NULL;
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 device_list = wifi_state_get_device_list();
600 for (list = device_list; list; list = list->next) {
601 wifi_device_data_s *device_data = list->data;
602 if (device_data->powered == TRUE) {
603 wifi_set_early_suspend(device_data->interface_name, FALSE);
604 DBG("Unset early suspend [%s]", device_data->interface_name);
606 netconfig_wifi_bgscan_stop(device_data->interface_name);
607 netconfig_wifi_bgscan_set_exp_interval(device_data->interface_name, SCAN_EXPONENTIAL_MIN);
608 netconfig_wifi_bgscan_start(device_data->interface_name, TRUE);
610 } else if ((new_state == VCONFKEY_PM_STATE_LCDOFF) && (prev_state < VCONFKEY_PM_STATE_LCDOFF) && (wifi_state != VCONFKEY_WIFI_OFF)) {
611 device_list = wifi_state_get_device_list();
612 for (list = device_list; list; list = list->next) {
613 wifi_device_data_s *device_data = list->data;
614 wifi_set_early_suspend(device_data->interface_name, TRUE);
615 DBG("Set early suspend [%s]", device_data->interface_name);
619 prev_state = new_state;
622 static void __netconfig_telephony_ready_changed_cb(keynode_t *node, void *data)
624 int telephony_ready = 0;
625 char *interface_name = data;
628 telephony_ready = vconf_keynode_get_bool(node);
630 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
632 if (telephony_ready != 0) {
633 if (netconfig_tapi_check_sim_state() == FALSE) {
634 DBG("Sim is not initialized yet.");
641 DBG("Turn Wi-Fi on automatically");
643 #if defined TIZEN_WEARABLE
644 wifi_power_on_wearable(interface_name, TRUE);
646 wifi_power_on(interface_name);
650 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __netconfig_telephony_ready_changed_cb);
651 g_free(interface_name);
654 int wifi_power_driver_and_supplicant(const char *interface_name, gboolean enable)
656 /* There are 3 thumb rules for Wi-Fi power management
657 * 1. Do not make exposed API to control wpa_supplicant and driver directly.
658 * It probably breaks ConnMan technology operation.
660 * 2. Do not remove driver and wpa_supplicant if ConnMan already enabled.
661 * It breaks ConnMan technology operation.
663 * 3. Final the best rule: make it as simple as possible.
664 * Simple code enables easy maintenance and reduces logical errors.
667 if (enable == TRUE) {
668 return _load_driver_and_supplicant(interface_name);
670 if (wifi_state_get_powered(interface_name) == TRUE)
673 return _remove_driver_and_supplicant(interface_name);
677 void wifi_power_recover_firmware(const char *interface_name)
679 wifi_firmware_recovery_mode = TRUE;
681 netconfig_wifi_bgscan_stop(interface_name);
683 wifi_power_off(interface_name);
686 int wifi_power_on(const char *interface_name)
689 wifi_tech_state_e tech_state;
691 tech_state = wifi_state_get_technology_state(interface_name);
692 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
693 INFO("Net-Config WiFi connman technology state %d", tech_state);
697 if (__is_wifi_restricted() == TRUE)
700 if (netconfig_is_wifi_tethering_on() == TRUE) {
701 /* TODO: Wi-Fi tethering turns off here */
703 ERR("Failed to turn tethering off");
707 err = wifi_power_driver_and_supplicant(interface_name, TRUE);
708 if (err < 0 && err != -EALREADY)
711 err = _set_connman_technology_power(interface_name, TRUE);
712 if (err < 0 && err != -EALREADY)
713 wifi_power_driver_and_supplicant(interface_name, FALSE);
718 int wifi_power_off(const char *interface_name)
722 err = _set_connman_technology_power(interface_name, FALSE);
723 if (err == -EALREADY)
724 wifi_state_update_power_state(interface_name, FALSE);
729 #if defined TIZEN_WEARABLE
730 int wifi_power_on_wearable(const char *interface_name, gboolean device_picker_test)
733 wifi_tech_state_e tech_state;
735 tech_state = wifi_state_get_technology_state(interface_name);
736 if (tech_state >= NETCONFIG_WIFI_TECH_POWERED)
739 err = wifi_power_driver_and_supplicant(interface_name, TRUE);
740 if (err < 0 && err != -EALREADY)
743 err = _set_connman_technology_power(interface_name, TRUE);
744 if (err < 0 && err != -EALREADY) {
745 wifi_power_driver_and_supplicant(interface_name, FALSE);
749 if (device_picker_test == TRUE)
750 netconfig_wifi_enable_device_picker_test();
756 void wifi_power_initialize(void)
758 GSList *interface_list = NULL;
760 /* Initialize Airplane mode */
761 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_mode);
762 DBG("Airplane[%s]", airplane_mode > 0 ? "ON" : "OFF");
764 /* Update the last Wi-Fi power state */
765 interface_list = netconfig_setting_get_interfaces_for_last_powered();
766 for (; interface_list; interface_list = interface_list->next) {
767 const char *interface_name = interface_list->data;
769 if (TIZEN_TELEPHONY_ENABLE) {
770 int telephony_ready = 0;
771 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
772 if (telephony_ready == 0) {
773 DBG("Telephony API is not initialized yet");
774 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY,
775 __netconfig_telephony_ready_changed_cb,
776 g_strdup(interface_name));
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(interface_name, TRUE);
786 wifi_power_on(interface_name);
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,
801 __emergency_mode_changed_cb, NULL);
802 vconf_notify_key_changed(VCONFKEY_PM_STATE, __pm_state_changed_cb, NULL);
805 void wifi_power_deinitialize(void)
809 gboolean handle_load_driver(Wifi *wifi,
810 GDBusMethodInvocation *context,
811 const gchar *ifname, gboolean device_picker_test)
815 DBG("Wi-Fi power on requested [%s]", ifname);
817 g_return_val_if_fail(wifi != NULL, TRUE);
819 if (!netconfig_dpm_update_from_wifi()) {
820 DBG("DPM policy restricts Wi-Fi");
821 netconfig_error_permission_denied(context);
825 if (TIZEN_WLAN_BOARD_SPRD)
826 wifi_firmware_download();
828 #if defined TIZEN_WEARABLE
829 err = wifi_power_on_wearable(ifname, device_picker_test);
831 err = wifi_power_on(ifname);
833 if (device_picker_test == TRUE)
834 netconfig_wifi_enable_device_picker_test();
837 if (err == -EALREADY)
838 netconfig_error_already_exists(context);
839 else if (err == -EPERM)
840 netconfig_error_permission_denied(context);
842 netconfig_error_wifi_driver_failed(context);
848 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0, TRUE);
850 wifi_complete_load_driver(wifi, context);
854 gboolean handle_remove_driver(Wifi *wifi, GDBusMethodInvocation *context,
859 DBG("Wi-Fi power off requested [%s]", ifname);
861 g_return_val_if_fail(wifi != NULL, TRUE);
863 err = wifi_power_off(ifname);
865 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, TRUE);
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, TRUE);
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");