return (freq / 5) - 1000;
}
+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;
+
+ return 0;
+}
+
static char * nl80211_getval(const char *ifname, const char *buf, const char *key)
{
int i, len;
}
}
-int nl80211_get_mode(const char *ifname, char *buf)
+int nl80211_get_mode(const char *ifname, int *buf)
{
return wext_get_mode(ifname, buf);
}
return -1;
}
-int nl80211_get_channel(const char *ifname, int *buf)
+
+static int nl80211_get_frequency_cb(struct nl_msg *msg, void *arg)
{
- char *first;
+ int *freq = arg;
+ struct nlattr **attr = nl80211_parse(msg);
+ struct nlattr *binfo[NL80211_BSS_MAX + 1];
- if (!wext_get_channel(ifname, buf))
- return 0;
+ static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = {
+ [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 },
+ };
- else if ((first = nl80211_phy2ifname(nl80211_ifname2phy(ifname))) != NULL)
- return wext_get_channel(first, buf);
+ if (attr[NL80211_ATTR_BSS] &&
+ !nla_parse_nested(binfo, NL80211_BSS_MAX,
+ attr[NL80211_ATTR_BSS], bss_policy))
+ {
+ if (binfo[NL80211_BSS_FREQUENCY])
+ *freq = nla_get_u32(binfo[NL80211_BSS_FREQUENCY]);
+ }
- return -1;
+ return NL_SKIP;
}
int nl80211_get_frequency(const char *ifname, int *buf)
{
- char *first;
+ char *res, *channel;
+ struct nl80211_msg_conveyor *req;
- if (!wext_get_frequency(ifname, buf))
- return 0;
+ *buf = 0;
- else if ((first = nl80211_phy2ifname(nl80211_ifname2phy(ifname))) != NULL)
- return wext_get_frequency(first, buf);
+ if ((res = nl80211_hostapd_info(ifname)) &&
+ (channel = nl80211_getval(NULL, res, "channel")))
+ {
+ *buf = nl80211_channel2freq(atoi(channel),
+ nl80211_getval(NULL, res, "hw_mode"));
+ }
+ else
+ {
+ res = nl80211_phy2ifname(ifname);
+ req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP);
+
+ if (req)
+ {
+ nl80211_send(req, nl80211_get_frequency_cb, buf);
+ nl80211_free(req);
+ }
+ }
+
+ return (*buf == 0) ? -1 : 0;
+}
+
+int nl80211_get_channel(const char *ifname, int *buf)
+{
+ if (!nl80211_get_frequency(ifname, buf))
+ {
+ *buf = nl80211_freq2channel(*buf);
+ return 0;
+ }
return -1;
}
+
int nl80211_get_txpower(const char *ifname, int *buf)
{
return wext_get_txpower(ifname, buf);
nl80211_free(req);
}
- if (dbm_max > -1)
+ if (dbm_max > 0)
{
for (dbm_cur = 0, dbm_cnt = 0;
dbm_cur < dbm_max;
memcpy(sl->e->mac, nla_data(bss[NL80211_BSS_BSSID]), 6);
if (caps & (1<<1))
- memcpy(sl->e->mode, "Ad-Hoc", 6);
+ sl->e->mode = IWINFO_OPMODE_ADHOC;
else
- memcpy(sl->e->mode, "Master", 6);
+ sl->e->mode = IWINFO_OPMODE_MASTER;
if (caps & (1<<4))
sl->e->crypto.enabled = 1;
if (bss[NL80211_BSS_SIGNAL_MBM])
{
- sl->e->signal = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]) / 100;
+ sl->e->signal =
+ (uint8_t)((int32_t)nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]) / 100);
rssi = sl->e->signal - 0x100;
static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len)
{
- struct nl_msg *ssids = NULL;
struct nl80211_msg_conveyor *req;
struct nl80211_scanlist sl = { .e = (struct iwinfo_scanlist_entry *)buf };
*len = sl.len * sizeof(struct iwinfo_scanlist_entry);
return *len ? 0 : -1;
-
-nla_put_failure:
- if (ssids)
- nlmsg_free(ssids);
- return -1;
}
int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
memcpy(e->ssid, ssid, min(strlen(ssid), sizeof(e->ssid) - 1));
/* Mode (assume master) */
- sprintf((char *)e->mode, "Master");
+ e->mode = IWINFO_OPMODE_MASTER;
/* Channel */
e->channel = nl80211_freq2channel(freq);
nl80211_get_scancrypto(cipher, &e->crypto);
/* advance to next line */
- while( *res && *res++ != '\n' );
+ while (*res && *res++ != '\n');
count++;
e++;