X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=contrib%2Fpackage%2Fiwinfo%2Fsrc%2Fiwinfo_nl80211.c;h=7f27e25338063e9bb31bfc71232f58f3cd2c965e;hp=3e0e7dd522d709657e1b3090a83a61435a4836d3;hb=7c8824f0faf082f03037b554a4b57da863661fcb;hpb=653c9e782f54f3ab980b678227d0429259ce038b diff --git a/contrib/package/iwinfo/src/iwinfo_nl80211.c b/contrib/package/iwinfo/src/iwinfo_nl80211.c index 3e0e7dd52..7f27e2533 100644 --- a/contrib/package/iwinfo/src/iwinfo_nl80211.c +++ b/contrib/package/iwinfo/src/iwinfo_nl80211.c @@ -27,11 +27,12 @@ #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 ) { @@ -52,6 +53,13 @@ static int nl80211_init(void) 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; @@ -128,6 +136,12 @@ static void nl80211_free(struct nl80211_msg_conveyor *cv) 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) @@ -331,6 +345,9 @@ static char * nl80211_wpasupp_info(const char *ifname, const char *cmd) 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; @@ -567,6 +584,7 @@ int nl80211_get_signal(const char *ifname, int *buf) 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]; @@ -584,10 +602,11 @@ int nl80211_get_noise(const char *ifname, int *buf) 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); @@ -595,7 +614,7 @@ int nl80211_get_noise(const char *ifname, int *buf) nl80211_free(req); } - return -1; + return rv; } int nl80211_get_quality(const char *ifname, int *buf) @@ -937,7 +956,7 @@ int nl80211_get_txpwrlist(const char *ifname, char *buf, int *len) break; } } - } + } nl80211_free(res); } @@ -1155,10 +1174,50 @@ int nl80211_get_freqlist(const char *ifname, char *buf, int *len) 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; } -