From 0d17a301dc80babdfbf16c6eafa7da6e3fb7cdd7 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 25 Nov 2006 05:04:23 +0000 Subject: [PATCH] - Add noise floor in ieee80211_nodestats; return it as zero until we can update the api's so the driver can provide noise floor data - Add a bandaid so IEEE80211_IOC_STA_STATS works for sta mode; when all nodes are in the station table this will no longer be needed - Fix braino in IEEE80211_IOC_STA_INFO implementation; was supposed to take a MAC address and return info for that sta or all stations if ff:ff:ff:ff:ff was supplied -- but somehow this didn't get implemented; implement the intended semantics Obtained-from: FreeBSD (sam@freebsd.org) # NOTE: The RSSI statistics in ieee80211_nodestats is still unsigned --- sys/netproto/802_11/ieee80211_ioctl.h | 9 ++-- sys/netproto/802_11/wlan/ieee80211_ioctl.c | 56 +++++++++++++++++----- 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/sys/netproto/802_11/ieee80211_ioctl.h b/sys/netproto/802_11/ieee80211_ioctl.h index 2ba8cf1785..9ee0b46b8a 100644 --- a/sys/netproto/802_11/ieee80211_ioctl.h +++ b/sys/netproto/802_11/ieee80211_ioctl.h @@ -30,7 +30,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/net80211/ieee80211_ioctl.h,v 1.10.2.4 2005/12/22 19:18:23 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/ieee80211_ioctl.h,v 1.3 2006/09/01 15:12:11 sephe Exp $ + * $DragonFly: src/sys/netproto/802_11/ieee80211_ioctl.h,v 1.4 2006/11/25 05:04:23 sephe Exp $ */ #ifndef _NET80211_IEEE80211_IOCTL_H_ #define _NET80211_IEEE80211_IOCTL_H_ @@ -43,7 +43,7 @@ #include /* - * Per/node (station) statistics available when operating as an AP. + * Per/node (station) statistics. */ struct ieee80211_nodestats { uint32_t ns_rx_data; /* rx data frames */ @@ -309,7 +309,7 @@ struct ieee80211req_sta_info { uint16_t isi_flags; /* channel flags */ uint16_t isi_state; /* state flags */ uint8_t isi_authmode; /* authentication algorithm */ - uint8_t isi_rssi; + uint8_t isi_rssi; /* receive signal strength */ uint8_t isi_capinfo; /* capabilities */ uint8_t isi_erp; /* ERP element */ uint8_t isi_macaddr[IEEE80211_ADDR_LEN]; @@ -317,6 +317,7 @@ struct ieee80211req_sta_info { /* negotiated rates */ uint8_t isi_rates[IEEE80211_RATE_MAXSIZE]; uint8_t isi_txrate; /* index to isi_rates[] */ + int8_t isi_noise; /* noise floor */ uint16_t isi_ie_len; /* IE length */ uint16_t isi_associd; /* assoc response */ uint16_t isi_txpower; /* current tx power */ @@ -431,7 +432,6 @@ struct ieee80211req { #define IEEE80211_IOC_CHANINFO 42 /* channel info list */ #define IEEE80211_IOC_TXPOWMAX 43 /* max tx power for channel */ #define IEEE80211_IOC_STA_TXPOW 44 /* per-station tx power limit */ -#define IEEE80211_IOC_STA_INFO 45 /* station/neighbor info */ #define IEEE80211_IOC_WME_CWMIN 46 /* WME: ECWmin */ #define IEEE80211_IOC_WME_CWMAX 47 /* WME: ECWmax */ #define IEEE80211_IOC_WME_AIFS 48 /* WME: AIFSN */ @@ -446,6 +446,7 @@ struct ieee80211req { #define IEEE80211_IOC_MCAST_RATE 72 /* tx rate for mcast frames */ #define IEEE80211_IOC_FRAGTHRESHOLD 73 /* tx fragmentation threshold */ #define IEEE80211_IOC_BURST 75 /* packet bursting */ +#define IEEE80211_IOC_STA_INFO 78 /* station/neighbor info */ #define IEEE80211_IOC_RATECTL 255 /* diff --git a/sys/netproto/802_11/wlan/ieee80211_ioctl.c b/sys/netproto/802_11/wlan/ieee80211_ioctl.c index a5887499d0..1b34b692a9 100644 --- a/sys/netproto/802_11/wlan/ieee80211_ioctl.c +++ b/sys/netproto/802_11/wlan/ieee80211_ioctl.c @@ -30,7 +30,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/net80211/ieee80211_ioctl.c,v 1.25.2.12 2006/04/03 17:21:05 sam Exp $ - * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ioctl.c,v 1.6 2006/11/23 13:43:05 sephe Exp $ + * $DragonFly: src/sys/netproto/802_11/wlan/ieee80211_ioctl.c,v 1.7 2006/11/25 05:04:23 sephe Exp $ */ /* @@ -965,8 +965,12 @@ ieee80211_ioctl_getstastats(struct ieee80211com *ic, struct ieee80211req *ireq) if (error != 0) return error; ni = ieee80211_find_node(&ic->ic_sta, macaddr); - if (ni == NULL) - return EINVAL; /* XXX */ + if (ni == NULL) { + /* XXX special-case sta-mode until bss is node in ic_sta */ + if (ic->ic_opmode != IEEE80211_M_STA) + return ENOENT; + ni = ieee80211_ref_node(ic->ic_bss); + } if (ireq->i_len > sizeof(struct ieee80211req_sta_stats)) ireq->i_len = sizeof(struct ieee80211req_sta_stats); /* NB: copy out only the statistics */ @@ -1121,6 +1125,7 @@ get_sta_info(void *arg, struct ieee80211_node *ni) si->isi_state = ni->ni_flags; si->isi_authmode = ni->ni_authmode; si->isi_rssi = ic->ic_node_getrssi(ni); + si->isi_noise = 0; /* XXX */ si->isi_capinfo = ni->ni_capinfo; si->isi_erp = ni->ni_erp; IEEE80211_ADDR_COPY(si->isi_macaddr, ni->ni_macaddr); @@ -1165,15 +1170,34 @@ get_sta_info(void *arg, struct ieee80211_node *ni) static int ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) { + uint8_t macaddr[IEEE80211_ADDR_LEN]; + const int off = __offsetof(struct ieee80211req_sta_req, info); + struct ieee80211_node *ni; struct stainforeq req; int error; - if (ireq->i_len < sizeof(struct stainforeq)) + if (ireq->i_len < sizeof(struct ieee80211req_sta_req)) return EFAULT; + error = copyin(ireq->i_data, macaddr, IEEE80211_ADDR_LEN); + if (error != 0) + return error; + if (IEEE80211_ADDR_EQ(macaddr, ic->ic_ifp->if_broadcastaddr)) { + ni = NULL; + } else { + ni = ieee80211_find_node(&ic->ic_sta, macaddr); + if (ni == NULL) { + /* XXX special-case sta-mode until bss is in ic_sta */ + if (ic->ic_opmode != IEEE80211_M_STA) + return EINVAL; /* XXX */ + ni = ieee80211_ref_node(ic->ic_bss); + } + } - error = 0; req.space = 0; - ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); + if (ni == NULL) + ieee80211_iterate_nodes(&ic->ic_sta, get_sta_space, &req); + else + get_sta_space(&req, ni); if (req.space > ireq->i_len) req.space = ireq->i_len; if (req.space > 0) { @@ -1183,16 +1207,24 @@ ieee80211_ioctl_getstainfo(struct ieee80211com *ic, struct ieee80211req *ireq) space = req.space; /* XXX M_WAITOK after driver lock released */ p = kmalloc(space, M_TEMP, M_NOWAIT); - if (p == NULL) - return ENOMEM; + if (p == NULL) { + error = ENOMEM; + goto bad; + } req.si = p; - ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); + if (ni == NULL) + ieee80211_iterate_nodes(&ic->ic_sta, get_sta_info, &req); + else + get_sta_info(&req, ni); ireq->i_len = space - req.space; - error = copyout(p, ireq->i_data, ireq->i_len); + error = copyout(p, (uint8_t *)ireq->i_data + off, ireq->i_len); kfree(p, M_TEMP); - } else + } else { ireq->i_len = 0; - + } +bad: + if (ni != NULL) + ieee80211_free_node(ni); return error; } -- 2.41.0