#define min(x, y) ((x) < (y)) ? (x) : (y)
+extern struct iwinfo_iso3166_label ISO3166_Names[];
static struct nl80211_state *nls = NULL;
static int nl80211_init(void)
{
- int err;
+ int err, fd;
if( !nls )
{
goto err;
}
+ fd = nl_socket_get_fd(nls->nl_sock);
+ if( fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) < 0 )
+ {
+ err = -EINVAL;
+ goto err;
+ }
+
if( genl_ctrl_alloc_cache(nls->nl_sock, &nls->nl_cache)) {
err = -ENOMEM;
goto err;
if( cv && cv->msg )
nlmsg_free(cv->msg);
+
+ if( cv )
+ {
+ cv->cb = NULL;
+ cv->msg = NULL;
+ }
}
static struct nl80211_msg_conveyor * nl80211_msg(const char *ifname, int cmd, int flags)
remote_length = sizeof(remote.sun_family) + sprintf(remote.sun_path,
"/var/run/wpa_supplicant-%s/%s", ifname, ifname);
+ if( fcntl(sock, F_SETFD, fcntl(sock, F_GETFD) | FD_CLOEXEC) < 0 )
+ goto out;
+
if( connect(sock, (struct sockaddr *) &remote, remote_length) )
goto out;
int nl80211_get_noise(const char *ifname, int *buf)
{
+ int rv = -1;
struct nl80211_msg_conveyor *req, *res;
struct nlattr *si[NL80211_SURVEY_INFO_MAX + 1];
if( res->attr[NL80211_ATTR_SURVEY_INFO] )
{
if( !nla_parse_nested(si, NL80211_SURVEY_INFO_MAX,
- res->attr[NL80211_ATTR_SURVEY_INFO], sp) )
+ res->attr[NL80211_ATTR_SURVEY_INFO], sp) &&
+ si[NL80211_SURVEY_INFO_NOISE] )
{
*buf = (int8_t)nla_get_u8(si[NL80211_SURVEY_INFO_NOISE]);
- return 0;
+ rv = 0;
}
}
nl80211_free(res);
nl80211_free(req);
}
- return -1;
+ return rv;
}
int nl80211_get_quality(const char *ifname, int *buf)
break;
}
}
- }
+ }
nl80211_free(res);
}
return wext_get_freqlist(ifname, buf, len);
}
+int nl80211_get_country(const char *ifname, char *buf)
+{
+ int rv = -1;
+ struct nl80211_msg_conveyor *req, *res;
+
+ req = nl80211_msg(ifname, NL80211_CMD_GET_REG, 0);
+ if( req )
+ {
+ res = nl80211_send(req);
+ if( res )
+ {
+ if( res->attr[NL80211_ATTR_REG_ALPHA2] )
+ {
+ memcpy(buf, nla_data(res->attr[NL80211_ATTR_REG_ALPHA2]), 2);
+ rv = 0;
+ }
+ nl80211_free(res);
+ }
+ nl80211_free(req);
+ }
+
+ return rv;
+}
+
+int nl80211_get_countrylist(const char *ifname, char *buf, int *len)
+{
+ int i, count;
+ struct iwinfo_iso3166_label *l;
+ struct iwinfo_country_entry *e = (struct iwinfo_country_entry *)buf;
+
+ for( l = ISO3166_Names, count = 0; l->iso3166; l++, e++, count++ )
+ {
+ e->iso3166 = l->iso3166;
+ e->ccode[0] = (l->iso3166 / 256);
+ e->ccode[1] = (l->iso3166 % 256);
+ }
+
+ *len = (count * sizeof(struct iwinfo_country_entry));
+ return 0;
+}
+
int nl80211_get_mbssid_support(const char *ifname, int *buf)
{
/* We assume that multi bssid is always possible */
*buf = 1;
return 0;
}
-