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

📄 ieee80211_scan_ap.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * Flush all per-scan state. */static intap_flush(struct ieee80211_scan_state *ss){	struct ap_state *as = ss->ss_priv;	struct scan_entry *se, *next;	SCAN_AP_LOCK_IRQ(as);	memset(as->as_maxrssi, 0, sizeof(as->as_maxrssi));	TAILQ_FOREACH_SAFE(se, &as->as_entry, se_list, next) {		TAILQ_REMOVE(&as->as_entry, se, se_list);		LIST_REMOVE(se, se_hash);		FREE(se, M_80211_SCAN);	}	ss->ss_last = 0;		/* ensure no channel will be picked */	SCAN_AP_UNLOCK_IRQ(as);	return 0;}/* This function must be invoked with locks acquired */static voidsaveie(u_int8_t **iep, const u_int8_t *ie){	if (ie == NULL)		*iep = NULL;	else		ieee80211_saveie(iep, ie);}/* This function must be invoked with locks acquired */static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic, int i, int freq){	struct ieee80211_channel *c;	int j;	/* The normal ordering in the channel list is b channel	 * immediately followed by g so optimize the search for	 * this.  We'll still do a full search just in case. */	for (j = i + 1; j < ic->ic_nchans; j++) {		c = &ic->ic_channels[j];		if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))			return c;	}	for (j = 0; j < i; j++) {		c = &ic->ic_channels[j];		if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))			return c;	}	return NULL;}/* * Start an ap scan by populating the channel list. */static intap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap){	struct ap_state *as 	    = ss->ss_priv;	struct ieee80211com *ic     = NULL;	const struct scanlist *sl   = NULL;	struct ieee80211_channel *c = NULL;	int i;	unsigned int mode = 0;	SCAN_AP_LOCK_IRQ(as);	ic = vap->iv_ic;	/* Determine mode flags to match, or leave zero for auto mode */	as->as_vap_desired_mode = vap->iv_des_mode;	as->as_required_mode    = 0;	if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) {		as->as_required_mode = chanflags[as->as_vap_desired_mode];		if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) && 		    (as->as_required_mode != IEEE80211_CHAN_ST)) {			/* Fixup for dynamic turbo flags */			if (as->as_vap_desired_mode == IEEE80211_MODE_11G)				as->as_required_mode = IEEE80211_CHAN_108G;			else				as->as_required_mode = IEEE80211_CHAN_108A;		}	}	ss->ss_last = 0;	/* Use the table of ordered channels to construct the list	 * of channels for scanning.  Any channels in the ordered	 * list not in the master list will be discarded. */	for (sl = staScanTable; sl->list != NULL; sl++) {		mode = sl->mode;		/* The scan table marks 2.4Ghz channels as b		 * so if the desired mode is 11g, then use		 * the 11b channel list but upgrade the mode. */		if (as->as_vap_desired_mode &&		    (as->as_vap_desired_mode != mode) && 		    (as->as_vap_desired_mode == IEEE80211_MODE_11G) && 		    (mode == IEEE80211_MODE_11B))			mode = IEEE80211_MODE_11G;		/* If we are in "AUTO" mode, upgrade the mode to auto. 		 * This lets add_channels upgrade an 11b channel to 		 * 11g if available. */		if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B))			mode = IEEE80211_MODE_AUTO;		/* Add the list of the channels; any that are not		 * in the master channel list will be discarded. */		add_channels(ic, ss, mode, sl->list, sl->count);	}	/* Add the channels from the ic (from HAL) that are not present	 * in the staScanTable, assuming they pass the sanity checks... */	for (i = 0; i < ic->ic_nchans; i++) {		c = &ic->ic_channels[i];		/* XR is not supported on turbo channels */		if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR)			continue;		/* Dynamic channels are scanned in base mode */		if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c))			continue;		/* Use any 11g channel instead of 11b one. */		if (vap->iv_des_mode == IEEE80211_MODE_AUTO && 		    IEEE80211_IS_CHAN_B(c) &&		    find11gchannel(ic, i, c->ic_freq))			continue;		/* Do not add channels already put into the scan list by the		 * scan table - these have already been filtered by mode		 * and for whether they are in the active channel list. */		if (checktable(staScanTable, c))			continue;		/* Make sure the channel is active */		if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))			continue;		/* Don't overrun */		if (ss->ss_last >= IEEE80211_SCAN_MAX)			break;		ss->ss_chans[ss->ss_last++] = c;	}	ss->ss_next = 0;	/* XXX tunables */	ss->ss_mindwell = msecs_to_jiffies(200);	/* 200ms */	ss->ss_maxdwell = msecs_to_jiffies(300);	/* 300ms */#ifdef IEEE80211_DEBUG	if (ieee80211_msg_scan(vap)) {		printk("%s: scan set ", vap->iv_dev->name);		ieee80211_scan_dump_channels(ss);		printk(" dwell min %ld max %ld\n",			ss->ss_mindwell, ss->ss_maxdwell);	}#endif /* IEEE80211_DEBUG */	as->as_newscan = 1;	SCAN_AP_UNLOCK_IRQ(as);	return 0;}/* * Restart a bg scan. */static intap_restart(struct ieee80211_scan_state *ss, struct ieee80211vap *vap){	struct ap_state *as = ss->ss_priv;	as->as_newscan = 1;	return 0;}/* * Cancel an ongoing scan. */static intap_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap){	struct ap_state *as = ss->ss_priv;	IEEE80211_CANCEL_TQUEUE(&as->as_actiontq);	return 0;}/* * Record max rssi on channel. */static intap_add(struct ieee80211_scan_state *ss, const struct ieee80211_scanparams *sp,	const struct ieee80211_frame *wh, int subtype, int rssi, u_int64_t rtsf){	struct ap_state *as              = ss->ss_priv;	const u_int8_t *macaddr          = wh->i_addr2;	struct ieee80211vap *vap         = ss->ss_vap;	struct ieee80211com *ic          = vap->iv_ic;	struct scan_entry *se            = NULL;	struct ieee80211_scan_entry *ise = NULL;	int hash = AP_HASH(macaddr);	int chan;	/* This section provides scan results to wireless extensions */	SCAN_AP_LOCK_IRQ(as);	chan = ieee80211_chan2ieee(ic, ic->ic_curchan);	/* This is the only information used for channel selection by AP */	if (rssi > as->as_maxrssi[chan])		as->as_maxrssi[chan] = rssi;	LIST_FOREACH(se, &as->as_hash[hash], se_hash)		if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&		    (sp->ssid[1] == se->base.se_ssid[1]) &&		    !memcmp(se->base.se_ssid + 2, sp->ssid + 2, 			    se->base.se_ssid[1]))			goto found;	MALLOC(se, struct scan_entry *, sizeof(struct scan_entry),		M_80211_SCAN, M_NOWAIT | M_ZERO);	if (se == NULL) {		SCAN_AP_UNLOCK_IRQ_EARLY(as);		return 0;	}	se->se_scangen = as->as_scangen-1;	IEEE80211_ADDR_COPY(se->base.se_macaddr, macaddr);	TAILQ_INSERT_TAIL(&as->as_entry, se, se_list);	LIST_INSERT_HEAD(&as->as_hash[hash], se, se_hash);found:	ise = &se->base;	/* XXX: AP beaconing multiple SSID w/ same BSSID */	if ((sp->ssid[1] != 0) &&	    ((subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) || 	     (ise->se_ssid[1] == 0)))		memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]);	memcpy(ise->se_rates, sp->rates, 		IEEE80211_SANITISE_RATESIZE(2 + sp->rates[1]));	if (sp->xrates != NULL) {		memcpy(ise->se_xrates, sp->xrates, 				IEEE80211_SANITISE_RATESIZE(2 + sp->xrates[1]));	} else		ise->se_xrates[1] = 0;	IEEE80211_ADDR_COPY(ise->se_bssid, wh->i_addr3);	/* Record RSSI data using extended precision LPF filter.*/	if (se->se_lastupdate == 0)		/* First sample */		se->se_avgrssi = RSSI_IN(rssi);	else					/* Avg. w/ previous samples */		RSSI_LPF(se->se_avgrssi, rssi);	se->base.se_rssi = RSSI_GET(se->se_avgrssi);	ise->se_rtsf = rtsf;	memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp));	ise->se_intval = sp->bintval;	ise->se_capinfo = sp->capinfo;	ise->se_chan = ic->ic_curchan;	ise->se_fhdwell = sp->fhdwell;	ise->se_fhindex = sp->fhindex;	ise->se_erp = sp->erp;	ise->se_timoff = sp->timoff;	if (sp->tim != NULL) {		const struct ieee80211_tim_ie *tim =		    (const struct ieee80211_tim_ie *)sp->tim;		ise->se_dtimperiod = tim->tim_period;	}	saveie(&ise->se_wme_ie, sp->wme);	saveie(&ise->se_wpa_ie, sp->wpa);	saveie(&ise->se_rsn_ie, sp->rsn);	saveie(&ise->se_ath_ie, sp->ath);	se->se_lastupdate = jiffies;		/* update time */	se->se_seen = 1;	se->se_notseen = 0;	SCAN_AP_UNLOCK_IRQ(as);	return 1;}struct pc_params {	struct ieee80211vap *vap;	struct ieee80211_scan_state *ss;	int flags;};struct channel {	struct ieee80211_channel *chan;	int orig;	struct pc_params *params;};/* This function must be invoked with locks acquired */static intpc_cmp_radar(struct ieee80211_channel *a, struct ieee80211_channel *b){	/* a is better than b (return < 0) when b is marked while a is not */	return !!IEEE80211_IS_CHAN_RADAR(a) - !!IEEE80211_IS_CHAN_RADAR(b);}/* This function must be invoked with locks acquired */static intpc_cmp_keepmode(struct pc_params *params, struct ieee80211_channel *a,		struct ieee80211_channel *b){	struct ieee80211com *ic = params->vap->iv_ic;	struct ieee80211_channel *cur = ic->ic_bsschan;	if (!(params->flags & IEEE80211_SCAN_KEEPMODE))		return 0;	/* a is better than b (return < 0) when (a, cur) have the same mode 	 * and (b, cur) do not. */	return		!!IEEE80211_ARE_CHANS_SAME_MODE(b, cur) -		!!IEEE80211_ARE_CHANS_SAME_MODE(a, cur);}/* This function must be invoked with locks acquired */static intpc_cmp_sc(struct ieee80211com *ic, struct ieee80211_channel *a,		struct ieee80211_channel *b){	/* a is better than b (return < 0) when a has more chan nodes than b */	return		ic->ic_chan_nodes[b->ic_ieee] -		ic->ic_chan_nodes[a->ic_ieee];}/* This function must be invoked with locks acquired */static intpc_cmp_rssi(struct ap_state *as, struct ieee80211_channel *a,		struct ieee80211_channel *b){	/* a is better than b (return < 0) when a has rssi less than b */	return		as->as_maxrssi[a->ic_ieee] -		as->as_maxrssi[b->ic_ieee];}/* This function must be invoked with locks acquired */static intpc_cmp_samechan(struct ieee80211com *ic, struct ieee80211_channel *a,		struct ieee80211_channel *b){	struct ieee80211_channel *ic_bsschan = ic->ic_bsschan;	if (ic_bsschan == IEEE80211_CHAN_ANYC)		return 0;	/* a is better than b (return < 0) when a is current (and b is not) */	return (b == ic_bsschan) - (a == ic_bsschan);}/* This function must be invoked with locks acquired */static intpc_cmp_orig(struct channel *a, struct channel *b){	return a->orig - b->orig;}/* This function must be invoked with locks acquired */static intpc_cmp(const void *_a, const void *_b){

⌨️ 快捷键说明

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