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