{
if (freq == 2484)
return 14;
-
- if (freq < 2484)
+ else if (freq < 2484)
return (freq - 2407) / 5;
-
- return (freq / 5) - 1000;
+ else if (freq >= 4910 && freq <= 4980)
+ return (freq - 4000) / 5;
+ else
+ return (freq - 5000) / 5;
}
static int nl80211_channel2freq(int channel, const char *band)
{
- if (channel == 14)
- return 2484;
-
- if ((channel < 14) && (!band || band[0] != 'a'))
- return (channel * 5) + 2407;
-
- if (channel > 0)
- return (1000 + channel) * 5;
+ if (!band || band[0] != 'a')
+ {
+ if (channel == 14)
+ return 2484;
+ else if (channel < 14)
+ return (channel * 5) + 2407;
+ }
+ else
+ {
+ if (channel >= 182 && channel <= 196)
+ return (channel * 5) + 4000;
+ else
+ return (channel * 5) + 5000;
+ }
return 0;
}
{
send(sock, "ATTACH", 6, 0);
- if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0)
+ if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)-1) <= 0)
goto out;
}
send(sock, cmd, strlen(cmd), 0);
- while( numtry++ < 5 )
+ /* we might have to scan up to 72 channels / 256ms per channel */
+ /* this makes up to 18.5s hence 10 tries */
+ while( numtry++ < 10 )
{
- if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)) <= 0)
+ char *bracket;
+
+ /* make sure there is a terminating nul byte */
+ if (nl80211_wpactl_recv(sock, buffer, sizeof(buffer)-1) <= 0)
{
if (event)
continue;
if ((!event && buffer[0] != '<') || (event && strstr(buffer, event)))
break;
+
+ /* there may be more than max(numtry) BSS-ADDED events */
+ /* ignore them similar to wpa_cli */
+ if (buffer[0] == '<' &&
+ (bracket=strchr(buffer,'>')) != NULL &&
+ strncmp(bracket+1,"CTRL-EVENT-BSS-ADDED",20) == 0)
+ numtry--;
}
rv = buffer;
static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
[NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
+ [NL80211_BSS_STATUS] = { .type = NLA_U32 },
};
if (attr[NL80211_ATTR_BSS] &&
!nla_parse_nested(binfo, NL80211_BSS_MAX,
attr[NL80211_ATTR_BSS], bss_policy))
{
- if (binfo[NL80211_BSS_FREQUENCY])
+ if (binfo[NL80211_BSS_STATUS] && binfo[NL80211_BSS_FREQUENCY])
*freq = nla_get_u32(binfo[NL80211_BSS_FREQUENCY]);
}
int nl80211_get_frequency(const char *ifname, int *buf)
{
+ int chn;
char *res, *channel;
struct nl80211_msg_conveyor *req;
(res = nl80211_hostapd_info(ifname)) &&
(channel = nl80211_getval(NULL, res, "channel")))
{
- *buf = nl80211_channel2freq(atoi(channel),
- nl80211_getval(NULL, res, "hw_mode"));
+ chn = atoi(channel);
+ *buf = nl80211_channel2freq(chn, nl80211_getval(NULL, res, "hw_mode"));
}
else
{
int nl80211_get_txpower(const char *ifname, int *buf)
{
+#if 0
char *res;
char path[PATH_MAX];
if ((*buf = nl80211_readint(path)) > -1)
return 0;
+#endif
return wext_get_txpower(ifname, buf);
}
if (caps & (1<<1))
sl->e->mode = IWINFO_OPMODE_ADHOC;
- else
+ else if (caps & (1<<0))
sl->e->mode = IWINFO_OPMODE_MASTER;
+ else
+ sl->e->mode = IWINFO_OPMODE_MESHPOINT;
if (caps & (1<<4))
sl->e->crypto.enabled = 1;
{
nl80211_get_quality_max(ifname, &qmax);
- /* skip header line */
- while (*res++ != '\n');
+ count = -1;
- count = 0;
-
- while (sscanf(res, "%17s %d %d %255s%*[ \t]%127[^\n]\n",
- bssid, &freq, &rssi, cipher, ssid) > 0)
- {
+ do {
+ if (res[0] == '<')
+ {
+ /* skip log lines */
+ goto nextline;
+ }
+ if (count < 0)
+ {
+ /* skip header line */
+ count++;
+ goto nextline;
+ }
+ if (sscanf(res, "%17s %d %d %255s%*[ \t]%127[^\n]\n",
+ bssid, &freq, &rssi, cipher, ssid) < 5)
+ {
+ /* skip malformed lines */
+ goto nextline;
+ }
/* BSSID */
e->mac[0] = strtol(&bssid[0], NULL, 16);
e->mac[1] = strtol(&bssid[3], NULL, 16);
memcpy(e->ssid, ssid, min(strlen(ssid), sizeof(e->ssid) - 1));
/* Mode (assume master) */
- e->mode = IWINFO_OPMODE_MASTER;
+ if (strstr(cipher,"[MESH]"))
+ e->mode = IWINFO_OPMODE_MESHPOINT;
+ else
+ e->mode = IWINFO_OPMODE_MASTER;
/* Channel */
e->channel = nl80211_freq2channel(freq);
/* Crypto */
nl80211_get_scancrypto(cipher, &e->crypto);
- /* advance to next line */
- while (*res && *res++ != '\n');
-
count++;
e++;
memset(ssid, 0, sizeof(ssid));
memset(bssid, 0, sizeof(bssid));
memset(cipher, 0, sizeof(cipher));
- }
+
+ nextline:
+ /* advance to next line */
+ while( *res && *res++ != '\n' );
+ }
+ while( *res );
*len = count * sizeof(struct iwinfo_scanlist_entry);
return 0;