📄 assoc.c
字号:
#endif
/*
==========================================================================
Description:
peer sends assoc rsp back
Parameters:
Elme - MLME message containing the received frame
==========================================================================
*/
VOID PeerAssocRspAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT CapabilityInfo, Status, Aid;
UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
UCHAR Addr2[MAC_ADDR_LEN];
EDCA_PARM EdcaParm;
#if WPA_SUPPLICANT_SUPPORT
union iwreq_data wrqu;
#endif
if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &EdcaParm))
{
// The frame is for me ?
if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
{
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status);
RTMPCancelTimer(&pAd->MlmeAux.AssocTimer);
if(Status == MLME_SUCCESS)
{
//
// There may some packets will be drop, if we haven't set the BSS type!
// For example: EAPOL packet and the case of WHQL lost Packets.
// Since this may some delays to set those variables at LinkUp(..) on this (Mlme) thread.
//
// This is a trick, set the BSS type here.
//
if (pAd->PortCfg.BssType == BSS_INFRA)
{
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
}
// go to procedure listed on page 376
AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen, &EdcaParm);
#if WPA_SUPPLICANT_SUPPORT
if (pAd->PortCfg.WPA_Supplicant == TRUE) {
// collect associate info
link_status_handler(pAd);
//send associnfo event to wpa_supplicant
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
}
#endif
}
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
}
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerAssocRspAction() sanity check fail\n");
}
}
/*
==========================================================================
Description:
peer sends reassoc rsp
Parametrs:
Elem - MLME message cntaining the received frame
==========================================================================
*/
VOID PeerReassocRspAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT CapabilityInfo;
USHORT Status;
USHORT Aid;
UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
UCHAR Addr2[MAC_ADDR_LEN];
EDCA_PARM EdcaParm;
#if WPA_SUPPLICANT_SUPPORT
union iwreq_data wrqu;
#endif
if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &EdcaParm))
{
if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
{
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status);
RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer);
if(Status == MLME_SUCCESS)
{
// go to procedure listed on page 376
AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen, &EdcaParm);
#if WPA_SUPPLICANT_SUPPORT
if (pAd->PortCfg.WPA_Supplicant == TRUE) {
//collect associate info
link_status_handler(pAd);
//send associnfo event to wpa_supplicant
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
}
DBGPRINT(RT_DEBUG_OFF, "ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status);
#endif
}
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
}
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerReassocRspAction() sanity check fail\n");
}
}
/*
==========================================================================
Description:
procedures on IEEE 802.11/1999 p.376
Parametrs:
==========================================================================
*/
VOID AssocPostProc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr2,
IN USHORT CapabilityInfo,
IN USHORT Aid,
IN UCHAR SupRate[],
IN UCHAR SupRateLen,
IN UCHAR ExtRate[],
IN UCHAR ExtRateLen,
IN PEDCA_PARM pEdcaParm)
{
ULONG Idx;
UCHAR VarIesOffset;
pAd->MlmeAux.BssType = BSS_INFRA;
COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
pAd->MlmeAux.Aid = Aid;
pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
// filter out un-supported rates
pAd->MlmeAux.SupRateLen = SupRateLen;
NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
// filter out un-supported rates
pAd->MlmeAux.ExtRateLen = ExtRateLen;
NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
// Set New WPA information
Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
if (Idx == BSS_NOT_FOUND)
{
DBGPRINT_ERR("ASSOC - Can't find BSS after receiving Assoc response\n");
}
else
{
// Mod by James to fix OID_802_11_ASSOCIATION_INFORMATION
pAd->PortCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION); //+ sizeof(NDIS_802_11_FIXED_IEs); // Filled in assoc request
pAd->PortCfg.AssocInfo.AvailableResponseFixedIEs =
NDIS_802_11_AI_RESFI_CAPABILITIES | NDIS_802_11_AI_RESFI_STATUSCODE | NDIS_802_11_AI_RESFI_ASSOCIATIONID;
pAd->PortCfg.AssocInfo.ResponseFixedIEs.Capabilities = CapabilityInfo;
pAd->PortCfg.AssocInfo.ResponseFixedIEs.StatusCode = MLME_SUCCESS; // Should be success, add failed later
pAd->PortCfg.AssocInfo.ResponseFixedIEs.AssociationId = Aid;
// Copy BSS VarIEs to PortCfg associnfo structure.
// First add Supported rates
VarIesOffset = 0;
NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &SupRateIe, 1);
VarIesOffset += 1;
NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &SupRateLen, 1);
VarIesOffset += 1;
NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, SupRate, SupRateLen);
VarIesOffset += SupRateLen;
// NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &ExtRateIe, 1);
// VarIesOffset += 1;
// NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, &ExtRateLen, 1);
// VarIesOffset += 1;
// NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, ExtRate, ExtRateLen);
// VarIesOffset += ExtRateLen;
// Second add RSN
NdisMoveMemory(pAd->PortCfg.ResVarIEs + VarIesOffset, pAd->ScanTab.BssEntry[Idx].VarIEs, pAd->ScanTab.BssEntry[Idx].VarIELen);
VarIesOffset += pAd->ScanTab.BssEntry[Idx].VarIELen;
// Set Variable IEs Length
pAd->PortCfg.ResVarIELen = VarIesOffset;
pAd->PortCfg.AssocInfo.ResponseIELength = VarIesOffset;
}
}
/*
==========================================================================
Description:
left part of IEEE 802.11/1999 p.374
Parameters:
Elem - MLME message containing the received frame
==========================================================================
*/
VOID PeerDisassocAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
UCHAR Addr2[MAC_ADDR_LEN];
USHORT Reason;
#if WPA_SUPPLICANT_SUPPORT
union iwreq_data wrqu;
#endif
if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
{
if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->PortCfg.Bssid, Addr2))
{
LinkDown(pAd, TRUE);
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
#if WPA_SUPPLICANT_SUPPORT
if (pAd->PortCfg.WPA_Supplicant == TRUE) {
// send disassoc event to wpa_supplicant
memset(&wrqu, 0, sizeof(wrqu));
wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
}
#endif
#if 0
// 2004-09-11 john: can't remember why AP will DISASSOCIATE us.
// But since it says for 2430 only, we temporaily remove the patch.
// 2002/11/21 -
// patch RT2430/RT2420 hangup issue. We suspect this AP DIS-ASSOCIATE frame
// is caused by PHY hangup, so we reset PHY, then auto recover the connection.
// if this attempt fails, then remains in LinkDown and leaves the problem
// to MlmePeriodicExec()
// NICPatchRT2430Bug(pAd);
pAd->RalinkCounters.BeenDisassociatedCount ++;
// Remove auto recover effort when disassociate by AP, re-enable for patch 2430 only
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Disassociated by AP, Auto Recovery attempt #%d\n", pAd->RalinkCounters.BeenDisassociatedCount);
MlmeAutoReconnectLastSSID(pAd);
#endif
}
}
else
{
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - PeerDisassocAction() sanity check fail\n");
}
}
/*
==========================================================================
Description:
what the state machine will do after assoc timeout
==========================================================================
*/
VOID AssocTimeoutAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - AssocTimeoutAction\n");
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
Status = MLME_REJ_TIMEOUT;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
}
/*
==========================================================================
Description:
what the state machine will do after reassoc timeout
==========================================================================
*/
VOID ReassocTimeoutAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - ReassocTimeoutAction\n");
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
Status = MLME_REJ_TIMEOUT;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
}
/*
==========================================================================
Description:
what the state machine will do after disassoc timeout
==========================================================================
*/
VOID DisassocTimeoutAction(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - DisassocTimeoutAction\n");
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
Status = MLME_SUCCESS;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
}
VOID InvalidStateWhenAssoc(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenAssoc(state=%d), reset ASSOC state machine\n",
pAd->Mlme.AssocMachine.CurrState);
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
Status = MLME_STATE_MACHINE_REJECT;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
}
VOID InvalidStateWhenReassoc(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenReassoc(state=%d), reset ASSOC state machine\n",
pAd->Mlme.AssocMachine.CurrState);
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
Status = MLME_STATE_MACHINE_REJECT;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
}
VOID InvalidStateWhenDisassociate(
IN PRTMP_ADAPTER pAd,
IN MLME_QUEUE_ELEM *Elem)
{
USHORT Status;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - InvalidStateWhenDisassoc(state=%d), reset ASSOC state machine\n",
pAd->Mlme.AssocMachine.CurrState);
pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
Status = MLME_STATE_MACHINE_REJECT;
MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
}
/*
==========================================================================
Description:
right part of IEEE 802.11/1999 page 374
Note:
This event should never cause ASSOC state machine perform state
transition, and has no relationship with CNTL machine. So we separate
this routine as a service outside of ASSOC state transition table.
==========================================================================
*/
VOID Cls3errAction(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pAddr)
{
HEADER_802_11 DisassocHdr;
PCHAR pOutBuffer = NULL;
ULONG FrameLen = 0;
USHORT Reason = REASON_CLS3ERR;
USHORT NStatus;
// allocate memory
NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
if (NStatus != NDIS_STATUS_SUCCESS)
return;
DBGPRINT(RT_DEBUG_TRACE, "ASSOC - Class 3 Error, Send DISASSOC frame\n");
MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->PortCfg.Bssid);
MakeOutgoingFrame(pOutBuffer, &FrameLen,
sizeof(HEADER_802_11), &DisassocHdr,
2, &Reason,
END_OF_ARGS);
MiniportMMRequest(pAd, pOutBuffer, FrameLen);
pAd->PortCfg.DisassocReason = REASON_CLS3ERR;
COPY_MAC_ADDR(pAd->PortCfg.DisassocSta, pAddr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -