📄 sync.c
字号:
pAd->PortCfg.RtsRate = RATE_6; break; default: pAd->PortCfg.MlmeRate = RATE_2; pAd->PortCfg.RtsRate = RATE_2; break; } // copy QOS related information if (pAd->PortCfg.bWmmCapable) { memcpy(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM)); memcpy(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); memcpy(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else { memset(&pAd->MlmeAux.APEdcaParm, 0, sizeof(EDCA_PARM)); memset(&pAd->MlmeAux.APQbssLoad, 0, sizeof(QBSS_LOAD_PARM)); memset(&pAd->MlmeAux.APQosCapability, 0, sizeof(QOS_CAPABILITY_PARM)); } DBGPRINT(RT_DEBUG_TRACE, "SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen); //Used the default TX Power Percentage. pAd->PortCfg.TxPowerPercentage = pAd->PortCfg.TxPowerDefault; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); } // not to me BEACON, ignored } // sanity check fail, ignore this frame}/* ========================================================================== Description: receive BEACON from peer ========================================================================== */VOID PeerBeacon( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem){ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN]; CHAR Ssid[MAX_LEN_OF_SSID]; CF_PARM CfParm; UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0; UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0; USHORT CapabilityInfo, AtimWin, BeaconPeriod; LARGE_INTEGER TimeStamp; USHORT TbttNumToNextWakeUp; UCHAR Erp; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen, ExtRateLen; UCHAR CkipFlag; UCHAR LenVIE; UCHAR AironetCellPowerLimit; EDCA_PARM EdcaParm; QBSS_LOAD_PARM QbssLoad; QOS_CAPABILITY_PARM QosCapability; ULONG RalinkIe; // New for WPA security suites UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5 NDIS_802_11_VARIABLE_IEs *pVIE = NULL; DBGPRINT(RT_DEBUG_TRACE, "--> %s\n", __FUNCTION__); if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) { DBGPRINT(RT_DEBUG_ERROR, "<-- %s: Mode not specified\n", __FUNCTION__); return; } // Init Variable IE structure pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; pVIE->Length = 0; if (PeerBeaconAndProbeRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Bssid, Ssid, &SsidLen, &BssType, &BeaconPeriod, &Channel, &NewChannel, &TimeStamp, &CfParm, &AtimWin, &CapabilityInfo, &Erp, &DtimCount, &DtimPeriod, &BcastFlag, &MessageToMe, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &CkipFlag, &AironetCellPowerLimit, &EdcaParm, &QbssLoad, &QosCapability, &RalinkIe, &LenVIE, pVIE)) { BOOLEAN is_my_bssid, is_my_ssid; ULONG Bssidx; unsigned long Now; BSS_ENTRY *pBss; CHAR RealRssi = -85; //assume -85 dB UCHAR PeerTxType; // Disqualify 11b only adhoc when we are in 11g only adhoc mode if (BssType == BSS_ADHOC) { PeerTxType = PeerTxTypeInUseSanity(Channel, SupRate, SupRateLen, ExtRate, ExtRateLen); if ((pAd->PortCfg.AdhocMode == ADHOC_11G) && (PeerTxType == CCK_RATE)) { return; } else if ((pAd->PortCfg.AdhocMode == ADHOC_11B) && (PeerTxType == OFDM_RATE)) { return; } } RealRssi = ConvertToRssi(pAd, Elem->Rssi, RSSI_NO_1); is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->PortCfg.Bssid)? TRUE : FALSE; is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen)? TRUE:FALSE; // ignore BEACON not for my SSID if ((! is_my_ssid) && (! is_my_bssid)) return; // // Housekeeping "SsidBssTab" table for later-on ROAMing usage. // Bssidx = BssTableSearch(&pAd->MlmeAux.SsidBssTab, Bssid, Channel); if (Bssidx == BSS_NOT_FOUND) { // discover new AP of this network, create BSS entry Bssidx = BssTableSetEntry(pAd, &pAd->MlmeAux.SsidBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, Channel, RealRssi + pAd->BbpRssiToDbmDelta, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Bssidx == BSS_NOT_FOUND) // return if BSS table full return; DBGPRINT(RT_DEBUG_INFO, "SYNC - New AP added to SsidBssTab[%d], RSSI=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", Bssidx, RealRssi, Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]); } if ((pAd->PortCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel)) { // channel sanity check for (index = 0 ; index < pAd->ChannelListNum; index++) { if (pAd->ChannelList[index].Channel == NewChannel) { pAd->MlmeAux.SsidBssTab.BssEntry[Bssidx].Channel = NewChannel; pAd->PortCfg.Channel = NewChannel; AsicSwitchChannel(pAd, pAd->PortCfg.Channel); AsicLockChannel(pAd, pAd->PortCfg.Channel); LinkDown(pAd, FALSE); RTMPusecDelay(1000000); // use delay to prevent STA do reassoc DBGPRINT(RT_DEBUG_TRACE, "PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel); break; } } if (index >= pAd->ChannelListNum) { DBGPRINT_ERR("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->PortCfg.Channel, pAd->ChannelListNum); } } // if the ssid matched & bssid unmatched, we should select the bssid with large value. // This might happened when two STA start at the same time if ((! is_my_bssid) && ADHOC_ON(pAd)) { INT i; // Add to safe guard adhoc wep status mismatch if (pAd->PortCfg.WepStatus != pAd->MlmeAux.SsidBssTab.BssEntry[Bssidx].WepStatus) { DBGPRINT(RT_DEBUG_TRACE, "SYNC - Not matched wep status %d %d\n", pAd->PortCfg.WepStatus, pAd->MlmeAux.SsidBssTab.BssEntry[Bssidx].WepStatus); return; } // collapse into the ADHOC network which has bigger BSSID value. for (i = 0; i < 6; i++) { if (Bssid[i] < pAd->PortCfg.Bssid[i]) break; if (Bssid[i] > pAd->PortCfg.Bssid[i]) { DBGPRINT(RT_DEBUG_TRACE, "SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n", Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]); AsicDisableSync(pAd); COPY_MAC_ADDR(pAd->PortCfg.Bssid, Bssid); AsicSetBssid(pAd, pAd->PortCfg.Bssid); MakeIbssBeacon(pAd); // re-build BEACON frame AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory break; } } } DBGPRINT(RT_DEBUG_INFO, "SYNC - PeerBeacon from %02x:%02x:%02x:%02x:%02x:%02x - Dtim=%d/%d, Rssi=%ddBm\n", Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5], DtimCount, DtimPeriod, RealRssi); Now = jiffies; pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[Bssidx]; pBss->Rssi = RealRssi + pAd->BbpRssiToDbmDelta; // lastest RSSI pBss->LastBeaconRxTime = Now; // last RX timestamp // // BEACON from my BSSID - either IBSS or INFRA network // if (is_my_bssid) { pAd->PortCfg.LastBeaconRxTime = Now; DBGPRINT(RT_DEBUG_INFO,"Rx My BEACON\n"); // Used the default TX Power Percentage, that set from UI. pAd->PortCfg.TxPowerPercentage = pAd->PortCfg.TxPowerDefault; // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps // after last 11b peer left for several seconds, we'll auto switch back to 11G rate // in MlmePeriodicExec() if (ADHOC_ON(pAd) && (SupRateLen+ExtRateLen <= 4)) { // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left pAd->PortCfg.Last11bBeaconRxTime = Now; if (pAd->PortCfg.MaxTxRate > RATE_11) { DBGPRINT(RT_DEBUG_TRACE, "SYNC - 11b peer joined. down-grade to 11b TX rates \n"); memcpy(pAd->ActiveCfg.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); pAd->ActiveCfg.SupRateLen = SupRateLen; memcpy(pAd->ActiveCfg.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES); pAd->ActiveCfg.ExtRateLen = ExtRateLen; MlmeUpdateTxRates(pAd, FALSE); MakeIbssBeacon(pAd); // re-build BEACON frame AsicEnableIbssSync(pAd); // copy to on-chip memory } } // check if RSSI reaches threshold RealRssi = ConvertToRssi(pAd, Elem->Rssi, RSSI_NO_1); pAd->PortCfg.LastRssi = RealRssi + pAd->BbpRssiToDbmDelta; pAd->PortCfg.AvgRssiX8 = (pAd->PortCfg.AvgRssiX8 - pAd->PortCfg.AvgRssi) + pAd->PortCfg.LastRssi; pAd->PortCfg.AvgRssi = pAd->PortCfg.AvgRssiX8 >> 3; if ((pAd->PortCfg.RssiTriggerMode == RSSI_TRIGGERED_UPON_BELOW_THRESHOLD) && (pAd->PortCfg.LastRssi < pAd->PortCfg.RssiTrigger)) { DBGPRINT(RT_DEBUG_TRACE, "SYNC - NdisMIndicateStatus *** RSSI %d dBm, less than threshold %d dBm\n", pAd->PortCfg.LastRssi - pAd->BbpRssiToDbmDelta, pAd->PortCfg.RssiTrigger - pAd->BbpRssiToDbmDelta); } else if ((pAd->PortCfg.RssiTriggerMode == RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD) && (pAd->PortCfg.LastRssi > pAd->PortCfg.RssiTrigger)) { DBGPRINT(RT_DEBUG_TRACE, "SYNC - NdisMIndicateStatus *** RSSI %d dBm, greater than threshold %d dBm\n", pAd->PortCfg.LastRssi - pAd->BbpRssiToDbmDelta, pAd->PortCfg.RssiTrigger - pAd->BbpRssiToDbmDelta); } if (INFRA_ON(pAd)) // && (pAd->PortCfg.PhyMode == PHY_11BG_MIXED)) { BOOLEAN bUseShortSlot, bUseBGProtection; // decide to use/change to - // 1. long slot (20 us) or short slot (9 us) time // 2. turn on/off RTS/CTS and/or CTS-to-self protection // 3. short preamble bUseShortSlot = pAd->PortCfg.UseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) AsicSetSlotTime(pAd, bUseShortSlot); bUseBGProtection = (pAd->PortCfg.UseBGProtection == 1) || // always use ((pAd->PortCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp)); if (pAd->PortCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP bUseBGProtection = FALSE; if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) { if (bUseBGProtection) OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); else OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP changed B/G protection to %d\n", bUseBGProtection); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) && ERP_IS_USE_BARKER_PREAMBLE(Erp)) { MlmeSetTxPreamble(pAd, Rt802_11PreambleLong); DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP forced to use LONG preamble\n"); } if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (EdcaParm.bValid == TRUE) && (EdcaParm.EdcaUpdateCount != pAd->PortCfg.APEdcaParm.EdcaUpdateCount)) { DBGPRINT(RT_DEBUG_TRACE, "SYNC - AP change EDCA parameters(from %d to %d)\n", pAd->PortCfg.APEdcaParm.EdcaUpdateCount, EdcaParm.EdcaUpdateCount); AsicSetEdcaParm(pAd, &EdcaParm); } // copy QOS related information memcpy(&pAd->PortCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); memcpy(&pAd->PortCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } // only INFRASTRUCTURE mode support power-saving feature if (INFRA_ON(pAd) && (pAd->PortCfg.Psm == PWR_SAVE)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -