2195913052e2ae8d33701fa94026d2d8e28c7b9d
[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 (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
84                 return -ENODEV;
85
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 }
104
105 static int __netconfig_p2p_firmware_stop(void)
106 {
107         if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
108                 return -ENODEV;
109
110         int rv = 0;
111         const char *path = WLAN_DRIVER_SCRIPT;
112         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
113         char *const envs[] = { NULL };
114
115         rv = netconfig_interface_down(WLAN_IFACE_NAME);
116         if (rv != TRUE)
117                 return -EIO;
118
119         rv = netconfig_execute_file(path, args, envs);
120         if (rv < 0)
121                 return -EIO;
122
123         DBG("Successfully removed p2p device driver");
124         return 0;
125 }
126
127 static int __netconfig_softap_firmware_start(void)
128 {
129         if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING))
130                 return -ENODEV;
131
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 }
147
148 static int __netconfig_softap_firmware_stop(void)
149 {
150         if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING))
151                 return -ENODEV;
152
153         int rv = 0;
154         const char *path = WLAN_DRIVER_SCRIPT;
155         char *const args[] = { "/usr/bin/wlan.sh", "stop", NULL };
156         char *const envs[] = { NULL };
157
158         rv = netconfig_interface_down(WLAN_IFACE_NAME);
159         if (rv != TRUE)
160                 return -EIO;
161
162         rv = netconfig_execute_file(path, args, envs);
163         if (rv < 0)
164                 return -EIO;
165
166         DBG("Successfully removed softap device driver");
167         return 0;
168 }
169
170 static int __netconfig_wifi_firmware_start(enum netconfig_wifi_firmware type)
171 {
172         if (emulator_is_emulated() == TRUE)
173                 return -EIO;
174
175         switch (type) {
176         case NETCONFIG_WIFI_STA:
177                 return __netconfig_sta_firmware_start();
178         case NETCONFIG_WIFI_P2P:
179                 return __netconfig_p2p_firmware_start();
180         case NETCONFIG_WIFI_SOFTAP:
181                 return __netconfig_softap_firmware_start();
182         default:
183                 break;
184         }
185
186         return -ENXIO;
187 }
188
189 static int __netconfig_wifi_firmware_stop(enum netconfig_wifi_firmware type)
190 {
191         if (emulator_is_emulated() == TRUE)
192                 return -EIO;
193
194         switch (type) {
195         case NETCONFIG_WIFI_STA:
196                 return __netconfig_sta_firmware_stop();
197         case NETCONFIG_WIFI_P2P:
198                 return __netconfig_p2p_firmware_stop();
199         case NETCONFIG_WIFI_SOFTAP:
200                 return __netconfig_softap_firmware_stop();
201         default:
202                 break;
203         }
204
205         return -ENXIO;
206 }
207
208 int netconfig_wifi_firmware(enum netconfig_wifi_firmware type, gboolean enable)
209 {
210         int err;
211         static enum netconfig_wifi_firmware current_driver = NETCONFIG_WIFI_OFF;
212         enum netconfig_wifi_firmware alias = type;
213
214         DBG("Wi-Fi current firmware %d (type: %d %s)", current_driver, type,
215                                                         enable == TRUE ? "enable" : "disable");
216
217         if (enable == FALSE) {
218                 if (current_driver == NETCONFIG_WIFI_OFF) {
219                         return -EALREADY;
220                 } else if (current_driver == alias) {
221
222                         err = __netconfig_wifi_firmware_stop(type);
223                         if (err < 0 && err != -EALREADY)
224                                 return err;
225
226                         current_driver = NETCONFIG_WIFI_OFF;
227
228                         return err;
229                 }
230
231                 return -EIO;
232         }
233
234         if (current_driver > NETCONFIG_WIFI_OFF) {
235                 if (current_driver == alias)
236                         return -EALREADY;
237
238                 return -EIO;
239         }
240
241         err = __netconfig_wifi_firmware_start(type);
242         if (err < 0)
243                 DBG("Failed to execute script file");
244         else
245                 current_driver = alias;
246
247         return err;
248 }
249
250 gboolean handle_start(WifiFirmware *firmware, GDBusMethodInvocation *context, const gchar *device)
251 {
252         int err;
253
254         g_return_val_if_fail(firmware != NULL, TRUE);
255
256         DBG("Wi-Fi firmware start %s", device != NULL ? device : "null");
257
258         if (g_strcmp0("p2p", device) == 0)
259                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, TRUE);
260         else if (g_strcmp0("softap", device) == 0)
261                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, TRUE);
262         else
263                 err = -EINVAL;
264
265         if (err < 0) {
266                 if (err == -EALREADY)
267                         netconfig_error_already_exists(context);
268                 else if (g_strcmp0("softap", device) == 0 && err == -EIO && netconfig_is_wifi_direct_on() == FALSE) {
269                         if (netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, FALSE) == 0 && netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, TRUE) == 0) {
270                                 wifi_firmware_complete_start(firmware, context);
271                                 return TRUE;
272                         } else
273                                 netconfig_error_wifi_driver_failed(context);
274                 } else
275                         netconfig_error_wifi_driver_failed(context);
276
277                 return TRUE;
278         }
279
280         wifi_firmware_complete_start(firmware, context);
281         return TRUE;
282 }
283
284 gboolean handle_stop(WifiFirmware *firmware, GDBusMethodInvocation *context, const gchar *device)
285 {
286         int err;
287
288         g_return_val_if_fail(firmware != NULL, TRUE);
289
290         DBG("Wi-Fi firmware stop %s", device != NULL ? device : "null");
291
292         if (g_strcmp0("p2p", device) == 0)
293                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, FALSE);
294         else if (g_strcmp0("softap", device) == 0)
295                 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, FALSE);
296         else
297                 err = -EINVAL;
298
299         if (err < 0) {
300                 if (err == -EALREADY)
301                         netconfig_error_already_exists(context);
302                 else
303                         netconfig_error_wifi_driver_failed(context);
304
305                 return TRUE;
306         }
307
308         wifi_firmware_complete_stop(firmware, context);
309         return TRUE;
310 }