/* ========================================================================== 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; }
/* ========================================================================== 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); }
/* ========================================================================== 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; } }
/* ========================================================================== 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; }