blob: 53b67dec331a5943bea4afdc88847e865d5d18ef [file] [log] [blame]
/******************************************************************************
*
* This file is provided under a dual license. When you use or
* distribute this software, you may choose to be licensed under
* version 2 of the GNU General Public License ("GPLv2 License")
* or BSD License.
*
* GPLv2 License
*
* Copyright(C) 2016 MediaTek Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See http://www.gnu.org/licenses/gpl-2.0.html for more details.
*
* BSD LICENSE
*
* Copyright(C) 2016 MediaTek Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#include "p2p_precomp.h"
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;
*peNextState = P2P_STATE_REQING_CHANNEL;
} else {
#if 0
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, &(prP2pFsmInfo->rP2pFsmTimeoutTimer), 5000);
}
} while (FALSE);
return fgIsTransOut;
} /* p2pStateInit_IDLE */
VOID p2pStateAbort_IDLE(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState)
{
P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
do {
ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo;
if (prChnlReqInfo->fgIsChannelRequested) {
/* Release channel before timeout. */
p2pFuncReleaseCh(prAdapter, prChnlReqInfo);
}
/* Stop timer for leaving this state. */
cnmTimerStopTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer));
} while (FALSE);
} /* p2pStateAbort_IDLE */
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, &(prP2pFsmInfo->rP2pFsmTimeoutTimer), prChnlReqInfo->u4MaxInterval);
kalP2PIndicateChannelReady(prAdapter->prGlueInfo,
prChnlReqInfo->u8Cookie,
prChnlReqInfo->ucReqChnlNum,
prChnlReqInfo->eBand, prChnlReqInfo->eChnlSco, prChnlReqInfo->u4MaxInterval);
} while (FALSE);
} /* p2pStateInit_CHNL_ON_HAND */
VOID
p2pStateAbort_CHNL_ON_HAND(IN P_ADAPTER_T prAdapter,
IN P_P2P_FSM_INFO_T prP2pFsmInfo,
IN P_BSS_INFO_T prP2pBssInfo, IN ENUM_P2P_STATE_T eNextState)
{
P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
do {
ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL));
prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
cnmTimerStopTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer));
/* Restore the original channel info. */
prP2pBssInfo->ucPrimaryChannel = prChnlReqInfo->ucOriChnlNum;
prP2pBssInfo->eBand = prChnlReqInfo->eOriBand;
prP2pBssInfo->eBssSCO = prChnlReqInfo->eOriChnlSco;
#if 0
if (eNextState != P2P_STATE_CHNL_ON_HAND) {
/* Indicate channel return. */
kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo);
/* Return Channel. */
p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
}
#endif
} while (FALSE);
} /* p2pStateAbort_CHNL_ON_HAND */
VOID
p2pStateAbort_REQING_CHANNEL(IN P_ADAPTER_T prAdapter, IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN ENUM_P2P_STATE_T eNextState)
{
P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T) NULL;
P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T) NULL;
do {
ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (eNextState < P2P_STATE_NUM));
prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
if (eNextState == P2P_STATE_IDLE) {
if (prP2pBssInfo->eIntendOPMode == OP_MODE_ACCESS_POINT) {
/* Intend to be AP. */
/* Setup for AP mode. */
#if 0
p2pFuncStartGO(prAdapter,
prP2pBssInfo,
prP2pSpecificBssInfo->aucGroupSsid,
prP2pSpecificBssInfo->u2GroupSsidLen,
prP2pSpecificBssInfo->ucPreferredChannel,
prP2pSpecificBssInfo->eRfBand,
prP2pSpecificBssInfo->eRfSco, prP2pFsmInfo->fgIsApMode);
#endif
} else {
/* Return Channel. */
p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
}
}
} while (FALSE);
} /* p2pStateInit_AP_CHANNEL_DETECT */
VOID
p2pStateAbort_AP_CHANNEL_DETECT(IN P_ADAPTER_T prAdapter,
IN P_P2P_FSM_INFO_T prP2pFsmInfo,
IN P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo, IN ENUM_P2P_STATE_T eNextState)
{
P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = (P_P2P_CHNL_REQ_INFO_T) NULL;
P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T) NULL;
do {
if (eNextState == P2P_STATE_REQING_CHANNEL) {
UINT_8 ucPreferedChnl = 0;
ENUM_BAND_T eBand = BAND_NULL;
ENUM_CHNL_EXT_T eSco = CHNL_EXT_SCN;
prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo);
/* Determine the channel for AP. */
if (cnmPreferredChannel(prAdapter, &eBand, &ucPreferedChnl, &eSco) == FALSE) {
#if 0
prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
ucPreferedChnl = prP2pConnSettings->ucOperatingChnl;
if ((ucPreferedChnl) == 0) {
if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) {
/* What to do? */
ASSERT(FALSE);
/* TODO: Pick up a valid channel from channel list. */
}
}
#endif
}
prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS;
prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl;
prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand;
prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco;
} else {
/* p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); */
}
} while (FALSE);
} /* p2pStateAbort_AP_CHANNEL_DETECT */
/*----------------------------------------------------------------------------*/
/*!
* @brief Process of JOIN Abort. Leave JOIN State & Abort JOIN.
*
* @param (none)
*
* @return (none)
*/
/*----------------------------------------------------------------------------*/
VOID
p2pStateAbort_GC_JOIN(IN P_ADAPTER_T prAdapter,
IN P_P2P_FSM_INFO_T prP2pFsmInfo, IN P_P2P_JOIN_INFO_T prJoinInfo, IN ENUM_P2P_STATE_T eNextState)
{
P_MSG_JOIN_ABORT_T prJoinAbortMsg = (P_MSG_JOIN_ABORT_T) NULL;
do {
ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL) && (prJoinInfo != NULL));
if (prJoinInfo->fgIsJoinComplete == FALSE) {
prJoinAbortMsg =
(P_MSG_JOIN_ABORT_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_ABORT_T));
if (!prJoinAbortMsg) {
DBGLOG(P2P, TRACE, "Fail to allocate join abort message buffer\n");
ASSERT(FALSE);
return;
}
prJoinAbortMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_ABORT;
prJoinAbortMsg->ucSeqNum = prJoinInfo->ucSeqNumOfReqMsg;
prJoinAbortMsg->prStaRec = prJoinInfo->prTargetStaRec;
mboxSendMsg(prAdapter, MBOX_ID_0, (P_MSG_HDR_T) prJoinAbortMsg, MSG_SEND_METHOD_BUF);
}
/* Stop Join Timer. */
cnmTimerStopTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer));
/* Release channel requested. */
p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo));
} while (FALSE);
return;
} /* p2pStateAbort_GC_JOIN */