2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <vconf-keys.h>
31 #include "netsupplicant.h"
32 #include "wifi-firmware.h"
33 #include "network-statistics.h"
35 #define WLAN_DRIVER_SCRIPT "/usr/bin/wlan.sh"
37 #define QUAD_CPUS_COUNT 4
38 #define TEMP_BUFFER_LEN 100
39 #define WIFI_MAC_ADD_PATH "/sys/class/net/wlan0/address"
43 enum netconfig_wifi_firmware type;
46 static GSList *wifi_driver_list;
48 static void __netconfig_wifi_driver_free(gpointer data)
50 wifi_driver_s *driver = (wifi_driver_s *) data;
52 DBG("Remove wifi driver [%d:%s]", driver->type, driver->interface_name);
54 g_free(driver->interface_name);
58 static gint __netconfig_cmp_wifi_driver(gconstpointer a, gconstpointer b)
60 wifi_driver_s *drv_a = (wifi_driver_s *)a;
61 wifi_driver_s *drv_b = (wifi_driver_s *)b;
63 if (g_strcmp0(drv_a->interface_name, drv_b->interface_name))
69 static GSList * __netconfig_is_wifi_driver_in_list(
70 enum netconfig_wifi_firmware type, const char *interface_name)
72 wifi_driver_s driver = { .type = type, .interface_name = (char *)interface_name };
73 GSList *found = g_slist_find_custom(wifi_driver_list, &driver,
74 __netconfig_cmp_wifi_driver);
79 static gboolean __netconfig_add_wifi_driver_to_list(
80 enum netconfig_wifi_firmware type, const char *interface_name)
83 wifi_driver_s *driver;
85 found = __netconfig_is_wifi_driver_in_list(type, interface_name);
89 driver = g_try_new0(wifi_driver_s, 1);
91 ERR("g_try_new0 failed!!!");
95 driver->interface_name = g_strdup(interface_name);
96 if (!driver->interface_name) {
97 ERR("g_strdup failed!!!");
104 wifi_driver_list = g_slist_prepend(wifi_driver_list, driver);
108 static gboolean __netconfig_remove_wifi_driver_from_list(
109 enum netconfig_wifi_firmware type, const char *interface_name)
113 found = __netconfig_is_wifi_driver_in_list(type, interface_name);
117 __netconfig_wifi_driver_free(found->data);
118 wifi_driver_list = g_slist_delete_link(wifi_driver_list, found);
123 static int __netconfig_sta_firmware_start(const char *interface_name)
126 const char *path = WLAN_DRIVER_SCRIPT;
127 char *const args[] = { "/usr/bin/wlan.sh", "start", (char *)interface_name, NULL };
128 char *const envs[] = { NULL };
130 rv = netconfig_execute_file(path, args, envs);
134 rv = netconfig_interface_up(interface_name);
138 DBG("Successfully loaded wireless device driver");
142 static int __netconfig_sta_firmware_stop(const char *interface_name)
145 const char *path = WLAN_DRIVER_SCRIPT;
146 char *const args[] = { "/usr/bin/wlan.sh", "stop", (char *)interface_name, NULL };
147 char *const envs[] = { NULL };
149 rv = netconfig_interface_down(interface_name);
153 rv = netconfig_execute_file(path, args, envs);
157 DBG("Successfully removed wireless device driver");
161 static int __netconfig_p2p_firmware_start(const char *interface_name)
163 if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
167 const char *path = WLAN_DRIVER_SCRIPT;
168 char *const args[] = { "/usr/bin/wlan.sh", "p2p", (char *)interface_name, NULL };
169 char *const envs[] = { NULL };
171 rv = netconfig_execute_file(path, args, envs);
175 #if defined TIZEN_WLAN_USE_P2P_INTERFACE
176 rv = netconfig_interface_up(interface_name);
181 DBG("Successfully loaded p2p device driver");
185 static int __netconfig_p2p_firmware_stop(const char *interface_name)
187 if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT))
191 const char *path = WLAN_DRIVER_SCRIPT;
192 char *const args[] = { "/usr/bin/wlan.sh", "stop", (char *)interface_name, NULL };
193 char *const envs[] = { NULL };
195 rv = netconfig_interface_down(interface_name);
199 rv = netconfig_execute_file(path, args, envs);
203 DBG("Successfully removed p2p device driver");
207 static int __netconfig_softap_firmware_start(const char *interface_name)
209 if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING)
210 && !netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_SOFTAP))
214 const char *path = WLAN_DRIVER_SCRIPT;
215 char *const args[] = { "/usr/bin/wlan.sh", "softap", (char *)interface_name, NULL };
216 char *const envs[] = { NULL };
218 rv = netconfig_execute_file(path, args, envs);
222 if (netconfig_interface_up(interface_name) == FALSE)
225 DBG("Successfully loaded softap device driver");
229 static int __netconfig_softap_firmware_stop(const char *interface_name)
231 if (!netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_TETHERING)
232 && !netconfig_check_feature_supported(NETCONFIG_SUPPORTED_FEATURE_WIFI_SOFTAP))
236 const char *path = WLAN_DRIVER_SCRIPT;
237 char *const args[] = { "/usr/bin/wlan.sh", "stop", (char *)interface_name, NULL };
238 char *const envs[] = { NULL };
240 rv = netconfig_interface_down(interface_name);
244 rv = netconfig_execute_file(path, args, envs);
248 DBG("Successfully removed softap device driver");
252 static int __netconfig_wifi_firmware_start(enum netconfig_wifi_firmware type,
253 const char *interface_name)
255 if (emulator_is_emulated() == TRUE)
259 case NETCONFIG_WIFI_STA:
260 return __netconfig_sta_firmware_start(interface_name);
261 case NETCONFIG_WIFI_P2P:
262 return __netconfig_p2p_firmware_start(interface_name);
263 case NETCONFIG_WIFI_SOFTAP:
264 return __netconfig_softap_firmware_start(interface_name);
272 static int __netconfig_wifi_firmware_stop(enum netconfig_wifi_firmware type,
273 const char *interface_name)
275 if (emulator_is_emulated() == TRUE)
279 case NETCONFIG_WIFI_STA:
280 return __netconfig_sta_firmware_stop(interface_name);
281 case NETCONFIG_WIFI_P2P:
282 return __netconfig_p2p_firmware_stop(interface_name);
283 case NETCONFIG_WIFI_SOFTAP:
284 return __netconfig_softap_firmware_stop(interface_name);
292 static int __netconfig_set_rps_cpus(const char *interface_name)
296 char t_buf[TEMP_BUFFER_LEN];
297 char r_buf[TEMP_BUFFER_LEN];
299 if (access(WIFI_MAC_ADD_PATH, F_OK) != 0) {
300 DBG("WiFi driver is not loaded... ");
303 DBG("WiFi driver loaded... ");
306 snprintf(t_buf, TEMP_BUFFER_LEN,
307 "/sys/class/net/%s/queues/rx-0/rps_cpus",
309 DBG("Command : [%s]", t_buf);
312 while ((fd = open(t_buf, O_RDWR | O_CLOEXEC)) >= 0) {
314 count = read(fd, r_buf, 1);
321 DBG("read size = %zd", count);
324 if (r_buf[0] == 'e') {
326 DBG("e is already written");
327 snprintf(t_buf, TEMP_BUFFER_LEN,
328 "/sys/class/net/%s/queues/rx-%d/rps_cpus",
329 interface_name, curr);
330 DBG("Command : [%s]", t_buf);
336 if (lseek(fd, 0, SEEK_SET) < 0) {
342 count = write(fd, "e", 1);
349 DBG("write size = %zd", count);
353 snprintf(t_buf, TEMP_BUFFER_LEN,
354 "/sys/class/net/%s/queues/rx-%d/rps_cpus",
355 interface_name, curr);
356 DBG("Command : [%s]", t_buf);
362 int netconfig_wifi_firmware(enum netconfig_wifi_firmware type,
363 const char *interface_name, gboolean enable)
367 DBG("Wi-Fi firmware (type: %d %s) for %s", type, enable == TRUE ? "enable" : "disable",
368 interface_name ? interface_name : "");
370 GSList *found = __netconfig_is_wifi_driver_in_list(type, interface_name);
372 if (enable == FALSE) {
373 wifi_driver_s *driver;
378 driver = (wifi_driver_s *) found->data;
380 if (type != driver->type)
383 err = __netconfig_wifi_firmware_stop(type, interface_name);
384 if (err < 0 && err != -EALREADY)
387 __netconfig_remove_wifi_driver_from_list(type, interface_name);
393 wifi_driver_s *driver = (wifi_driver_s *) found->data;
395 DBG("Wi-Fi interface (%s) already in use", interface_name);
397 if (type == driver->type)
403 err = __netconfig_wifi_firmware_start(type, interface_name);
405 DBG("Failed to execute script file");
407 __netconfig_add_wifi_driver_to_list(type, interface_name);
409 if (__netconfig_set_rps_cpus(interface_name) < 0)
410 DBG("Failed to set rps_cpus");
415 gboolean handle_start(WifiFirmware *firmware, GDBusMethodInvocation *context,
416 const gchar *device, const gchar *ifname)
420 g_return_val_if_fail(firmware != NULL, TRUE);
422 DBG("Wi-Fi firmware start %s", device != NULL ? device : "null");
424 if (g_strcmp0("p2p", device) == 0)
425 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, ifname, TRUE);
426 else if (g_strcmp0("softap", device) == 0)
427 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, ifname, TRUE);
432 if (err == -EALREADY)
433 netconfig_error_already_exists(context);
434 else if (g_strcmp0("softap", device) == 0 &&
435 err == -EIO && netconfig_is_wifi_direct_on() == FALSE) {
436 if (netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, ifname, FALSE) == 0 &&
437 netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, ifname, TRUE) == 0) {
438 wifi_firmware_complete_start(firmware, context);
441 netconfig_error_wifi_driver_failed(context);
443 netconfig_error_wifi_driver_failed(context);
448 wifi_firmware_complete_start(firmware, context);
452 gboolean handle_stop(WifiFirmware *firmware, GDBusMethodInvocation *context,
453 const gchar *device, const gchar *ifname)
457 g_return_val_if_fail(firmware != NULL, TRUE);
459 DBG("Wi-Fi firmware stop %s", device != NULL ? device : "null");
461 if (g_strcmp0("p2p", device) == 0)
462 err = netconfig_wifi_firmware(NETCONFIG_WIFI_P2P, ifname, FALSE);
463 else if (g_strcmp0("softap", device) == 0)
464 err = netconfig_wifi_firmware(NETCONFIG_WIFI_SOFTAP, ifname, FALSE);
469 if (err == -EALREADY)
470 netconfig_error_already_exists(context);
472 netconfig_error_wifi_driver_failed(context);
477 wifi_firmware_complete_stop(firmware, context);