测试在MT7620A上跑openwrt;router模式下,手机连接MT7620A板子就是失败。
经过分析发现:
在ralink的wifi driver中WPA成对密钥的四次握手,以及组密钥协商信令过程,
如果AP未及时收到client回复的信令,可能会主动踢掉client,或者很快重发WPA成对密钥的第一个信令;
如果使用iwpriv ra0 set Debug=3 输出更多log信息的话,会看到client反复不停连接AP,log中有很多如下的信息
WPARetryExec---> ReTryCounter
因此确实因为某些原因处理速度慢的话,可以考虑修改AP这边的以下代码。 不过也可能是其他原因造成的wifi driver处理速度太慢,需要进一步深究。
VOID WPARetryExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { MAC_TABLE_ENTRY *pEntry = (MAC_TABLE_ENTRY *)FunctionContext; if ((pEntry) && IS_ENTRY_CLIENT(pEntry)) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pEntry->pAd; pEntry->ReTryCounter++; DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec---> ReTryCounter=%d, WpaState=%d \n", pEntry->ReTryCounter, pEntry->WpaState)); switch (pEntry->AuthMode) { case Ndis802_11AuthModeWPA: case Ndis802_11AuthModeWPAPSK: case Ndis802_11AuthModeWPA2: case Ndis802_11AuthModeWPA2PSK: /* 1. GTK already retried, give up and disconnect client. */ if (pEntry->ReTryCounter > (GROUP_MSG1_RETRY_TIMER_CTR + 1)) { /* send wireless event - for group key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_GROUP_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Group Key HS exceed retry count, Disassociate client, pEntry->ReTryCounter %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_GROUP_KEY_HS_TIMEOUT, FALSE); } /* 2. Retry GTK. */ else if (pEntry->ReTryCounter > GROUP_MSG1_RETRY_TIMER_CTR) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry 2-way group-key Handshake \n")); if (pEntry->GTKState == REKEY_NEGOTIATING) { WPAStart2WayGroupHS(pAd, pEntry); RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); } } /* 3. 4-way message 1 retried more than three times. Disconnect client */ else if (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3)) { /* send wireless event - for pairwise key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::MSG1 timeout, pEntry->ReTryCounter = %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_4_WAY_TIMEOUT, FALSE); } /* 4. Retry 4 way message 1, the last try, the timeout is 3 sec for EAPOL-Start */ else if (pEntry->ReTryCounter == (PEER_MSG1_RETRY_TIMER_CTR + 3)) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::Retry MSG1, the last try\n")); WPAStart4WayHS(pAd , pEntry, PEER_MSG3_RETRY_EXEC_INTV); } /* 4. Retry 4 way message 1 */ else if (pEntry->ReTryCounter < (PEER_MSG1_RETRY_TIMER_CTR + 3)) { if ((pEntry->WpaState == AS_PTKSTART) || (pEntry->WpaState == AS_INITPSK) || (pEntry->WpaState == AS_INITPMK)) { DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry MSG1 of 4-way Handshake\n")); WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); } } break; default: break; } }
尝试做的一些修改,简单试了一下,可以解决一些问题,供参考:
/* 3. 4-way message 1 retried more than three times. Disconnect client */ //else if (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3)) else if ( ( (pEntry->ReTryCounter > (PEER_MSG1_RETRY_TIMER_CTR + 3)) && (pEntry->ReTryCounter < PEER_MSG3_RETRY_TIMER_CTR) ) || ( (pEntry->ReTryCounter > (PEER_MSG3_RETRY_TIMER_CTR + 3)) && (pEntry->ReTryCounter < GROUP_MSG1_RETRY_TIMER_CTR) ) ) { /* send wireless event - for pairwise key handshaking timeout */ RTMPSendWirelessEvent(pAd, IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::MSG1 or MSG3 timeout, pEntry->ReTryCounter = %d\n", pEntry->ReTryCounter)); MlmeDeAuthAction(pAd, pEntry, REASON_4_WAY_TIMEOUT, FALSE); }
/* 4. Retry 4 way message 1 */ else if (pEntry->ReTryCounter < (PEER_MSG1_RETRY_TIMER_CTR + 3)) { if ((pEntry->WpaState == AS_PTKSTART) || (pEntry->WpaState == AS_INITPSK) || (pEntry->WpaState == AS_INITPMK)) { //DBGPRINT(RT_DEBUG_TRACE, ("WPARetryExec::ReTry MSG1 of 4-way Handshake\n")); //WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); } }