diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net80211/ieee80211_node.c | 15 | ||||
-rw-r--r-- | sys/net80211/ieee80211_output.c | 39 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.h | 3 | ||||
-rw-r--r-- | sys/net80211/ieee80211_var.h | 8 |
4 files changed, 61 insertions, 4 deletions
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 72108d075b2..de4ee19c471 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.c,v 1.24 2007/06/16 13:17:05 damien Exp $ */ +/* $OpenBSD: ieee80211_node.c,v 1.25 2007/07/02 16:46:44 damien Exp $ */ /* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */ /*- @@ -110,6 +110,17 @@ ieee80211_node_attach(struct ifnet *ifp) ic->ic_max_aid = 0; } else memset(ic->ic_aid_bitmap, 0, size); + + if (ic->ic_caps & (IEEE80211_C_HOSTAP | IEEE80211_C_IBSS)) { + ic->ic_tim_len = howmany(ic->ic_max_aid, 8); + MALLOC(ic->ic_tim_bitmap, u_int8_t *, ic->ic_tim_len, M_DEVBUF, + M_NOWAIT); + if (ic->ic_tim_bitmap == NULL) { + printf("%s: no memory for TIM bitmap!\n", __func__); + ic->ic_tim_len = 0; + } else + memset(ic->ic_tim_bitmap, 0, ic->ic_tim_len); + } } struct ieee80211_node * @@ -152,6 +163,8 @@ ieee80211_node_detach(struct ifnet *ifp) ieee80211_free_allnodes(ic); if (ic->ic_aid_bitmap != NULL) FREE(ic->ic_aid_bitmap, M_DEVBUF); + if (ic->ic_tim_bitmap != NULL) + FREE(ic->ic_tim_bitmap, M_DEVBUF); } /* diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 4e3535c7c49..b3c069ad513 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_output.c,v 1.31 2007/07/02 16:19:49 damien Exp $ */ +/* $OpenBSD: ieee80211_output.c,v 1.32 2007/07/02 16:46:44 damien Exp $ */ /* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */ /*- @@ -660,6 +660,43 @@ ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic) } /* + * Add a TIM element to a frame (see Annex L). + */ +u_int8_t * +ieee80211_add_tim(u_int8_t *frm, struct ieee80211com *ic) +{ + u_int i, offset = 0, len; + + /* find first non-zero octet in the virtual bit map */ + for (i = 0; i < ic->ic_tim_len && ic->ic_tim_bitmap[i] == 0; i++); + + /* clear the lsb as it is reserved for the broadcast indication bit */ + if (i < ic->ic_tim_len) + offset = i & ~1; + + /* find last non-zero octet in the virtual bit map */ + for (i = ic->ic_tim_len - 1; i > 0 && ic->ic_tim_bitmap[i] != 0; i--); + + len = i - offset + 1; + + *frm++ = IEEE80211_ELEMID_TIM; + *frm++ = len + 3; /* length */ + *frm++ = ic->ic_dtim_count; /* DTIM count */ + *frm++ = ic->ic_dtim_period; /* DTIM period */ + + /* Bitmap Control */ + *frm = offset; + /* set broadcast/multicast indication bit if necessary */ + if (ic->ic_dtim_count == 0 && ic->ic_tim_mcast) + *frm |= 0x01; + frm++; + + /* Partial Virtual Bitmap */ + memcpy(frm, &ic->ic_tim_bitmap[offset], len); + return frm + len; +} + +/* * Add a QoS Capability element to a frame. */ u_int8_t * diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index a73eca10896..9964a0fd49e 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_proto.h,v 1.15 2007/06/21 21:06:12 damien Exp $ */ +/* $OpenBSD: ieee80211_proto.h,v 1.16 2007/07/02 16:46:44 damien Exp $ */ /* $NetBSD: ieee80211_proto.h,v 1.3 2003/10/13 04:23:56 dyoung Exp $ */ /*- @@ -84,6 +84,7 @@ extern u_int8_t *ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *); extern u_int8_t *ieee80211_add_ssid(u_int8_t *, const u_int8_t *, u_int); extern u_int8_t *ieee80211_add_erp(u_int8_t *, struct ieee80211com *); +extern u_int8_t *ieee80211_add_tim(u_int8_t *, struct ieee80211com *); extern u_int8_t *ieee80211_add_qos_capability(u_int8_t *, struct ieee80211com *); extern u_int8_t *ieee80211_add_edca_params(u_int8_t *, struct ieee80211com *); diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index d1c6805f06c..12ca583d61a 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_var.h,v 1.25 2007/06/21 20:11:16 damien Exp $ */ +/* $OpenBSD: ieee80211_var.h,v 1.26 2007/07/02 16:46:44 damien Exp $ */ /* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */ /*- @@ -253,6 +253,12 @@ struct ieee80211com { */ struct ieee80211_edca_ac_params ic_edca_ac[EDCA_NUM_AC]; u_int ic_edca_updtcount; + + u_int8_t *ic_tim_bitmap; + u_int ic_tim_len; + u_int ic_tim_mcast; + u_int ic_dtim_period; + u_int ic_dtim_count; }; #define ic_if ic_ac.ac_if #define ic_softc ic_if.if_softc |