📄 sync.c
字号:
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];
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;
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;
// 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])
{
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=%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;
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -