/*
	==========================================================================
	Description:
		Prepare Measurement request action frame and enqueue it into
		management queue waiting for transmition.

	Parametrs:
		1. the destination mac address of the frame.

	Return	: None.
	==========================================================================
 */
VOID EnqueueMeasurementReq(
	IN PRTMP_ADAPTER pAd,
	IN PUCHAR pDA,
	IN UINT8 MeasureToken,
	IN UINT8 MeasureReqMode,
	IN UINT8 MeasureReqType,
	IN UINT8 MeasureCh,
	IN UINT16 MeasureDuration)
{
	PUCHAR pOutBuffer = NULL;
	NDIS_STATUS NStatus;
	ULONG FrameLen;
	HEADER_802_11 ActHdr;
	MEASURE_REQ_INFO MeasureReqIE;
	UINT8 RmReqDailogToken = RandomByte(pAd);
	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);

	// build action frame header.
	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
						pAd->CurrentAddress);

	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
	if(NStatus != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
		return;
	}
	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
	FrameLen = sizeof(HEADER_802_11);

	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);

	// fill Dialog Token
	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);

	// prepare Measurement IE.
	NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
	MeasureReqIE.Token = RmReqDailogToken;
	MeasureReqIE.ReqMode.word = MeasureReqMode;
	MeasureReqIE.ReqType = MeasureReqType;
	MeasureReqIE.MeasureReq.ChNum = MeasureCh;
	MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
	MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
	InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);

	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
	MlmeFreeMemory(pAd, pOutBuffer);

	return;
}
/*
	==========================================================================
	Description:
		Prepare Measurement report action frame and enqueue it into
		management queue waiting for transmition.

	Parametrs:
		1. the destination mac address of the frame.

	Return	: None.
	==========================================================================
 */
VOID EnqueueMeasurementRep(
	IN PRTMP_ADAPTER pAd,
	IN PUCHAR pDA,
	IN UINT8 DialogToken,
	IN UINT8 MeasureToken,
	IN UINT8 MeasureReqMode,
	IN UINT8 MeasureReqType,
	IN UINT8 ReportInfoLen,
	IN PUINT8 pReportInfo)
{
	PUCHAR pOutBuffer = NULL;
	NDIS_STATUS NStatus;
	ULONG FrameLen;
	HEADER_802_11 ActHdr;
	MEASURE_REPORT_INFO MeasureRepIE;

	// build action frame header.
	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
						pAd->CurrentAddress);

	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
	if(NStatus != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
		return;
	}
	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
	FrameLen = sizeof(HEADER_802_11);

	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);

	// fill Dialog Token
	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);

	// prepare Measurement IE.
	NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
	MeasureRepIE.Token = MeasureToken;
	MeasureRepIE.ReportMode.word = MeasureReqMode;
	MeasureRepIE.ReportType = MeasureReqType;
	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);

	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
	MlmeFreeMemory(pAd, pOutBuffer);

	return;
}
/*
	==========================================================================
	Description:
		Prepare TPC Report action frame and enqueue it into
		management queue waiting for transmition.

	Parametrs:
		1. the destination mac address of the frame.

	Return	: None.
	==========================================================================
 */
VOID EnqueueTPCRep(
	IN PRTMP_ADAPTER pAd,
	IN PUCHAR pDA,
	IN UINT8 DialogToken,
	IN UINT8 TxPwr,
	IN UINT8 LinkMargin)
{
	PUCHAR pOutBuffer = NULL;
	NDIS_STATUS NStatus;
	ULONG FrameLen;

	HEADER_802_11 ActHdr;

	// build action frame header.
	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
						pAd->CurrentAddress);

	NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);  //Get an unused nonpaged memory
	if(NStatus != NDIS_STATUS_SUCCESS)
	{
		DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__));
		return;
	}
	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
	FrameLen = sizeof(HEADER_802_11);

	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);

	// fill Dialog Token
	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);

	// Insert TPC Request IE.
	InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);

	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
	MlmeFreeMemory(pAd, pOutBuffer);

	return;
}
Esempio n. 4
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;
}
Esempio n. 5
0
VOID RRM_EnqueueNeighborRep(
	IN PRTMP_ADAPTER pAd,
	IN PMAC_TABLE_ENTRY pEntry,
	IN UINT8 DialogToken,
	IN PCHAR pSsid,
	IN UINT8 SsidLen)
{
#define MIN(_x, _y) ((_x) > (_y) ? (_x) : (_y))
	INT loop;
	HEADER_802_11 ActHdr;
	PUCHAR pOutBuffer = NULL;
	NDIS_STATUS NStatus;
	ULONG FrameLen;
	ULONG PktLen;

	if ((pEntry == NULL) || (pEntry->func_tb_idx >= pAd->ApCfg.BssidNum))
	{
		DBGPRINT(RT_DEBUG_ERROR, ("%s: Invalid STA.\n", __FUNCTION__));
		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;
	}

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

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

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

#ifdef AP_SCAN_SUPPORT
	/* insert NeighborRep IE. */
	for (loop = 0; loop < pAd->ScanTab.BssNr; loop++)
	{
		UINT8 BssMatch = FALSE;
		BSS_ENTRY *pBssEntry = &pAd->ScanTab.BssEntry[loop];

		/* Discards all remain Bss if the packet length exceed packet buffer size. */
		PktLen = FrameLen + sizeof(RRM_NEIGHBOR_REP_INFO)
				+ (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].RrmCfg.bDot11kRRMNeighborRepTSFEnable == TRUE ? 6 : 0);
		if (PktLen >= MGMT_DMA_BUFFER_SIZE)
			break;

		if (SsidLen != 0)
			BssMatch = RTMPEqualMemory(pBssEntry->Ssid, pSsid,
								MIN(SsidLen, pBssEntry->SsidLen));
		else
			BssMatch = TRUE;

		if (BssMatch)
		{
			RRM_BSSID_INFO BssidInfo;
			BssidInfo.word = 0;
			BssidInfo.field.APReachAble = 3;
			BssidInfo.field.Security = 0; /* rrm to do. */
			BssidInfo.field.KeyScope = 0; /* "report AP has same authenticator as the AP. */
			BssidInfo.field.SepctrumMng = (pBssEntry->CapabilityInfo & (1 << 8))?1:0;
			BssidInfo.field.Qos = (pBssEntry->CapabilityInfo & (1 << 9))?1:0;
			BssidInfo.field.APSD = (pBssEntry->CapabilityInfo & (1 << 11))?1:0;
			BssidInfo.field.RRM = (pBssEntry->CapabilityInfo & RRM_CAP_BIT)?1:0;
			BssidInfo.field.DelayBlockAck = (pBssEntry->CapabilityInfo & (1 << 14))?1:0;
			BssidInfo.field.ImmediateBA = (pBssEntry->CapabilityInfo & (1 << 15))?1:0;

	
/* 
	reference 2012 spec.
	802.11-2012.pdf
	page#581 (0 is not euqal to no security )
	The Security bit, if 1, indicates that the AP identified by this BSSID supports the same security provisioning
	as used by the STA in its current association. If the bit is 0, it indicates either that the AP does not support
	the same security provisioning or that the security information is not available at this time.
*/

			
			BssidInfo.field.KeyScope = 0; /* "report AP has same authenticator as the AP. */
/*
	reference 2012 spec.
	802.11-2012.pdf
	page#582 (0 means information is not available  )
	The Key Scope bit, when set, indicates the AP indicated by this BSSID has the same authenticator as the AP
	sending the report. If this bit is 0, it indicates a distinct authenticator or the information is not available.
*/

			BssidInfo.field.SepctrumMng = (pBssEntry->CapabilityInfo & (1 << 8))?1:0;
			BssidInfo.field.Qos = (pBssEntry->CapabilityInfo & (1 << 9))?1:0;
			BssidInfo.field.APSD = (pBssEntry->CapabilityInfo & (1 << 11))?1:0;
			BssidInfo.field.RRM = (pBssEntry->CapabilityInfo & RRM_CAP_BIT)?1:0;
			BssidInfo.field.DelayBlockAck = (pBssEntry->CapabilityInfo & (1 << 14))?1:0;
			BssidInfo.field.ImmediateBA = (pBssEntry->CapabilityInfo & (1 << 15))?1:0;


			BssidInfo.field.MobilityDomain = (pBssEntry->bHasMDIE )?1:0;
			BssidInfo.field.HT = (pBssEntry->HtCapabilityLen != 0)?1:0;
#ifdef DOT11_VHT_AC			
			BssidInfo.field.VHT = (pBssEntry->vht_cap_len != 0)?1:0;
#endif /* DOT11_VHT_AC */

			/*
			reference spec:
			dot11FrameRprtPhyType OBJECT-TYPE
			SYNTAX INTEGER {
			fhss(1),
			dsss(2),
			irbaseband(3),
			ofdm(4),
			hrdsss(5),
			erp(6),
			ht(7),
			vht(9)
			}

			*/
			
			if (pBssEntry->Channel > 14) // 5G case
			{
				if (pBssEntry->HtCapabilityLen != 0) // HT or Higher case
				{
#ifdef DOT11_VHT_AC				
					if (pBssEntry->vht_cap_len != 0)
						pBssEntry->CondensedPhyType = 9;
					else
#endif /* DOT11_VHT_AC */
						pBssEntry->CondensedPhyType = 7;
				}
				else // OFDM case
				{
					pBssEntry->CondensedPhyType = 4;
				}
			}
			else // 2.4G case
			{

				if (pBssEntry->HtCapabilityLen != 0) //HT case
					pBssEntry->CondensedPhyType = 7;
				else if (ERP_IS_NON_ERP_PRESENT(pBssEntry->Erp)) //ERP case
					pBssEntry->CondensedPhyType = 6;
				else if (pBssEntry->SupRateLen > 4)// OFDM case (1,2,5.5,11 for CCK 4 Rates)
					pBssEntry->CondensedPhyType = 4;

				/* no CCK's definition in spec. */
			}

			RRM_InsertNeighborRepIE(pAd, (pOutBuffer + FrameLen), &FrameLen,
				sizeof(RRM_NEIGHBOR_REP_INFO), pBssEntry->Bssid,
				BssidInfo, pBssEntry->RegulatoryClass,
				pBssEntry->Channel, pBssEntry->CondensedPhyType);
		}

		/*
			shall insert Neighbor Report TSF offset
			when the MIB attribute
			dot11RRMNeighborReportTSFOffsetEnabled is true.
		*/
		if (pAd->ApCfg.MBSSID[pEntry->func_tb_idx].RrmCfg.bDot11kRRMNeighborRepTSFEnable)
		{
			UINT32 Ttfs = (UINT32)(pBssEntry->TTSF[3] << 24)
					+ (UINT32)(pBssEntry->TTSF[2] << 16)
					+ (UINT32)(pBssEntry->TTSF[1] << 8)
					+ (UINT32)(pBssEntry->TTSF[0]);

			UINT32 Ptfs = (UINT32)(pBssEntry->PTSF[3] << 24)
					+ (UINT32)(pBssEntry->PTSF[2] << 16)
					+ (UINT32)(pBssEntry->PTSF[1] << 8)
					+ (UINT32)(pBssEntry->PTSF[0]);

			RRM_InsertNeighborTSFOffsetSubIE(pAd, (pOutBuffer + FrameLen),
						&FrameLen, cpu2le16((UINT16)ABS(Ttfs, Ptfs)),
						pBssEntry->BeaconPeriod);
		}
	}
#endif /* AP_SCAN_SUPPORT */
	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);

	if (pOutBuffer)
		MlmeFreeMemory(pAd, pOutBuffer);

	return;
}