Home | History | Annotate | Download | only in wpa_supplicant_lib
      1 #include "includes.h"
      2 #include <sys/ioctl.h>
      3 #include <net/if_arp.h>
      4 #include <net/if.h>
      5 #include <sys/stat.h>
      6 #include <fcntl.h>
      7 #include <sys/types.h>
      8 #include <sys/wait.h>
      9 #include <netlink/genl/genl.h>
     10 #include <netlink/genl/family.h>
     11 #include <netlink/genl/ctrl.h>
     12 #include <netlink/msg.h>
     13 #include <netlink/attr.h>
     14 
     15 #include "linux_wext.h"
     16 #include "common.h"
     17 #include "driver.h"
     18 #include "eloop.h"
     19 #include "driver_wext.h"
     20 #include "ieee802_11_defs.h"
     21 #include "wpa_common.h"
     22 #include "wpa_ctrl.h"
     23 #include "wpa_supplicant_i.h"
     24 #include "config_ssid.h"
     25 #include "wpa_debug.h"
     26 #include "linux_ioctl.h"
     27 #include "hardware_legacy/driver_nl80211.h"
     28 
     29 #define WPA_EVENT_DRIVER_STATE          "CTRL-EVENT-DRIVER-STATE "
     30 #define DRV_NUMBER_SEQUENTIAL_ERRORS     4
     31 
     32 #define BLUETOOTH_COEXISTENCE_MODE_ENABLED   0
     33 #define BLUETOOTH_COEXISTENCE_MODE_DISABLED  1
     34 #define BLUETOOTH_COEXISTENCE_MODE_SENSE     2
     35 
     36 static int g_drv_errors = 0;
     37 
     38 static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
     39 {
     40 	g_drv_errors++;
     41 	if (g_drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
     42 		g_drv_errors = 0;
     43 		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
     44 	}
     45 }
     46 
     47 static int wpa_driver_toggle_btcoex_state(char state)
     48 {
     49 	int ret;
     50 	int fd = open("/sys/devices/platform/wl1271/bt_coex_state", O_RDWR, 0);
     51 	if (fd == -1)
     52 		return -1;
     53 
     54 	ret = write(fd, &state, sizeof(state));
     55 	close(fd);
     56 
     57 	wpa_printf(MSG_DEBUG, "%s:  set btcoex state to '%c' result = %d", __func__,
     58 		   state, ret);
     59 	return ret;
     60 }
     61 
     62 int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
     63 				  size_t buf_len )
     64 {
     65 	struct i802_bss *bss = priv;
     66 	struct wpa_driver_nl80211_data *drv = bss->drv;
     67 	struct ifreq ifr;
     68 	int ret = 0;
     69 
     70 	if (os_strcasecmp(cmd, "STOP") == 0) {
     71 		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
     72 		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
     73 	} else if (os_strcasecmp(cmd, "START") == 0) {
     74 		linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
     75 		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
     76 	} else if (os_strcasecmp(cmd, "RELOAD") == 0) {
     77 		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
     78 	} else if (os_strncasecmp(cmd, "BTCOEXMODE ", 11) == 0) {
     79 		int mode = atoi(cmd + 11);
     80 		if (mode == BLUETOOTH_COEXISTENCE_MODE_DISABLED) { /* disable BT-coex */
     81 			ret = wpa_driver_toggle_btcoex_state('0');
     82 		} else if (mode == BLUETOOTH_COEXISTENCE_MODE_SENSE) { /* enable BT-coex */
     83 			ret = wpa_driver_toggle_btcoex_state('1');
     84 		} else {
     85 			wpa_printf(MSG_DEBUG, "invalid btcoex mode: %d", mode);
     86 			ret = -1;
     87 		}
     88 	} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
     89 		u8 macaddr[ETH_ALEN] = {};
     90 
     91 		ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
     92 		if (!ret)
     93 			ret = os_snprintf(buf, buf_len,
     94 					  "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
     95 	} else {
     96 		wpa_printf(MSG_INFO, "%s: Unsupported command %s", __func__, cmd);
     97 	}
     98 	return ret;
     99 }
    100