📄 aironet.c
字号:
if (CCABusyFraction < 10) CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1; pLoad->CCABusy = CCABusyFraction; DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction)); DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen)); pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT)); DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen)); // 4. Clear channel load measurement flag RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT); // 5. reset to idle state pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));}/* ======================================================================== Routine Description: Arguments: Return Value: None Note: ========================================================================*/VOID NoiseHistReportAction( IN PRTMP_ADAPTER pAd, IN UCHAR Index){ PMEASUREMENT_REPORT_ELEMENT pReport; PNOISE_HIST_REPORT pNoise; PUCHAR pDest; UCHAR i,NoiseCnt; USHORT TotalRPICnt, TotalRPISum; DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n")); // 0. Disable Rx with promiscuous reception, make it back to normal RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification. // 1. Setup pointer for processing beacon & probe response pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; // 2. Fill Measurement report element field. pReport->Eid = IE_MEASUREMENT_REPORT; // Fixed Length at 16, not include Eid and length fields pReport->Length = 16; pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token; pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode; pReport->Type = MSRN_TYPE_NOISE_HIST_REQ; // 3. Fill noise histogram report measurement data pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); pNoise = (PNOISE_HIST_REPORT) pDest; pNoise->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel; pNoise->Spare = 0; pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration; // 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU // We estimate 4000 normal packets received durning 10 seconds test. // Adjust it if required. // 3 is a good value for pAd->StaCfg.NHFactor // TotalRPICnt = pNoise->Duration * 3 / 10; TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10; TotalRPISum = 0; for (i = 0; i < 8; i++) { TotalRPISum += pAd->StaCfg.RPIDensity[i]; DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i])); } // Double check if the counter is larger than our expectation. // We will replace it with the total number plus a fraction. if (TotalRPISum > TotalRPICnt) TotalRPICnt = TotalRPISum + pNoise->Duration / 20; DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt)); // 5. Initialize noise count for the total summation of 0xff NoiseCnt = 0; for (i = 1; i < 8; i++) { pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt); if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0)) pNoise->Density[i]++; NoiseCnt += pNoise->Density[i]; DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d] = 0x%02x\n", i, pNoise->Density[i])); } // 6. RPI[0] represents the rest of counts pNoise->Density[0] = 0xff - NoiseCnt; DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0] = 0x%02x\n", pNoise->Density[0])); pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT)); // 7. Clear channel load measurement flag RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT); // 8. reset to idle state pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));}/* ======================================================================== Routine Description: Prepare Beacon report action, Arguments: pAd Pointer to our adapter Return Value: None Note: ========================================================================*/VOID BeaconReportAction( IN PRTMP_ADAPTER pAd, IN UCHAR Index) { DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n")); // Looks like we don't have anything thing need to do here. // All measurement report already finished in AddBeaconReport // The length is in the FrameReportLen // reset Beacon index for next beacon request pAd->StaCfg.LastBssIndex = 0xff; // reset to idle state pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));}/* ======================================================================== Routine Description: Arguments: Index Current BSSID in CCXBsstab entry index Return Value: Note: ========================================================================*/VOID AironetAddBeaconReport( IN PRTMP_ADAPTER pAd, IN ULONG Index, IN PMLME_QUEUE_ELEM pElem) { PVOID pMsg; PUCHAR pSrc, pDest; UCHAR ReqIdx; ULONG MsgLen; USHORT Length; PFRAME_802_11 pFrame; PMEASUREMENT_REPORT_ELEMENT pReport; PEID_STRUCT pEid; PBEACON_REPORT pBeaconReport; PBSS_ENTRY pBss; // 0. Setup pointer for processing beacon & probe response pMsg = pElem->Msg; MsgLen = pElem->MsgLen; pFrame = (PFRAME_802_11) pMsg; pSrc = pFrame->Octet; // Start from AP TSF pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index]; ReqIdx = pAd->StaCfg.CurrentRMReqIdx; // Filter out not same channel reception // if (pAd->StaCfg.CCXScanChannel != pBss->Channel) // return; // 1 Check the Index, if we already create this entry, only update the average RSSI if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff)) { pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]]; // Point to bss report information pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); pBeaconReport = (PBEACON_REPORT) pDest; // Update Rx power, in dBm // Get the original RSSI readback from BBP pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta; // Average the Rssi reading pBeaconReport->RxPower = (pBeaconReport->RxPower + pBss->Rssi) / 2; // Get to dBm format pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta; DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ", pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5])); DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256)); // pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta; // DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%d], Rssi %d\n", Index, pBeaconReport->RxPower - 256)); DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index])); // Update other information here // Done return; } // 2. Update reported Index pAd->StaCfg.LastBssIndex = Index; // 3. Setup the buffer address for copying this BSSID into reporting frame // The offset should start after 802.11 header and report frame header. pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; // 4. Save the start offset of each Bss in report frame pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen; // 5. Fill Measurement report fields pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; pReport->Eid = IE_MEASUREMENT_REPORT; pReport->Length = 0; pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token; pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode; pReport->Type = MSRN_TYPE_BEACON_REQ; Length = sizeof(MEASUREMENT_REPORT_ELEMENT); pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); // 6. Start thebeacon report format pBeaconReport = (PBEACON_REPORT) pDest; pDest += sizeof(BEACON_REPORT); Length += sizeof(BEACON_REPORT); // 7. Copy Channel number pBeaconReport->Channel = pBss->Channel; pBeaconReport->Spare = 0; pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration; pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS); // 8. Rx power, in dBm pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta; DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ", pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5])); DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256)); DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen)); pBeaconReport->BeaconInterval = pBss->BeaconPeriod; COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3); NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4); NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4); // 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo pSrc += (TIMESTAMP_LEN + 2); pBeaconReport->CapabilityInfo = *(USHORT *)pSrc; // 10. Point to start of element ID pSrc += 2; pEid = (PEID_STRUCT) pSrc; // 11. Start process all variable Eid oayload and add the appropriate to the frame report while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen)) { // Only limited EID are required to report for CCX 2. It includes SSID, Supported rate, // FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set, // TIM (report first 4 bytes only, radio measurement capability switch (pEid->Eid) { case IE_SSID: case IE_SUPP_RATES: case IE_FH_PARM: case IE_DS_PARM: case IE_CF_PARM: case IE_IBSS_PARM: NdisMoveMemory(pDest, pEid, pEid->Len + 2); pDest += (pEid->Len + 2); Length += (pEid->Len + 2); break; case IE_MEASUREMENT_CAPABILITY: // Since this IE is duplicated with WPA security IE, we has to do sanity check before // recognize it. // 1. It also has fixed 6 bytes IE length. if (pEid->Len != 6) break; // 2. Check the Cisco Aironet OUI if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3)) { // Matched, this is what we want NdisMoveMemory(pDest, pEid, pEid->Len + 2); pDest += (pEid->Len + 2); Length += (pEid->Len + 2); } break; case IE_TIM: if (pEid->Len > 4) { // May truncate and report the first 4 bytes only, with the eid & len, total should be 6 NdisMoveMemory(pDest, pEid, 6); pDest += 6; Length += 6; } else { NdisMoveMemory(pDest, pEid, pEid->Len + 2); pDest += (pEid->Len + 2); Length += (pEid->Len + 2); } break; default: break; } // 12. Move to next element ID pSrc += (2 + pEid->Len); pEid = (PEID_STRUCT) pSrc; } // 13. Update the length in the header, not include EID and length pReport->Length = Length - 4; // 14. Update the frame report buffer data length pAd->StaCfg.FrameReportLen += Length; DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));}/* ======================================================================== Routine Description: Arguments: Index Current BSSID in CCXBsstab entry index Return Value: Note: ========================================================================*/VOID AironetCreateBeaconReportFromBssTable( IN PRTMP_ADAPTER pAd){ PMEASUREMENT_REPORT_ELEMENT pReport; PBEACON_REPORT pBeaconReport; UCHAR Index, ReqIdx; USHORT Length; PUCHAR pDest; PBSS_ENTRY pBss; // 0. setup base pointer ReqIdx = pAd->StaCfg.CurrentRMReqIdx; for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++) { // 1. Setup the buffer address for copying this BSSID into reporting frame // The offset should start after 802.11 header and report frame header. pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index]; Length = 0; // 2. Fill Measurement report fields pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; pReport->Eid = IE_MEASUREMENT_REPORT; pReport->Length = 0; pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token; pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode; pReport->Type = MSRN_TYPE_BEACON_REQ; Length = sizeof(MEASUREMENT_REPORT_ELEMENT); pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); // 3. Start the beacon report format pBeaconReport = (PBEACON_REPORT) pDest; pDest += sizeof(BEACON_REPORT); Length += sizeof(BEACON_REPORT); // 4. Copy Channel number pBeaconReport->Channel = pBss->Channel; pBeaconReport->Spare = 0; pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration; pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS); pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta; pBeaconReport->BeaconInterval = pBss->BeaconPeriod; pBeaconReport->CapabilityInfo = pBss->CapabilityInfo; COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid); NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4); NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8); // 5. Create SSID *pDest++ = 0x00; *pDest++ = pBss->SsidLen; NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen); pDest += pBss->SsidLen; Length += (2 + pBss->SsidLen);// TODO: 2004-09-13 john - should we add EXT_RATE IE??? // 6. Create SupportRates *pDest++ = 0x01; *pDest++ = pBss->SupRateLen; NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen); pDest += pBss->SupRateLen; Length += (2 + pBss->SupRateLen); // 7. DS Parameter *pDest++ = 0x03; *pDest++ = 1; *pDest++ = pBss->Channel; Length += 3; // 8. IBSS parameter if presents if (pBss->BssType == BSS_ADHOC) { *pDest++ = 0x06; *pDest++ = 2; *(PUSHORT) pDest = pBss->AtimWin; pDest += 2; Length += 4; } // 9. Update length field, not include EID and length pReport->Length = Length - 4; // 10. Update total frame size pAd->StaCfg.FrameReportLen += Length; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -