📄 sync.c
字号:
//2007/12/07:KH add for hidden SSID if(SsidLen!=0&&Ssid[0]!=0)//hidden SSID { NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen); pAd->MlmeAux.SsidLen = SsidLen; } else { if(pAd->PortCfg.SsidLen>0) { NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->PortCfg.Ssid, pAd->PortCfg.SsidLen); pAd->MlmeAux.SsidLen = pAd->PortCfg.SsidLen; } else //Only when the status is LINK DOWN. if(pAd->PortCfg.LastSsidLen>0) { NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->PortCfg.LastSsid, pAd->PortCfg.LastSsidLen); pAd->MlmeAux.SsidLen =pAd->PortCfg.LastSsidLen; } DBGPRINT(RT_DEBUG_TRACE, "SYNC - receive desired BEACON at JoinWaitBeacon record the hidden as the setting of *.dat SSID[%d]=%s\n",pAd->MlmeAux.SsidLen,pAd->MlmeAux.Ssid); } } else { Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel); if (Idx != BSS_NOT_FOUND) { // // Multiple SSID case, used correct CapabilityInfo // CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; } } pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; pAd->MlmeAux.BssType = BssType; pAd->MlmeAux.BeaconPeriod = BeaconPeriod; pAd->MlmeAux.Channel = Channel; pAd->MlmeAux.AtimWin = AtimWin; pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod; pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pAd->MlmeAux.APRalinkIe = RalinkIe; // Copy AP's supported rate to MlmeAux for creating assoication request // Also filter out not supported rate pAd->MlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen); pAd->MlmeAux.ExtRateLen = ExtRateLen; NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen); RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen); // // Update MlmeRate & RtsRate. // We need to update those rates, for example on Roaming A to B, // MlmeRate will be RATE_6(OFDM) on 11A, but when roam to B. // RATE_6 can't be recognized by 11B AP and vice versa. // PeerTxType = PeerTxTypeInUseSanity(Channel, SupRate, SupRateLen, ExtRate, ExtRateLen); switch (PeerTxType) { case CCK_RATE: //CCK case CCKOFDM_RATE: //CCK + OFDM pAd->PortCfg.MlmeRate = RATE_2; pAd->PortCfg.RtsRate = RATE_2; break; case OFDM_RATE: //OFDM pAd->PortCfg.MlmeRate = RATE_6; 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) { NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM)); NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM)); } else { NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM)); NdisZeroMemory(&pAd->MlmeAux.APQosCapability, 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+1]; 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; USHORT LenVIE; // edit by johnli, variable ie length could be > 256 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; if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) 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, Now; BSS_ENTRY *pBss; CHAR RealRssi = -85; //assume -85 dB UCHAR PeerTxType; RealRssi = ConvertToRssi(pAd, Elem->Rssi, RSSI_NO_1); // 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; } } 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_TRACE, "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) && (BssType == BSS_ADHOC)) { 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]) { 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; } else if (Bssid[i] < pAd->PortCfg.Bssid[i]) // Linyi: fix the bug break; } } DBGPRINT(RT_DEBUG_INFO, "SYNC - PeerBeacon from %02x:%02x:%02x:%02x:%02x:%02x - Dtim=%d/%d, Rssi=%02x\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"); NdisMoveMemory(pAd->ActiveCfg.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); pAd->ActiveCfg.SupRateLen = SupRateLen; NdisMoveMemory(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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -