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