Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Apr 2009 13:44:59 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r191689 - projects/mesh11s/sys/net80211
Message-ID:  <200904301344.n3UDixdY013795@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Thu Apr 30 13:44:59 2009
New Revision: 191689
URL: http://svn.freebsd.org/changeset/base/191689

Log:
  Move ieee80211_recv_action() to ieee80211_input.c and
  ieee80211_send_action() to ieee80211_output.c because they are used both
  by 11s and 11n.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/mesh11s/sys/net80211/ieee80211_ht.c
  projects/mesh11s/sys/net80211/ieee80211_ht.h
  projects/mesh11s/sys/net80211/ieee80211_input.c
  projects/mesh11s/sys/net80211/ieee80211_input.h
  projects/mesh11s/sys/net80211/ieee80211_output.c
  projects/mesh11s/sys/net80211/ieee80211_proto.h

Modified: projects/mesh11s/sys/net80211/ieee80211_ht.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ht.c	Thu Apr 30 13:36:26 2009	(r191688)
+++ projects/mesh11s/sys/net80211/ieee80211_ht.c	Thu Apr 30 13:44:59 2009	(r191689)
@@ -1732,84 +1732,6 @@ ieee80211_aggr_recv_action(struct ieee80
 }
 
 /*
- * Process a received 802.11n action frame.
- * Aggregation-related frames are assumed to be handled
- * already; we handle any other frames we can, otherwise
- * complain about being unsupported (with debugging).
- */
-void
-ieee80211_recv_action(struct ieee80211_node *ni,
-	const uint8_t *frm, const uint8_t *efrm)
-{
-	struct ieee80211vap *vap = ni->ni_vap;
-	const struct ieee80211_action *ia;
-	int chw;
-
-	ia = (const struct ieee80211_action *) frm;
-	switch (ia->ia_category) {
-	case IEEE80211_ACTION_CAT_BA:
-		IEEE80211_NOTE(vap,
-		    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-		    "%s: BA action %d not implemented", __func__,
-		    ia->ia_action);
-		vap->iv_stats.is_rx_mgtdiscard++;
-		break;
-	case IEEE80211_ACTION_CAT_HT:
-		switch (ia->ia_action) {
-		case IEEE80211_ACTION_HT_TXCHWIDTH:
-			chw = frm[2] == IEEE80211_A_HT_TXCHWIDTH_2040 ? 40 : 20;
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-		            "%s: HT txchwidth, width %d%s",
-			    __func__, chw, ni->ni_chw != chw ? "*" : "");
-			if (chw != ni->ni_chw) {
-				ni->ni_chw = chw;
-				/* XXX notify on change */
-			}
-			break;
-		case IEEE80211_ACTION_HT_MIMOPWRSAVE: {
-			const struct ieee80211_action_ht_mimopowersave *mps =
-			    (const struct ieee80211_action_ht_mimopowersave *) ia;
-			/* XXX check iv_htcaps */
-			if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA)
-				ni->ni_flags |= IEEE80211_NODE_MIMO_PS;
-			else
-				ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS;
-			if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE)
-				ni->ni_flags |= IEEE80211_NODE_MIMO_RTS;
-			else
-				ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS;
-			/* XXX notify on change */
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-		            "%s: HT MIMO PS (%s%s)", __func__,
-			    (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ?
-				"on" : "off",
-			    (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ?
-				"+rts" : ""
-			);
-			break;
-		}
-		default:
-			IEEE80211_NOTE(vap,
-			   IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-		           "%s: HT action %d not implemented", __func__,
-			   ia->ia_action);
-			vap->iv_stats.is_rx_mgtdiscard++;
-			break;
-		}
-		break;
-	default:
-		IEEE80211_NOTE(vap,
-		    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-		    "%s: category %d not implemented", __func__,
-		    ia->ia_category);
-		vap->iv_stats.is_rx_mgtdiscard++;
-		break;
-	}
-}
-
-/*
  * Transmit processing.
  */
 
@@ -2102,199 +2024,6 @@ bad:
 }
 
 /*
- * Send an action management frame.  The arguments are stuff
- * into a frame without inspection; the caller is assumed to
- * prepare them carefully (e.g. based on the aggregation state).
- */
-int
-ieee80211_send_action(struct ieee80211_node *ni,
-	int category, int action, uint16_t args[4])
-{
-#define	senderr(_x, _v)	do { vap->iv_stats._v++; ret = _x; goto bad; } while (0)
-#define	ADDSHORT(frm, v) do {			\
-	frm[0] = (v) & 0xff;			\
-	frm[1] = (v) >> 8;			\
-	frm += 2;				\
-} while (0)
-	struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211com *ic = ni->ni_ic;
-	struct ieee80211_bpf_params params;
-	struct mbuf *m;
-	uint8_t *frm;
-	uint16_t baparamset;
-	int ret, addsize;
-
-	KASSERT(ni != NULL, ("null node"));
-
-	/*
-	 * Hold a reference on the node so it doesn't go away until after
-	 * the xmit is complete all the way in the driver.  On error we
-	 * will remove our reference.
-	 */
-	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
-		"ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
-		__func__, __LINE__,
-		ni, ether_sprintf(ni->ni_macaddr),
-		ieee80211_node_refcnt(ni)+1);
-	ieee80211_ref_node(ni);
-
-	addsize = 0;
-	switch (category) {
-	case IEEE80211_ACTION_CAT_BA:
-	case IEEE80211_ACTION_CAT_HT:
-		addsize += sizeof(struct ieee80211_action_ba_addbaresponse);
-		break;
-	case IEEE80211_ACTION_CAT_MESHPEERING:
-		addsize += sizeof(uint16_t);		/* capabilities */
-		addsize += 2 + vap->iv_meshidlen;	/* Mesh ID */
-		addsize += sizeof(struct ieee80211_meshconf_ie);
-		/* On Open frames, the peer link ID is not sent */
-		if (action == IEEE80211_ACTION_MESHPEERING_OPEN)
-			addsize += sizeof(struct ieee80211_meshpeer_ie) - 2;
-		else
-			addsize += sizeof(struct ieee80211_meshpeer_ie);
-		break;
-	}
-	m = ieee80211_getmgtframe(&frm,
-		ic->ic_headroom + sizeof(struct ieee80211_frame),
-		  sizeof(uint16_t)	/* action+category */
-		/* XXX may action payload */
-		+ addsize
-		
-	);
-	if (m == NULL)
-		senderr(ENOMEM, is_tx_nobuf);
-
-	*frm++ = category;
-	*frm++ = action;
-	switch (category) {
-	case IEEE80211_ACTION_CAT_BA:
-		switch (action) {
-		case IEEE80211_ACTION_BA_ADDBA_REQUEST:
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-			    "send ADDBA request: dialogtoken %d "
-			    "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x",
-			    args[0], args[1], MS(args[1], IEEE80211_BAPS_TID),
-			    args[2], args[3]);
-
-			*frm++ = args[0];	/* dialog token */
-			ADDSHORT(frm, args[1]);	/* baparamset */
-			ADDSHORT(frm, args[2]);	/* batimeout */
-			ADDSHORT(frm, args[3]);	/* baseqctl */
-			break;
-		case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-			    "send ADDBA response: dialogtoken %d status %d "
-			    "baparamset 0x%x (tid %d) batimeout %d",
-			    args[0], args[1], args[2],
-			    MS(args[2], IEEE80211_BAPS_TID), args[3]);
-
-			*frm++ = args[0];	/* dialog token */
-			ADDSHORT(frm, args[1]);	/* statuscode */
-			ADDSHORT(frm, args[2]);	/* baparamset */
-			ADDSHORT(frm, args[3]);	/* batimeout */
-			break;
-		case IEEE80211_ACTION_BA_DELBA:
-			/* XXX */
-			baparamset = SM(args[0], IEEE80211_DELBAPS_TID)
-				   | args[1]
-				   ;
-			ADDSHORT(frm, baparamset);
-			ADDSHORT(frm, args[2]);	/* reason code */
-
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-			    "send DELBA action: tid %d, initiator %d reason %d",
-			    args[0], args[1], args[2]);
-			break;
-		default:
-			goto badaction;
-		}
-		break;
-	case IEEE80211_ACTION_CAT_HT:
-		switch (action) {
-		case IEEE80211_ACTION_HT_TXCHWIDTH:
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
-			    ni, "send HT txchwidth: width %d",
-			    IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20
-			);
-			*frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 
-				IEEE80211_A_HT_TXCHWIDTH_2040 :
-				IEEE80211_A_HT_TXCHWIDTH_20;
-			break;
-		default:
-			goto badaction;
-		}
-		break;
-	case IEEE80211_ACTION_CAT_MESHPEERING:
-
-		switch (action) {
-		case IEEE80211_ACTION_MESHPEERING_OPEN:
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
-			    "send PEER OPEN action: lid %x", args[0]);
-			*frm++ = 0;	/* capabilites */
-			*frm++ = 0;
-			frm = ieee80211_add_meshid(frm, vap);
-			frm = ieee80211_add_meshconf(frm, vap);
-			*frm++ = IEEE80211_ELEMID_MESHPEER;
-			*frm++ = 3;			        /* len */
-			*frm++ = IEEE80211_MESH_PEER_LINK_OPEN; /* subtype */
-			ADDSHORT(frm, args[0]);		        /* local ID */
-			break;
-		case IEEE80211_ACTION_MESHPEERING_CONFIRM:
-			IEEE80211_NOTE(vap,
-			    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
-			    "send PEER CONFIRM action: lid %x, pid %x",
-			    args[0], args[1]);
-			*frm++ = 0;	/* capabilites */
-			*frm++ = 0;
-			*frm++ = 0;	/* status code */
-			*frm++ = 0;
-			*frm++ = 0;	/* AID */
-			*frm++ = 0;
-			frm = ieee80211_add_meshid(frm, vap);
-			frm = ieee80211_add_meshconf(frm, vap);
-			*frm++ = IEEE80211_ELEMID_MESHPEER;
-			*frm++ = 5;				   /* len */
-			*frm++ = IEEE80211_MESH_PEER_LINK_CONFIRM; /* subtype */
-			ADDSHORT(frm, args[0]);
-			ADDSHORT(frm, args[1]);
-			break;
-		}
-		break;
-	default:
-	badaction:
-		IEEE80211_NOTE(vap,
-		    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
-		    "%s: unsupported category %d action %d", __func__,
-		    category, action);
-		senderr(EINVAL, is_tx_unknownmgt);
-		/* NOTREACHED */
-	}
-	m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
-
-	memset(&params, 0, sizeof(params));
-	params.ibp_pri = WME_AC_VO;
-	params.ibp_rate0 = ni->ni_txparms->mgmtrate;
-	/* NB: we know all frames are unicast */
-	params.ibp_try0 = ni->ni_txparms->maxretry;
-	params.ibp_power = ni->ni_txpower;
-	return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION,
-	     &params);
-bad:
-	ieee80211_free_node(ni);
-	if (m != NULL)
-		m_freem(m);
-	return ret;
-#undef ADDSHORT
-#undef senderr
-}
-
-/*
  * Construct the MCS bit mask for inclusion
  * in an HT information element.
  */

Modified: projects/mesh11s/sys/net80211/ieee80211_ht.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ht.h	Thu Apr 30 13:36:26 2009	(r191688)
+++ projects/mesh11s/sys/net80211/ieee80211_ht.h	Thu Apr 30 13:44:59 2009	(r191689)
@@ -186,16 +186,12 @@ void	ieee80211_parse_htinfo(struct ieee8
 void	ieee80211_ht_updateparams(struct ieee80211_node *, const uint8_t *,
 		const uint8_t *);
 void	ieee80211_ht_updatehtcap(struct ieee80211_node *, const uint8_t *);
-void	ieee80211_recv_action(struct ieee80211_node *,
-		const uint8_t *, const uint8_t *);
 int	ieee80211_ampdu_request(struct ieee80211_node *,
 		struct ieee80211_tx_ampdu *);
 void	ieee80211_ampdu_stop(struct ieee80211_node *,
 		struct ieee80211_tx_ampdu *, int);
 int	ieee80211_send_bar(struct ieee80211_node *, struct ieee80211_tx_ampdu *,
 		ieee80211_seq);
-int	ieee80211_send_action(struct ieee80211_node *,
-		int, int, uint16_t [4]);
 uint8_t	*ieee80211_add_htcap(uint8_t *, struct ieee80211_node *);
 uint8_t	*ieee80211_add_htcap_vendor(uint8_t *, struct ieee80211_node *);
 uint8_t	*ieee80211_add_htinfo(uint8_t *, struct ieee80211_node *);

Modified: projects/mesh11s/sys/net80211/ieee80211_input.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_input.c	Thu Apr 30 13:36:26 2009	(r191688)
+++ projects/mesh11s/sys/net80211/ieee80211_input.c	Thu Apr 30 13:44:59 2009	(r191689)
@@ -739,6 +739,85 @@ ieee80211_parse_action(struct ieee80211_
 	return 0;
 }
 
+/*
+ * Process a received 802.11 action frame.
+ * Aggregation-related frames are assumed to be handled
+ * already; we handle any other frames we can, otherwise
+ * complain about being unsupported (with debugging).
+ */
+void
+ieee80211_recv_action(struct ieee80211_node *ni,
+	const uint8_t *frm, const uint8_t *efrm)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+	const struct ieee80211_action *ia;
+	int chw;
+
+	ia = (const struct ieee80211_action *) frm;
+	switch (ia->ia_category) {
+	case IEEE80211_ACTION_CAT_BA:
+		IEEE80211_NOTE(vap,
+		    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+		    "%s: BA action %d not implemented", __func__,
+		    ia->ia_action);
+		vap->iv_stats.is_rx_mgtdiscard++;
+		break;
+	case IEEE80211_ACTION_CAT_HT:
+		switch (ia->ia_action) {
+		case IEEE80211_ACTION_HT_TXCHWIDTH:
+			chw = frm[2] == IEEE80211_A_HT_TXCHWIDTH_2040 ? 40 : 20;
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+		            "%s: HT txchwidth, width %d%s",
+			    __func__, chw, ni->ni_chw != chw ? "*" : "");
+			if (chw != ni->ni_chw) {
+				ni->ni_chw = chw;
+				/* XXX notify on change */
+			}
+			break;
+		case IEEE80211_ACTION_HT_MIMOPWRSAVE: {
+			const struct ieee80211_action_ht_mimopowersave *mps =
+			    (const struct ieee80211_action_ht_mimopowersave *) ia;
+			/* XXX check iv_htcaps */
+			if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA)
+				ni->ni_flags |= IEEE80211_NODE_MIMO_PS;
+			else
+				ni->ni_flags &= ~IEEE80211_NODE_MIMO_PS;
+			if (mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_MODE)
+				ni->ni_flags |= IEEE80211_NODE_MIMO_RTS;
+			else
+				ni->ni_flags &= ~IEEE80211_NODE_MIMO_RTS;
+			/* XXX notify on change */
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+		            "%s: HT MIMO PS (%s%s)", __func__,
+			    (ni->ni_flags & IEEE80211_NODE_MIMO_PS) ?
+				"on" : "off",
+			    (ni->ni_flags & IEEE80211_NODE_MIMO_RTS) ?
+				"+rts" : ""
+			);
+			break;
+		}
+		default:
+			IEEE80211_NOTE(vap,
+			   IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+		           "%s: HT action %d not implemented", __func__,
+			   ia->ia_action);
+			vap->iv_stats.is_rx_mgtdiscard++;
+			break;
+		}
+		break;
+	default:
+		IEEE80211_NOTE(vap,
+		    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+		    "%s: category %d not implemented", __func__,
+		    ia->ia_category);
+		vap->iv_stats.is_rx_mgtdiscard++;
+		break;
+	}
+}
+
+
 #ifdef IEEE80211_DEBUG
 /*
  * Debugging support.

Modified: projects/mesh11s/sys/net80211/ieee80211_input.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_input.h	Thu Apr 30 13:36:26 2009	(r191688)
+++ projects/mesh11s/sys/net80211/ieee80211_input.h	Thu Apr 30 13:44:59 2009	(r191689)
@@ -156,4 +156,6 @@ int	ieee80211_alloc_challenge(struct iee
 int	ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *,
 		struct ieee80211_scanparams *);
 int	ieee80211_parse_action(struct ieee80211_node *, struct mbuf *);
+void	ieee80211_recv_action(struct ieee80211_node *, const uint8_t *,
+		const uint8_t *);
 #endif /* _NET80211_IEEE80211_INPUT_H_ */

Modified: projects/mesh11s/sys/net80211/ieee80211_output.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_output.c	Thu Apr 30 13:36:26 2009	(r191688)
+++ projects/mesh11s/sys/net80211/ieee80211_output.c	Thu Apr 30 13:44:59 2009	(r191689)
@@ -527,6 +527,204 @@ ieee80211_send_setup(
 }
 
 /*
+ * Send an action management frame.  The arguments are stuff
+ * into a frame without inspection; the caller is assumed to
+ * prepare them carefully (e.g. based on the aggregation state).
+ */
+int
+ieee80211_send_action(struct ieee80211_node *ni,
+	int category, int action, uint16_t args[4])
+{
+#define	senderr(_x, _v)	do { vap->iv_stats._v++; ret = _x; goto bad; } while (0)
+#define	ADDSHORT(frm, v) do {			\
+	frm[0] = (v) & 0xff;			\
+	frm[1] = (v) >> 8;			\
+	frm += 2;				\
+} while (0)
+#define	MS(_v, _f)	(((_v) & _f) >> _f##_S)
+#define	SM(_v, _f)	(((_v) << _f##_S) & _f)
+	struct ieee80211vap *vap = ni->ni_vap;
+	struct ieee80211com *ic = ni->ni_ic;
+	struct ieee80211_bpf_params params;
+	struct mbuf *m;
+	uint8_t *frm;
+	uint16_t baparamset;
+	int ret, addsize;
+
+	KASSERT(ni != NULL, ("null node"));
+
+	/*
+	 * Hold a reference on the node so it doesn't go away until after
+	 * the xmit is complete all the way in the driver.  On error we
+	 * will remove our reference.
+	 */
+	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
+		"ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
+		__func__, __LINE__,
+		ni, ether_sprintf(ni->ni_macaddr),
+		ieee80211_node_refcnt(ni)+1);
+	ieee80211_ref_node(ni);
+
+	addsize = 0;
+	switch (category) {
+	case IEEE80211_ACTION_CAT_BA:
+	case IEEE80211_ACTION_CAT_HT:
+		addsize += sizeof(struct ieee80211_action_ba_addbaresponse);
+		break;
+	case IEEE80211_ACTION_CAT_MESHPEERING:
+		addsize += sizeof(uint16_t);		/* capabilities */
+		addsize += 2 + vap->iv_meshidlen;	/* Mesh ID */
+		addsize += sizeof(struct ieee80211_meshconf_ie);
+		/* On Open frames, the peer link ID is not sent */
+		if (action == IEEE80211_ACTION_MESHPEERING_OPEN)
+			addsize += sizeof(struct ieee80211_meshpeer_ie) - 2;
+		else
+			addsize += sizeof(struct ieee80211_meshpeer_ie);
+		break;
+	}
+	m = ieee80211_getmgtframe(&frm,
+		ic->ic_headroom + sizeof(struct ieee80211_frame),
+		  sizeof(uint16_t)	/* action+category */
+		/* XXX may action payload */
+		+ addsize
+		
+	);
+	if (m == NULL)
+		senderr(ENOMEM, is_tx_nobuf);
+
+	*frm++ = category;
+	*frm++ = action;
+	switch (category) {
+	case IEEE80211_ACTION_CAT_BA:
+		switch (action) {
+		case IEEE80211_ACTION_BA_ADDBA_REQUEST:
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+			    "send ADDBA request: dialogtoken %d "
+			    "baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x",
+			    args[0], args[1], MS(args[1], IEEE80211_BAPS_TID),
+			    args[2], args[3]);
+
+			*frm++ = args[0];	/* dialog token */
+			ADDSHORT(frm, args[1]);	/* baparamset */
+			ADDSHORT(frm, args[2]);	/* batimeout */
+			ADDSHORT(frm, args[3]);	/* baseqctl */
+			break;
+		case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+			    "send ADDBA response: dialogtoken %d status %d "
+			    "baparamset 0x%x (tid %d) batimeout %d",
+			    args[0], args[1], args[2],
+			    MS(args[2], IEEE80211_BAPS_TID), args[3]);
+
+			*frm++ = args[0];	/* dialog token */
+			ADDSHORT(frm, args[1]);	/* statuscode */
+			ADDSHORT(frm, args[2]);	/* baparamset */
+			ADDSHORT(frm, args[3]);	/* batimeout */
+			break;
+		case IEEE80211_ACTION_BA_DELBA:
+			/* XXX */
+			baparamset = SM(args[0], IEEE80211_DELBAPS_TID)
+				   | args[1]
+				   ;
+			ADDSHORT(frm, baparamset);
+			ADDSHORT(frm, args[2]);	/* reason code */
+
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+			    "send DELBA action: tid %d, initiator %d reason %d",
+			    args[0], args[1], args[2]);
+			break;
+		default:
+			goto badaction;
+		}
+		break;
+	case IEEE80211_ACTION_CAT_HT:
+		switch (action) {
+		case IEEE80211_ACTION_HT_TXCHWIDTH:
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
+			    ni, "send HT txchwidth: width %d",
+			    IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 40 : 20
+			);
+			*frm++ = IEEE80211_IS_CHAN_HT40(ni->ni_chan) ? 
+				IEEE80211_A_HT_TXCHWIDTH_2040 :
+				IEEE80211_A_HT_TXCHWIDTH_20;
+			break;
+		default:
+			goto badaction;
+		}
+		break;
+	case IEEE80211_ACTION_CAT_MESHPEERING:
+
+		switch (action) {
+		case IEEE80211_ACTION_MESHPEERING_OPEN:
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
+			    "send PEER OPEN action: lid %x", args[0]);
+			*frm++ = 0;	/* capabilites */
+			*frm++ = 0;
+			frm = ieee80211_add_meshid(frm, vap);
+			frm = ieee80211_add_meshconf(frm, vap);
+			*frm++ = IEEE80211_ELEMID_MESHPEER;
+			*frm++ = 3;			        /* len */
+			*frm++ = IEEE80211_MESH_PEER_LINK_OPEN; /* subtype */
+			ADDSHORT(frm, args[0]);		        /* local ID */
+			break;
+		case IEEE80211_ACTION_MESHPEERING_CONFIRM:
+			IEEE80211_NOTE(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
+			    "send PEER CONFIRM action: lid %x, pid %x",
+			    args[0], args[1]);
+			*frm++ = 0;	/* capabilites */
+			*frm++ = 0;
+			*frm++ = 0;	/* status code */
+			*frm++ = 0;
+			*frm++ = 0;	/* AID */
+			*frm++ = 0;
+			frm = ieee80211_add_meshid(frm, vap);
+			frm = ieee80211_add_meshconf(frm, vap);
+			*frm++ = IEEE80211_ELEMID_MESHPEER;
+			*frm++ = 5;				   /* len */
+			*frm++ = IEEE80211_MESH_PEER_LINK_CONFIRM; /* subtype */
+			ADDSHORT(frm, args[0]);
+			ADDSHORT(frm, args[1]);
+			break;
+		}
+		break;
+	default:
+	badaction:
+		IEEE80211_NOTE(vap,
+		    IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
+		    "%s: unsupported category %d action %d", __func__,
+		    category, action);
+		senderr(EINVAL, is_tx_unknownmgt);
+		/* NOTREACHED */
+	}
+	m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
+
+	memset(&params, 0, sizeof(params));
+	params.ibp_pri = WME_AC_VO;
+	params.ibp_rate0 = ni->ni_txparms->mgmtrate;
+	/* NB: we know all frames are unicast */
+	params.ibp_try0 = ni->ni_txparms->maxretry;
+	params.ibp_power = ni->ni_txpower;
+	return ieee80211_mgmt_output(ni, m, IEEE80211_FC0_SUBTYPE_ACTION,
+	     &params);
+bad:
+	ieee80211_free_node(ni);
+	if (m != NULL)
+		m_freem(m);
+	return ret;
+#undef ADDSHORT
+#undef senderr
+#undef MS
+#undef SM
+}
+
+
+/*
  * Send a management frame to the specified node.  The node pointer
  * must have a reference as the pointer will be passed to the driver
  * and potentially held for a long time.  If the frame is successfully

Modified: projects/mesh11s/sys/net80211/ieee80211_proto.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_proto.h	Thu Apr 30 13:36:26 2009	(r191688)
+++ projects/mesh11s/sys/net80211/ieee80211_proto.h	Thu Apr 30 13:44:59 2009	(r191689)
@@ -65,6 +65,7 @@ void	ieee80211_syncflag_ext(struct ieee8
 int	ieee80211_input_all(struct ieee80211com *, struct mbuf *,
 		int, int, uint32_t);
 struct ieee80211_bpf_params;
+int	ieee80211_send_action(struct ieee80211_node *, int, int, uint16_t [4]);
 int	ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
 		struct ieee80211_bpf_params *);
 int	ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904301344.n3UDixdY013795>