summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_node.c15
-rw-r--r--sys/net80211/ieee80211_output.c39
-rw-r--r--sys/net80211/ieee80211_proto.h3
-rw-r--r--sys/net80211/ieee80211_var.h8
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