[WCNCR00147874] softap: Fix bug of Stop AP flow
[Description]
Fix the bug of p2pFuncDissolve().
p2pFuncDissolve() will call p2pFuncDisconnect() and
it may delete the client node from rStaRecOfClientList List.
and the LINK_FOR_EACH_ENTRY loop corrupted and lost
the prCurrStaRec->Next pointer.
Change-Id: I942d9c337acec45e380cf8ef5dc90a255cfc3129
Feature: softap
CR-Id: WCNCR00147874
Signed-off-by: Th3 Huang <th3.huang@mediatek.com>
diff --git a/mgmt/p2p_func.c b/mgmt/p2p_func.c
index f7c4659..a690309 100644
--- a/mgmt/p2p_func.c
+++ b/mgmt/p2p_func.c
@@ -1282,6 +1282,10 @@
p2pFuncDissolve(IN P_ADAPTER_T prAdapter,
IN P_BSS_INFO_T prP2pBssInfo, IN BOOLEAN fgSendDeauth, IN UINT_16 u2ReasonCode)
{
+ P_STA_RECORD_T prCurrStaRec, prExistStaRec;
+ P_LINK_T prClientList;
+ BOOLEAN fgIsExist;
+
DEBUGFUNC("p2pFuncDissolve()");
do {
@@ -1320,23 +1324,31 @@
/* Under AP mode, we would net send deauthentication frame to each STA.
* We only stop the Beacon & let all stations timeout.
*/
- {
- P_STA_RECORD_T prCurrStaRec;
- P_LINK_T prClientList;
+ /* Send deauth. */
+ authSendDeauthFrame(prAdapter,
+ prP2pBssInfo,
+ NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL);
- /* Send deauth. */
- authSendDeauthFrame(prAdapter,
- prP2pBssInfo,
- NULL, (P_SW_RFB_T) NULL, u2ReasonCode, (PFN_TX_DONE_HANDLER) NULL);
+ prClientList = &prP2pBssInfo->rStaRecOfClientList;
- prClientList = &prP2pBssInfo->rStaRecOfClientList;
+ LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {
+ ASSERT(prCurrStaRec);
+ p2pFuncDisconnect(prAdapter, prP2pBssInfo, prCurrStaRec, TRUE, u2ReasonCode);
- LINK_FOR_EACH_ENTRY(prCurrStaRec, prClientList, rLinkEntry, STA_RECORD_T) {
- ASSERT(prCurrStaRec);
- p2pFuncDisconnect(prAdapter, prP2pBssInfo, prCurrStaRec, TRUE, u2ReasonCode);
+ /* The current StaRec may be removed in p2pFuncDisconnect() due to */
+ /* The limited resource, like the Cmd Free list */
+ fgIsExist = FALSE;/* Check the StaRec is not removed */
+ LINK_FOR_EACH_ENTRY(prExistStaRec, prClientList, rLinkEntry, STA_RECORD_T) {
+ if (prCurrStaRec == prExistStaRec) {
+ fgIsExist = TRUE;
+ break;
+ }
}
+ if (!fgIsExist)/* This StaRec was be deleted */
+ /* Reset prCurrStaRec to the first element of prClientList */
+ prCurrStaRec =
+ LINK_ENTRY(prClientList->prNext, STA_RECORD_T, rLinkEntry);
}
-
break;
default:
return; /* 20110420 -- alreay in Device Mode. */