Revert: [TNEXT-136] Check model name for wlan driver
[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
33 #define WLAN_DRIVER_SCRIPT                      "/usr/bin/wlan.sh"
34 #define WLAN_IFACE_NAME                         "wlan0"
35
36 #define WLAN_P2P_IFACE_NAME_TV                  "p2p0"
37 #define WLAN_P2P_IFACE_NAME_COMMON                      "wlan0"
38 #define WLAN_P2P_IFACE_NAME ((TIZEN_TV) ? (WLAN_P2P_IFACE_NAME_TV) : (WLAN_P2P_IFACE_NAME_COMMON))
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 #if defined TIZEN_WLAN_USE_P2P_INTERFACE
94         rv = netconfig_interface_up(WLAN_P2P_IFACE_NAME);
95         if (rv != TRUE)
96                 return -EIO;
97 #endif
98
99         DBG("Successfully loaded p2p device driver");
100         return 0;
101 #else
102         return -ENODEV;
103 #endif
104 }
105
106 static int __netconfig_p2p_firmware_stop(void)
107 {
108 #if defined TIZEN_P2P_ENABLE
109         int rv = 0;
110         const char *path = WLAN_DRIVER_SCRIPT;
111         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
112         char *const envs[] = { NULL };
113
114         rv = netconfig_interface_down(WLAN_IFACE_NAME);
115         if (rv != TRUE)
116                 return -EIO;
117
118         rv = netconfig_execute_file(path, args, envs);
119         if (rv < 0)
120                 return -EIO;
121
122         DBG("Successfully removed p2p device driver");
123         return 0;
124 #else
125         return -ENODEV;
126 #endif
127 }
128
129 static int __netconfig_softap_firmware_start(void)
130 {
131 #if defined TIZEN_TETHERING_ENABLE
132         int rv = 0;
133         const char *path = WLAN_DRIVER_SCRIPT;
134         char *const args[] = { "/usr/bin/wlan.sh", "softap", NULL };
135         char *const envs[] = { NULL };
136
137         rv = netconfig_execute_file(path, args, envs);
138         if (rv < 0)
139                 return -EIO;
140
141         if (netconfig_interface_up(WLAN_IFACE_NAME) == FALSE)
142                 return -EIO;
143
144         DBG("Successfully loaded softap device driver");
145         return 0;
146 #else
147         return -ENODEV;
148 #endif
149 }
150
151 static int __netconfig_softap_firmware_stop(void)
152 {
153 #if defined TIZEN_TETHERING_ENABLE
154         int rv = 0;
155         const char *path = WLAN_DRIVER_SCRIPT;
156         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
157         char *const envs[] = { NULL };
158
159         rv = netconfig_interface_down(WLAN_IFACE_NAME);
160         if (rv != TRUE)
161                 return -EIO;
162
163         rv = netconfig_execute_file(path, args, envs);
164         if (rv < 0)
165                 return -EIO;
166
167         DBG("Successfully removed softap device driver");
168         return 0;
169 #else
170         return -ENODEV;
171 #endif
172 }
173
174 static int __netconfig_wifi_firmware_start(enum netconfig_wifi_firmware type)
175 {
176         if (emulator_is_emulated() == TRUE)
177                 return -EIO;
178
179         switch (type) {
180         case NETCONFIG_WIFI_STA:
181                 return __netconfig_sta_firmware_start();
182         case NETCONFIG_WIFI_P2P:
183                 return __netconfig_p2p_firmware_start();
184         case NETCONFIG_WIFI_SOFTAP:
185                 return __netconfig_softap_firmware_start();
186         default:
187                 break;
188         }
189
190         return -ENXIO;
191 }
192
193 static int __netconfig_wifi_firmware_stop(enum netconfig_wifi_firmware type)
194 {
195         if (emulator_is_emulated() == TRUE)
196                 return -EIO;
197
198         switch (type) {
199         case NETCONFIG_WIFI_STA:
200                 return __netconfig_sta_firmware_stop();
201         case NETCONFIG_WIFI_P2P:
202                 return __netconfig_p2p_firmware_stop();
203         case NETCONFIG_WIFI_SOFTAP:
204                 return __netconfig_softap_firmware_stop();
205         default:
206                 break;
207         }
208
209         return -ENXIO;
210 }
211
212 int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
213 {
214         int err;
215         static enum netconfig_wifi_firmware current_driver = NETCONFIG_WIFI_OFF;
216         enum netconfig_wifi_firmware alias = type;
217
218 #if defined WLAN_CONCURRENT_MODE
219         int flight_mode = 0;
220
221         if (type == NETCONFIG_WIFI_P2P)
222                 alias = NETCONFIG_WIFI_STA;
223 #endif
224
225         DBG("Wi-Fi current firmware %d (type: %d %s)", current_driver, type,
226                                                         enable == TRUE ? "enable" : "disable");
227
228         if (enable == FALSE) {
229                 if (current_driver == NETCONFIG_WIFI_OFF) {
230                         return -EALREADY;
231                 } else if (current_driver == alias) {
232
233 #if defined WLAN_CONCURRENT_MODE
234                         netconfig_vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &flight_mode);
235                         if (flight_mode == 0 && type == NETCONFIG_WIFI_STA &&
236                                         netconfig_is_wifi_direct_on() == TRUE) {
237                                 netconfig_interface_down(WIFI_IFNAME);
238
239                                 return -EALREADY;
240                         }
241
242                         if (type == NETCONFIG_WIFI_P2P && wifi_state_get_technology_state() > NETCONFIG_WIFI_TECH_OFF) {
243                                 netconfig_interface_down(WLAN_P2P_IFACE_NAME);
244
245                                 return -EALREADY;
246                         }
247 #endif
248                         err = __netconfig_wifi_firmware_stop(type);
249                         if (err < 0 && err != -EALREADY)
250                                 return err;
251
252                         current_driver = NETCONFIG_WIFI_OFF;
253
254                         return err;
255                 }
256
257                 return -EIO;
258         }
259
260         if (current_driver > NETCONFIG_WIFI_OFF) {
261                 if (current_driver == alias) {
262
263 #if defined WLAN_CONCURRENT_MODE
264                         if (type == NETCONFIG_WIFI_STA)
265                                 netconfig_interface_up(WIFI_IFNAME);
266 #if defined TIZEN_P2P_ENABLE
267                         else if (type == NETCONFIG_WIFI_P2P)
268                                 netconfig_interface_up(WLAN_P2P_IFACE_NAME);
269 #endif
270 #endif
271                         return -EALREADY;
272                 }
273
274                 return -EIO;
275         }
276
277         err = __netconfig_wifi_firmware_start(type);
278         if (err < 0)
279                 DBG("Failed to execute script file");
280         else
281                 current_driver = alias;
282
283         return err;
284 }
285
286 gboolean handle_start(WifiFirmware *firmware, GDBusMethodInvocation *context, const gchar *device)
287 {
288         int err;
289
290         g_return_val_if_fail(firmware != NULL, FALSE);
291
292         DBG("Wi-Fi firmware start %s", device != NULL ? device : "null");
293
294         if (g_strcmp0("p2p", device) == 0)
295                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, TRUE);
296         else if (g_strcmp0("softap", device) == 0)
297                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, TRUE);
298         else
299                 err = -EINVAL;
300
301         if (err < 0) {
302                 if (err == -EALREADY)
303                         netconfig_error_already_exists(context);
304                 else if (g_strcmp0("softap", device) == 0 && err == -EIO && netconfig_is_wifi_direct_on() == FALSE) {
305                         if (netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, FALSE) == 0 && netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, TRUE) == 0) {
306                                 wifi_firmware_complete_start(firmware, context);
307                                 return TRUE;
308                         } else
309                                 netconfig_error_wifi_driver_failed(context);
310                 } else
311                         netconfig_error_wifi_driver_failed(context);
312
313                 return FALSE;
314         }
315
316         wifi_firmware_complete_start(firmware, context);
317         return TRUE;
318 }
319
320 gboolean handle_stop(WifiFirmware *firmware, GDBusMethodInvocation *context, const gchar *device)
321 {
322         int err;
323
324         g_return_val_if_fail(firmware != NULL, FALSE);
325
326         DBG("Wi-Fi firmware stop %s", device != NULL ? device : "null");
327
328         if (g_strcmp0("p2p", device) == 0)
329                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, FALSE);
330         else if (g_strcmp0("softap", device) == 0)
331                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, FALSE);
332         else
333                 err = -EINVAL;
334
335         if (err < 0) {
336                 if (err == -EALREADY)
337                         netconfig_error_already_exists(context);
338                 else
339                         netconfig_error_wifi_driver_failed(context);
340
341                 return FALSE;
342         }
343
344         wifi_firmware_complete_stop(firmware, context);
345         return TRUE;
346 }