VOID p2pStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_FSM_INFO_T prP2pFsmInfo) { P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL; do { ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); /* Store the original channel info. */ prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; /* RX Probe Request would check primary channel. */ prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; prP2pBssInfo->eBand = prChnlReqInfo->eBand; prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; DBGLOG(P2P, TRACE, ("start a channel on hand timer.\n")); cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), prChnlReqInfo->u4MaxInterval); kalP2PIndicateChannelReady(prAdapter->prGlueInfo, prChnlReqInfo->u8Cookie, prChnlReqInfo->ucReqChnlNum, prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); } while (FALSE); return; } /* p2pStateInit_CHNL_ON_HAND */
VOID p2pDevStateInit_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_DEV_FSM_INFO_T prP2pDevFsmInfo, IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo) { do { ASSERT_BREAK((prAdapter != NULL) && (prP2pDevFsmInfo != NULL) && (prChnlReqInfo != NULL)); ASSERT(prChnlReqInfo->eChnlReqType == CH_REQ_TYPE_P2P_LISTEN); prChnlReqInfo->ucOriChnlNum = prP2pBssInfo->ucPrimaryChannel; prChnlReqInfo->eOriBand = prP2pBssInfo->eBand; prChnlReqInfo->eOriChnlSco = prP2pBssInfo->eBssSCO; prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucReqChnlNum; prP2pBssInfo->eBand = prChnlReqInfo->eBand; prP2pBssInfo->eBssSCO = prChnlReqInfo->eChnlSco; cnmTimerStartTimer(prAdapter, &(prP2pDevFsmInfo->rP2pFsmTimeoutTimer), prChnlReqInfo->u4MaxInterval); kalP2PIndicateChannelReady(prAdapter->prGlueInfo, prChnlReqInfo->u8Cookie, prChnlReqInfo->ucReqChnlNum, prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval); } while (FALSE); return; } /* p2pDevStateInit_CHNL_ON_HAND */
/*----------------------------------------------------------------------------*/ VOID rlmObssTriggerScan(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo) { P_MSG_SCN_SCAN_REQ prScanReqMsg; ASSERT(prBssInfo); prScanReqMsg = (P_MSG_SCN_SCAN_REQ) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ)); ASSERT(prScanReqMsg); if (!prScanReqMsg) { DBGLOG(RLM, WARN, "No buf for OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); return; } /* It is ok that ucSeqNum is set to fixed value because the same network * OBSS scan interval is limited to OBSS_SCAN_MIN_INTERVAL (min 10 sec) * and scan module don't care seqNum of OBSS scanning */ prScanReqMsg->rMsgHdr.eMsgId = MID_RLM_SCN_SCAN_REQ; prScanReqMsg->ucSeqNum = 0x33; prScanReqMsg->ucNetTypeIndex = prBssInfo->ucNetTypeIndex; prScanReqMsg->eScanType = SCAN_TYPE_ACTIVE_SCAN; prScanReqMsg->ucSSIDType = SCAN_REQ_SSID_WILDCARD; prScanReqMsg->ucSSIDLength = 0; prScanReqMsg->eScanChannel = SCAN_CHANNEL_2G4; prScanReqMsg->u2IELen = 0; mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prScanReqMsg, MSG_SEND_METHOD_BUF); DBGLOG(RLM, INFO, "Timeout to trigger OBSS scan (NetIdx=%d)!!\n", prBssInfo->ucNetTypeIndex); }
BOOLEAN p2pStateInit_IDLE ( IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, OUT P_ENUM_P2P_STATE_T peNextState ) { BOOLEAN fgIsTransOut = FALSE; // P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T)NULL; do { ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (peNextState != NULL)); if ((prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) && IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); fgIsTransOut = TRUE; prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; DBGLOG(P2P, INFO,("p2pStateInit_IDLE GO Scan \n")); *peNextState = P2P_STATE_REQING_CHANNEL; } else { #if 0 else if (IS_NET_PWR_STATE_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX)) { ASSERT((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) || (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE)); prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; if (prChnlReqInfo->fgIsChannelRequested) { /* Start a timer for return channel. */ DBGLOG(P2P, TRACE, ("start a GO channel timer.\n")); } } #endif cnmTimerStartTimer(prAdapter, &(prAdapter->rP2pFsmTimeoutTimer), 5000); } } while (FALSE); return fgIsTransOut; } /* p2pStateInit_IDLE */
/*----------------------------------------------------------------------------*/ static inline VOID secFsmTrans_SEND_DEAUTH_to_COUNTERMEASURE(IN P_ADAPTER_T prAdapter, IN P_STA_RECORD_T prSta) { ASSERT(prAdapter); ASSERT(prSta); if (!IS_STA_IN_AIS(prSta)) { DBGLOG(RSN, INFO, "Counter Measure should occur at AIS network!!\n"); /* ASSERT(0); */ return; } /* Start the 60 sec timer */ cnmTimerStartTimer(prAdapter, &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, SEC_TO_MSEC(COUNTER_MEASURE_TIMEOUT_INTERVAL_SEC)); return; }
/*----------------------------------------------------------------------------*/ BOOLEAN rlmUpdateBwByChListForAP ( P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo ) { UINT_8 ucLevel; BOOLEAN fgBwChange; ASSERT(prAdapter); ASSERT(prBssInfo); fgBwChange = FALSE; if (prBssInfo->eBssSCO == CHNL_EXT_SCN) { return fgBwChange; } ucLevel = rlmObssChnlLevel(prBssInfo, prBssInfo->eBand, prBssInfo->ucPrimaryChannel, prBssInfo->eBssSCO); if (ucLevel == CHNL_LEVEL0) { /* Forced to 20MHz, so extended channel is SCN and STA width is zero */ prBssInfo->fgObssActionForcedTo20M = TRUE; if (prBssInfo->ucHtOpInfo1 != (UINT_8) CHNL_EXT_SCN) { prBssInfo->ucHtOpInfo1 = (UINT_8) CHNL_EXT_SCN; fgBwChange = TRUE; } cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, OBSS_20_40M_TIMEOUT * MSEC_PER_SEC); } /* Clear up all channel lists */ prBssInfo->auc2G_20mReqChnlList[0] = 0; prBssInfo->auc2G_NonHtChnlList[0] = 0; prBssInfo->auc2G_PriChnlList[0] = 0; prBssInfo->auc2G_SecChnlList[0] = 0; prBssInfo->auc5G_20mReqChnlList[0] = 0; prBssInfo->auc5G_NonHtChnlList[0] = 0; prBssInfo->auc5G_PriChnlList[0] = 0; prBssInfo->auc5G_SecChnlList[0] = 0; return fgBwChange; }
/*----------------------------------------------------------------------------*/ VOID rlmObssScanDone ( P_ADAPTER_T prAdapter, P_MSG_HDR_T prMsgHdr ) { P_MSG_SCN_SCAN_DONE prScanDoneMsg; P_BSS_INFO_T prBssInfo; P_MSDU_INFO_T prMsduInfo; P_ACTION_20_40_COEXIST_FRAME prTxFrame; UINT_16 i, u2PayloadLen; ASSERT(prMsgHdr); prScanDoneMsg = (P_MSG_SCN_SCAN_DONE) prMsgHdr; prBssInfo = &prAdapter->rWifiVar.arBssInfo[prScanDoneMsg->ucNetTypeIndex]; ASSERT(prBssInfo); DBGLOG(RLM, INFO, ("OBSS Scan Done (NetIdx=%d, Mode=%d)\n", prScanDoneMsg->ucNetTypeIndex, prBssInfo->eCurrentOPMode)); cnmMemFree(prAdapter, prMsgHdr); #if CFG_ENABLE_WIFI_DIRECT /* AP mode */ if ((prAdapter->fgIsP2PRegistered) && (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { return; } #endif /* STA mode */ if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE || !RLM_NET_PARAM_VALID(prBssInfo) || prBssInfo->u2ObssScanInterval == 0) { DBGLOG(RLM, WARN, ("OBSS Scan Done (NetIdx=%d) -- Aborted!!\n", prBssInfo->ucNetTypeIndex)); return; } /* To do: check 2.4G channel list to decide if obss mgmt should be * sent to associated AP. Note: how to handle concurrent network? * To do: invoke rlmObssChnlLevel() to decide if 20/40 BSS coexistence * management frame is needed. */ if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || prBssInfo->auc2G_NonHtChnlList[0] > 0) && (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN)) != NULL) { DBGLOG(RLM, INFO, ("Send 20/40 coexistence mgmt(20mReq=%d, NonHt=%d)\n", prBssInfo->auc2G_20mReqChnlList[0], prBssInfo->auc2G_NonHtChnlList[0])); prTxFrame = (P_ACTION_20_40_COEXIST_FRAME) ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION; COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID); COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr); COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID); prTxFrame->ucCategory = CATEGORY_PUBLIC_ACTION; prTxFrame->ucAction = ACTION_PUBLIC_20_40_COEXIST; /* To do: find correct algorithm */ prTxFrame->rBssCoexist.ucId = ELEM_ID_20_40_BSS_COEXISTENCE; prTxFrame->rBssCoexist.ucLength = 1; prTxFrame->rBssCoexist.ucData = (prBssInfo->auc2G_20mReqChnlList[0] > 0) ? BSS_COEXIST_20M_REQ : 0; u2PayloadLen = 2 + 3; if (prBssInfo->auc2G_NonHtChnlList[0] > 0) { ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G); prTxFrame->rChnlReport.ucId = ELEM_ID_20_40_INTOLERANT_CHNL_REPORT; prTxFrame->rChnlReport.ucLength = prBssInfo->auc2G_NonHtChnlList[0] + 1; prTxFrame->rChnlReport.ucRegulatoryClass = 81; /* 2.4GHz, ch1~13 */ for (i = 0; i < prBssInfo->auc2G_NonHtChnlList[0] && i < CHNL_LIST_SZ_2G; i++) { prTxFrame->rChnlReport.aucChannelList[i] = prBssInfo->auc2G_NonHtChnlList[i+1]; } u2PayloadLen += IE_SIZE(&prTxFrame->rChnlReport); } ASSERT((WLAN_MAC_HEADER_LEN + u2PayloadLen) <= PUBLIC_ACTION_MAX_LEN); /* Clear up channel lists in 2.4G band */ prBssInfo->auc2G_20mReqChnlList[0] = 0; prBssInfo->auc2G_NonHtChnlList[0] = 0; //4 Update information of MSDU_INFO_T prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT; /* Management frame */ prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex; prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex; prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; prMsduInfo->fgIs802_1x = FALSE; prMsduInfo->fgIs802_11 = TRUE; prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen; prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter); prMsduInfo->pfTxDoneHandler = NULL; prMsduInfo->fgIsBasicRate = FALSE; //4 Enqueue the frame to send this action frame. nicTxEnqueueMsdu(prAdapter, prMsduInfo); } /* end of prMsduInfo != NULL */ if (prBssInfo->u2ObssScanInterval > 0) { DBGLOG(RLM, INFO, ("Set OBSS timer (NetIdx=%d, %d sec)\n", prBssInfo->ucNetTypeIndex, prBssInfo->u2ObssScanInterval)); cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer, prBssInfo->u2ObssScanInterval * MSEC_PER_SEC); } }
VOID p2pStateInit_GC_JOIN ( IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_BSS_INFO_T prP2pBssInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN P_BSS_DESC_T prBssDesc ) { P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T)NULL; P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL; P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL; do { ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prP2pBssInfo != NULL) && (prJoinInfo != NULL) && (prBssDesc != NULL)); prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; if (prBssDesc->ucSSIDLen) { COPY_SSID(prP2pConnSettings->aucSSID, prP2pConnSettings->ucSSIDLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); } // Setup a join timer. DBGLOG(P2P, TRACE, ("Start a join init timer\n")); cnmTimerStartTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer), (prP2pFsmInfo->u4GrantInterval - AIS_JOIN_CH_GRANT_THRESHOLD)); //2 <1> We are goin to connect to this BSS prBssDesc->fgIsConnecting = TRUE; //2 <2> Setup corresponding STA_RECORD_T prStaRec = bssCreateStaRecFromBssDesc(prAdapter, (prBssDesc->fgIsP2PPresent?(STA_TYPE_P2P_GO):(STA_TYPE_LEGACY_AP)), NETWORK_TYPE_P2P_INDEX, prBssDesc); if (prStaRec == NULL) { DBGLOG(P2P, TRACE, ("Create station record fail\n")); break; } prJoinInfo->prTargetStaRec = prStaRec; prJoinInfo->fgIsJoinComplete = FALSE; prJoinInfo->u4BufLength = 0; //2 <2.1> Sync. to FW domain cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1); if (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL; prStaRec->fgIsReAssoc = FALSE; prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings; switch (prP2pConnSettings->eAuthMode) { case AUTH_MODE_OPEN: /* Note: Omit break here. */ case AUTH_MODE_WPA: case AUTH_MODE_WPA_PSK: case AUTH_MODE_WPA2: case AUTH_MODE_WPA2_PSK: prJoinInfo->ucAvailableAuthTypes = (UINT_8)AUTH_TYPE_OPEN_SYSTEM; break; case AUTH_MODE_SHARED: prJoinInfo->ucAvailableAuthTypes = (UINT_8)AUTH_TYPE_SHARED_KEY; break; case AUTH_MODE_AUTO_SWITCH: DBGLOG(P2P, LOUD, ("JOIN INIT: eAuthMode == AUTH_MODE_AUTO_SWITCH\n")); prJoinInfo->ucAvailableAuthTypes = (UINT_8)(AUTH_TYPE_OPEN_SYSTEM | AUTH_TYPE_SHARED_KEY); break; default: ASSERT(!(prP2pConnSettings->eAuthMode == AUTH_MODE_WPA_NONE)); DBGLOG(P2P, ERROR, ("JOIN INIT: Auth Algorithm : %d was not supported by JOIN\n", prP2pConnSettings->eAuthMode)); /* TODO(Kevin): error handling ? */ return; } prStaRec->ucTxAuthAssocRetryLimit = P2P_TX_AUTH_ASSOCI_RETRY_LIMIT; } else { ASSERT(FALSE); // TODO: Shall we considering ROAMIN case for P2P Device?. } //2 <4> Use an appropriate Authentication Algorithm Number among the ucAvailableAuthTypes. if (prJoinInfo->ucAvailableAuthTypes & (UINT_8)AUTH_TYPE_OPEN_SYSTEM) { DBGLOG(P2P, TRACE, ("JOIN INIT: Try to do Authentication with AuthType == OPEN_SYSTEM.\n")); prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8)AUTH_TYPE_OPEN_SYSTEM; prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_OPEN_SYSTEM; } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8)AUTH_TYPE_SHARED_KEY) { DBGLOG(P2P, TRACE, ("JOIN INIT: Try to do Authentication with AuthType == SHARED_KEY.\n")); prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8)AUTH_TYPE_SHARED_KEY; prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_SHARED_KEY; } else if (prJoinInfo->ucAvailableAuthTypes & (UINT_8)AUTH_TYPE_FAST_BSS_TRANSITION) { DBGLOG(P2P, TRACE, ("JOIN INIT: Try to do Authentication with AuthType == FAST_BSS_TRANSITION.\n")); prJoinInfo->ucAvailableAuthTypes &= ~(UINT_8)AUTH_TYPE_FAST_BSS_TRANSITION; prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_FAST_BSS_TRANSITION; } else { ASSERT(0); } //4 <5> Overwrite Connection Setting for eConnectionPolicy == ANY (Used by Assoc Req) if (prBssDesc->ucSSIDLen) { COPY_SSID(prJoinInfo->rSsidStruct.aucSsid, prJoinInfo->rSsidStruct.ucSsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen); } //2 <5> Backup desired channel. //2 <6> Send a Msg to trigger SAA to start JOIN process. prJoinReqMsg = (P_MSG_JOIN_REQ_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T)); if (!prJoinReqMsg) { DBGLOG(P2P, TRACE, ("Allocation Join Message Fail\n")); ASSERT(FALSE); return; } prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START; prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg; prJoinReqMsg->prStaRec = prStaRec; // TODO: Consider fragmentation info in station record. mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T)prJoinReqMsg, MSG_SEND_METHOD_BUF); } while (FALSE); return; } /* p2pStateInit_GC_JOIN */