sync.c
来自「Ralink RT61 SoftAP Driver source code. 」· C语言 代码 · 共 1,606 行 · 第 1/5 页
C
1,606 行
whenever driver need to start a site survey of all supported channels.
Return:
ch - the first channel number of current country code setting
==========================================================================
*/
UCHAR FirstChannel(
IN PRTMP_ADAPTER pAd)
{
return pAd->ChannelList[0].Channel;
}
/*
==========================================================================
Description:
This routine returns the next channel number. This routine is called
during driver need to start a site survey of all supported channels.
Return:
next_channel - the next channel number valid in current country code setting.
Note:
return 0 if no more next channel
==========================================================================
*/
UCHAR NextChannel(
IN PRTMP_ADAPTER pAd,
IN UCHAR channel)
{
int i;
UCHAR next_channel = 0;
for (i = 0; i < (pAd->ChannelListNum - 1); i++)
if (channel == pAd->ChannelList[i].Channel)
{
next_channel = pAd->ChannelList[i+1].Channel;
break;
}
return next_channel;
}
/*
==========================================================================
Description:
Update PortCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
and 3) PHY-mode user selected.
The outcome is used by driver when doing site survey.
==========================================================================
*/
VOID BuildChannelList(
IN PRTMP_ADAPTER pAd)
{
UCHAR i, j, index=0, num=0;
PUCHAR pChannelList=NULL;
NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
// if not 11a-only mode, channel list starts from 2.4Ghz band
if (pAd->PortCfg.PhyMode != PHY_11A)
{
switch (pAd->PortCfg.CountryRegion & 0x7f)
{
case REGION_0_BG_BAND: // 1 -11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
index += BG_BAND_REGION_0_SIZE;
break;
case REGION_1_BG_BAND: // 1 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
index += BG_BAND_REGION_1_SIZE;
break;
case REGION_2_BG_BAND: // 10 - 11
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
index += BG_BAND_REGION_2_SIZE;
break;
case REGION_3_BG_BAND: // 10 - 13
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
index += BG_BAND_REGION_3_SIZE;
break;
case REGION_4_BG_BAND: // 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
index += BG_BAND_REGION_4_SIZE;
break;
case REGION_5_BG_BAND: // 1 - 14
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
index += BG_BAND_REGION_5_SIZE;
break;
case REGION_6_BG_BAND: // 3 - 9
NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
index += BG_BAND_REGION_6_SIZE;
break;
default: // Error. should never happen
break;
}
}
if (pAd->PortCfg.PhyMode == PHY_11A)
{
switch (pAd->PortCfg.CountryRegionForABand & 0x7f)
{
case REGION_0_A_BAND:
num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
break;
case REGION_1_A_BAND:
num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
break;
case REGION_2_A_BAND:
num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
break;
case REGION_3_A_BAND:
num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
break;
case REGION_4_A_BAND:
num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
break;
case REGION_5_A_BAND:
num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
break;
case REGION_6_A_BAND:
num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
break;
case REGION_7_A_BAND:
num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
break;
case REGION_8_A_BAND:
num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
break;
case REGION_9_A_BAND:
num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
break;
case REGION_10_A_BAND:
num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
break;
default: // Error. should never happen
DBGPRINT(RT_DEBUG_WARN,"countryregion=%d not support", pAd->PortCfg.CountryRegionForABand);
break;
}
if (num != 0)
{
for (i=0; i<num; i++)
{
for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
{
if (pChannelList[i] == pAd->TxPower[j].Channel)
{
NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
}
}
}
index += num;
}
}
pAd->ChannelListNum = index;
DBGPRINT(RT_DEBUG_TRACE,"country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
pAd->PortCfg.CountryRegion, pAd->PortCfg.CountryRegionForABand, pAd->RfIcType, pAd->PortCfg.PhyMode, pAd->ChannelListNum);
for (i=0;i<index;i++)
{
DBGPRINT(RT_DEBUG_TRACE,"channel #%d\n", pAd->ChannelList[i].Channel);
}
}
/*
==========================================================================
Description:
MLME SCAN req state machine procedure
==========================================================================
*/
VOID MlmeScanReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType;
ULONG Now;
// Suspend MSDU transmission here
RTMPSuspendMsduTransmission(pAd);
// first check the parameter sanity
if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, Ssid, &SsidLen, &ScanType))
{
DBGPRINT(RT_DEBUG_TRACE, "SYNC - MlmeScanReqAction\n");
Now = jiffies;
pAd->LastScanTime = Now;
RTMPCancelTimer(&pAd->Mlme.SyncAux.ScanTimer);
// record desired BSS parameters
pAd->Mlme.SyncAux.BssType = BssType;
pAd->Mlme.SyncAux.ScanType = ScanType;
pAd->Mlme.SyncAux.SsidLen = SsidLen;
NdisMoveMemory(pAd->Mlme.SyncAux.Ssid, Ssid, SsidLen);
// start from the first channel
pAd->Mlme.SyncAux.Channel = FirstChannel(pAd);
ScanNextChannel(pAd);
}
else
{
DBGPRINT(RT_DEBUG_ERROR, "SYNC - MlmeScanReqAction() sanity check fail. BUG!!!\n");
pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
}
}
/*
==========================================================================
Description:
Process the received ProbeRequest from clients
Parameters:
Elem - msg containing the ProbeReq frame
==========================================================================
*/
VOID PeerProbeReqAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Addr2[MAC_ADDR_LEN];
CHAR Ssid[MAX_LEN_OF_SSID];
UCHAR SsidLen, apidx = 0;
HEADER_802_11 ProbeRspHdr;
PUCHAR pOutBuffer = NULL;
ULONG FrameLen = 0, TmpLen;
LONGLONG FakeTimestamp;
UCHAR SsidIe = IE_SSID, DsIe = IE_DS_PARM, SuppIe = IE_SUPP_RATES,
DsLen = 1, RSNIe = IE_WPA, RSNIe2 = IE_WPA2;
pAd->PortCfg.bGetAPConfig = FALSE;
if (! PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
return;
for (apidx = MAIN_MBSSID; apidx < pAd->PortCfg.BssidNum; apidx++)
{
// if in bridge mode, no need to reply probe req.
if (pAd->WdsTab.Mode == WDS_BRIDGE_MODE)
break;
if (((SsidLen == 0) && (pAd->PortCfg.MBSSID[apidx].bHideSsid == 0))
|| ((SsidLen == pAd->PortCfg.MBSSID[apidx].SsidLen) && NdisEqualMemory(Ssid, pAd->PortCfg.MBSSID[apidx].Ssid, (ULONG)SsidLen)))
{
// allocate and send out ProbeRsp frame
pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG);
if(pOutBuffer == NULL)
break;
DBGPRINT(RT_DEBUG_INFO, "SYNC - IF(ra%d)Send PROBE_RSP to %02x:%02x:%02x:%02x:%02x:%02x...\n", apidx,
Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5] );
MgtMacHeaderInit(pAd, &ProbeRspHdr, SUBTYPE_PROBE_RSP, 0, Addr2, pAd->PortCfg.MBSSID[apidx].Bssid);
if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSK))
RSNIe = IE_WPA;
else if ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) || (pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK))
RSNIe = IE_WPA2;
// Append RSN_IE when WPA OR WPAPSK,
if (((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G))
&& (pAd->PortCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA))
{
UCHAR SupportedRatesLen = 4, ErpLen = 1;
UCHAR ExtendedRatesIe = IE_EXT_SUPP_RATES, ErpIe = IE_ERP;
UCHAR ExtendedRatesLen = pAd->PortCfg.SupportedRatesLen - SupportedRatesLen;
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &ProbeRspHdr,
TIMESTAMP_LEN, &FakeTimestamp,
2, &pAd->PortCfg.BeaconPeriod,
2, &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
1, &SsidIe,
1, &pAd->PortCfg.MBSSID[apidx].SsidLen,
pAd->PortCfg.MBSSID[apidx].SsidLen, pAd->PortCfg.MBSSID[apidx].Ssid,
1, &SuppIe,
1, &SupportedRatesLen,
SupportedRatesLen, pAd->PortCfg.SupportedRates,
1, &DsIe,
1, &DsLen,
1, &pAd->PortCfg.Channel,
1, &ErpIe,
1, &ErpLen,
1, &pAd->Mlme.ErpIeContent,
1, &ExtendedRatesIe,
1, &ExtendedRatesLen,
ExtendedRatesLen, &pAd->PortCfg.SupportedRates[SupportedRatesLen],
END_OF_ARGS);
}
else if( pAd->PortCfg.MBSSID[apidx].AuthMode < Ndis802_11AuthModeWPA)
{
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &ProbeRspHdr,
TIMESTAMP_LEN, &FakeTimestamp,
2, &pAd->PortCfg.BeaconPeriod,
2, &pAd->PortCfg.MBSSID[apidx].CapabilityInfo,
1, &SsidIe,
1, &pAd->PortCfg.MBSSID[apidx].SsidLen,
pAd->PortCfg.MBSSID[apidx].SsidLen, pAd->PortCfg.MBSSID[apidx].Ssid,
1, &SuppIe,
1, &pAd->PortCfg.SupportedRatesLen,
pAd->PortCfg.SupportedRatesLen, pAd->PortCfg.SupportedRates,
1, &DsIe,
1, &DsLen,
1, &pAd->PortCfg.Channel,
END_OF_ARGS);
}
else if (((pAd->PortCfg.PhyMode == PHY_11BG_MIXED) || (pAd->PortCfg.PhyMode == PHY_11G))
&& ((pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1WPA2) ||(pAd->PortCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPAPSKWPA2PSK)))
{
UCHAR SupportedRatesLen = 4, ErpLen = 1;
UCHAR ExtendedRatesIe = IE_EXT_SUPP_RATES, ErpIe = IE_ERP;
UCHAR ExtendedRatesLen = pAd->PortCfg.SupportedRatesLen - SupportedRatesLen;
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &ProbeRspHdr,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?