Remove unused vconf key
[platform/core/connectivity/net-config.git] / src / wifi-power.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <errno.h>
21 #include <vconf.h>
22 #include <vconf-keys.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <glib.h>
26 #include <tzplatform_config.h>
27
28 #include "log.h"
29 #include "util.h"
30 #include "netdbus.h"
31 #include "neterror.h"
32 #include "wifi-wps.h"
33 #include "wifi-bssid-scan.h"
34 #include "wifi-power.h"
35 #include "wifi-state.h"
36 #include "netsupplicant.h"
37 #include "network-state.h"
38 #include "network-dpm.h"
39 #include "wifi-firmware.h"
40 #include "wifi-background-scan.h"
41
42
43 #define WLAN_SUPPLICANT_SCRIPT          "/usr/bin/wpa_supp.sh"
44 #define P2P_SUPPLICANT_SCRIPT           "/usr/bin/p2p_supp.sh"
45
46 #define VCONF_WIFI_OFF_STATE_BY_AIRPLANE        "file/private/wifi/wifi_off_by_airplane"
47 #define VCONF_WIFI_OFF_STATE_BY_RESTRICTED      "file/private/wifi/wifi_off_by_restricted"
48 #define VCONF_WIFI_OFF_STATE_BY_EMERGENCY       "file/private/wifi/wifi_off_by_emergency"
49 #if !defined TIZEN_WEARABLE
50 #define VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT      "db/setting/network_with_lcd_off_limit"
51 #endif
52
53 #define WLAN_MAC_ADDRESS_FILEPATH   "/sys/class/net/wlan0/address"
54 #define WLAN_MAC_ADDR_MAX           20
55 #define VCONF_WIFI_BSSID_ADDRESS        "db/wifi/bssid_address"
56
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"
61
62 #define NETCONFIG_TECH_WAITING_INTERVAL 500
63 #define NETCONFIG_TECH_WAITING_COUNT 6
64
65 static gboolean connman_wifi_technology_state = FALSE;
66 static gboolean wifi_firmware_recovery_mode = FALSE;
67 static int airplane_mode = 0;
68
69 static gboolean __is_wifi_restricted(void)
70 {
71 #if defined TIZEN_WEARABLE
72         return FALSE;
73 #endif
74         int restricted_mode = 0;
75
76         netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted_mode);
77         if (restricted_mode != 0) {
78                 DBG("network restricted mode[%d]", restricted_mode);
79                 return TRUE;
80         }
81
82         return FALSE;
83 }
84
85 static void __technology_reply(GObject *source_object, GAsyncResult *res, gpointer user_data)
86 {
87         GVariant *reply;
88         GDBusConnection *conn = NULL;
89         GError *error = NULL;
90
91         conn = G_DBUS_CONNECTION(source_object);
92         reply = g_dbus_connection_call_finish(conn, res, &error);
93
94         if (reply == NULL) {
95                 if (error != NULL) {
96                         if (g_strstr_len(error->message, strlen(error->message),
97                                         CONNMAN_ERROR_INTERFACE ".AlreadyEnabled") != NULL) {
98                                 wifi_state_update_power_state(TRUE);
99                         } else if (g_strstr_len(error->message, strlen(error->message),
100                                         CONNMAN_ERROR_INTERFACE ".AlreadyDisabled") != NULL) {
101                                 wifi_state_update_power_state(FALSE);
102                         } else {
103                                 ERR("Fail to request status [%d: %s]", error->code, error->message);
104                                 wifi_state_update_power_state(FALSE);
105                         }
106                         g_error_free(error);
107                 } else {
108                         ERR("Fail to request status");
109                         wifi_state_update_power_state(FALSE);
110                 }
111         } else {
112                 DBG("Successfully requested");
113                 g_variant_unref(reply);
114         }
115
116         netconfig_gdbus_pending_call_unref();
117 }
118
119 static int __execute_supplicant(gboolean enable)
120 {
121         int rv = 0;
122         const char *path = WLAN_SUPPLICANT_SCRIPT;
123         char *const args_enable[] = { "/usr/bin/wpa_supp.sh", "start", NULL };
124         char *const args_disable[] = { "/usr/bin/wpa_supp.sh", "stop", NULL };
125         char *const envs[] = { NULL };
126         static gboolean enabled = FALSE;
127
128         if (enabled == enable)
129                 return -EALREADY;
130
131         if (enable == TRUE)
132                 rv = netconfig_execute_file(path, args_enable, envs);
133         else
134                 rv = netconfig_execute_file(path, args_disable, envs);
135         if (rv < 0)
136                 return -EIO;
137
138         DBG("wpa_supplicant %s", enable == TRUE ? "started" : "stopped");
139
140         enabled = enable;
141
142         return 0;
143 }
144
145 void netconfig_wifi_recover_firmware(void)
146 {
147         wifi_firmware_recovery_mode = TRUE;
148
149         netconfig_wifi_bgscan_stop();
150
151         wifi_power_off();
152 }
153
154 static int _load_driver_and_supplicant(void)
155 {
156         int err = 0;
157         wifi_tech_state_e tech_state;
158
159         tech_state = wifi_state_get_technology_state();
160         if (tech_state > NETCONFIG_WIFI_TECH_OFF)
161                 return -EALREADY;
162
163         err = __execute_supplicant(TRUE);
164         if (err < 0 && err != -EALREADY)
165                 return err;
166
167         err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, TRUE);
168         if (err < 0 && err != -EALREADY) {
169                 __execute_supplicant(FALSE);
170                 return err;
171         }
172
173         wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_WPS_ONLY);
174
175         return 0;
176 }
177
178 static int _remove_driver_and_supplicant(void)
179 {
180         int err = 0;
181
182         DBG("remove driver and supplicant");
183         if (wifi_firmware_recovery_mode != TRUE &&
184                                         netconfig_wifi_is_bssid_scan_started() == TRUE) {
185                 DBG("Wi-Fi WPS mode");
186                 return 0;
187         }
188
189         err = netconfig_wifi_firmware(NETCONFIG_WIFI_STA, FALSE);
190         if (err < 0 && err != -EALREADY)
191                 return err;
192
193         err = __execute_supplicant(FALSE);
194         if (err < 0 && err != -EALREADY)
195                 return err;
196
197         wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_OFF);
198
199         // reset service state
200         wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
201
202         if (wifi_firmware_recovery_mode == TRUE) {
203                 if (wifi_power_on() < 0)
204                         ERR("Failed to recover Wi-Fi firmware");
205
206                 wifi_firmware_recovery_mode = FALSE;
207         }
208
209         return 0;
210 }
211
212 static gboolean __check_and_set_technology_enable(gpointer data)
213 {
214         static int retry_count = NETCONFIG_TECH_WAITING_COUNT;
215         gboolean value_enable = TRUE;
216         gboolean reply = FALSE;
217         GVariant *params = NULL;
218         char key[] = "Powered";
219
220         if (wifi_state_is_technology_available() == FALSE) {
221                 retry_count--;
222                 if (retry_count > 0)
223                         return TRUE;
224         }
225
226         params = g_variant_new("(sv)", key, g_variant_new_boolean(value_enable));
227
228         reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
229                                         CONNMAN_WIFI_TECHNOLOGY_PREFIX,
230                                         CONNMAN_TECHNOLOGY_INTERFACE,
231                                         "SetProperty", params, __technology_reply);
232
233         if (reply != TRUE) {
234                 ERR("Fail to set technology enable");
235                 wifi_state_update_power_state(FALSE);
236
237                 retry_count = NETCONFIG_TECH_WAITING_COUNT;
238                 return FALSE;
239         }
240
241         retry_count = NETCONFIG_TECH_WAITING_COUNT;
242         return FALSE;
243 }
244
245 static int _set_connman_technology_power(gboolean enable)
246 {
247         gboolean reply = FALSE;
248         GVariant *params = NULL;
249         char key[] = "Powered";
250         gboolean value_enable = TRUE;
251         gboolean value_disable = FALSE;
252
253         if (connman_wifi_technology_state == enable)
254                 return -EALREADY;
255
256         if (enable && wifi_state_is_technology_available() == FALSE) {
257                 netconfig_start_timer(NETCONFIG_TECH_WAITING_INTERVAL,
258                                 __check_and_set_technology_enable, NULL, NULL);
259                 connman_wifi_technology_state = enable;
260                 return 0;
261         }
262
263         params = g_variant_new("(sv)", key, (enable == TRUE) ?
264                 g_variant_new_boolean(value_enable) : g_variant_new_boolean(value_disable));
265
266         reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
267                                         CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE,
268                                         "SetProperty", params, __technology_reply);
269
270         if (reply != TRUE) {
271                 ERR("Fail to set technology %s", enable == TRUE ? "enable" : "disable");
272                 return -ESRCH;
273         }
274
275         /* If Wi-Fi powered off,
276          * Do not remove Wi-Fi driver until ConnMan technology state updated
277          */
278         if (enable == TRUE)
279                 connman_wifi_technology_state = enable;
280
281         /* To be keep safe, early disable Wi-Fi tech state */
282         if (enable != TRUE)
283                 wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_WPS_ONLY);
284
285         return 0;
286 }
287
288 static void __netconfig_set_wifi_bssid(void)
289 {
290         int rv = 0;
291         char bssid[WLAN_MAC_ADDR_MAX];
292
293         FILE *fp = fopen(WLAN_MAC_ADDRESS_FILEPATH, "r");
294
295         if (fp == NULL) {
296                 ERR("Fail to open %s", WLAN_MAC_ADDRESS_FILEPATH);
297                 return;
298         }
299
300         fseek(fp, 0L, SEEK_SET);
301         rv = fscanf(fp, "%17s", bssid);
302
303         if (rv < 0)
304                 ERR("Fail to read bssid");
305
306         netconfig_set_vconf_str(VCONF_WIFI_BSSID_ADDRESS, bssid);
307
308         fclose(fp);
309 }
310
311 void netconfig_wifi_disable_technology_state_by_only_connman_signal(void)
312 {
313         /* Important: it's only done by ConnMan technology signal update */
314         connman_wifi_technology_state = FALSE;
315 }
316
317 #if defined TIZEN_WEARABLE
318 int netconfig_wifi_on_wearable(gboolean device_picker_test)
319 {
320         int err = 0;
321         int ps_mode;
322
323         if (netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ps_mode) < 0) {
324                 ERR("Fail to get VCONFKEY_SETAPPL_PSMODE");
325                 return -EIO;
326         }
327
328         if (ps_mode > SETTING_PSMODE_NORMAL) {
329                 WARN("ps mode is on(%d), Not turn on Wi-Fi", ps_mode);
330                 return -EPERM;
331         }
332
333         err = wifi_power_driver_and_supplicant(TRUE);
334         if (err < 0 && err != -EALREADY)
335                 return err;
336
337         err = _set_connman_technology_power(TRUE);
338
339         if (device_picker_test == TRUE)
340                 netconfig_wifi_enable_device_picker_test();
341
342         return err;
343 }
344 #else
345 static void __netconfig_wifi_restrict_mode(keynode_t *node, void *user_data)
346 {
347         int wifi_state = 0, restricted = 0;
348         int wifi_off_by_restricted = 0;
349
350         netconfig_vconf_get_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, &wifi_off_by_restricted);
351
352         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
353
354         if (node != NULL)
355                 restricted = vconf_keynode_get_bool(node);
356         else
357                 netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE, &restricted);
358
359         DBG("network restricted mode %s", restricted > 0 ? "ON" : "OFF");
360         DBG("Wi-Fi state %d, Wi-Fi was off by restricted mode %s", wifi_state,
361                         wifi_off_by_restricted ? "Yes" : "No");
362
363         if (restricted > 0) {
364                 /* network restricted on */
365                 if (wifi_state == VCONFKEY_WIFI_OFF)
366                         return;
367
368                 wifi_power_off();
369
370                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 1);
371         } else {
372                 /* network restricted off */
373                 if (!wifi_off_by_restricted)
374                         return;
375
376                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_RESTRICTED, 0);
377
378                 if (wifi_state > VCONFKEY_WIFI_OFF)
379                         return;
380
381                 wifi_power_on();
382         }
383 }
384 #endif
385
386 static void __netconfig_wifi_airplane_mode(keynode_t *node, void *user_data)
387 {
388         int wifi_state = 0, airplane_state = 0;
389         int wifi_off_by_airplane = 0;
390
391         netconfig_vconf_get_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, &wifi_off_by_airplane);
392         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
393
394         if (node != NULL)
395                 airplane_state = vconf_keynode_get_bool(node);
396         else
397                 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_state);
398
399         DBG("airplane mode %s (prev:%d)", airplane_state > 0 ? "ON" : "OFF", airplane_mode);
400         DBG("Wi-Fi state(or use) %d, Wi-Fi was off by flight mode %s", wifi_state,
401                         wifi_off_by_airplane ? "Yes" : "No");
402
403         if (airplane_mode == airplane_state)
404                 return ;
405
406         airplane_mode = airplane_state;
407
408         if (airplane_state > 0) {
409                 /* airplane mode on */
410                 if (wifi_state == VCONFKEY_WIFI_OFF)
411                         return;
412
413                 wifi_power_off();
414
415                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 1);
416         } else {
417                 /* airplane mode off */
418                 if (!wifi_off_by_airplane)
419                         return;
420
421                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0);
422                 if (wifi_state > VCONFKEY_WIFI_OFF)
423                         return;
424
425                 wifi_power_on();
426         }
427 }
428
429 static void __emergency_mode_changed_cb(keynode_t *node, void *user_data)
430 {
431         int wifi_state = 0, emergency = 0;
432         int wifi_off_by_emergency = 0;
433 #if !defined TIZEN_WEARABLE
434         int emergency_by_fmm = 0;
435 #endif
436         netconfig_vconf_get_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, &wifi_off_by_emergency);
437         netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
438
439 #if !defined TIZEN_WEARABLE
440         netconfig_vconf_get_bool(VCONFKEY_SETAPPL_NETWORK_PERMIT_WITH_LCD_OFF_LIMIT, &emergency_by_fmm);
441         DBG("emergency mode by Find My Mobile (%d)", emergency_by_fmm);
442         if (emergency_by_fmm == 1)
443                 return;
444 #endif
445
446         if (node != NULL)
447                 emergency = vconf_keynode_get_int(node);
448         else
449                 netconfig_vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &emergency);
450
451         DBG("emergency mode %s", emergency > SETTING_PSMODE_POWERFUL ? "ON" : "OFF");
452         DBG("Wi-Fi state %d, Wi-Fi was off by emergency mode %s", wifi_state, wifi_off_by_emergency ? "Yes" : "No");
453
454 #if defined TIZEN_WEARABLE
455         if (emergency == SETTING_PSMODE_WEARABLE) {
456                 /* basic power saving mode on */
457         } else if (emergency == SETTING_PSMODE_WEARABLE_ENHANCED) {
458                 /* enhanced power saving mode on */
459                 if (wifi_state == VCONFKEY_WIFI_OFF)
460                         return;
461
462                 wifi_power_off();
463                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1);
464         } else {
465                 /* power saving mode off */
466                 if (!wifi_off_by_emergency)
467                         return;
468
469                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0);
470                 if (wifi_state > VCONFKEY_WIFI_OFF)
471                         return;
472
473                 wifi_power_on_wearable(TRUE);
474         }
475 #else
476         if (emergency > SETTING_PSMODE_POWERFUL) {
477                 /* emergency mode on */
478                 if (wifi_state == VCONFKEY_WIFI_OFF)
479                         return;
480
481                 wifi_power_off();
482
483                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 1);
484         } else {
485                 /* emergency mode off */
486                 if (!wifi_off_by_emergency)
487                         return;
488
489                 netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_EMERGENCY, 0);
490
491                 if (wifi_state > VCONFKEY_WIFI_OFF)
492                         return;
493
494                 wifi_power_on();
495         }
496 #endif
497
498 }
499
500 static void __pm_state_changed_cb(keynode_t* node, void* user_data)
501 {
502         int new_state = -1;
503         int wifi_state = 0;
504         static int prev_state = VCONFKEY_PM_STATE_NORMAL;
505
506         if (netconfig_vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) < 0) {
507                 ERR("Fail to get VCONFKEY_WIFI_STATE");
508                 return;
509         }
510
511         /* PM state
512          *      VCONFKEY_PM_STATE_NORMAL = 1,
513          *      VCONFKEY_PM_STATE_LCDDIM,
514          *      VCONFKEY_PM_STATE_LCDOFF,
515          *      VCONFKEY_PM_STATE_SLEEP
516          */
517         if (node != NULL)
518                 new_state = vconf_keynode_get_int(node);
519         else
520                 netconfig_vconf_get_int(VCONFKEY_PM_STATE, &new_state);
521
522         DBG("wifi state: %d (0 off / 1 on / 2 connected)", wifi_state);
523         DBG("Old PM state: %d, current: %d (1 normal / 2 lcddim / 3 lcdoff / 4 sleep)", prev_state, new_state);
524
525         if ((new_state == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) {
526                 netconfig_wifi_bgscan_stop();
527                 netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
528                 netconfig_wifi_bgscan_start(TRUE);
529         }
530
531         prev_state = new_state;
532 }
533
534 static void __netconfig_telephony_ready_changed_cb(keynode_t * node, void *data)
535 {
536         int telephony_ready = 0;
537
538         if (node != NULL)
539                 telephony_ready = vconf_keynode_get_bool(node);
540         else
541                 netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
542
543         if (telephony_ready != 0) {
544                 if (netconfig_tapi_check_sim_state() == FALSE) {
545                         DBG("Sim is not initialized yet.");
546
547                         goto done;
548                 }
549         } else
550                 return;
551
552         DBG("Turn Wi-Fi on automatically");
553
554 #if defined TIZEN_WEARABLE
555         wifi_power_on_wearable(TRUE);
556 #else
557         wifi_power_on();
558 #endif
559
560 done:
561         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY, __netconfig_telephony_ready_changed_cb);
562 }
563
564 int wifi_power_driver_and_supplicant(gboolean enable)
565 {
566         /* There are 3 thumb rules for Wi-Fi power management
567          *   1. Do not make exposed API to control wpa_supplicant and driver directly.
568          *      It probably breaks ConnMan technology operation.
569          *
570          *   2. Do not remove driver and wpa_supplicant if ConnMan already enabled.
571          *      It breaks ConnMan technology operation.
572          *
573          *   3. Final the best rule: make it as simple as possible.
574          *      Simple code enables easy maintenance and reduces logical errors.
575          */
576         if (enable == TRUE) {
577                 return _load_driver_and_supplicant();
578         } else {
579                 if (connman_wifi_technology_state == TRUE)
580                         return -ENOSYS;
581
582                 return _remove_driver_and_supplicant();
583         }
584 }
585
586 void wifi_power_disable_technology_state_by_only_connman_signal(void)
587 {
588         /* Important: it's only done by ConnMan technology signal update */
589         connman_wifi_technology_state = FALSE;
590 }
591
592 void wifi_power_recover_firmware(void)
593 {
594         wifi_firmware_recovery_mode = TRUE;
595
596         netconfig_wifi_bgscan_stop();
597
598         wifi_power_off();
599 }
600
601 int wifi_power_on(void)
602 {
603         int err = 0;
604         wifi_tech_state_e tech_state;
605
606         tech_state = wifi_state_get_technology_state();
607         if (tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
608                 /* There can be a scenario where wifi is automatically *
609                  * activated by connman if wifi was powered in last boot. *
610                  * So we should update connman_wifi_technology_state variable *
611                  * if it is found that wifi_tech_state variable is *
612                  * NETCONFIG_WIFI_TECH_POWERED and connman_wifi_technology_state *
613                  * variable is FALSE. Earlier connman_wifi_technology_state *
614                  * variable was only updated when wifi was Powered on from *
615                  * net-config resulting in variable not getting updated. *
616                  * This caused wifi to not get deactivated after reboot if *
617                  * last power state was activated */
618                 ERR("Net-Config WiFi connman technology state %d",
619                                 connman_wifi_technology_state);
620                 if (connman_wifi_technology_state == FALSE)
621                         connman_wifi_technology_state = TRUE;
622                 return -EALREADY;
623         }
624
625         if (__is_wifi_restricted() == TRUE)
626                 return -EPERM;
627
628         if (netconfig_is_wifi_tethering_on() == TRUE) {
629                 /* TODO: Wi-Fi tethering turns off here */
630                 /* return TRUE; */
631                 ERR("Failed to turn tethering off");
632                 return -EBUSY;
633         }
634
635         err = wifi_power_driver_and_supplicant(TRUE);
636         if (err < 0 && err != -EALREADY)
637                 return err;
638
639         err = _set_connman_technology_power(TRUE);
640
641         return err;
642 }
643
644 int wifi_power_off(void)
645 {
646         int err;
647
648         err = _set_connman_technology_power(FALSE);
649         if (err == -EALREADY)
650                 wifi_state_update_power_state(FALSE);
651
652         return 0;
653 }
654
655 #if defined TIZEN_WEARABLE
656 int wifi_power_on_wearable(gboolean device_picker_test)
657 {
658         int err = 0;
659         wifi_tech_state_e tech_state;
660
661         tech_state = wifi_state_get_technology_state();
662         if (tech_state >= NETCONFIG_WIFI_TECH_POWERED)
663                 return -EALREADY;
664
665         err = wifi_power_driver_and_supplicant(TRUE);
666         if (err < 0 && err != -EALREADY)
667                 return err;
668
669         err = _set_connman_technology_power(TRUE);
670
671         if (device_picker_test == TRUE)
672                 netconfig_wifi_enable_device_picker_test();
673
674         return err;
675 }
676 #endif
677
678 void wifi_power_initialize(void)
679 {
680         int wifi_last_power_state = 0;
681
682         /* Initialize Airplane mode */
683         netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &airplane_mode);
684         DBG("Airplane[%s]", airplane_mode > 0 ? "ON" : "OFF");
685
686         /* Update the last Wi-Fi power state */
687         netconfig_vconf_get_int(VCONF_WIFI_LAST_POWER_STATE, &wifi_last_power_state);
688         if (wifi_last_power_state > VCONFKEY_WIFI_OFF) {
689                 if (TIZEN_TELEPHONY_ENABLE) {
690                         int telephony_ready = 0;
691                         netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_READY, &telephony_ready);
692                         if (telephony_ready == 0) {
693                                 DBG("Telephony API is not initialized yet");
694                                 vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY,
695                                                 __netconfig_telephony_ready_changed_cb, NULL);
696                         } else {
697                                 if (netconfig_tapi_check_sim_state() == FALSE)
698                                         DBG("SIM is not initialized yet");
699                         }
700                 }
701                 DBG("Turn Wi-Fi on automatically");
702 #if defined TIZEN_WEARABLE
703                 wifi_power_on_wearable(TRUE);
704 #else
705                 wifi_power_on();
706 #endif
707         }
708
709 #if defined TIZEN_WEARABLE
710         vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
711                         __netconfig_wifi_airplane_mode, NULL);
712 #else
713         vconf_notify_key_changed(VCONFKEY_SETAPPL_NETWORK_RESTRICT_MODE,
714                         __netconfig_wifi_restrict_mode, NULL);
715         vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
716                         __netconfig_wifi_airplane_mode, NULL);
717 #endif
718
719         vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, __emergency_mode_changed_cb, NULL);
720         vconf_notify_key_changed(VCONFKEY_PM_STATE, __pm_state_changed_cb, NULL);
721 }
722
723 void wifi_power_deinitialize(void)
724 {
725 }
726
727 gboolean handle_load_driver(Wifi *wifi,
728                 GDBusMethodInvocation *context, gboolean device_picker_test)
729 {
730         int err;
731
732         DBG("Wi-Fi power on requested");
733
734         g_return_val_if_fail(wifi != NULL, TRUE);
735
736         if (!netconfig_dpm_update_from_wifi()) {
737                 DBG("DPM policy restricts Wi-Fi");
738                 netconfig_error_permission_denied(context);
739                 return TRUE;
740         }
741
742         if (TIZEN_WLAN_BOARD_SPRD)
743                 wifi_firmware_download();
744
745 #if defined TIZEN_WEARABLE
746         err = wifi_power_on_wearable(device_picker_test);
747 #else
748         err = wifi_power_on();
749
750         if (device_picker_test == TRUE)
751                 netconfig_wifi_enable_device_picker_test();
752 #endif
753         if (err < 0) {
754                 if (err == -EALREADY)
755                         netconfig_error_already_exists(context);
756                 else if (err == -EPERM)
757                         netconfig_error_permission_denied(context);
758                 else
759                         netconfig_error_wifi_driver_failed(context);
760
761                 return TRUE;
762         }
763
764
765         netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0);
766         __netconfig_set_wifi_bssid();
767
768         wifi_complete_load_driver(wifi, context);
769         return TRUE;
770 }
771
772 gboolean handle_remove_driver(Wifi *wifi, GDBusMethodInvocation *context)
773 {
774         int err;
775
776         DBG("Wi-Fi power off requested");
777
778         g_return_val_if_fail(wifi != NULL, TRUE);
779
780         err = wifi_power_off();
781         if (err < 0) {
782                 if (err == -EINPROGRESS)
783                         netconfig_error_inprogress(context);
784                 else if (err == -EALREADY)
785                         netconfig_error_already_exists(context);
786                 else if (err == -EPERM)
787                         netconfig_error_permission_denied(context);
788                 else
789                         netconfig_error_wifi_driver_failed(context);
790                 return TRUE;
791         }
792
793         netconfig_set_vconf_int(VCONF_WIFI_OFF_STATE_BY_AIRPLANE, 0);
794
795         wifi_complete_remove_driver(wifi, context);
796         return TRUE;
797 }
798
799 gboolean handle_load_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
800 {
801         ERR("Deprecated");
802
803         wifi_complete_load_p2p_driver(wifi, context);
804         return TRUE;
805 }
806
807 gboolean handle_remove_p2p_driver(Wifi *wifi, GDBusMethodInvocation *context)
808 {
809         ERR("Deprecated");
810
811         wifi_complete_remove_p2p_driver(wifi, context);
812         return TRUE;
813 }
814
815 static int __netconfig_get_random_mac(unsigned char *mac_buf, int mac_len)
816 {
817         DBG("Generate Random Mac address of ethernet");
818         FILE *fp;
819         int rc;
820
821         fp = fopen(OS_RANDOM_FILE, "rb");
822
823         if (fp == NULL) {
824                 ERR("Could not open /dev/urandom");
825                 return -1;
826         }
827         rc = fread(mac_buf, 1, mac_len, fp);
828         if (fp)
829                 fclose(fp);
830
831         return rc != mac_len ? -1 : 0;
832 }
833
834 void __netconfig_set_ether_macaddr()
835 {
836         DBG("Set wired Mac address ");
837         char *mac_addr = NULL;
838         char rand_addr[WLAN_MAC_ADDR_MAX];
839         int rv = -1;
840
841         mac_addr = vconf_get_str(VCONF_ETH_MAC_ADDRESS);
842         if (mac_addr == NULL) {
843                 DBG("vconf_get_str Failed\n");
844                 return;
845         }
846         /* Checking Invalid MAC Address */
847         if ((strlen(mac_addr) == 0)) {
848                 ERR("Failed to get valid MAC Address from vconf");
849                 /*Generate the Random Mac address*/
850                 unsigned char rand_mac_add[ETH_MAC_ADDR_SIZE+1];
851
852                 if (__netconfig_get_random_mac(rand_mac_add, ETH_MAC_ADDR_SIZE) == -1) {
853
854                         ERR("Could not generate the Random Mac address");
855                         free(mac_addr);
856                         return;
857                 }
858
859                 rand_mac_add[0] &= 0xFE; /*Clear multicase bit*/
860                 rand_mac_add[0] |= 0x02; /*set local assignment bit*/
861
862                 /*Set the Mac address in Vconf*/
863                 snprintf(rand_addr, WLAN_MAC_ADDR_MAX, "%x:%x:%x:%x:%x:%x",
864                                 rand_mac_add[0], rand_mac_add[1],
865                                 rand_mac_add[2], rand_mac_add[3],
866                                 rand_mac_add[4], rand_mac_add[5]);
867
868                 netconfig_set_vconf_str(VCONF_ETH_MAC_ADDRESS, rand_addr);
869         } else { /* Valid MAC address */
870                 g_strlcpy(rand_addr, mac_addr, WLAN_MAC_ADDR_MAX);
871         }
872
873         DBG("MAC Address of eth0 [%s]", rand_addr);
874         const char *path = NET_EXEC_PATH;
875         char *const args[] = { "/sbin/ifconfig", "eth0", "hw",
876                 "ether", rand_addr, "up", NULL};
877         char *const envs[] = { NULL };
878         rv = netconfig_execute_file(path, args, envs);
879
880         if (rv < 0)
881                 ERR("Unable to execute system command");
882         free(mac_addr);
883
884 }