/*
* PowerMgrKeepAlive.c
*
* Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
* 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 Texas Instruments 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
* OWNER 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.
*/
/**
* \file PowerMgrKeepAlive.c
* \brief implement user keep-alive messages
*/
#define __FILE_ID__ FILE_ID_73
#include "osTIType.h"
#include "TWDriver.h"
#include "STADExternalIf.h"
#include "txCtrl_Api.h"
typedef struct
{
TI_HANDLE hTWD;
TI_HANDLE hReport;
TI_HANDLE hOs;
TI_HANDLE hTxCtrl;
TKeepAliveConfig tCurrentConfig;
TI_BOOL bConnected;
TI_UINT8 wlanHeader[ WLAN_WITH_SNAP_QOS_HEADER_MAX_SIZE + AES_AFTER_HEADER_FIELD_SIZE ];
TI_UINT32 wlanHeaderLength;
TI_UINT8 tempBuffer[ KEEP_ALIVE_TEMPLATE_MAX_LENGTH + WLAN_WITH_SNAP_QOS_HEADER_MAX_SIZE + AES_AFTER_HEADER_FIELD_SIZE ];
} TPowerMgrKL;
TI_STATUS powerMgrKLConfigureMessage (TI_HANDLE hPowerMgrKL, TI_UINT32 uMessageIndex);
/**
* \fn powerMgrKL_create
* \brief Creates the power manager keep-alive sub-module
*
* Allocates memory for the keep-alive object
*
* \param hOS - handle to the os object
* \return A handle to the power manager keep-alive sub-module
* \sa powerMgrKL_destroy, powerMgrKL_init
*/
TI_HANDLE powerMgrKL_create (TI_HANDLE hOS)
{
TPowerMgrKL *pPowerMgrKL;
/* allocate memory for the power manager keep-alive object */
pPowerMgrKL = os_memoryAlloc (hOS, sizeof(TPowerMgrKL));
if ( NULL == pPowerMgrKL)
{
return NULL;
}
/* store OS handle */
pPowerMgrKL->hOs = hOS;
return (TI_HANDLE)pPowerMgrKL;
}
/**
* \fn powerMgrKL_destroy
* \brief Destroys the power manager keep-alive sub-module
*
* De-allocates keep-alive object memory
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \return None
* \sa powerMgrKL_create, powerMgrKL_init
*/
void powerMgrKL_destroy (TI_HANDLE hPowerMgrKL)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
os_memoryFree (pPowerMgrKL->hOs, hPowerMgrKL, sizeof(TPowerMgrKL));
}
/**
* \fn powerMgrKL_init
* \brief Initailize the power manager keep-alive sub-module
*
* Stores handles to other modules
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \param hReport - handle to the report object
* \param hTWD - handle to the TWD object
* \param hTxCtrl - handle to the TX control object
* \return None
* \sa powerMgrKL_destroy, powerMgrKL_create, powerMgrKL_setDefaults
*/
void powerMgrKL_init (TI_HANDLE hPowerMgrKL,
TStadHandlesList *pStadHandles)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
/* store handles */
pPowerMgrKL->hTWD = pStadHandles->hTWD;
pPowerMgrKL->hReport = pStadHandles->hReport;
pPowerMgrKL->hTxCtrl = pStadHandles->hTxCtrl;
}
/**
* \fn powerMgrKL_setDefaults
* \brief Set powr-manager keep-aive default initialization values
*
* Set powr-manager keep-aive default initialization values
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \return None
* \sa powerMgrKL_init
*/
void powerMgrKL_setDefaults (TI_HANDLE hPowerMgrKL)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
TI_UINT32 uIndex;
/* mark the global enable / disable flag as enabled */
pPowerMgrKL->tCurrentConfig.enaDisFlag = TI_TRUE;
/* mark all messages as disabled */
for (uIndex = 0; uIndex < KEEP_ALIVE_MAX_USER_MESSAGES; uIndex++)
{
pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag = TI_FALSE;
}
/* mark STA as disconnected */
pPowerMgrKL->bConnected = TI_FALSE;
}
/**
* \fn powerMgrKL_start
* \brief Notifies the power-manager keep-alive upon connection to a BSS
*
* Set all configured templates to the FW
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \return TI_OK if succesful, TI_NOK otherwise
* \sa powerMgrKL_stop, powerMgrKL_setParam
*/
TI_STATUS powerMgrKL_start (TI_HANDLE hPowerMgrKL)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
TI_UINT32 uIndex;
TI_STATUS status = TI_OK;
/* mark STA as connected */
pPowerMgrKL->bConnected = TI_TRUE;
/* build WLAN header */
status = txCtrlServ_buildWlanHeader (pPowerMgrKL->hTxCtrl, &(pPowerMgrKL->wlanHeader[ 0 ]), &(pPowerMgrKL->wlanHeaderLength));
/* download all enabled templates to the FW (through TWD)*/
for (uIndex = 0; uIndex < KEEP_ALIVE_MAX_USER_MESSAGES; uIndex++)
{
/*
* if the message is enabled (disabled messages shouldn't be configured on connection,
* as they are disabled by default in the FW) */
if (TI_TRUE == pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag)
{
/* configure keep-alive to the FW (through command builder */
status = powerMgrKLConfigureMessage (hPowerMgrKL, uIndex);
}
}
return status;
}
/**
* \fn powerMgrKL_stop
* \brief Notifies the power-manager keep-alive upon disconnection from a BSS
*
* Delete all configured templates from the FW and internal storage
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \return TI_OK if succesful, TI_NOK otherwise
* \sa powerMgrKL_start, powerMgrKL_setParam
*/
void powerMgrKL_stop (TI_HANDLE hPowerMgrKL, TI_BOOL bDisconnect)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
TI_UINT32 uIndex;
/* mark STA as disconnected */
pPowerMgrKL->bConnected = TI_FALSE;
/* if this is a real disconnect */
if (TI_TRUE == bDisconnect)
{
/* for all congfiured messages */
for (uIndex = 0; uIndex < KEEP_ALIVE_MAX_USER_MESSAGES; uIndex++)
{
/* mark the message as disabled */
pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag = TI_FALSE;
}
}
/* for roaming, don't do anything */
}
/**
* \fn powerMgrKL_setParam
* \brief Handles a parametr change from user-mode
*
* Handles addition / removal of a template and global enable / disable flag
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \param pParam - A pointer to the paramter being set
* \return TI_OK if succesful, TI_NOK otherwise
* \sa powerMgrKL_start, powerMgrKL_stop
*/
TI_STATUS powerMgrKL_setParam (TI_HANDLE hPowerMgrKL, paramInfo_t *pParam)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
TI_UINT32 uIndex;
TKeepAliveTemplate *pNewTmpl;
TI_STATUS status = TI_OK;
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_INFORMATION , "Keep-alive set param called with param type %d\n", pParam->paramType);
switch (pParam->paramType)
{
/* global keep-alive enable / disable flag */
case POWER_MGR_KEEP_ALIVE_ENA_DIS:
pPowerMgrKL->tCurrentConfig.enaDisFlag = pParam->content.powerMgrKeepAliveEnaDis;
return TWD_CfgKeepAliveEnaDis(pPowerMgrKL->hTWD,
(TI_UINT8)pParam->content.powerMgrKeepAliveEnaDis);
break;
/* keep-alive template and parameters configuration */
case POWER_MGR_KEEP_ALIVE_ADD_REM:
pNewTmpl = pParam->content.pPowerMgrKeepAliveTemplate;
uIndex = pNewTmpl->keepAliveParams.index;
/* if STA is connected */
if (TI_TRUE == pPowerMgrKL->bConnected)
{
/* if keep-alive is already configured for this index */
if (TI_TRUE == pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag)
{
/* disable previous keep-alive */
pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag = TI_FALSE;
status = TWD_CfgKeepAlive (pPowerMgrKL->hTWD, &(pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams));
if (TI_OK != status)
{
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKL_setParam: error trying to clear current template %d\n", status);
return status;
}
}
/* copy configuration */
os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tCurrentConfig.templates[ uIndex ]),
pNewTmpl, sizeof (TKeepAliveTemplate));
/* configure keep-alive to the FW (through command builder */
return powerMgrKLConfigureMessage (hPowerMgrKL, uIndex);
}
/* STA disconnected */
else
{
/* copy configuration */
os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tCurrentConfig.templates[ uIndex ]),
pNewTmpl, sizeof (TKeepAliveTemplate));
}
return TI_OK;
break;
default:
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "power manager keep-alive: set param with unknown param type %d\n", pParam->paramType);
return PARAM_NOT_SUPPORTED;
break;
}
}
/**
* \fn powerMgrKL_getParam
* \brief Handles a parametr request from user-mode
*
* Retrieves configuration
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \param pParam - A pointer to the paramter being retrieved
* \return TI_OK if succesful, TI_NOK otherwise
* \sa powerMgrKL_start, powerMgrKL_stop
*/
TI_STATUS powerMgrKL_getParam (TI_HANDLE hPowerMgrKL, paramInfo_t *pParam)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_INFORMATION , "Keep-alive get param called with param type %d\n", pParam->paramType);
switch (pParam->paramType)
{
case POWER_MGR_KEEP_ALIVE_GET_CONFIG:
pParam->paramLength = sizeof (TKeepAliveConfig);
os_memoryCopy (pPowerMgrKL->hOs, (void*)pParam->content.pPowerMgrKeepAliveConfig,
(void*)&(pPowerMgrKL->tCurrentConfig), sizeof (TKeepAliveConfig));
return TI_OK;
break;
default:
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "power manager keep-alive: get param with unknown param type %d\n", pParam->paramType);
return PARAM_NOT_SUPPORTED;
break;
}
}
/**
* \fn powerMgrKLConfigureMessage
* \brief Configures keep-alive message (template and parameters)
*
* Configures a keepa-live message from internal database.
*
* \param hPowerMgrKL - handle to the power-manager keep-alive object
* \param uMessageIndex - index of message to configure (from internal database)
* \return TI_OK if succesful, TI_NOK otherwise
* \sa powerMgrKL_start, powerMgrKL_setParam
*/
TI_STATUS powerMgrKLConfigureMessage (TI_HANDLE hPowerMgrKL, TI_UINT32 uMessageIndex)
{
TPowerMgrKL *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
TI_STATUS status = TI_OK;
/* if the keep-alive for this index is enabled */
if (TI_TRUE == pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].keepAliveParams.enaDisFlag)
{
/* configure template - first the template itself */
TSetTemplate tTemplate;
tTemplate.type = KEEP_ALIVE_TEMPLATE;
tTemplate.index = uMessageIndex;
os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tempBuffer),
&(pPowerMgrKL->wlanHeader), pPowerMgrKL->wlanHeaderLength); /* copy WLAN header - was built on connection */
os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tempBuffer[ pPowerMgrKL->wlanHeaderLength ]),
&(pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].msgBuffer[ 0 ]),
pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].msgBufferLength); /* copy template data */
tTemplate.ptr = &(pPowerMgrKL->tempBuffer[ 0 ]);
tTemplate.len = pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].msgBufferLength + pPowerMgrKL->wlanHeaderLength;
tTemplate.uRateMask = RATE_MASK_UNSPECIFIED;
status = TWD_CmdTemplate (pPowerMgrKL->hTWD, &tTemplate, NULL, NULL);
if (TI_OK != status)
{
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKLConfigureMessage: error trying to set new template %d\n", status);
return status;
}
/* and than the parameters */
status = TWD_CfgKeepAlive (pPowerMgrKL->hTWD, &(pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].keepAliveParams));
if (TI_OK != status)
{
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKLConfigureMessage: error trying to set new keep-alive params %d\n", status);
return status;
}
}
/* keep-alive for this index is disabled - just disable it */
else
{
status = TWD_CfgKeepAlive (pPowerMgrKL->hTWD, &(pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].keepAliveParams));
if (TI_OK != status)
{
TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKLConfigureMessage: error trying to set new keep-alive params %d\n", status);
return status;
}
}
return status;
}