1/*
2 * PowerMgrKeepAlive.c
3 *
4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 *  * Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 *  * Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in
15 *    the documentation and/or other materials provided with the
16 *    distribution.
17 *  * Neither the name Texas Instruments nor the names of its
18 *    contributors may be used to endorse or promote products derived
19 *    from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34
35/**
36 * \file  PowerMgrKeepAlive.c
37 * \brief implement user keep-alive messages
38 */
39
40#define __FILE_ID__  FILE_ID_73
41#include "osTIType.h"
42#include "TWDriver.h"
43#include "STADExternalIf.h"
44#include "txCtrl_Api.h"
45
46typedef struct
47{
48    TI_HANDLE           hTWD;
49    TI_HANDLE           hReport;
50    TI_HANDLE           hOs;
51    TI_HANDLE           hTxCtrl;
52    TKeepAliveConfig    tCurrentConfig;
53    TI_BOOL             bConnected;
54    TI_UINT8            wlanHeader[ WLAN_WITH_SNAP_QOS_HEADER_MAX_SIZE + AES_AFTER_HEADER_FIELD_SIZE ];
55    TI_UINT32           wlanHeaderLength;
56    TI_UINT8            tempBuffer[ KEEP_ALIVE_TEMPLATE_MAX_LENGTH + WLAN_WITH_SNAP_QOS_HEADER_MAX_SIZE + AES_AFTER_HEADER_FIELD_SIZE ];
57} TPowerMgrKL;
58
59TI_STATUS powerMgrKLConfigureMessage (TI_HANDLE hPowerMgrKL, TI_UINT32 uMessageIndex);
60
61/**
62 * \fn     powerMgrKL_create
63 * \brief  Creates the power manager keep-alive sub-module
64 *
65 * Allocates memory for the keep-alive object
66 *
67 * \param  hOS - handle to the os object
68 * \return A handle to the power manager keep-alive sub-module
69 * \sa     powerMgrKL_destroy, powerMgrKL_init
70 */
71TI_HANDLE powerMgrKL_create (TI_HANDLE hOS)
72{
73    TPowerMgrKL     *pPowerMgrKL;
74
75    /* allocate memory for the power manager keep-alive object */
76    pPowerMgrKL = os_memoryAlloc (hOS, sizeof(TPowerMgrKL));
77    if ( NULL == pPowerMgrKL)
78    {
79        return NULL;
80    }
81
82    /* store OS handle */
83    pPowerMgrKL->hOs = hOS;
84
85    return (TI_HANDLE)pPowerMgrKL;
86}
87
88/**
89 * \fn     powerMgrKL_destroy
90 * \brief  Destroys the power manager keep-alive sub-module
91 *
92 * De-allocates keep-alive object memory
93 *
94 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
95 * \return None
96 * \sa     powerMgrKL_create, powerMgrKL_init
97 */
98void powerMgrKL_destroy (TI_HANDLE hPowerMgrKL)
99{
100    TPowerMgrKL     *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
101
102    os_memoryFree (pPowerMgrKL->hOs, hPowerMgrKL, sizeof(TPowerMgrKL));
103}
104
105/**
106 * \fn     powerMgrKL_init
107 * \brief  Initailize the power manager keep-alive sub-module
108 *
109 * Stores handles to other modules
110 *
111 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
112 * \param  hReport - handle to the report object
113 * \param  hTWD - handle to the TWD object
114 * \param  hTxCtrl - handle to the TX control object
115 * \return None
116 * \sa     powerMgrKL_destroy, powerMgrKL_create, powerMgrKL_setDefaults
117 */
118void powerMgrKL_init (TI_HANDLE hPowerMgrKL,
119                      TStadHandlesList *pStadHandles)
120{
121    TPowerMgrKL     *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
122
123    /* store handles */
124    pPowerMgrKL->hTWD       = pStadHandles->hTWD;
125    pPowerMgrKL->hReport    = pStadHandles->hReport;
126    pPowerMgrKL->hTxCtrl    = pStadHandles->hTxCtrl;
127}
128
129/**
130 * \fn     powerMgrKL_setDefaults
131 * \brief  Set powr-manager keep-aive default initialization values
132 *
133 * Set powr-manager keep-aive default initialization values
134 *
135 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
136 * \return None
137 * \sa     powerMgrKL_init
138 */
139void powerMgrKL_setDefaults (TI_HANDLE hPowerMgrKL)
140{
141    TPowerMgrKL     *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
142    TI_UINT32       uIndex;
143
144    /* mark the global enable / disable flag as enabled */
145    pPowerMgrKL->tCurrentConfig.enaDisFlag = TI_TRUE;
146
147    /* mark all messages as disabled */
148    for (uIndex = 0; uIndex < KEEP_ALIVE_MAX_USER_MESSAGES; uIndex++)
149    {
150        pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag = TI_FALSE;
151    }
152
153    /* mark STA as disconnected */
154    pPowerMgrKL->bConnected = TI_FALSE;
155}
156
157/**
158 * \fn     powerMgrKL_start
159 * \brief  Notifies the power-manager keep-alive upon connection to a BSS
160 *
161 * Set all configured templates to the FW
162 *
163 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
164 * \return TI_OK if succesful, TI_NOK otherwise
165 * \sa     powerMgrKL_stop, powerMgrKL_setParam
166 */
167TI_STATUS powerMgrKL_start (TI_HANDLE hPowerMgrKL)
168{
169    TPowerMgrKL     *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
170    TI_UINT32       uIndex;
171    TI_STATUS       status = TI_OK;
172
173    /* mark STA as connected */
174    pPowerMgrKL->bConnected = TI_TRUE;
175
176    /* build WLAN header */
177    status = txCtrlServ_buildWlanHeader (pPowerMgrKL->hTxCtrl, &(pPowerMgrKL->wlanHeader[ 0 ]), &(pPowerMgrKL->wlanHeaderLength));
178
179    /* download all enabled templates to the FW (through TWD)*/
180    for (uIndex = 0; uIndex < KEEP_ALIVE_MAX_USER_MESSAGES; uIndex++)
181    {
182        /*
183         * if the message is enabled (disabled messages shouldn't be configured on connection,
184         * as they are disabled by default in the FW) */
185
186        if (TI_TRUE == pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag)
187        {
188            /* configure keep-alive to the FW (through command builder */
189            status = powerMgrKLConfigureMessage (hPowerMgrKL, uIndex);
190        }
191    }
192    return status;
193}
194
195/**
196 * \fn     powerMgrKL_stop
197 * \brief  Notifies the power-manager keep-alive upon disconnection from a BSS
198 *
199 * Delete all configured templates from the FW and internal storage
200 *
201 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
202 * \return TI_OK if succesful, TI_NOK otherwise
203 * \sa     powerMgrKL_start, powerMgrKL_setParam
204 */
205void powerMgrKL_stop (TI_HANDLE hPowerMgrKL, TI_BOOL bDisconnect)
206{
207    TPowerMgrKL     *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
208    TI_UINT32       uIndex;
209
210    /* mark STA as disconnected */
211    pPowerMgrKL->bConnected = TI_FALSE;
212
213    /* if this is a real disconnect */
214    if (TI_TRUE == bDisconnect)
215    {
216        /* for all congfiured messages */
217        for (uIndex = 0; uIndex < KEEP_ALIVE_MAX_USER_MESSAGES; uIndex++)
218        {
219            /* mark the message as disabled */
220            pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag = TI_FALSE;
221        }
222    }
223    /* for roaming, don't do anything */
224}
225
226/**
227 * \fn     powerMgrKL_setParam
228 * \brief  Handles a parametr change from user-mode
229 *
230 * Handles addition / removal of a template and global enable / disable flag
231 *
232 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
233 * \param  pParam - A pointer to the paramter being set
234 * \return TI_OK if succesful, TI_NOK otherwise
235 * \sa     powerMgrKL_start, powerMgrKL_stop
236 */
237TI_STATUS powerMgrKL_setParam (TI_HANDLE hPowerMgrKL, paramInfo_t *pParam)
238{
239    TPowerMgrKL         *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
240    TI_UINT32           uIndex;
241    TKeepAliveTemplate  *pNewTmpl;
242    TI_STATUS           status = TI_OK;
243
244    TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_INFORMATION , "Keep-alive set param called with param type %d\n", pParam->paramType);
245
246    switch (pParam->paramType)
247    {
248    /* global keep-alive enable / disable flag */
249    case POWER_MGR_KEEP_ALIVE_ENA_DIS:
250
251        pPowerMgrKL->tCurrentConfig.enaDisFlag = pParam->content.powerMgrKeepAliveEnaDis;
252        return TWD_CfgKeepAliveEnaDis(pPowerMgrKL->hTWD,
253                                      (TI_UINT8)pParam->content.powerMgrKeepAliveEnaDis);
254        break;
255
256    /* keep-alive template and parameters configuration */
257    case POWER_MGR_KEEP_ALIVE_ADD_REM:
258
259        pNewTmpl = pParam->content.pPowerMgrKeepAliveTemplate;
260        uIndex = pNewTmpl->keepAliveParams.index;
261
262        /* if STA is connected */
263        if (TI_TRUE == pPowerMgrKL->bConnected)
264        {
265            /* if keep-alive is already configured for this index */
266            if (TI_TRUE == pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag)
267            {
268                /* disable previous keep-alive */
269                pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams.enaDisFlag = TI_FALSE;
270                status = TWD_CfgKeepAlive (pPowerMgrKL->hTWD, &(pPowerMgrKL->tCurrentConfig.templates[ uIndex ].keepAliveParams));
271                if (TI_OK != status)
272                {
273                    TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKL_setParam: error trying to clear current template %d\n", status);
274                    return status;
275                }
276            }
277
278            /* copy configuration */
279            os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tCurrentConfig.templates[ uIndex ]),
280                           pNewTmpl, sizeof (TKeepAliveTemplate));
281
282            /* configure keep-alive to the FW (through command builder */
283            return powerMgrKLConfigureMessage (hPowerMgrKL, uIndex);
284        }
285        /* STA disconnected */
286        else
287        {
288            /* copy configuration */
289            os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tCurrentConfig.templates[ uIndex ]),
290                           pNewTmpl, sizeof (TKeepAliveTemplate));
291        }
292        return TI_OK;
293        break;
294
295    default:
296        TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "power manager keep-alive: set param with unknown param type %d\n", pParam->paramType);
297        return PARAM_NOT_SUPPORTED;
298        break;
299    }
300}
301
302/**
303 * \fn     powerMgrKL_getParam
304 * \brief  Handles a parametr request from user-mode
305 *
306 * Retrieves configuration
307 *
308 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
309 * \param  pParam - A pointer to the paramter being retrieved
310 * \return TI_OK if succesful, TI_NOK otherwise
311 * \sa     powerMgrKL_start, powerMgrKL_stop
312 */
313TI_STATUS powerMgrKL_getParam (TI_HANDLE hPowerMgrKL, paramInfo_t *pParam)
314{
315    TPowerMgrKL     *pPowerMgrKL = (TPowerMgrKL*)hPowerMgrKL;
316
317    TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_INFORMATION , "Keep-alive get param called with param type %d\n", pParam->paramType);
318
319    switch (pParam->paramType)
320    {
321    case POWER_MGR_KEEP_ALIVE_GET_CONFIG:
322
323        pParam->paramLength = sizeof (TKeepAliveConfig);
324        os_memoryCopy (pPowerMgrKL->hOs, (void*)pParam->content.pPowerMgrKeepAliveConfig,
325                       (void*)&(pPowerMgrKL->tCurrentConfig), sizeof (TKeepAliveConfig));
326
327        return TI_OK;
328        break;
329
330    default:
331        TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "power manager keep-alive: get param with unknown param type %d\n", pParam->paramType);
332        return PARAM_NOT_SUPPORTED;
333        break;
334    }
335}
336
337/**
338 * \fn     powerMgrKLConfigureMessage
339 * \brief  Configures keep-alive message (template and parameters)
340 *
341 * Configures a keepa-live message from internal database.
342 *
343 * \param  hPowerMgrKL - handle to the power-manager keep-alive object
344 * \param  uMessageIndex - index of message to configure (from internal database)
345 * \return TI_OK if succesful, TI_NOK otherwise
346 * \sa     powerMgrKL_start, powerMgrKL_setParam
347 */
348TI_STATUS powerMgrKLConfigureMessage (TI_HANDLE hPowerMgrKL, TI_UINT32 uMessageIndex)
349{
350    TPowerMgrKL     *pPowerMgrKL    = (TPowerMgrKL*)hPowerMgrKL;
351    TI_STATUS       status          = TI_OK;
352
353    /* if the keep-alive for this index is enabled */
354    if (TI_TRUE == pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].keepAliveParams.enaDisFlag)
355    {
356        /* configure template - first the template itself */
357        TSetTemplate    tTemplate;
358
359        tTemplate.type = KEEP_ALIVE_TEMPLATE;
360        tTemplate.index = uMessageIndex;
361        os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tempBuffer),
362                       &(pPowerMgrKL->wlanHeader), pPowerMgrKL->wlanHeaderLength); /* copy WLAN header - was built on connection */
363        os_memoryCopy (pPowerMgrKL->hOs, &(pPowerMgrKL->tempBuffer[ pPowerMgrKL->wlanHeaderLength ]),
364                       &(pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].msgBuffer[ 0 ]),
365                       pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].msgBufferLength); /* copy template data */
366        tTemplate.ptr = &(pPowerMgrKL->tempBuffer[ 0 ]);
367        tTemplate.len = pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].msgBufferLength + pPowerMgrKL->wlanHeaderLength;
368        tTemplate.uRateMask = RATE_MASK_UNSPECIFIED;
369        status = TWD_CmdTemplate (pPowerMgrKL->hTWD, &tTemplate, NULL, NULL);
370        if (TI_OK != status)
371        {
372            TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKLConfigureMessage: error trying to set new template %d\n", status);
373            return status;
374        }
375
376        /* and than the parameters */
377        status = TWD_CfgKeepAlive (pPowerMgrKL->hTWD, &(pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].keepAliveParams));
378        if (TI_OK != status)
379        {
380            TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKLConfigureMessage: error trying to set new keep-alive params %d\n", status);
381            return status;
382        }
383    }
384    /* keep-alive for this index is disabled - just disable it */
385    else
386    {
387        status = TWD_CfgKeepAlive (pPowerMgrKL->hTWD, &(pPowerMgrKL->tCurrentConfig.templates[ uMessageIndex ].keepAliveParams));
388        if (TI_OK != status)
389        {
390            TRACE1(pPowerMgrKL->hReport, REPORT_SEVERITY_ERROR , "powerMgrKLConfigureMessage: error trying to set new keep-alive params %d\n", status);
391            return status;
392        }
393    }
394
395    return status;
396}
397