summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2004-12-23 12:27:26 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2004-12-23 12:27:26 +0000
commit5b3741465a246af2b76c661980d5cbda025f0a91 (patch)
tree4473c8672ea5c1430160978759bf4ce98ae0b36f /sys
parent807cdc363609813a12255e42680c9488df2b7e9e (diff)
From dyoung@NetBSD:
ieee80211.h r 1.9 #define the difference in microseconds between a fast and a slow preamble and PLCP header. ieee80211_output.c r 1.19 Fix a bug in ieee80211_compute_duration: the 802.11 Duration field in an 802.11 unicast data packet is equal to the duration of the SIFS and Acknowledgement. That is, the amount of time reserved *after* the packet has finished transmitting. Change the arguments to ieee80211_compute_duration: pass the entire packet length, not just the payload length. Add a 'debug' argument to ieee80211_compute_duration and its helper subroutine, ieee80211_compute_duration1. If debug != 0, ieee80211_compute_duration printfs its arguments and several local variables. In rtw(4), load the 802.11 Duration field with the result from ieee80211_compute_duration.
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211.h6
-rw-r--r--sys/net80211/ieee80211_output.c46
-rw-r--r--sys/net80211/ieee80211_proto.h4
3 files changed, 35 insertions, 21 deletions
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index d8f80a7e849..c58e06aa7d7 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211.h,v 1.3 2004/12/23 11:54:08 jsg Exp $ */
+/* $OpenBSD: ieee80211.h,v 1.4 2004/12/23 12:27:25 jsg Exp $ */
/* $NetBSD: ieee80211.h,v 1.6 2004/04/30 23:51:53 dyoung Exp $ */
/*-
@@ -565,8 +565,12 @@ struct ieee80211_duration {
/* IEEE 802.11b durations for DSSS PHY in microseconds */
#define IEEE80211_DUR_DS_LONG_PREAMBLE 144
#define IEEE80211_DUR_DS_SHORT_PREAMBLE 72
+#define IEEE80211_DUR_DS_PREAMBLE_DIFFERENCE \
+ (IEEE80211_DUR_DS_LONG_PREAMBLE - IEEE80211_DUR_DS_SHORT_PREAMBLE)
#define IEEE80211_DUR_DS_FAST_PLCPHDR 24
#define IEEE80211_DUR_DS_SLOW_PLCPHDR 48
+#define IEEE80211_DUR_DS_PLCPHDR_DIFFERENCE \
+ (IEEE80211_DUR_DS_SLOW_PLCPHDR - IEEE80211_DUR_DS_FAST_PLCPHDR)
#define IEEE80211_DUR_DS_SLOW_ACK 112
#define IEEE80211_DUR_DS_FAST_ACK 56
#define IEEE80211_DUR_DS_SLOW_CTS 112
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 0334d0aeb77..9ba36cb708c 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_output.c,v 1.2 2004/12/23 11:54:09 jsg Exp $ */
+/* $OpenBSD: ieee80211_output.c,v 1.3 2004/12/23 12:27:25 jsg Exp $ */
/* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */
/*-
@@ -329,26 +329,27 @@ ieee80211_compute_duration1(int len, uint32_t flags, int rate,
return -1;
}
+ d->d_plcp_len = data_dur;
+
d->d_rts_dur = data_dur + 3 * (IEEE80211_DUR_DS_SIFS +
IEEE80211_DUR_DS_SHORT_PREAMBLE +
IEEE80211_DUR_DS_FAST_PLCPHDR) + cts + ack;
- d->d_data_dur = data_dur + IEEE80211_DUR_DS_SIFS +
- 2 * (IEEE80211_DUR_DS_SHORT_PREAMBLE +
- IEEE80211_DUR_DS_FAST_PLCPHDR) + ack;
- d->d_plcp_len = data_dur;
+ /* Note that this is the amount of time reserved *after*
+ * the packet is transmitted: just long enough for a SIFS
+ * and an ACK.
+ */
+ d->d_data_dur = IEEE80211_DUR_DS_SIFS +
+ IEEE80211_DUR_DS_SHORT_PREAMBLE + IEEE80211_DUR_DS_FAST_PLCPHDR +
+ ack;
if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
return 0;
- d->d_rts_dur += 3 * (IEEE80211_DUR_DS_LONG_PREAMBLE -
- IEEE80211_DUR_DS_SHORT_PREAMBLE) +
- 3 * (IEEE80211_DUR_DS_SLOW_PLCPHDR -
- IEEE80211_DUR_DS_FAST_PLCPHDR);
- d->d_data_dur += 2 * (IEEE80211_DUR_DS_LONG_PREAMBLE -
- IEEE80211_DUR_DS_SHORT_PREAMBLE) +
- 2 * (IEEE80211_DUR_DS_SLOW_PLCPHDR -
- IEEE80211_DUR_DS_FAST_PLCPHDR);
+ d->d_rts_dur += 3 * IEEE80211_DUR_DS_PREAMBLE_DIFFERENCE +
+ 3 * IEEE80211_DUR_DS_PLCPHDR_DIFFERENCE;
+ d->d_data_dur += IEEE80211_DUR_DS_PREAMBLE_DIFFERENCE +
+ IEEE80211_DUR_DS_PLCPHDR_DIFFERENCE;
return 0;
}
@@ -357,7 +358,7 @@ ieee80211_compute_duration1(int len, uint32_t flags, int rate,
*
* wh: 802.11 header
*
- * paylen: payload length (no FCS, no WEP header)
+ * len: packet length
*
* rate: MSDU speed, units 500kb/s
*
@@ -377,18 +378,20 @@ ieee80211_compute_duration1(int len, uint32_t flags, int rate,
* of first/only fragment
*/
int
-ieee80211_compute_duration(struct ieee80211_frame *wh, int paylen,
+ieee80211_compute_duration(struct ieee80211_frame *wh, int len,
uint32_t flags, int fraglen, int rate, struct ieee80211_duration *d0,
- struct ieee80211_duration *dn, int *npktp)
+ struct ieee80211_duration *dn, int *npktp, int debug)
{
int rc;
- int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen;
+ int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
hdrlen = sizeof(struct ieee80211_frame_addr4);
else
hdrlen = sizeof(struct ieee80211_frame);
+ paylen = len - hdrlen;
+
if ((flags & IEEE80211_F_WEPON) != 0) {
overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
#if 0 /* 802.11 lets us extend a fragment's length by the length of
@@ -424,10 +427,17 @@ ieee80211_compute_duration(struct ieee80211_frame *wh, int paylen,
else
firstlen = paylen + overlen;
+ if (debug) {
+ printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
+ "fraglen %d overlen %d len %d rate %d flags %08x\n",
+ __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
+ overlen, len, rate, flags);
+ }
rc = ieee80211_compute_duration1(firstlen + hdrlen, flags, rate, d0);
if (rc == -1)
return rc;
- if (npkt > 1) {
+
+ if (npkt <= 1) {
*dn = *d0;
return 0;
}
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 384779987c9..3ef2136ee35 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_proto.h,v 1.3 2004/12/23 11:54:09 jsg Exp $ */
+/* $OpenBSD: ieee80211_proto.h,v 1.4 2004/12/23 12:27:25 jsg Exp $ */
/* $NetBSD: ieee80211_proto.h,v 1.3 2003/10/13 04:23:56 dyoung Exp $ */
/*-
@@ -82,7 +82,7 @@ extern int ieee80211_ibss_merge(struct ieee80211com *,
struct ieee80211_node *, u_int64_t);
extern int ieee80211_compute_duration(struct ieee80211_frame *, int,
uint32_t, int, int, struct ieee80211_duration *,
- struct ieee80211_duration *, int *);
+ struct ieee80211_duration *, int *, int);
extern const char *ieee80211_state_name[IEEE80211_S_MAX];
#endif /* _NET80211_IEEE80211_PROTO_H_ */