2 * Driver interaction with Linux nl80211/cfg80211 - Android specific
3 * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (c) 2009-2010, Atheros Communications
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
12 #include <sys/ioctl.h>
14 #include <netlink/genl/genl.h>
15 #include <netlink/genl/family.h>
16 #include <netlink/genl/ctrl.h>
19 #include "utils/common.h"
20 #include "driver_nl80211.h"
21 #include "android_drv.h"
24 typedef struct android_wifi_priv_cmd
{
28 } android_wifi_priv_cmd
;
30 static int drv_errors
= 0;
32 static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data
*drv
)
35 if (drv_errors
> DRV_NUMBER_SEQUENTIAL_ERRORS
) {
37 wpa_msg(drv
->ctx
, MSG_INFO
, WPA_EVENT_DRIVER_STATE
"HANGED");
42 static int android_priv_cmd(struct i802_bss
*bss
, const char *cmd
)
44 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
46 android_wifi_priv_cmd priv_cmd
;
47 char buf
[MAX_DRV_CMD_SIZE
];
50 os_memset(&ifr
, 0, sizeof(ifr
));
51 os_memset(&priv_cmd
, 0, sizeof(priv_cmd
));
52 os_strlcpy(ifr
.ifr_name
, bss
->ifname
, IFNAMSIZ
);
54 os_memset(buf
, 0, sizeof(buf
));
55 os_strlcpy(buf
, cmd
, sizeof(buf
));
58 priv_cmd
.used_len
= sizeof(buf
);
59 priv_cmd
.total_len
= sizeof(buf
);
60 ifr
.ifr_data
= &priv_cmd
;
62 ret
= ioctl(drv
->global
->ioctl_sock
, SIOCDEVPRIVATE
+ 1, &ifr
);
64 wpa_printf(MSG_ERROR
, "%s: failed to issue private commands",
66 wpa_driver_send_hang_msg(drv
);
75 int android_pno_start(struct i802_bss
*bss
,
76 struct wpa_driver_scan_params
*params
)
78 struct wpa_driver_nl80211_data
*drv
= bss
->drv
;
80 android_wifi_priv_cmd priv_cmd
;
81 int ret
= 0, i
= 0, bp
;
82 char buf
[WEXT_PNO_MAX_COMMAND_SIZE
];
84 bp
= WEXT_PNOSETUP_HEADER_SIZE
;
85 os_memcpy(buf
, WEXT_PNOSETUP_HEADER
, bp
);
86 buf
[bp
++] = WEXT_PNO_TLV_PREFIX
;
87 buf
[bp
++] = WEXT_PNO_TLV_VERSION
;
88 buf
[bp
++] = WEXT_PNO_TLV_SUBVERSION
;
89 buf
[bp
++] = WEXT_PNO_TLV_RESERVED
;
91 while (i
< WEXT_PNO_AMOUNT
&& (size_t) i
< params
->num_ssids
) {
92 /* Check that there is enough space needed for 1 more SSID, the
93 * other sections and null termination */
94 if ((bp
+ WEXT_PNO_SSID_HEADER_SIZE
+ MAX_SSID_LEN
+
95 WEXT_PNO_NONSSID_SECTIONS_SIZE
+ 1) >= (int) sizeof(buf
))
97 wpa_hexdump_ascii(MSG_DEBUG
, "For PNO Scan",
98 params
->ssids
[i
].ssid
,
99 params
->ssids
[i
].ssid_len
);
100 buf
[bp
++] = WEXT_PNO_SSID_SECTION
;
101 buf
[bp
++] = params
->ssids
[i
].ssid_len
;
102 os_memcpy(&buf
[bp
], params
->ssids
[i
].ssid
,
103 params
->ssids
[i
].ssid_len
);
104 bp
+= params
->ssids
[i
].ssid_len
;
108 buf
[bp
++] = WEXT_PNO_SCAN_INTERVAL_SECTION
;
109 os_snprintf(&buf
[bp
], WEXT_PNO_SCAN_INTERVAL_LENGTH
+ 1, "%x",
110 WEXT_PNO_SCAN_INTERVAL
);
111 bp
+= WEXT_PNO_SCAN_INTERVAL_LENGTH
;
113 buf
[bp
++] = WEXT_PNO_REPEAT_SECTION
;
114 os_snprintf(&buf
[bp
], WEXT_PNO_REPEAT_LENGTH
+ 1, "%x",
116 bp
+= WEXT_PNO_REPEAT_LENGTH
;
118 buf
[bp
++] = WEXT_PNO_MAX_REPEAT_SECTION
;
119 os_snprintf(&buf
[bp
], WEXT_PNO_MAX_REPEAT_LENGTH
+ 1, "%x",
120 WEXT_PNO_MAX_REPEAT
);
121 bp
+= WEXT_PNO_MAX_REPEAT_LENGTH
+ 1;
123 memset(&ifr
, 0, sizeof(ifr
));
124 memset(&priv_cmd
, 0, sizeof(priv_cmd
));
125 os_strlcpy(ifr
.ifr_name
, bss
->ifname
, IFNAMSIZ
);
128 priv_cmd
.used_len
= bp
;
129 priv_cmd
.total_len
= bp
;
130 ifr
.ifr_data
= &priv_cmd
;
132 ret
= ioctl(drv
->global
->ioctl_sock
, SIOCDEVPRIVATE
+ 1, &ifr
);
135 wpa_printf(MSG_ERROR
, "ioctl[SIOCSIWPRIV] (pnosetup): %d",
137 wpa_driver_send_hang_msg(drv
);
143 return android_priv_cmd(bss
, "PNOFORCE 1");
147 int android_pno_stop(struct i802_bss
*bss
)
149 return android_priv_cmd(bss
, "PNOFORCE 0");
154 #ifdef ANDROID_LIB_STUB
156 int wpa_driver_set_p2p_noa(void *priv
, u8 count
, int start
, int duration
)
162 int wpa_driver_get_p2p_noa(void *priv
, u8
*buf
, size_t len
)
168 int wpa_driver_set_p2p_ps(void *priv
, int legacy_ps
, int opp_ps
, int ctwindow
)
174 int wpa_driver_set_ap_wps_p2p_ie(void *priv
, const struct wpabuf
*beacon
,
175 const struct wpabuf
*proberesp
,
176 const struct wpabuf
*assocresp
)
181 #endif /* ANDROID_LIB_STUB */
182 #endif /* ANDROID_P2P */
185 int android_nl_socket_set_nonblocking(struct nl_handle
*handle
)
187 return fcntl(nl_socket_get_fd(handle
), F_SETFL
, O_NONBLOCK
);