📄 mlme.c
字号:
VOID MlmeHandler( IN PRT2570ADAPTER pAd) { MLME_QUEUE_ELEM *Elem = NULL; // Only accept MLME and Frame from peer side, no other (control/data) frame should // get into this state machine NdisAcquireSpinLock(&pAd->Mlme.TaskLock); if(pAd->Mlme.Running) { NdisReleaseSpinLock(&pAd->Mlme.TaskLock); return; } else { pAd->Mlme.Running = TRUE; } NdisReleaseSpinLock(&pAd->Mlme.TaskLock); while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) { if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS)) { DBGPRINT(RT_DEBUG_TRACE, "Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %d)\n", pAd->Mlme.Queue.Num); break; } //From message type, determine which state machine I should drive if (MlmeDequeue(&pAd->Mlme.Queue, &Elem) && pAd->PortCfg.BssType!=BSS_MONITOR) { // if dequeue success switch (Elem->Machine) { case ASSOC_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem); break; case AUTH_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem); break; case AUTH_RSP_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem); break; case SYNC_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem); break; case MLME_CNTL_STATE_MACHINE: MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem); break; case WPA_PSK_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem); break; default: DBGPRINT(RT_DEBUG_TRACE, "ERROR: Illegal machine %d in MlmeHandler()\n",Elem->Machine); break; } // end of switch // free MLME element Elem->Occupied = FALSE; Elem->MsgLen = 0; } else { DBGPRINT(RT_DEBUG_ERROR, "ERROR: empty Elem in MlmeQueue\n"); } } if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS)) { DBGPRINT(RT_DEBUG_TRACE, "MlmeHandler, Reset Mlme! (queue num = %d)\n", pAd->Mlme.Queue.Num); MlmeQueueDestroy(&pAd->Mlme.Queue); // Cancel all timer events // Be careful to cancel new added timer RTMPCancelTimer(&pAd->Mlme.AssocAux.AssocTimer); RTMPCancelTimer(&pAd->Mlme.AssocAux.ReassocTimer); RTMPCancelTimer(&pAd->Mlme.AssocAux.DisassocTimer); RTMPCancelTimer(&pAd->Mlme.AuthAux.AuthTimer); // RTMPCancelTimer(&pAd->Mlme.AuthRspAux.AuthRspTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.SyncAux.BeaconTimer); RTMPCancelTimer(&pAd->Mlme.SyncAux.ScanTimer); // Set all state machines back IDLE pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS); } NdisAcquireSpinLock(&pAd->Mlme.TaskLock); pAd->Mlme.Running = FALSE; NdisReleaseSpinLock(&pAd->Mlme.TaskLock);}VOID MlmeSuspend( IN PRT2570ADAPTER pAd) { MLME_QUEUE_ELEM *Elem = NULL; DBGPRINT(RT_DEBUG_TRACE, "==>MlmeSuspend\n"); // Cancel pending timers RTMPCancelTimer(&pAd->Mlme.AssocAux.AssocTimer); RTMPCancelTimer(&pAd->Mlme.AssocAux.ReassocTimer); RTMPCancelTimer(&pAd->Mlme.AssocAux.DisassocTimer); RTMPCancelTimer(&pAd->Mlme.AuthAux.AuthTimer); // RTMPCancelTimer(&pAd->Mlme.AuthRspAux.AuthRspTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.SyncAux.BeaconTimer); RTMPCancelTimer(&pAd->Mlme.SyncAux.ScanTimer); NdisAcquireSpinLock(&pAd->Mlme.TaskLock); if(pAd->Mlme.Running) { NdisReleaseSpinLock(&pAd->Mlme.TaskLock); return; } else { pAd->Mlme.Running = TRUE; } NdisReleaseSpinLock(&pAd->Mlme.TaskLock); // Remove all Mlme queues elements while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) { //From message type, determine which state machine I should drive if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) { // free MLME element Elem->Occupied = FALSE; Elem->MsgLen = 0; } else { DBGPRINT(RT_DEBUG_ERROR, "ERROR: empty Elem in MlmeQueue\n"); } } // Remove running state NdisAcquireSpinLock(&pAd->Mlme.TaskLock); pAd->Mlme.Running = FALSE; NdisReleaseSpinLock(&pAd->Mlme.TaskLock); RTUSBCleanUpMLMEWaitQueue(pAd); RTUSBCleanUpMLMEBulkOutQueue(pAd); // Set all state machines back IDLE pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);//steven:for test DBGPRINT(RT_DEBUG_TRACE, "<==MlmeSuspend\n");}VOID MlmeResume( IN PRT2570ADAPTER pAd){ DBGPRINT(RT_DEBUG_TRACE, "==>MlmeResume\n"); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS);//steven:for test if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);//steven:for test // Set all state machines back IDLE pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; DBGPRINT(RT_DEBUG_TRACE, "<==MlmeResume\n");}/* ========================================================================== Description: This routine is executed periodically to - 1. Decide if it's a right time to turn on PwrMgmt bit of all outgoiing frames 2. Calculate ChannelQuality based on statistics of the last period, so that TX rate won't toggling very frequently between a successful TX and a failed TX. 3. If the calculated ChannelQuality indicated current connection not healthy, then a ROAMing attempt is tried here. IRQL = DISPATCH_LEVEL ========================================================================== */#define ADHOC_BEACON_LOST_TIME 10000 // 10 secVOID MlmePeriodicExec( IN unsigned long data){ PRT2570ADAPTER pAd = (PRT2570ADAPTER)data; ULONG Now32; // Timer need to reset every time, so using do-while loop do { if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))) { DBGPRINT_RAW(RT_DEBUG_TRACE, "<---MlmePeriodicExec\n"); break; } if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_PENDING)) { RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_PENDING); NdisMIndicateStatus(pAd->AdapterHandle, NDIS_STATUS_MEDIA_DISCONNECT, (PVOID)NULL, 0); NdisMIndicateStatusComplete(pAd->AdapterHandle); DBGPRINT(RT_DEBUG_TRACE, "NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"); } if (pAd->PortCfg.bHardwareRadio == TRUE) { RTUSBEnqueueInternalCmd(pAd, RT_OID_CHECK_GPIO); } if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) { DBGPRINT_RAW(RT_DEBUG_TRACE, "<---RADIO OFF\n"); break; } if (pAd->RalinkCounters.MgmtRingFullCount >= 2) { PCmdQElmt cmdqelmt; RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); NdisAcquireSpinLock(&pAd->CmdQLock); while (pAd->CmdQ.size > 0) { RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt); if (cmdqelmt->CmdFromNdis == TRUE) { if ((cmdqelmt->command != OID_802_11_BSSID_LIST_SCAN) && (cmdqelmt->command != RT_OID_802_11_BSSID) && (cmdqelmt->command != OID_802_11_SSID) && (cmdqelmt->command != OID_802_11_DISASSOCIATE)) {#if 0 if (cmdqelmt->SetOperation) NdisMSetInformationComplete(pAd->AdapterHandle, NDIS_STATUS_NOT_ACCEPTED); else NdisMQueryInformationComplete(pAd->AdapterHandle, NDIS_STATUS_NOT_ACCEPTED);#endif } if ((cmdqelmt->command != RT_OID_SINGLE_READ_MAC) && (cmdqelmt->command != RT_OID_MULTI_READ_MAC) && (cmdqelmt->command != RT_OID_VENDOR_READ_BBP) && (cmdqelmt->command != RT_OID_USB_VENDOR_EEPROM_READ)) { if (cmdqelmt->buffer != NULL) kfree(cmdqelmt->buffer); } kfree(cmdqelmt); } else cmdqelmt->InUse = FALSE; } NdisReleaseSpinLock(&pAd->CmdQLock); RTUSBEnqueueInternalCmd(pAd, RT_OID_RESET_FROM_ERROR); DBGPRINT_RAW(RT_DEBUG_ERROR, "<---MlmePeriodicExec (Mgmt Ring Full)\n"); break; } pAd->RalinkCounters.MgmtRingFullCount = 0; if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_JOIN_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REASSOC_IN_PROGRESS))) { break;//steven:for test } pAd->Mlme.PeriodicRound ++; RTUSBEnqueueInternalCmd(pAd, RT_OID_PERIODIC_EXECUT); Now32 = jiffies; if (INFRA_ON(pAd)) { // Check for EAPOL frame sent after MIC countermeasures if (pAd->PortCfg.MicErrCnt >= 3) { MLME_DISASSOC_REQ_STRUCT DisassocReq; // disassoc from current AP first DBGPRINT(RT_DEBUG_TRACE, "MLME - disassociate with current AP after sending second continuous EAPOL frame\n"); DisassocParmFill(pAd, &DisassocReq, &pAd->PortCfg.Bssid, REASON_MIC_FAILURE); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; pAd->PortCfg.bBlockAssoc = TRUE; } else if (time_after((unsigned long)Now32, (unsigned long)(pAd->PortCfg.LastBeaconRxTime + BEACON_LOST_TIME))) { DBGPRINT(RT_DEBUG_TRACE, "BEACON lost for more than %d msec, let CQI = 0\n", BEACON_LOST_TIME); pAd->Mlme.ChannelQuality = 0; // Lost AP, send disconnect & link down event RTUSBEnqueueInternalCmd(pAd, RT_OID_LINK_DOWN); } else { atomic_set(&(pAd->PortCfg.DataPacketsFromAP), 0); MlmeCheckForPsmChange(pAd); } } else if (ADHOC_ON(pAd)) { // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can // join later. if (time_after((unsigned long)Now32, (unsigned long)(pAd->PortCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)) && (pAd->MediaState == NdisMediaStateConnected)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -