85838658b7a7b183e4a1b00ddcbb3fd297f7f4f5
[platform/core/connectivity/net-config.git] / src / wifi-firmware.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
24 #include "log.h"
25 #include "util.h"
26 #include "netdbus.h"
27 #include "emulator.h"
28 #include "neterror.h"
29 #include "netsupplicant.h"
30 #include "wifi-firmware.h"
31 #include "network-statistics.h"
32 #if defined WLAN_CHECK_POWERSAVE
33 #include "wifi-powersave.h"
34 #endif
35
36 #define WLAN_DRIVER_SCRIPT                      "/usr/bin/wlan.sh"
37 #define WLAN_IFACE_NAME                         "wlan0"
38 #define WLAN_P2P_IFACE_NAME                     "p2p0"
39
40 static int __netconfig_sta_firmware_start(void)
41 {
42         int rv = 0;
43         const char *path = WLAN_DRIVER_SCRIPT;
44         char *const args[] = { "/usr/bin/wlan.sh", "start", NULL };
45         char *const envs[] = { NULL };
46
47         rv = netconfig_execute_file(path, args, envs);
48         if (rv < 0)
49                 return -EIO;
50
51         rv = netconfig_interface_up(WLAN_IFACE_NAME);
52         if (rv != TRUE)
53                 return -EIO;
54
55         DBG("Successfully loaded wireless device driver");
56         return 0;
57 }
58
59 static int __netconfig_sta_firmware_stop(void)
60 {
61         int rv = 0;
62         const char *path = WLAN_DRIVER_SCRIPT;
63         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
64         char *const envs[] = { NULL };
65
66         /* Update statistics before driver remove */
67         netconfig_wifi_statistics_update_powered_off();
68
69         rv = netconfig_interface_down(WLAN_IFACE_NAME);
70         if (rv != TRUE)
71                 return -EIO;
72
73         rv = netconfig_execute_file(path, args, envs);
74         if (rv < 0)
75                 return -EIO;
76
77         DBG("Successfully removed wireless device driver");
78         return 0;
79 }
80
81 static int __netconfig_p2p_firmware_start(void)
82 {
83 #if defined TIZEN_P2P_ENABLE
84         int rv = 0;
85         const char *path = WLAN_DRIVER_SCRIPT;
86         char *const args[] = { "/usr/bin/wlan.sh", "p2p", NULL };
87         char *const envs[] = { NULL };
88
89         rv = netconfig_execute_file(path, args, envs);
90         if (rv < 0)
91                 return -EIO;
92
93         rv = netconfig_interface_up(WLAN_IFACE_NAME);
94         if (rv != TRUE)
95                 return -EIO;
96
97 #if defined TIZEN_WLAN_USE_P2P_INTERFACE
98         rv = netconfig_interface_up(WLAN_P2P_IFACE_NAME);
99         if (rv != TRUE)
100                 return -EIO;
101 #endif
102
103         DBG("Successfully loaded p2p device driver");
104         return 0;
105 #else
106         return -ENODEV;
107 #endif
108 }
109
110 static int __netconfig_p2p_firmware_stop(void)
111 {
112 #if defined TIZEN_P2P_ENABLE
113         int rv = 0;
114         const char *path = WLAN_DRIVER_SCRIPT;
115         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
116         char *const envs[] = { NULL };
117
118         rv = netconfig_interface_down(WLAN_IFACE_NAME);
119         if (rv != TRUE)
120                 return -EIO;
121
122         rv = netconfig_execute_file(path, args, envs);
123         if (rv < 0)
124                 return -EIO;
125
126         DBG("Successfully removed p2p device driver");
127         return 0;
128 #else
129         return -ENODEV;
130 #endif
131 }
132
133 static int __netconfig_softap_firmware_start(void)
134 {
135 #if defined TIZEN_TETHERING_ENABLE
136         int rv = 0;
137         const char *path = WLAN_DRIVER_SCRIPT;
138         char *const args[] = { "/usr/bin/wlan.sh", "softap", NULL };
139         char *const envs[] = { NULL };
140
141         rv = netconfig_execute_file(path, args, envs);
142         if (rv < 0)
143                 return -EIO;
144
145         if (netconfig_interface_up(WLAN_IFACE_NAME) == FALSE)
146                 return -EIO;
147
148         DBG("Successfully loaded softap device driver");
149         return 0;
150 #else
151         return -ENODEV;
152 #endif
153 }
154
155 static int __netconfig_softap_firmware_stop(void)
156 {
157 #if defined TIZEN_TETHERING_ENABLE
158         int rv = 0;
159         const char *path = WLAN_DRIVER_SCRIPT;
160         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
161         char *const envs[] = { NULL };
162
163         rv = netconfig_interface_down(WLAN_IFACE_NAME);
164         if (rv != TRUE)
165                 return -EIO;
166
167         rv = netconfig_execute_file(path, args, envs);
168         if (rv < 0)
169                 return -EIO;
170
171         DBG("Successfully removed softap device driver");
172         return 0;
173 #else
174         return -ENODEV;
175 #endif
176 }
177
178 static int __netconfig_wifi_firmware_start(enum netconfig_wifi_firmware type)
179 {
180         if (netconfig_emulator_is_emulated() == TRUE)
181                 return -EIO;
182
183         switch (type) {
184         case NETCONFIG_WIFI_STA:
185                 return __netconfig_sta_firmware_start();
186         case NETCONFIG_WIFI_P2P:
187                 return __netconfig_p2p_firmware_start();
188         case NETCONFIG_WIFI_SOFTAP:
189                 return __netconfig_softap_firmware_start();
190         default:
191                 break;
192         }
193
194         return -ENXIO;
195 }
196
197 static int __netconfig_wifi_firmware_stop(enum netconfig_wifi_firmware type)
198 {
199         if (netconfig_emulator_is_emulated() == TRUE)
200                 return -EIO;
201
202         switch (type) {
203         case NETCONFIG_WIFI_STA:
204                 return __netconfig_sta_firmware_stop();
205         case NETCONFIG_WIFI_P2P:
206                 return __netconfig_p2p_firmware_stop();
207         case NETCONFIG_WIFI_SOFTAP:
208                 return __netconfig_softap_firmware_stop();
209         default:
210                 break;
211         }
212
213         return -ENXIO;
214 }
215
216 int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
217 {
218         int err;
219         static enum netconfig_wifi_firmware current_driver = NETCONFIG_WIFI_OFF;
220         enum netconfig_wifi_firmware alias = type;
221
222 #if defined WLAN_CONCURRENT_MODE
223         int flight_mode = 0;
224
225         if (type == NETCONFIG_WIFI_P2P)
226                 alias = NETCONFIG_WIFI_STA;
227 #endif
228
229         DBG("Wi-Fi current firmware %d (type: %d %s)", current_driver, type,
230                                                         enable == TRUE ? "enable" : "disable");
231
232         if (enable == FALSE) {
233                 if (current_driver == NETCONFIG_WIFI_OFF) {
234                         return -EALREADY;
235                 } else if (current_driver == alias) {
236 #if defined WLAN_CHECK_POWERSAVE
237                         if (type == NETCONFIG_WIFI_STA &&
238                                         netconfig_wifi_is_powersave_mode() == TRUE) {
239                                 netconfig_interface_down(WIFI_IFNAME);
240
241                                 return -EALREADY;
242                         }
243 #endif
244
245 #if defined WLAN_CONCURRENT_MODE
246 #if defined TIZEN_TELEPHONY_ENABLE
247                         vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &flight_mode);
248 #endif
249                         if (flight_mode == 0 && type == NETCONFIG_WIFI_STA &&
250                                         netconfig_is_wifi_direct_on() == TRUE) {
251                                 netconfig_interface_down(WIFI_IFNAME);
252
253                                 return -EALREADY;
254                         }
255
256                         if (type == NETCONFIG_WIFI_P2P &&
257                                         netconfig_wifi_state_get_technology_state() >
258                                                 NETCONFIG_WIFI_TECH_OFF) {
259                                 netconfig_interface_down(WLAN_P2P_IFACE_NAME);
260
261                                 return -EALREADY;
262                         }
263 #endif
264                         err = __netconfig_wifi_firmware_stop(type);
265                         if (err < 0 && err != -EALREADY)
266                                 return err;
267
268                         current_driver = NETCONFIG_WIFI_OFF;
269
270                         return err;
271                 }
272
273                 return -EIO;
274         }
275
276         if (current_driver > NETCONFIG_WIFI_OFF) {
277                 if (current_driver == alias) {
278 #if defined WLAN_CHECK_POWERSAVE
279                         if (type == NETCONFIG_WIFI_STA &&
280                                         netconfig_wifi_is_powersave_mode() == TRUE) {
281                                 netconfig_interface_up(WIFI_IFNAME);
282
283                                 return -EALREADY;
284                         }
285 #endif
286
287 #if defined WLAN_CONCURRENT_MODE
288                         if (type == NETCONFIG_WIFI_STA)
289                                 netconfig_interface_up(WIFI_IFNAME);
290 #if defined TIZEN_P2P_ENABLE
291                         else if (type == NETCONFIG_WIFI_P2P)
292                                 netconfig_interface_up(WLAN_P2P_IFACE_NAME);
293 #endif
294 #endif
295                         return -EALREADY;
296                 }
297
298                 return -EIO;
299         }
300
301         err = __netconfig_wifi_firmware_start(type);
302         if (err < 0)
303                 DBG("Failed to execute script file");
304         else
305                 current_driver = alias;
306
307         return err;
308 }
309
310 gboolean handle_start(WifiFirmware *firmware, GDBusMethodInvocation *context, const gchar *device)
311 {
312         int err;
313
314         g_return_val_if_fail(firmware != NULL, FALSE);
315
316         DBG("Wi-Fi firmware start %s", device != NULL ? device : "null");
317
318         if (g_strcmp0("p2p", device) == 0)
319                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, TRUE);
320         else if (g_strcmp0("softap", device) == 0)
321                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, TRUE);
322         else
323                 err = -EINVAL;
324
325         if (err < 0) {
326                 if (err == -EALREADY)
327                         netconfig_error_already_exists(context);
328                 else
329                         netconfig_error_wifi_driver_failed(context);
330
331                 wifi_firmware_complete_start(firmware, context);
332                 return FALSE;
333         }
334
335         wifi_firmware_complete_start(firmware, context);
336         return TRUE;
337 }
338
339 gboolean handle_stop(WifiFirmware *firmware, GDBusMethodInvocation *context, const gchar *device)
340 {
341         int err;
342
343         g_return_val_if_fail(firmware != NULL, FALSE);
344
345         DBG("Wi-Fi firmware stop %s", device != NULL ? device : "null");
346
347         if (g_strcmp0("p2p", device) == 0)
348                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, FALSE);
349         else if (g_strcmp0("softap", device) == 0)
350                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, FALSE);
351         else
352                 err = -EINVAL;
353
354         if (err < 0) {
355                 if (err == -EALREADY)
356                         netconfig_error_already_exists(context);
357                 else
358                         netconfig_error_wifi_driver_failed(context);
359
360                 wifi_firmware_complete_start(firmware, context);
361                 return FALSE;
362         }
363
364         wifi_firmware_complete_start(firmware, context);
365         return TRUE;
366 }