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

📄 if_wlp_wavelan_roam.c

📁 WaveLAN无线网卡Linux驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		else {			if (sc->sc_rs.rs_apreg) {#ifdef WLP_DEBUG				printf("Aborting Registration!\n");#endif				SendRECReq(a->ap_softc);	/* XXX */			}			sc->sc_rs.rs_apreg = a;			/* NWID Promisc Mode */			SetNWID(sc, a->ap_beacon.snwid, 1);			SendSOReq(sc, a);	/* Send a Sign-on Request */			sc->sc_rs.rs_roam_mode = MODE_REG_CELL;		}		break;		/* switch() */	case MODE_STOP_CELL:		if (sc->sc_rs.rs_ap == 0)			panic("Stop Cell Search Mode && ap == 0");		if (sc->sc_rs.rs_apreg)			panic("Stop Cell Search Mode && apreq != 0");		if (SNR(sc->sc_rs.rs_ap) > REG_CELL(sc->sc_rs.rs_ap)) {			goto done;		} else if (SNR(sc->sc_rs.rs_ap) < FAST_CELL(sc->sc_rs.rs_ap)) {			sc->sc_rs.rs_roam_mode = MODE_FAST_CELL;			goto start;		} else {			sc->sc_rs.rs_roam_mode = MODE_REG_CELL;			goto start;		}		break;	default:		panic("roam_timer(): RoamMode is invalid");	}done:	timeout(roam_timer, (void *) sc, 2 * hz);	/* 2 seconds */quit:	splx(s);}static voidPurgeAccessPointList(sc)	struct wlp_softc *sc;{	struct accesspoint *a, *an;	for (a = sc->sc_rs.rs_aplist.lh_first; a;) {		an = a->ap_link.le_next;		if (AP_EXPIRED(a)) {#ifdef WLP_DEBUG			printf("NWID: %x expired at %ld.%ld\n",			       a->ap_beacon.snwid,			       a->ap_expire.tv_sec, a->ap_expire.tv_usec);#endif			if (a == sc->sc_rs.rs_ap) {				sc->sc_rs.rs_ap = 0;				sc->sc_rs.rs_roam_mode = MODE_FAST_CELL;			}			if (a == sc->sc_rs.rs_apreg) {				SendRECReq(sc);	/* XXX */				sc->sc_rs.rs_apreg = 0;				sc->sc_rs.rs_roam_mode = MODE_FAST_CELL;				sc->sc_rs.rs_SOReqRetrans = 0;			}			LIST_REMOVE(a, ap_link);			free(a, M_TEMP);		}		a = an;	}}struct accesspoint *BestAccessPoint1(sc)	struct wlp_softc *sc;{	struct accesspoint *a;	struct accesspoint *maxa = 0;	int             maxsnr = -1;	for (a = sc->sc_rs.rs_aplist.lh_first; a; a = a->ap_link.le_next) {		if (maxsnr < 0) {			maxsnr = SNR(a);			maxa = a;		} else if (SNR(a) > maxsnr) {			maxsnr = SNR(a);			maxa = a;		}	}#ifdef WLP_DEBUG      if(maxa == 0)              printf("%s: no Access Point found...\n", __FUNCTION__);#endif	return maxa;}static struct accesspoint *BestAccessPoint2(X, Y)	struct accesspoint *X;	struct accesspoint *Y;{	int             x = 0;	int             y = 0;	if (Y == 0)		return X;	/* X has prescedence */	if (X == 0)		return Y;	if (SNR(X) < FAST_CELL(X))		x = 1;	else if (SNR(X) < REG_CELL(X))		x = 2;	else if (SNR(X) < STOP_CELL(X))		x = 3;	else		x = 4;	if (SNR(Y) < FAST_CELL(Y))		y = 1;	else if (SNR(Y) < REG_CELL(Y))		y = 2;	else if (SNR(Y) < STOP_CELL(Y))		y = 3;	else		y = 4;	return (x >= y ? X : Y);}/* * ====================================================================== * Packet Processing Functions * ====================================================================== */static voidProcessBeacon(eh, m, sigstat)	struct ether_header *eh;	struct mbuf    *m;	int             sigstat;{	struct arpcom  *ac = (struct arpcom *) m->m_pkthdr.rcvif;	struct wlp_softc *sc;	struct pkt_beacon *p;	struct accesspoint *a;	if (ac == 0)		panic("ProcessBeacon(): ac = 0");	sc = (struct wlp_softc *) ac->ac_if.if_softc;	p = mtod(m, struct pkt_beacon *);	sc->sc_rs.rs_BeaconCount++;	if (sc->sc_rs.rs_domid && sc->sc_rs.rs_domid != ntohs(p->domid)) {		return;	}	p->snwid ^= htons(sc->sc_rs.rs_beaconkey);	for (a = sc->sc_rs.rs_aplist.lh_first; a; a = a->ap_link.le_next) {		if (a->ap_beacon.snwid == ntohs(p->snwid))			break;	}	/*	 * If this is a beacon from a new access point...	 */	if (a == 0) {		/*		 * Discard the Beacon if the SNR is < Fast Cell Search		 * Threshold		 */		if ((min((sigstat >> 16) & 0xFF, 36) -		     min((sigstat >> 8) & 0xFF, 36)) < p->fcell) {			return;		}		a = (struct accesspoint *)			malloc(sizeof(*a), M_TEMP, M_DONTWAIT);		if (!a) return;		bzero(a, sizeof(*a));		a->ap_beacon.pdutype = p->pdutype;		/* a->ap_beacon.sequence = p->sequence; */		a->ap_beacon.domid = ntohs(p->domid);		a->ap_beacon.snwid = ntohs(p->snwid);		/* a->ap_beacon.rfnoise = p->rfnoise; */		a->ap_beacon.threshold = p->threshold;		a->ap_beacon.scell = p->scell;		a->ap_beacon.rcell = p->rcell;		a->ap_beacon.fcell = p->fcell;		*((u_int16_t *) & a->ap_beacon.interval)			= ntohs(*((u_int16_t *) & p->interval));		*((u_int16_t *) & a->ap_beacon.timeout)			= ntohs(*((u_int16_t *) & p->timeout));		strncpy(a->ap_beacon.apname, p->apname, sizeof(p->apname));		/*		 * Save MAC Address and ifp		 */		bcopy(eh->ether_shost, a->ap_macaddr, ETHER_ADDR_LEN);		a->ap_softc = (struct wlp_softc *)			((struct ifnet *) m->m_pkthdr.rcvif)->if_softc;		LIST_INSERT_HEAD(&sc->sc_rs.rs_aplist, a, ap_link);#ifdef WLP_DEBUG		printf("%s: added %p to the AP list\n", __FUNCTION__, a);#endif	}	a->ap_beacon.sequence = p->sequence;	a->ap_beacon.rfnoise = p->rfnoise;#define sigavg(x, y)	( (x) ? (((x) + (y)) >> 1) : (y) )	a->ap_siglevel =		sigavg(a->ap_siglevel, min((sigstat >> 16) & 0xFF, 36));	a->ap_sillevel =		sigavg(a->ap_sillevel, min((sigstat >> 8) & 0xFF, 36));	a->ap_sigqual = sigstat & 0x0F;	AP_SET_EXPIRE(a);	sc->sc_rs.rs_BeaconKept++;}static voidProcessSORsp(eh, m)	struct ether_header *eh;	struct mbuf    *m;{	struct ifnet   *ifp = (struct ifnet *) m->m_pkthdr.rcvif;	struct wlp_softc *sc;	struct pkt_sorsp *p;	if (ifp == 0)		panic("ProcessSORsp(): ifp = 0");	sc = (struct wlp_softc *) ifp->if_softc;	p = mtod(m, struct pkt_sorsp *);	if (sc->sc_rs.rs_apreg == 0) {#ifdef WLP_DEBUG		printf("wlp%d: Received a SIGN-ON Response, but not registering\n",		       ifp->if_unit);#endif		return;	}	if (p->seq != (sc->sc_rs.rs_SOReqCnt - 1)) {#ifdef WLP_DEBUG		printf("\tERROR: Invalid Sequence Number %d (expected %d)\n",		       p->seq, sc->sc_rs.rs_SOReqCnt);#endif		return;	}	if (p->status != 0) {#ifdef WLP_DEBUG		printf("\tERROR: Sign-on Request Rejected (status = %d)\n",		       p->status);#endif		return;	}	/*	 * Save the Access Point Information...	 */	if (p->infoblock[0] > SORSP_INFOBLOCK_MAX_LEN - 1) {#ifdef WLP_DEBUG		printf("\tERROR: Sign-on Request has invalid infoblock length (%d)\n",		       p->infoblock[0]);#endif		return;	}	bcopy(p->infoblock, sc->sc_rs.rs_apreg->ap_infoblock, p->infoblock[0] + 1);	/* NWID Promisc Mode */	SetNWID(sc, sc->sc_rs.rs_apreg->ap_beacon.snwid, 1);	EnableTX(ifp);	sc->sc_rs.rs_SOReqRetrans = 0;	if (sc->sc_rs.rs_ap == 0 && sc->sc_rs.rs_SOReqFailed) {		/* Initial Sign-ON */		SendRECReq(sc);	/* XXX */	}	sc->sc_rs.rs_ap = sc->sc_rs.rs_apreg;	sc->sc_rs.rs_apreg = 0;#ifdef WLP_DEBUG	printf("-------------------- New Access Point --------------------\n");	dump_ap(sc->sc_rs.rs_ap);#endif}/* * ====================================================================== * Packet Building Functions... * ====================================================================== */static voidSendSOReq(sc, a)	struct wlp_softc *sc;	struct accesspoint *a;{	struct mbuf *m;	struct ether_header *eh;	struct pkt_soreq *p;	MGETHDR(m, M_DONTWAIT, MT_HEADER);	if (!m) return;	eh = mtod(m, struct ether_header *);	bzero((caddr_t) eh, MHLEN);	/*	 * Insert the SNAP goop...	 */	bcopy(ether_wavelan_snaphdr, (caddr_t) (eh + 1),	      sizeof(ether_wavelan_snaphdr));	/*	 * Insert the Sign On Request stuff...	 */	p = (struct pkt_soreq *)		(((caddr_t) (eh + 1)) + sizeof(ether_wavelan_snaphdr));	p->pdutype = PDUTYPE_SOREQ;	/* Sign-On Request */	p->seq = sc->sc_rs.rs_SOReqCnt++;	/* Not used by base station */	p->numaps = 0x00;	/* Not Presently Used */	p->roamstate = 0x00;	/* Not Presently Used */	p->reserved = 0x00;	/* SHOULD be 0x00 */	m->m_len = sizeof(*eh) + sizeof(ether_wavelan_snaphdr) +		sizeof(struct pkt_soreq);	if (sc->sc_rs.rs_ap && sc->sc_rs.rs_ap->ap_infoblock[0]) {		bcopy(sc->sc_rs.rs_ap->ap_infoblock,		      p->infoblock,		      sc->sc_rs.rs_ap->ap_infoblock[0]);		m->m_len += sc->sc_rs.rs_ap->ap_infoblock[0];	}	/*	 * Fill in the Ethernet header...	 */	bcopy(a->ap_softc->sc_ac.ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN);	bcopy(a->ap_macaddr, eh->ether_dhost, ETHER_ADDR_LEN);	eh->ether_type = htons(m->m_len - sizeof(*eh));	m->m_pkthdr.len = m->m_len =		BEACON_MIN_LEN + sizeof(ether_wavelan_snaphdr);	sc->sc_rs.rs_SOReqRetrans++;	/* Increment Sign-ON Counter */	wlptransmit(sc, m);	m_freem(m);#ifdef WLP_DEBUG	printf("-------------------- Registering --------------------\n");	dump_ap(a);#endif}static voidSendRECReq(sc)	struct wlp_softc *sc;{	struct mbuf *m;	struct ether_header *eh;	struct pkt_recreq *p;	MGETHDR(m, M_DONTWAIT, MT_HEADER);	if (m == 0)		return;	eh = mtod(m, struct ether_header *);	p = (struct pkt_recreq *)		(((caddr_t) (eh + 1)) + sizeof(ether_wavelan_snaphdr));	bzero((caddr_t) eh, MHLEN);	/* Ethernet Header */	bcopy(sc->sc_ac.ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN);	bcopy(ether_bridge_multiaddr, eh->ether_dhost, ETHER_ADDR_LEN);	eh->ether_type = htons(sizeof(ether_wavelan_snaphdr) +			       sizeof(struct pkt_recreq));	/* SNAP Header */	bcopy(ether_wavelan_snaphdr, (caddr_t) (eh + 1),	      sizeof(ether_wavelan_snaphdr));	/* WaveLAN Stuff */	p->pdutype = PDUTYPE_RECREQ;	m->m_pkthdr.len = m->m_len = sizeof(*eh) +		sizeof(ether_wavelan_snaphdr) + sizeof(struct pkt_recreq) +		RECREQ_PADDING_LEN;	wlptransmit(sc, m);	m_freem(m);	sc->sc_rs.rs_SOReqFailed = 0;}/* ====================================================================== */#ifdef WLP_DEBUGstatic voiddump_ap(a)	struct accesspoint *a;{	if (!a)		return;	printf("NAME: %s, MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x, NWID: %x\n",	       a->ap_beacon.apname, ETHER_ADDR_FORMAT(a->ap_macaddr),	       a->ap_beacon.snwid);	printf("\tEXPIRE: %ld.%ld, INTERVAL: %d, TIMEOUT: %d\n",	       a->ap_expire.tv_sec, a->ap_expire.tv_usec,               *((u_int16_t*) a->ap_beacon.interval),	       *((u_int16_t*) a->ap_beacon.timeout));	printf("\tSIGNAL: %2d %2d %2d %2d, THRESHOLD: %2d %2d %2d\n",	a->ap_siglevel, a->ap_sillevel, a->ap_sigqual, a->ap_beacon.rfnoise,	       a->ap_beacon.scell, a->ap_beacon.rcell, a->ap_beacon.fcell);}static voiddump_aplist(sc)	struct wlp_softc *sc;{	struct accesspoint *a;	printf("----------------------------------------\n");	for (a = sc->sc_rs.rs_aplist.lh_first; a; a = a->ap_link.le_next)		dump_ap(a);	printf("********* Current Base Station (mode: %s, time: %ld.%ld)\n",	       RoamModeString[sc->sc_rs.rs_roam_mode],	       time.tv_sec, time.tv_usec);	dump_ap(sc->sc_rs.rs_ap);	printf("----------------------------------------\n");}#endif /* WLP_DEBUG */#endif /* NCARD > 0 */#endif /* WAVELAN_ROAMING */

⌨️ 快捷键说明

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