Ejemplo n.º 1
0
/*
	==========================================================================
	Description:
		Process the received ProbeRequest from clients
	Parameters:
		Elem - msg containing the ProbeReq frame
	==========================================================================
 */
VOID APPeerProbeReqAction(
	IN PRTMP_ADAPTER pAd,
	IN MLME_QUEUE_ELEM *Elem)
{
	UCHAR         Addr2[MAC_ADDR_LEN];
	CHAR          Ssid[MAX_LEN_OF_SSID];
	UCHAR         SsidLen; //, Rates[MAX_LEN_OF_SUPPORTED_RATES], RatesLen;
	HEADER_802_11 ProbeRspHdr;
	NDIS_STATUS   NStatus;
	PUCHAR        pOutBuffer = NULL;
	ULONG         FrameLen = 0, TmpLen;
	LARGE_INTEGER FakeTimestamp;
	UCHAR         DsLen = 1;//, IbssLen = 2, TimLen=1,
				  //BitmapControl=0, VirtualBitmap=0;
	UCHAR   ErpIeLen = 1;
	UCHAR         apidx = 0;
	UCHAR   RSNIe=IE_WPA, RSNIe2=IE_WPA2;//, RSN_Len=22;
	BOOLEAN		bRequestRssi=FALSE;

#ifdef WSC_AP_SUPPORT
    UCHAR		  Addr3[MAC_ADDR_LEN];
    PFRAME_802_11 pFrame = (PFRAME_802_11)Elem->Msg;

	COPY_MAC_ADDR(Addr3, pFrame->Hdr.Addr3);
#endif // WSC_AP_SUPPORT //

#ifdef WDS_SUPPORT
	// if in bridge mode, no need to reply probe req.
	if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
		return;
#endif // WDS_SUPPORT //
	
	if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen, &bRequestRssi))
		return;

	for(apidx=0; apidx<pAd->ApCfg.BssidNum; apidx++)
	{
		RSNIe = IE_WPA;
	
		if ((pAd->ApCfg.MBSSID[apidx].MSSIDDev != NULL) &&
			!(RTMP_OS_NETDEV_STATE_RUNNING(pAd->ApCfg.MBSSID[apidx].MSSIDDev)))
		{
			/* the interface is down, so we can not send probe response */
			continue;
		} /* End of if */

		if (((SsidLen == 0) && (! pAd->ApCfg.MBSSID[apidx].bHideSsid)) ||
#ifdef WSC_AP_SUPPORT
            /* buffalo WPS testbed STA send ProbrRequest ssid length = 32 and ssid are not AP , but DA are AP. for WPS test send ProbeResponse */
			((SsidLen == 32) && MAC_ADDR_EQUAL(Addr3, pAd->ApCfg.MBSSID[apidx].Bssid) && (pAd->ApCfg.MBSSID[apidx].bHideSsid == 0)) ||
#endif // WSC_AP_SUPPORT //
		((SsidLen == pAd->ApCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, (ULONG) SsidLen)))
			;
		else
			continue; /* check next BSS */

		// allocate and send out ProbeRsp frame
		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
		if (NStatus != NDIS_STATUS_SUCCESS)
			return;
		MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->ApCfg.MBSSID[apidx].Bssid);

		 if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) ||
			(pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK))
			RSNIe = IE_WPA;
		else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) ||
			(pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK))
			RSNIe = IE_WPA2;
#ifdef WAPI_SUPPORT
		else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAICERT) ||
			(pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWAIPSK))
			RSNIe = IE_WAPI;
#endif // WAPI_SUPPORT //

		MakeOutgoingFrame(pOutBuffer,                 &FrameLen,
						  sizeof(HEADER_802_11),      &ProbeRspHdr,
						  TIMESTAMP_LEN,              &FakeTimestamp,
						  2,                          &pAd->CommonCfg.BeaconPeriod,
						  2,                          &pAd->ApCfg.MBSSID[apidx].CapabilityInfo,
						  1,                          &SsidIe,
						  1,                          &pAd->ApCfg.MBSSID[apidx].SsidLen,
						  pAd->ApCfg.MBSSID[apidx].SsidLen,     pAd->ApCfg.MBSSID[apidx].Ssid,
						  1,                          &SupRateIe,
						  1,                          &pAd->CommonCfg.SupRateLen,
						  pAd->CommonCfg.SupRateLen,      pAd->CommonCfg.SupRate,
						  1,                          &DsIe,
						  1,                          &DsLen,
						  1,                          &pAd->CommonCfg.Channel,
						  END_OF_ARGS);

		if (pAd->CommonCfg.ExtRateLen)
		{
			MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
							  1,                        &ErpIe,
							  1,                        &ErpIeLen,
							  1,                        &pAd->ApCfg.ErpIeContent,
							  1,                        &ExtRateIe,
							  1,                        &pAd->CommonCfg.ExtRateLen,
							  pAd->CommonCfg.ExtRateLen,    pAd->CommonCfg.ExtRate,
							  END_OF_ARGS);
			FrameLen += TmpLen;
		}

#ifdef A_BAND_SUPPORT
		// add Channel switch announcement IE
		if ((pAd->CommonCfg.Channel > 14)
			&& (pAd->CommonCfg.bIEEE80211H == 1)
			&& (pAd->CommonCfg.RadarDetect.RDMode == RD_SWITCHING_MODE))
		{
			UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT;
			UCHAR CSALen=3;
			UCHAR CSAMode=1;

			MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
							  1,                        &CSAIe,
							  1,                        &CSALen,
							  1,                        &CSAMode,
							  1,                        &pAd->CommonCfg.Channel,
							  1,                        &pAd->CommonCfg.RadarDetect.CSCount,
							  END_OF_ARGS);
			FrameLen += TmpLen;
		}
#endif // A_BAND_SUPPORT //

#ifdef DOT11_N_SUPPORT
		if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
			(pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable))
		{
			ULONG TmpLen;
			UCHAR	HtLen, AddHtLen, NewExtLen;
#ifdef RT_BIG_ENDIAN
			HT_CAPABILITY_IE HtCapabilityTmp;
			ADD_HT_INFO_IE	addHTInfoTmp;
#endif

#ifdef A_BAND_SUPPORT
   			if (pAd->CommonCfg.bExtChannelSwitchAnnouncement && (pAd->CommonCfg.Channel > 14))
			{
				HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE	HtExtChannelSwitchIe;

				build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe);
				MakeOutgoingFrame(pOutBuffer + FrameLen,             &TmpLen,
								  sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE),	&HtExtChannelSwitchIe,
								  END_OF_ARGS);
				FrameLen += TmpLen;
			}
#endif // A_BAND_SUPPORT //

			HtLen = sizeof(pAd->CommonCfg.HtCapability);
			AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
			NewExtLen = 1;
			//New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
#ifndef RT_BIG_ENDIAN
			MakeOutgoingFrame(pOutBuffer + FrameLen,            &TmpLen,
							  1,                                &HtCapIe,
							  1,                                &HtLen,
							 sizeof(HT_CAPABILITY_IE),          &pAd->CommonCfg.HtCapability,
							  1,                                &AddHtInfoIe,
							  1,                                &AddHtLen,
							 sizeof(ADD_HT_INFO_IE),          &pAd->CommonCfg.AddHTInfo,
							  1,                                &NewExtChanIe,
							  1,                                &NewExtLen,
							 sizeof(NEW_EXT_CHAN_IE),          &pAd->CommonCfg.NewExtChanOffset,
							  END_OF_ARGS);
#else
			NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
			*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
			{
				EXT_HT_CAP_INFO extHtCapInfo;

				NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
				*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
				NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));		
			}
#else				
			*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif // UNALIGNMENT_SUPPORT //

			NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen);
			*(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
			*(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));

			MakeOutgoingFrame(pOutBuffer + FrameLen,         &TmpLen,
								1,                           &HtCapIe,
								1,                           &HtLen,
								HtLen,                       &HtCapabilityTmp,
								1,                           &AddHtInfoIe,
								1,                           &AddHtLen,
								AddHtLen,                    &addHTInfoTmp,
								1,                           &NewExtChanIe,
								1,                           &NewExtLen,
								sizeof(NEW_EXT_CHAN_IE),     &pAd->CommonCfg.NewExtChanOffset,
								END_OF_ARGS);

#endif
			FrameLen += TmpLen;


		}
#endif // DOT11_N_SUPPORT //


		// Append RSN_IE when  WPA OR WPAPSK,
		if (pAd->ApCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA)
			; // enough information
		else if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
			(pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
		{
			MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
							  1,                        &RSNIe,
							  1,                        &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0],
							  pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0],  pAd->ApCfg.MBSSID[apidx].RSN_IE[0],
							  1,                        &RSNIe2,
							  1,                        &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1],
							  pAd->ApCfg.MBSSID[apidx].RSNIE_Len[1],  pAd->ApCfg.MBSSID[apidx].RSN_IE[1],
							  END_OF_ARGS);
			FrameLen += TmpLen;
		}
		else
		{
			MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
							  1,                        &RSNIe,
							  1,                        &pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0],
							  pAd->ApCfg.MBSSID[apidx].RSNIE_Len[0],  pAd->ApCfg.MBSSID[apidx].RSN_IE[0],
							  END_OF_ARGS);
			FrameLen += TmpLen;
		}

		// add WMM IE here
		if (pAd->ApCfg.MBSSID[apidx].bWmmCapable)
		{
			UCHAR i;
			UCHAR WmeParmIe[26] = {IE_VENDOR_SPECIFIC, 24, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0, 0};
			WmeParmIe[8] = pAd->ApCfg.BssEdcaParm.EdcaUpdateCount & 0x0f;
#ifdef UAPSD_AP_SUPPORT
            UAPSD_MR_IE_FILL(WmeParmIe[8], pAd);
#endif // UAPSD_AP_SUPPORT //
			for (i=QID_AC_BE; i<=QID_AC_VO; i++)
			{
				WmeParmIe[10+ (i*4)] = (i << 5)                                         +     // b5-6 is ACI
									   ((UCHAR)pAd->ApCfg.BssEdcaParm.bACM[i] << 4)     +     // b4 is ACM
									   (pAd->ApCfg.BssEdcaParm.Aifsn[i] & 0x0f);              // b0-3 is AIFSN
				WmeParmIe[11+ (i*4)] = (pAd->ApCfg.BssEdcaParm.Cwmax[i] << 4)           +     // b5-8 is CWMAX
									   (pAd->ApCfg.BssEdcaParm.Cwmin[i] & 0x0f);              // b0-3 is CWMIN
				WmeParmIe[12+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] & 0xff);        // low byte of TXOP
				WmeParmIe[13+ (i*4)] = (UCHAR)(pAd->ApCfg.BssEdcaParm.Txop[i] >> 8);          // high byte of TXOP
			}

			MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
							  26,                       WmeParmIe,
							  END_OF_ARGS);
			FrameLen += TmpLen;
		}

#ifdef AP_QLOAD_SUPPORT
		if (pAd->FlgQloadEnable != 0)
		{
			FrameLen += QBSS_LoadElementAppend(pAd, pOutBuffer+FrameLen);
		}
#endif // AP_QLOAD_SUPPORT //

#ifdef DOT11K_RRM_SUPPORT
		if (IS_RRM_ENABLE(pAd, apidx))
		{
		    // add country IE, power constraint IE
			if (pAd->CommonCfg.bCountryFlag)
			{
				ULONG TmpLen, TmpLen2=0;
				UCHAR TmpFrame[256];
				UCHAR CountryIe = IE_COUNTRY;

				NdisZeroMemory(TmpFrame, sizeof(TmpFrame));

				// prepare channel information
#ifdef EXT_BUILD_CHANNEL_LIST
				BuildBeaconChList(pAd, TmpFrame, &TmpLen2);
#else
				{
					UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
					MakeOutgoingFrame(TmpFrame+TmpLen2,     &TmpLen,
										1,                 	&pAd->ChannelList[0].Channel,
										1,                 	&pAd->ChannelListNum,
										1,                 	&MaxTxPower,
										END_OF_ARGS);
					TmpLen2 += TmpLen;
				}
#endif // EXT_BUILD_CHANNEL_LIST //

#ifdef DOT11K_RRM_SUPPORT
				if (IS_RRM_ENABLE(pAd, apidx)
					&& (pAd->CommonCfg.RegulatoryClass[0] != 0))
				{
					TmpLen2 = 0;
					NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
					RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2);
				}		
#endif // DOT11K_RRM_SUPPORT //

				// need to do the padding bit check, and concatenate it
				if ((TmpLen2%2) == 0)
				{
					UCHAR	TmpLen3 = TmpLen2+4;
					MakeOutgoingFrame(pOutBuffer+FrameLen,&TmpLen,
					                  1,                 	&CountryIe,
					                  1,                 	&TmpLen3,
					                  3,                 	pAd->CommonCfg.CountryCode,
					                  TmpLen2+1,				TmpFrame,
					                  END_OF_ARGS);
				}
				else
				{
					UCHAR	TmpLen3 = TmpLen2+3;
					MakeOutgoingFrame(pOutBuffer+FrameLen,&TmpLen,
					                  1,                 	&CountryIe,
					                  1,                 	&TmpLen3,
					                  3,                 	pAd->CommonCfg.CountryCode,
					                  TmpLen2,				TmpFrame,
					                  END_OF_ARGS);
				}
				FrameLen += TmpLen;
			}

			InsertTpcReportIE(pAd, pOutBuffer+FrameLen, &FrameLen,
			RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit), 0);
			RRM_InsertRRMEnCapIE(pAd, pOutBuffer+FrameLen, &FrameLen, apidx);
		}


		{
			INT loop;
			for (loop=0; loop<MAX_NUM_OF_REGULATORY_CLASS; loop++)
			{
				if (pAd->CommonCfg.RegulatoryClass[loop] == 0)
					break;
				InsertChannelRepIE(pAd, pOutBuffer+FrameLen, &FrameLen,
									(PSTRING)pAd->CommonCfg.CountryCode,
									pAd->CommonCfg.RegulatoryClass[loop]);
			}
		}

		/* Insert BSS AC Access Delay IE. */
		RRM_InsertBssACDelayIE(pAd, pOutBuffer+FrameLen, &FrameLen);

		/* Insert BSS Available Access Capacity IE. */
		RRM_InsertBssAvailableACIE(pAd, pOutBuffer+FrameLen, &FrameLen);
#endif // DOT11K_RRM_SUPPORT //

#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
	 	// P802.11n_D3.03
	 	// 7.3.2.60 Overlapping BSS Scan Parameters IE
	 	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
			(pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) &&
			(pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
	 	{
			OVERLAP_BSS_SCAN_IE  OverlapScanParam;
			ULONG	TmpLen;
			UCHAR	OverlapScanIE, ScanIELen;

			OverlapScanIE = IE_OVERLAPBSS_SCAN_PARM;
			ScanIELen = 14;
			OverlapScanParam.ScanPassiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveDwell);
			OverlapScanParam.ScanActiveDwell = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveDwell);
			OverlapScanParam.TriggerScanInt = cpu2le16(pAd->CommonCfg.Dot11BssWidthTriggerScanInt);
			OverlapScanParam.PassiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel);
			OverlapScanParam.ActiveTalPerChannel = cpu2le16(pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel);
			OverlapScanParam.DelayFactor = cpu2le16(pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
			OverlapScanParam.ScanActThre = cpu2le16(pAd->CommonCfg.Dot11OBssScanActivityThre);
			
			MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
								1,			&OverlapScanIE,
								1,			&ScanIELen,
								ScanIELen,	&OverlapScanParam,
								END_OF_ARGS);
			
			FrameLen += TmpLen;
	 	}



		// 7.3.2.27 Extended Capabilities IE
		{
			ULONG TmpLen;
			EXT_CAP_INFO_ELEMENT	extCapInfo;
			UCHAR extInfoLen;


			extInfoLen = sizeof(EXT_CAP_INFO_ELEMENT);
			NdisZeroMemory(&extCapInfo, extInfoLen);

			// P802.11n_D1.10
			// HT Information Exchange Support
			if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.Channel <= 14) &&
				(pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable) && 
				(pAd->CommonCfg.bBssCoexEnable == TRUE))
			{
			extCapInfo.BssCoexistMgmtSupport = 1;

			MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
								1, 			&ExtCapIe,
								1, 			&extInfoLen,
								extInfoLen, 	&extCapInfo,
								END_OF_ARGS);
				
			FrameLen += TmpLen;
		}
		}
#endif // DOT11N_DRAFT3 //
#endif // DOT11_N_SUPPORT //

		/* 
			add Ralink-specific IE here - Byte0.b0=1 for aggregation, Byte0.b1=1 for piggy-back
		                                  Byte0.b3=1 for rssi-feedback 
		 */
{
	ULONG TmpLen;
	UCHAR RalinkSpecificIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x00, 0x00, 0x00, 0x00};
	if (pAd->CommonCfg.bAggregationCapable)
		RalinkSpecificIe[5] |= 0x1;
	if (pAd->CommonCfg.bPiggyBackCapable)
		RalinkSpecificIe[5] |= 0x2;
#ifdef DOT11_N_SUPPORT
	if (pAd->CommonCfg.bRdg)
		RalinkSpecificIe[5] |= 0x4;
#endif // DOT11_N_SUPPORT //
#ifdef RSSI_FEEDBACK
	if (bRequestRssi == TRUE)
	{
	    MAC_TABLE_ENTRY       *pEntry=NULL;

		DBGPRINT(RT_DEBUG_ERROR, ("SYNC - Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] ));
    
		RalinkSpecificIe[5] |= 0x8;
		pEntry = MacTableLookup(pAd, Addr2);

		if (pEntry != NULL)
		{
			RalinkSpecificIe[6] = (UCHAR)pEntry->RssiSample.AvgRssi0;
			RalinkSpecificIe[7] = (UCHAR)pEntry->RssiSample.AvgRssi1;
			RalinkSpecificIe[8] = (UCHAR)pEntry->RssiSample.AvgRssi2;
		}
	}
#endif // RSSI_FEEDBACK //
	MakeOutgoingFrame(pOutBuffer+FrameLen,		 &TmpLen,
						9,						 RalinkSpecificIe,
						END_OF_ARGS);
	FrameLen += TmpLen;
}

#ifdef A_BAND_SUPPORT
		// add Channel switch announcement IE
		if ((pAd->CommonCfg.Channel > 14)
			&& (pAd->CommonCfg.bIEEE80211H == 1)
			&& (pAd->CommonCfg.RadarDetect.RDMode == RD_SWITCHING_MODE))
		{
			UCHAR CSAIe=IE_CHANNEL_SWITCH_ANNOUNCEMENT;
			UCHAR CSALen=3;
			UCHAR CSAMode=1;

			MakeOutgoingFrame(pOutBuffer+FrameLen,      &TmpLen,
							  1,                        &CSAIe,
							  1,                        &CSALen,
							  1,                        &CSAMode,
							  1,                        &pAd->CommonCfg.Channel,
							  1,                        &pAd->CommonCfg.RadarDetect.CSCount,
							  END_OF_ARGS);
			FrameLen += TmpLen;
#ifdef DOT11_N_SUPPORT
   			if (pAd->CommonCfg.bExtChannelSwitchAnnouncement)
			{
				HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE	HtExtChannelSwitchIe;

				build_ext_channel_switch_ie(pAd, &HtExtChannelSwitchIe);
				MakeOutgoingFrame(pOutBuffer + FrameLen,             &TmpLen,
								  sizeof(HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE),	&HtExtChannelSwitchIe,
								  END_OF_ARGS);
			}
#endif // DOT11_N_SUPPORT //
			FrameLen += TmpLen;
		}
#endif // A_BAND_SUPPORT //

	    // add country IE, power constraint IE
		if (pAd->CommonCfg.bCountryFlag)
		{
		    ULONG TmpLen2=0;
		    UCHAR TmpFrame[256];
		    UCHAR CountryIe = IE_COUNTRY;
		    UCHAR MaxTxPower=16;

#ifdef A_BAND_SUPPORT
			// Only 802.11a APs that comply with 802.11h are required to include a Power Constrint Element(IE=32)
			// in beacons and probe response frames
			if (pAd->CommonCfg.Channel > 14 && pAd->CommonCfg.bIEEE80211H == TRUE)
			{
		        // prepare power constraint IE
		        MakeOutgoingFrame(pOutBuffer+FrameLen,    &TmpLen,
		                          3,                 	PowerConstraintIE,
		                          END_OF_ARGS);
		        FrameLen += TmpLen;
			}
#endif // A_BAND_SUPPORT //

		    NdisZeroMemory(TmpFrame, sizeof(TmpFrame));

			// prepare channel information
		    MakeOutgoingFrame(TmpFrame+TmpLen2,     &TmpLen,
		                          1,                 	&pAd->ChannelList[0].Channel,
		                          1,                 	&pAd->ChannelListNum,
		                          1,                 	&MaxTxPower,
		                          END_OF_ARGS);
		    TmpLen2 += TmpLen;

		    // need to do the padding bit check, and concatenate it
		    if ((TmpLen2%2) == 0)
		    {
		       	UCHAR	TmpLen3 = TmpLen2+4;
			    MakeOutgoingFrame(pOutBuffer+FrameLen,  &TmpLen,
			                         1,                 	&CountryIe,
			                          1,                 	&TmpLen3,
			                          3,                 	pAd->CommonCfg.CountryCode,
			                          TmpLen2+1,				TmpFrame,
			                          END_OF_ARGS);
		    }
		    else
		    {
		       	UCHAR	TmpLen3 = TmpLen2+3;
			    MakeOutgoingFrame(pOutBuffer+FrameLen,  &TmpLen,
			                          1,                 	&CountryIe,
			                          1,                 	&TmpLen3,
			                          3,                 	pAd->CommonCfg.CountryCode,
			                          TmpLen2,				TmpFrame,
			                          END_OF_ARGS);
		    }
		    FrameLen += TmpLen;
		}// Country IE -

#ifdef DOT11_N_SUPPORT
		if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
			(pAd->ApCfg.MBSSID[apidx].DesiredHtPhyInfo.bHtEnable))
		{
			ULONG TmpLen;
			UCHAR	HtLen, AddHtLen;//, NewExtLen;
#ifdef RT_BIG_ENDIAN
			HT_CAPABILITY_IE HtCapabilityTmp;
			ADD_HT_INFO_IE	addHTInfoTmp;
#endif
			HtLen = sizeof(pAd->CommonCfg.HtCapability);
			AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);

		if (pAd->bBroadComHT == TRUE)
		{
			UCHAR	epigram_ie_len;
			UCHAR BROADCOM_HTC[4] = {0x0, 0x90, 0x4c, 0x33};
			UCHAR BROADCOM_AHTINFO[4] = {0x0, 0x90, 0x4c, 0x34};


			epigram_ie_len = HtLen + 4;
#ifndef RT_BIG_ENDIAN
			MakeOutgoingFrame(pOutBuffer + FrameLen,        &TmpLen,
						  1,                                &WpaIe,
							  1,                                &epigram_ie_len,
							  4,                                &BROADCOM_HTC[0],
							  HtLen,          					&pAd->CommonCfg.HtCapability,
							  END_OF_ARGS);
#else
				NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
				*(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
#ifdef UNALIGNMENT_SUPPORT
			{
				EXT_HT_CAP_INFO extHtCapInfo;

				NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
				*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
				NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));		
			}
#else				
			*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
#endif // UNALIGNMENT_SUPPORT //

				MakeOutgoingFrame(pOutBuffer + FrameLen,         &TmpLen,
								1,                               &WpaIe,
								1,                               &epigram_ie_len,
								4,                               &BROADCOM_HTC[0],
								HtLen,                           &HtCapabilityTmp,
								END_OF_ARGS);
#endif

				FrameLen += TmpLen;

				epigram_ie_len = AddHtLen + 4;
#ifndef RT_BIG_ENDIAN
				MakeOutgoingFrame(pOutBuffer + FrameLen,          &TmpLen,
								  1,                              &WpaIe,
								  1,                              &epigram_ie_len,
								  4,                              &BROADCOM_AHTINFO[0],
								  AddHtLen, 					  &pAd->CommonCfg.AddHTInfo,
								  END_OF_ARGS);
#else
				NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, AddHtLen);
				*(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
				*(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));

				MakeOutgoingFrame(pOutBuffer + FrameLen,         &TmpLen,
								1,                               &WpaIe,
								1,                               &epigram_ie_len,
								4,                               &BROADCOM_AHTINFO[0],
								AddHtLen,                        &addHTInfoTmp,
							  END_OF_ARGS);
#endif

				FrameLen += TmpLen;
			}
		}
#endif // DOT11_N_SUPPORT //


#ifdef WSC_AP_SUPPORT
		/* for windows 7 logo test */
		if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) &&
#ifdef DOT1X_SUPPORT
				(pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) && 
#endif // DOT1X_SUPPORT //
				(pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled))
		{
			/*
				Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based 
				or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP
				network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't
				receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and
				prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">>
				A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network.  
				The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero)
				http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp
			*/
			ULONG TempLen1 = 0;
			UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00};
			MakeOutgoingFrame(pOutBuffer+FrameLen,        &TempLen1,
								7,                            PROVISION_SERVICE_IE,
								END_OF_ARGS);
			FrameLen += TempLen1;
	    }

        // add Simple Config Information Element
        if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode > WSC_DISABLE) && (pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen))
        {
    		ULONG WscTmpLen = 0;
    		MakeOutgoingFrame(pOutBuffer+FrameLen,                                  &WscTmpLen,
    						  pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen,   pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.Value,
                              END_OF_ARGS);
    		FrameLen += WscTmpLen;
        }
#endif // WSC_AP_SUPPORT //

#ifdef DOT11R_FT_SUPPORT
		/* The Mobility Domain information element (MDIE) is present in Probe-
		** Request frame when dot11FastBssTransitionEnable is set to true. */
		if (pAd->ApCfg.MBSSID[apidx].FtCfg.FtCapFlag.Dot11rFtEnable)
		{
			PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].FtCfg;
			FT_CAP_AND_POLICY FtCap;
			FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs;
			FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap;
			FT_InsertMdIE(pAd, pOutBuffer + FrameLen, &FrameLen,
							pFtCfg->FtMdId, FtCap);
		}
#endif // DOT11R_FT_SUPPORT //

		// 802.11n 11.1.3.2.2 active scanning. sending probe response with MCS rate is		
		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
		MlmeFreeMemory(pAd, pOutBuffer);
	}
Ejemplo n.º 2
0
/*
	==========================================================================
	Description:
		Pre-build a BEACON frame in the shared memory
	==========================================================================
*/
VOID APMakeBssBeacon(RTMP_ADAPTER *pAd, INT apidx)
{
	UCHAR DsLen = 1, SsidLen;
	HEADER_802_11 BcnHdr;
	LARGE_INTEGER FakeTimestamp;
	ULONG FrameLen = 0;
	PUCHAR pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf;
#if defined(DOT11_N_SUPPORT) && defined(DOT11K_RRM_SUPPORT)
	UINT i;
#endif /* defined(DOT11_N_SUPPORT) && defined(DOT11K_RRM_SUPPORT) */
	HTTRANSMIT_SETTING BeaconTransmit = {.word = 0};   /* MGMT frame PHY rate setting when operatin at Ht rate. */
	UCHAR PhyMode, SupRateLen;
	MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx];
#ifdef SPECIFIC_TX_POWER_SUPPORT
	UCHAR TxPwrAdj = 0;
#endif /* SPECIFIC_TX_POWER_SUPPORT */
	
	if(!BeaconTransmitRequired(pAd, apidx, pMbss))
		return;

	PhyMode = pMbss->wdev.PhyMode;

	if (pMbss->bHideSsid)
		SsidLen = 0;
	else
		SsidLen = pMbss->SsidLen;

	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, 
						pMbss->wdev.if_addr,
						pMbss->wdev.bssid);
	
	/* for update framelen to TxWI later. */
	SupRateLen = pAd->CommonCfg.SupRateLen;
	if (PhyMode == WMODE_B)
		SupRateLen = 4;

	MakeOutgoingFrame(pBeaconFrame,                  &FrameLen,
					sizeof(HEADER_802_11),           &BcnHdr, 
					TIMESTAMP_LEN,                   &FakeTimestamp,
					2,                               &pAd->CommonCfg.BeaconPeriod,
					2,                               &pMbss->CapabilityInfo,
					1,                               &SsidIe, 
					1,                               &SsidLen, 
					SsidLen,                      pMbss->Ssid,
					1,                               &SupRateIe, 
					1,                               &SupRateLen,
					SupRateLen,                pAd->CommonCfg.SupRate, 
					1,                               &DsIe, 
					1,                               &DsLen, 
					1,                               &pAd->CommonCfg.Channel,
					END_OF_ARGS);

	if ((pAd->CommonCfg.ExtRateLen) && (PhyMode != WMODE_B))
	{
		ULONG TmpLen;
		MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
						1,                               &ExtRateIe, 
						1,                               &pAd->CommonCfg.ExtRateLen,
						pAd->CommonCfg.ExtRateLen,           pAd->CommonCfg.ExtRate, 
						END_OF_ARGS);
		FrameLen += TmpLen;
	}


    /* add country IE, power constraint IE */
	if (pAd->CommonCfg.bCountryFlag)
	{
		ULONG TmpLen, TmpLen2=0;
		UCHAR *TmpFrame = NULL;
		UCHAR CountryIe = IE_COUNTRY;

		os_alloc_mem(NULL, (UCHAR **)&TmpFrame, 256);
		if (TmpFrame != NULL)
		{
			NdisZeroMemory(TmpFrame, 256);

			/* prepare channel information */
#ifdef EXT_BUILD_CHANNEL_LIST
			BuildBeaconChList(pAd, TmpFrame, &TmpLen2);
#else
			{
				UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
				MakeOutgoingFrame(TmpFrame+TmpLen2,     &TmpLen,
									1,                 	&pAd->ChannelList[0].Channel,
									1,                 	&pAd->ChannelListNum,
									1,                 	&MaxTxPower,
									END_OF_ARGS);
				TmpLen2 += TmpLen;
			}
#endif /* EXT_BUILD_CHANNEL_LIST */

#ifdef DOT11K_RRM_SUPPORT
			if (IS_RRM_ENABLE(pAd, apidx)
				&& (pAd->CommonCfg.RegulatoryClass[0] != 0))
			{
				TmpLen2 = 0;
				NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
				RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2);
			}		
#endif /* DOT11K_RRM_SUPPORT */

			/* need to do the padding bit check, and concatenate it */
			if ((TmpLen2%2) == 0)
			{
				UCHAR	TmpLen3 = TmpLen2+4;
				MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
				                  1,                 	&CountryIe,
				                  1,                 	&TmpLen3,
				                  3,                 	pAd->CommonCfg.CountryCode,
				                  TmpLen2+1,				TmpFrame,
				                  END_OF_ARGS);
			}
			else
			{
				UCHAR	TmpLen3 = TmpLen2+3;
				MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
				                  1,                 	&CountryIe,
				                  1,                 	&TmpLen3,
				                  3,                 	pAd->CommonCfg.CountryCode,
				                  TmpLen2,				TmpFrame,
				                  END_OF_ARGS);
			}
			FrameLen += TmpLen;

			os_free_mem(NULL, TmpFrame);
		}
		else
			DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
	}

#ifdef DOT11K_RRM_SUPPORT
	if (IS_RRM_ENABLE(pAd, apidx))
	{
		InsertTpcReportIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
			RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit), 0);
		RRM_InsertRRMEnCapIE(pAd, pBeaconFrame+FrameLen, &FrameLen, apidx);
	}
#endif /* DOT11K_RRM_SUPPORT */

#ifdef DOT11_N_SUPPORT
	/* AP Channel Report */
#ifdef DOT11K_RRM_SUPPORT
	for (i=0; i<MAX_NUM_OF_REGULATORY_CLASS; i++)
	{
		if (pAd->CommonCfg.RegulatoryClass[i] == 0)
			break;

		InsertChannelRepIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
							(PSTRING)pAd->CommonCfg.CountryCode,
							pAd->CommonCfg.RegulatoryClass[i]);

	}
#else
	{
		UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT;
		ULONG	TmpLen;

		/*
			802.11n D2.0 Annex J, USA regulatory 
				class 32, channel set 1~7
				class 33, channel set 5-11
		*/
		UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7};
        UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11};
		UCHAR rclasslen = 8; /*sizeof(rclass32); */
		if (PhyMode == (WMODE_B | WMODE_G | WMODE_GN))
		{
			MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
							  1,                    &APChannelReportIe,
							  1,                    &rclasslen,
							  rclasslen,            rclass32,
   							  1,                    &APChannelReportIe,
							  1,                    &rclasslen,
							  rclasslen,            rclass33,
							  END_OF_ARGS);
			FrameLen += TmpLen;		
		}
	}
#endif

#endif /* DOT11_N_SUPPORT */

#ifdef DOT11R_FT_SUPPORT
	/* The Mobility Domain information element (MDIE) is present in Beacon
	** frame when dot11FastBssTransitionEnable is set to true. */
	if (pAd->ApCfg.MBSSID[apidx].FtCfg.FtCapFlag.Dot11rFtEnable)
	{
		PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].FtCfg;
		FT_CAP_AND_POLICY FtCap;
		NdisZeroMemory(&FtCap, sizeof(FT_CAP_AND_POLICY));
		FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs;
		FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap;
		FT_InsertMdIE(pAd, pBeaconFrame + FrameLen, &FrameLen,
						pFtCfg->FtMdId, FtCap);
	}
#endif /* DOT11R_FT_SUPPORT */

	BeaconTransmit.word = 0;

#ifdef SPECIFIC_TX_POWER_SUPPORT
        /* Specific Power for Long-Range Beacon */
	if ((pAd->ApCfg.MBSSID[apidx].TxPwrAdj != -1) /* && 
	    (BeaconTransmit.field.MODE == MODE_CCK)*/) 
	{
		TxPwrAdj = pAd->ApCfg.MBSSID[apidx].TxPwrAdj;
	}
#endif /* SPECIFIC_TX_POWER_SUPPORT */

	RTMPWriteTxWI(pAd, &pAd->BeaconTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID, 
					FrameLen, PID_MGMT, 0, 0,IFS_HTTXOP, &BeaconTransmit);

#ifdef SPECIFIC_TX_POWER_SUPPORT
#ifdef RTMP_MAC
		if ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RTMP))
        	pAd->BeaconTxWI.TXWI_O.TxPwrAdj = TxPwrAdj;
#endif /* RTMP_MAC */
#ifdef RLT_MAC
		if  ((IS_RT6352(pAd) || IS_MT76x2(pAd)) && (pAd->chipCap.hif_type == HIF_RLT))
			pAd->BeaconTxWI.TXWI_N.TxPwrAdj = TxPwrAdj;
#endif /* RLT_MAC */
#endif /* SPECIFIC_TX_POWER_SUPPORT */

	/*
		step 6. move BEACON TXD and frame content to on-chip memory
	*/
	 updateAllBeacon(pAd,  apidx, FrameLen);

	pMbss->TimIELocationInBeacon = (UCHAR)FrameLen; 
	pMbss->CapabilityInfoLocationInBeacon = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2;
}

void updateAllBeacon(RTMP_ADAPTER *pAd, INT apidx, ULONG FrameLen)
{
		UCHAR *ptr = NULL;
		MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[apidx];
		UINT32 longValue, reg_base;
		UINT i = 0;
		UINT8 TXWISize = pAd->chipCap.TXWISize;
		
		ptr = (PUCHAR)&pAd->BeaconTxWI;
#ifdef RT_BIG_ENDIAN
		RTMPWIEndianChange(pAd, ptr, TYPE_TXWI);
#endif
	
	
		reg_base = pAd->BeaconOffset[pMbss->BcnBufIdx];
		for (i=0; i < TXWISize; i+=4)
		{
			longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
			RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4);
			ptr += 4;
		}
	
		/* update BEACON frame content. start right after the TXWI field. */
		ptr = (PUCHAR)pMbss->BeaconBuf;
#ifdef RT_BIG_ENDIAN
		RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
#endif
	
		reg_base = pAd->BeaconOffset[pMbss->BcnBufIdx] + TXWISize;
		for (i= 0; i< FrameLen; i+=4)
		{
			longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
			RTMP_CHIP_UPDATE_BEACON(pAd, reg_base + i, longValue, 4);
			ptr += 4;
		}

}
Ejemplo n.º 3
0
VOID RRM_EnqueueLinkMeasureReq(
	IN PRTMP_ADAPTER pAd,
	IN UINT8 Aid,
	IN UINT8 apidx)
{
	UINT8 DialogToken = RandomByte(pAd);
	HEADER_802_11 ActHdr;
	PUCHAR pOutBuffer = NULL;
	NDIS_STATUS NStatus;
	ULONG FrameLen;
	PMAC_TABLE_ENTRY pEntry;

	if ((apidx >= pAd->ApCfg.BssidNum)
		|| (Aid >= MAX_LEN_OF_MAC_TABLE))
	{
		DBGPRINT(RT_DEBUG_ERROR, ("%s: Invalid STA. apidx=%d Aid=%d\n",
			__FUNCTION__, apidx, Aid));
		return;
	}

	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  /* Get an unused nonpaged memory */
	if(NStatus != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
		return;
	}

	pEntry = &pAd->MacTab.Content[Aid];

	/* build action frame header. */
	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pEntry->Addr,
						pAd->ApCfg.MBSSID[apidx].wdev.if_addr,
						pAd->ApCfg.MBSSID[apidx].wdev.bssid);

	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
	FrameLen = sizeof(HEADER_802_11);

	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
		CATEGORY_RM, RRM_LNK_MEASURE_REQ);
	
	/* fill Dialog Token */
	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);

	/* fill Tx Power Used field */
	{
		ULONG TempLen;
		UINT8 TxPwr = RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit);
		MakeOutgoingFrame(pOutBuffer + FrameLen,	&TempLen,
						1,							&TxPwr,
						END_OF_ARGS);

		FrameLen += TempLen;
	}
	

	/* fill Max Tx Power field */
	{
		ULONG TempLen;
		UINT8 MaxTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
		MakeOutgoingFrame(pOutBuffer + FrameLen,	&TempLen,
						1,							&MaxTxPwr,
						END_OF_ARGS);

		FrameLen += TempLen;
	}


	MeasureReqInsert(pAd, DialogToken);

	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);

	if (pOutBuffer)
		MlmeFreeMemory(pAd, pOutBuffer);

	return;
}
Ejemplo n.º 4
0
/*
	==========================================================================
	Description:
		Pre-build a BEACON frame in the shared memory
	==========================================================================
*/
VOID APMakeBssBeacon(
	IN PRTMP_ADAPTER	pAd,
	IN INT				apidx)
{
	UCHAR         DsLen = 1, SsidLen;//, TimLen = 4,
				  //BitmapControl = 0, VirtualBitmap = 0, EmptySsidLen = 0, SsidLen;
//	UCHAR         RSNIe=IE_WPA, RSNIe2=IE_WPA2;
	HEADER_802_11 BcnHdr;
	LARGE_INTEGER FakeTimestamp;
	ULONG         FrameLen = 0;
	PTXWI_STRUC    pTxWI = &pAd->BeaconTxWI;
	PUCHAR        pBeaconFrame = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf;
	UCHAR  *ptr;
	UINT  i;
	UINT32 longValue, reg_base;
	HTTRANSMIT_SETTING	BeaconTransmit;   // MGMT frame PHY rate setting when operatin at Ht rate.

	if(!BeaconTransmitRequired(pAd, apidx, &pAd->ApCfg.MBSSID[apidx]))
		return;


	if (pAd->ApCfg.MBSSID[apidx].bHideSsid)
		SsidLen = 0;
	else
		SsidLen = pAd->ApCfg.MBSSID[apidx].SsidLen;

	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->ApCfg.MBSSID[apidx].Bssid);

	
	// for update framelen to TxWI later.
	MakeOutgoingFrame(pBeaconFrame,                  &FrameLen,
					sizeof(HEADER_802_11),           &BcnHdr, 
					TIMESTAMP_LEN,                   &FakeTimestamp,
					2,                               &pAd->CommonCfg.BeaconPeriod,
					2,                               &pAd->ApCfg.MBSSID[apidx].CapabilityInfo,
					1,                               &SsidIe, 
					1,                               &SsidLen, 
					SsidLen,                         pAd->ApCfg.MBSSID[apidx].Ssid,
					1,                               &SupRateIe, 
					1,                               &pAd->CommonCfg.SupRateLen,
					pAd->CommonCfg.SupRateLen,       pAd->CommonCfg.SupRate, 
					1,                               &DsIe, 
					1,                               &DsLen, 
					1,                               &pAd->CommonCfg.Channel,
					END_OF_ARGS);

	if (pAd->CommonCfg.ExtRateLen)
	{
		ULONG TmpLen;
		MakeOutgoingFrame(pBeaconFrame+FrameLen,         &TmpLen,
						1,                               &ExtRateIe, 
						1,                               &pAd->CommonCfg.ExtRateLen,
						pAd->CommonCfg.ExtRateLen,           pAd->CommonCfg.ExtRate, 
						END_OF_ARGS);
		FrameLen += TmpLen;
	}


    // add country IE, power constraint IE
	if (pAd->CommonCfg.bCountryFlag)
	{
		ULONG TmpLen, TmpLen2=0;
		UCHAR TmpFrame[256];
		UCHAR CountryIe = IE_COUNTRY;

		NdisZeroMemory(TmpFrame, sizeof(TmpFrame));

		// prepare channel information
#ifdef EXT_BUILD_CHANNEL_LIST
		BuildBeaconChList(pAd, TmpFrame, &TmpLen2);
#else
		{
			UCHAR MaxTxPower = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
			MakeOutgoingFrame(TmpFrame+TmpLen2,     &TmpLen,
								1,                 	&pAd->ChannelList[0].Channel,
								1,                 	&pAd->ChannelListNum,
								1,                 	&MaxTxPower,
								END_OF_ARGS);
			TmpLen2 += TmpLen;
		}
#endif // EXT_BUILD_CHANNEL_LIST //

#ifdef DOT11K_RRM_SUPPORT
		if (IS_RRM_ENABLE(pAd, apidx)
			&& (pAd->CommonCfg.RegulatoryClass[0] != 0))
		{
			TmpLen2 = 0;
			NdisZeroMemory(TmpFrame, sizeof(TmpFrame));
			RguClass_BuildBcnChList(pAd, TmpFrame, &TmpLen2);
		}		
#endif // DOT11K_RRM_SUPPORT //

		// need to do the padding bit check, and concatenate it
		if ((TmpLen2%2) == 0)
		{
			UCHAR	TmpLen3 = TmpLen2+4;
			MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
			                  1,                 	&CountryIe,
			                  1,                 	&TmpLen3,
			                  3,                 	pAd->CommonCfg.CountryCode,
			                  TmpLen2+1,				TmpFrame,
			                  END_OF_ARGS);
		}
		else
		{
			UCHAR	TmpLen3 = TmpLen2+3;
			MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
			                  1,                 	&CountryIe,
			                  1,                 	&TmpLen3,
			                  3,                 	pAd->CommonCfg.CountryCode,
			                  TmpLen2,				TmpFrame,
			                  END_OF_ARGS);
		}
		FrameLen += TmpLen;
	}

#ifdef DOT11K_RRM_SUPPORT
	if (IS_RRM_ENABLE(pAd, apidx))
	{
		InsertTpcReportIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
			RTMP_GetTxPwr(pAd, pAd->CommonCfg.MlmeTransmit), 0);
		RRM_InsertRRMEnCapIE(pAd, pBeaconFrame+FrameLen, &FrameLen, apidx);
	}
#endif // DOT11K_RRM_SUPPORT //

#ifdef DOT11_N_SUPPORT
	// AP Channel Report
#ifdef DOT11K_RRM_SUPPORT
	for (i=0; i<MAX_NUM_OF_REGULATORY_CLASS; i++)
	{
		if (pAd->CommonCfg.RegulatoryClass[i] == 0)
			break;

		InsertChannelRepIE(pAd, pBeaconFrame+FrameLen, &FrameLen,
							(PSTRING)pAd->CommonCfg.CountryCode,
							pAd->CommonCfg.RegulatoryClass[i]);

	}
#else
	{
		UCHAR APChannelReportIe = IE_AP_CHANNEL_REPORT;
		ULONG	TmpLen;

		// 802.11n D2.0 Annex J
		// USA
		// regulatory class 32, channel set 1~7
		// regulatory class 33, channel set 5-11

		UCHAR rclass32[]={32, 1, 2, 3, 4, 5, 6, 7};
        UCHAR rclass33[]={33, 5, 6, 7, 8, 9, 10, 11};
		UCHAR rclasslen = 8; //sizeof(rclass32);
		if (pAd->CommonCfg.PhyMode == PHY_11BGN_MIXED)
		{
			MakeOutgoingFrame(pBeaconFrame+FrameLen,&TmpLen,
							  1,                    &APChannelReportIe,
							  1,                    &rclasslen,
							  rclasslen,            rclass32,
   							  1,                    &APChannelReportIe,
							  1,                    &rclasslen,
							  rclasslen,            rclass33,
							  END_OF_ARGS);
			FrameLen += TmpLen;		
		}
	}
#endif

#endif // DOT11_N_SUPPORT //

#ifdef WSC_AP_SUPPORT
    // add Simple Config Information Element
    if (((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode >= 1) && (pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen))
#ifdef HOSTAPD_SUPPORT
		|| pAd->ApCfg.HostapdWPS
#endif
		)
    {
		ULONG WscTmpLen = 0;
        
		MakeOutgoingFrame(pBeaconFrame+FrameLen,                            &WscTmpLen,
						  pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen,    pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value,
                              END_OF_ARGS);
		FrameLen += WscTmpLen;		  
    }

    if ((pAd->ApCfg.MBSSID[apidx].WscControl.WscConfMode != WSC_DISABLE) &&
#ifdef DOT1X_SUPPORT
        (pAd->ApCfg.MBSSID[apidx].IEEE8021X == FALSE) && 
#endif // DOT1X_SUPPORT //		
        (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled))
    {
        /*
            Non-WPS Windows XP and Vista PCs are unable to determine if a WEP enalbed network is static key based 
            or 802.1X based. If the legacy station gets an EAP-Rquest/Identity from the AP, it assume the WEP
            network is 802.1X enabled & will prompt the user for 802.1X credentials. If the legacy station doesn't
            receive anything after sending an EAPOL-Start, it will assume the WEP network is static key based and
            prompt user for the WEP key. <<from "WPS and Static Key WEP Networks">>
            A WPS enabled AP should include this IE in the beacon when the AP is hosting a static WEP key network.  
            The IE would be 7 bytes long with the Extended Capability field set to 0 (all bits zero)
            http://msdn.microsoft.com/library/default.asp?url=/library/en-us/randz/protocol/securing_public_wi-fi_hotspots.asp
        */
        ULONG TempLen = 0;
        UCHAR PROVISION_SERVICE_IE[7] = {0xDD, 0x05, 0x00, 0x50, 0xF2, 0x05, 0x00};
        MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TempLen,
						  7,                            PROVISION_SERVICE_IE,
                          END_OF_ARGS);
        FrameLen += TempLen;
    }
#endif // WSC_AP_SUPPORT //
    
#ifdef DOT11R_FT_SUPPORT
	/* The Mobility Domain information element (MDIE) is present in Beacon
	** frame when dot11FastBssTransitionEnable is set to true. */
	if (pAd->ApCfg.MBSSID[apidx].FtCfg.FtCapFlag.Dot11rFtEnable)
	{
		PFT_CFG pFtCfg = &pAd->ApCfg.MBSSID[apidx].FtCfg;
		FT_CAP_AND_POLICY FtCap;
		NdisZeroMemory(&FtCap, sizeof(FT_CAP_AND_POLICY));
		FtCap.field.FtOverDs = pFtCfg->FtCapFlag.FtOverDs;
		FtCap.field.RsrReqCap = pFtCfg->FtCapFlag.RsrReqCap;
		FT_InsertMdIE(pAd, pBeaconFrame + FrameLen, &FrameLen,
						pFtCfg->FtMdId, FtCap);
	}
#endif // DOT11R_FT_SUPPORT //

	BeaconTransmit.word = 0;
	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, BSS0Mcast_WCID, 
		FrameLen, PID_MGMT, 0, 0,IFS_HTTXOP, FALSE, &BeaconTransmit);

#ifdef RT3593
	/*
		Shared memory access selection (higher 8KB shared memory)
	*/
	RTMP_RF33_SHARED_MEM_SELECT(pAd);
#endif // RT3593 //

	//
	// step 6. move BEACON TXD and frame content to on-chip memory
	//
	ptr = (PUCHAR)&pAd->BeaconTxWI;
#ifdef RT_BIG_ENDIAN
    RTMPWIEndianChange(ptr, TYPE_TXWI);
#endif

	reg_base = pAd->BeaconOffset[pAd->ApCfg.MBSSID[apidx].BcnBufIdx];
	for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
	{
		longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
		RTMP_IO_WRITE32(pAd, reg_base + i, longValue);
		ptr += 4;
	}

	// update BEACON frame content. start right after the 16-byte TXWI field.
	ptr = (PUCHAR)pAd->ApCfg.MBSSID[apidx].BeaconBuf;
#ifdef RT_BIG_ENDIAN
    RTMPFrameEndianChange(pAd, ptr, DIR_WRITE, FALSE);
#endif


	reg_base = pAd->BeaconOffset[pAd->ApCfg.MBSSID[apidx].BcnBufIdx] + TXWI_SIZE;
	for (i= 0; i< FrameLen; i+=4)
	{
		longValue =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
		RTMP_IO_WRITE32(pAd, reg_base + i, longValue);
		ptr += 4;
	}

#ifdef RT3593
	/*
		Set the beacon offset (higher 8KB shared memory)
		Shared memory access selection (lower 8KB shared memory)
	*/
	RTMP_RF33_SHARED_MEM_DESELECT(pAd);
#endif // RT3593 //

	pAd->ApCfg.MBSSID[apidx].TimIELocationInBeacon = (UCHAR)FrameLen; 
	pAd->ApCfg.MBSSID[apidx].CapabilityInfoLocationInBeacon = sizeof(HEADER_802_11) + TIMESTAMP_LEN + 2;
}