⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee80211_beacon.c

📁 Linux下wifi实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |		IEEE80211_FC0_SUBTYPE_BEACON;	wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;	*(u_int16_t *)wh->i_dur = 0;	IEEE80211_ADDR_COPY(wh->i_addr1, ic->ic_dev->broadcast);	IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);	IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);	*(u_int16_t *)wh->i_seq = 0;	return skb;}EXPORT_SYMBOL(ieee80211_beacon_alloc);/* * Update the dynamic parts of a beacon frame based on the current state. */intieee80211_beacon_update(struct ieee80211_node *ni,	struct ieee80211_beacon_offsets *bo, struct sk_buff *skb, int mcast){	struct ieee80211vap *vap = ni->ni_vap;	struct ieee80211com *ic = ni->ni_ic;	int len_changed = 0;	u_int16_t capinfo;	IEEE80211_LOCK(ic);	if ((ic->ic_flags & IEEE80211_F_DOTH) &&	    (vap->iv_flags & IEEE80211_F_CHANSWITCH) &&	    (vap->iv_chanchange_count == ic->ic_chanchange_tbtt)) {		u_int8_t *frm;		struct ieee80211_channel *c;		vap->iv_chanchange_count = 0;		IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,			"%s: reinit beacon\n", __func__);		/* 		 * NB: ic_bsschan is in the DSPARMS beacon IE, so must set this		 *     prior to the beacon re-init, below.		 */		c = ieee80211_doth_findchan(vap, ic->ic_chanchange_chan);		if (c == NULL) {			IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,				"%s: find channel failure\n", __func__);			return 0;		}		ic->ic_bsschan = c;		skb_pull(skb, sizeof(struct ieee80211_frame));		skb_trim(skb, 0);		frm = skb->data;		skb_put(skb, ieee80211_beacon_init(ni, bo, frm) - frm); 		skb_push(skb, sizeof(struct ieee80211_frame));		vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;		ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;		/* NB: only for the first VAP to get here */		if (ic->ic_curchan != c) {			ic->ic_curchan = c;			ic->ic_set_channel(ic);		}		len_changed = 1;	}	/* XXX faster to recalculate entirely or just changes? */	if (vap->iv_opmode == IEEE80211_M_IBSS)		capinfo = IEEE80211_CAPINFO_IBSS;	else		capinfo = IEEE80211_CAPINFO_ESS;	if (vap->iv_flags & IEEE80211_F_PRIVACY)		capinfo |= IEEE80211_CAPINFO_PRIVACY;	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&	    IEEE80211_IS_CHAN_2GHZ(ic->ic_bsschan))		capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;	if (ic->ic_flags & IEEE80211_F_SHSLOT)		capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;	if (ic->ic_flags & IEEE80211_F_DOTH)		capinfo |= IEEE80211_CAPINFO_SPECTRUM_MGMT;	*bo->bo_caps = htole16(capinfo);	if (vap->iv_flags & IEEE80211_F_WME) {		struct ieee80211_wme_state *wme = &ic->ic_wme;		/*		 * Check for agressive mode change.  When there is		 * significant high priority traffic in the BSS		 * throttle back BE traffic by using conservative		 * parameters.  Otherwise BE uses agressive params		 * to optimize performance of legacy/non-QoS traffic.		 */		if (wme->wme_flags & WME_F_AGGRMODE) {			if (wme->wme_hipri_traffic >			    wme->wme_hipri_switch_thresh) {				IEEE80211_NOTE(vap, IEEE80211_MSG_WME, ni,					"%s: traffic %u, disable aggressive mode",					__func__, wme->wme_hipri_traffic);				wme->wme_flags &= ~WME_F_AGGRMODE;				ieee80211_wme_updateparams_locked(vap);				wme->wme_hipri_traffic =					wme->wme_hipri_switch_hysteresis;			} else				wme->wme_hipri_traffic = 0;		} else {			if (wme->wme_hipri_traffic <=			    wme->wme_hipri_switch_thresh) {				IEEE80211_NOTE(vap, IEEE80211_MSG_WME, ni,					"%s: traffic %u, enable aggressive mode",					__func__, wme->wme_hipri_traffic);				wme->wme_flags |= WME_F_AGGRMODE;				ieee80211_wme_updateparams_locked(vap);				wme->wme_hipri_traffic = 0;			} else				wme->wme_hipri_traffic =					wme->wme_hipri_switch_hysteresis;		}		/* XXX multi-bss */		if (vap->iv_flags & IEEE80211_F_WMEUPDATE) {			(void) ieee80211_add_wme_param(bo->bo_wme, wme, IEEE80211_VAP_UAPSD_ENABLED(vap));			vap->iv_flags &= ~IEEE80211_F_WMEUPDATE;		}	}	if (vap->iv_opmode == IEEE80211_M_HOSTAP) {	/* NB: no IBSS support*/		struct ieee80211_tim_ie *tie =			(struct ieee80211_tim_ie *) bo->bo_tim;		if (vap->iv_flags & IEEE80211_F_TIMUPDATE) {			u_int timlen, timoff, i;			/*			 * ATIM/DTIM needs updating.  If it fits in the			 * current space allocated then just copy in the			 * new bits.  Otherwise we need to move any trailing			 * data to make room.  Note that we know there is			 * contiguous space because ieee80211_beacon_allocate			 * ensures there is space in the mbuf to write a			 * maximal-size virtual bitmap (based on ic_max_aid).			 */			/*			 * Calculate the bitmap size and offset, copy any			 * trailer out of the way, and then copy in the			 * new bitmap and update the information element.			 * Note that the tim bitmap must contain at least			 * one byte and any offset must be even.			 */			if (vap->iv_ps_pending != 0) {				timoff = 128;		/* impossibly large */				for (i = 0; i < vap->iv_tim_len; i++)					if (vap->iv_tim_bitmap[i]) {						timoff = i &~ 1;						break;					}				KASSERT(timoff != 128, ("tim bitmap empty!"));				for (i = vap->iv_tim_len-1; i >= timoff; i--)					if (vap->iv_tim_bitmap[i])						break;				timlen = 1 + (i - timoff);			} else {				timoff = 0;				timlen = 1;			}			if (timlen != bo->bo_tim_len) {				/* copy up/down trailer */				int trailer_adjust =					(tie->tim_bitmap+timlen) - (bo->bo_tim_trailer);				memmove(tie->tim_bitmap+timlen, bo->bo_tim_trailer,					bo->bo_tim_trailerlen);				bo->bo_tim_trailer = tie->tim_bitmap+timlen;				bo->bo_chanswitch += trailer_adjust;				bo->bo_wme += trailer_adjust;				bo->bo_erp += trailer_adjust;				bo->bo_ath_caps += trailer_adjust;				bo->bo_xr += trailer_adjust;				if (timlen > bo->bo_tim_len)					skb_put(skb, timlen - bo->bo_tim_len);				else					skb_trim(skb, skb->len - (bo->bo_tim_len - timlen));				bo->bo_tim_len = timlen;				/* update information element */				tie->tim_len = 3 + timlen;				tie->tim_bitctl = timoff;				len_changed = 1;			}			memcpy(tie->tim_bitmap, vap->iv_tim_bitmap + timoff,				bo->bo_tim_len);			vap->iv_flags &= ~IEEE80211_F_TIMUPDATE;			IEEE80211_NOTE(vap, IEEE80211_MSG_POWER, ni,				"%s: TIM updated, pending %u, off %u, len %u",				__func__, vap->iv_ps_pending, timoff, timlen);		}		/* count down DTIM period */		if (tie->tim_count == 0)			tie->tim_count = tie->tim_period - 1;		else			tie->tim_count--;		/* update state for buffered multicast frames on DTIM */		if (mcast && (tie->tim_count == 0))			tie->tim_bitctl |= 1;		else			tie->tim_bitctl &= ~1;		if ((ic->ic_flags & IEEE80211_F_DOTH) &&		    (ic->ic_flags & IEEE80211_F_CHANSWITCH)) {			if (!vap->iv_chanchange_count) {				vap->iv_flags |= IEEE80211_F_CHANSWITCH;				/* copy out trailer to open up a slot */				memmove(bo->bo_chanswitch + IEEE80211_CHANSWITCHANN_BYTES, 					bo->bo_chanswitch, bo->bo_chanswitch_trailerlen);				/* add ie in opened slot */				bo->bo_chanswitch[0] = IEEE80211_ELEMID_CHANSWITCHANN;				bo->bo_chanswitch[1] = 3; /* fixed length */				bo->bo_chanswitch[2] = 1; /* stas get off for now */				bo->bo_chanswitch[3] = ic->ic_chanchange_chan;				bo->bo_chanswitch[4] = ic->ic_chanchange_tbtt;				/* update the trailer lens */				bo->bo_chanswitch_trailerlen += IEEE80211_CHANSWITCHANN_BYTES;				bo->bo_tim_trailerlen += IEEE80211_CHANSWITCHANN_BYTES;				bo->bo_wme += IEEE80211_CHANSWITCHANN_BYTES;				bo->bo_erp += IEEE80211_CHANSWITCHANN_BYTES;				bo->bo_ath_caps += IEEE80211_CHANSWITCHANN_BYTES;				bo->bo_xr += IEEE80211_CHANSWITCHANN_BYTES;				/* indicate new beacon length so other layers may manage memory */				skb_put(skb, IEEE80211_CHANSWITCHANN_BYTES);				len_changed = 1;			}			else				bo->bo_chanswitch[4]--;			vap->iv_chanchange_count++;			IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,				"%s: CHANSWITCH IE, change in %d\n",				__func__, bo->bo_chanswitch[4]);		}#ifdef ATH_SUPERG_XR		if (vap->iv_flags & IEEE80211_F_XRUPDATE) {			if (vap->iv_xrvap)				(void) ieee80211_add_xr_param(bo->bo_xr, vap);			vap->iv_flags &= ~IEEE80211_F_XRUPDATE;		}#endif		if (ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) {			(void) ieee80211_add_erp(bo->bo_erp, ic);			ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;		}	}	/* if it is a mode change beacon for dynamic turbo case */	if (((ic->ic_ath_cap & IEEE80211_ATHC_BOOST) != 0) ^	    IEEE80211_IS_CHAN_TURBO(ic->ic_curchan))		ieee80211_add_athAdvCap(bo->bo_ath_caps, vap->iv_bss->ni_ath_flags,			vap->iv_bss->ni_ath_defkeyindex);	IEEE80211_UNLOCK(ic);	return len_changed;}EXPORT_SYMBOL(ieee80211_beacon_update);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -