1/*
2 * connIbss.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/** \file connIbss.c
35 *  \brief IBSS connection implementation
36 *
37 *  \see connIbss.h
38 */
39
40/***************************************************************************/
41/*                                                                                                  */
42/*      MODULE: connIbss.c                                                              */
43/*    PURPOSE:  IBSS connection implementation                                          */
44/*                                                                                                  */
45/***************************************************************************/
46
47#define __FILE_ID__  FILE_ID_26
48#include "tidef.h"
49#include "report.h"
50#include "osApi.h"
51#include "conn.h"
52#include "connIbss.h"
53#include "timer.h"
54#include "fsm.h"
55#include "siteMgrApi.h"
56#include "sme.h"
57#include "rsnApi.h"
58#include "DataCtrl_Api.h"
59#include "paramOut.h"
60#include "connApi.h"
61#include "EvHandler.h"
62#include "currBss.h"
63#include "TrafficMonitorAPI.h"
64#include "healthMonitor.h"
65#include "TWDriver.h"
66
67
68/* Local functions prototypes */
69/* Local functions prototypes */
70static TI_STATUS waitDisconnToCmplt_to_idle (void *pData);
71static TI_STATUS idle_to_selfWait(void *pData);
72
73static TI_STATUS idle_to_rsnWait(void *pData);
74
75static TI_STATUS selfWait_to_waitToDisconnCmplt(void *pData);
76static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData);
77static TI_STATUS connected_to_waitToDisconnCmplt(void *pData);
78static TI_STATUS selfWait_to_rsnWait(void *pData);
79static TI_STATUS rsnWait_to_connected(void *pData);
80static TI_STATUS actionUnexpected(void *pData);
81static TI_STATUS actionNop(void *pData);
82static TI_STATUS selfw_merge_rsnw(void *pData);
83static TI_STATUS rsnw_merge_rsnw(void *pData);
84static TI_STATUS conn_merge_conn(void *pData);
85
86/********************************************/
87/*      Functions Implementations           */
88/********************************************/
89
90/***********************************************************************
91 *                        conn_ibssConfig
92 ***********************************************************************
93DESCRIPTION: IBSS Connection configuration function, called by the conection set param function
94                in the selection phase. Configures the connection state machine to IBSS connection mode
95
96INPUT:      hConn   -   Connection handle.
97
98OUTPUT:
99
100RETURN:     TI_OK on success, TI_NOK otherwise
101
102************************************************************************/
103TI_STATUS conn_ibssConfig(conn_t *pConn)
104{
105
106    fsm_actionCell_t    smMatrix[CONN_IBSS_NUM_STATES][CONN_IBSS_NUM_EVENTS] =
107    {
108
109        /* next state and actions for IDLE state */
110        {   {STATE_CONN_IBSS_SELF_WAIT, idle_to_selfWait    },  /* CONN_IBSS_CREATE */
111            {STATE_CONN_IBSS_RSN_WAIT,  idle_to_rsnWait     },  /* CONN_IBSS_CONNECT    */
112            {STATE_CONN_IBSS_IDLE,      actionNop           },   /* CONN_IBSS_DISCONNECT */
113            {STATE_CONN_IBSS_IDLE,      actionUnexpected    },   /* CONN_IBSS_RSN_SUCC */
114            {STATE_CONN_IBSS_IDLE,      actionUnexpected    },   /* CONN_IBSS_STA_JOINED */
115			{STATE_CONN_IBSS_IDLE,      actionUnexpected    },   /* CONN_IBSS_MERGE */
116			{STATE_CONN_IBSS_IDLE,      actionUnexpected    }    /* CONN_IBSS_DISCONN_COMPLETE */
117        },
118
119        /* next state and actions for SELF_WAIT state */
120        {   {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected    							},  /* CONN_IBSS_CREATE */
121            {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected    							},  /* CONN_IBSS_CONNECT    */
122            {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT,  selfWait_to_waitToDisconnCmplt 		},  /* CONN_IBSS_DISCONNECT */
123            {STATE_CONN_IBSS_SELF_WAIT, actionUnexpected    							},  /* CONN_IBSS_RSN_SUCC */
124            {STATE_CONN_IBSS_RSN_WAIT,  selfWait_to_rsnWait 							},  /* CONN_IBSS_STA_JOINED */
125			{STATE_CONN_IBSS_RSN_WAIT,  selfw_merge_rsnw    							},  /* CONN_IBSS_MERGE */
126			{STATE_CONN_IBSS_SELF_WAIT, actionUnexpected    							}   /* CONN_IBSS_DISCONN_COMPLETE */
127        },
128
129        /* next state and actions for RSN_WAIT state */
130        {   {STATE_CONN_IBSS_RSN_WAIT,  actionUnexpected    							},  /* CONN_IBSS_CREATE */
131            {STATE_CONN_IBSS_RSN_WAIT,  actionUnexpected    							},  /* CONN_IBSS_CONNECT    */
132            {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, rsnWait_to_waitToDisconnCmplt    		},  /* CONN_IBSS_DISCONNECT */
133            {STATE_CONN_IBSS_CONNECTED, rsnWait_to_connected							},  /* CONN_IBSS_RSN_SUCC */
134			{STATE_CONN_IBSS_RSN_WAIT,  actionUnexpected								}, 	/* CONN_IBSS_STA_JOINED */
135			{STATE_CONN_IBSS_RSN_WAIT,  rsnw_merge_rsnw     							},  /* CONN_IBSS_MERGE */
136			{STATE_CONN_IBSS_RSN_WAIT, actionUnexpected    								}   /* CONN_IBSS_DISCONN_COMPLETE */
137        },
138
139        /* next state and actions for CONNECTED state */
140        {   {STATE_CONN_IBSS_CONNECTED, actionUnexpected    							},  /* CONN_IBSS_CREATE */
141            {STATE_CONN_IBSS_CONNECTED, actionUnexpected    							},  /* CONN_IBSS_CONNECT    */
142            {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, connected_to_waitToDisconnCmplt  		},  /* CONN_IBSS_DISCONNECT */
143            {STATE_CONN_IBSS_CONNECTED, actionUnexpected    							},  /* CONN_IBSS_RSN_SUCC */
144			{STATE_CONN_IBSS_CONNECTED, actionUnexpected    							},  /* CONN_IBSS_STA_JOINED */
145			{STATE_CONN_IBSS_CONNECTED,  conn_merge_conn    							},  /* CONN_IBSS_MERGE */
146			{STATE_CONN_IBSS_CONNECTED, actionUnexpected    						   	}   /* CONN_IBSS_DISCONN_COMPLETE */
147        },
148
149		 /* next state and actions for STATE_CONN_IBSS_WAIT_DISCONN_CMPLT state */
150        {   {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected    		},  		/* CONN_IBSS_CREATE */
151            {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected    		},  		/* CONN_IBSS_CONNECT    */
152            {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected   		},  		/* CONN_IBSS_DISCONNECT */
153            {STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected    		},  		/* CONN_IBSS_RSN_SUCC */
154			{STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected    		},  		/* CONN_IBSS_STA_JOINED */
155			{STATE_CONN_IBSS_WAIT_DISCONN_CMPLT, actionUnexpected     		},  		/* CONN_IBSS_MERGE */
156			{STATE_CONN_IBSS_IDLE, 				 waitDisconnToCmplt_to_idle } 			/* CONN_IBSS_DISCONN_COMPLETE */
157        }
158
159    };
160
161    return fsm_Config(pConn->ibss_pFsm, (fsm_Matrix_t)smMatrix, CONN_IBSS_NUM_STATES, CONN_IBSS_NUM_EVENTS, conn_ibssSMEvent, pConn->hOs);
162}
163
164
165/***********************************************************************
166 *                        conn_ibssSMEvent
167 ***********************************************************************
168DESCRIPTION: IBSS Connection SM event processing function, called by the connection API
169                Perform the following:
170                -   Print the state movement as a result from the event
171                -   Calls the generic state machine event processing function which preform the following:
172                    -   Calls the correspoding callback function
173                    -   Move to next state
174
175INPUT:      currentState    -   Pointer to the connection current state.
176            event   -   Received event
177            pConn   -   Connection handle
178
179OUTPUT:
180
181RETURN:     TI_OK on success, TI_NOK otherwise
182
183************************************************************************/
184TI_STATUS conn_ibssSMEvent(TI_UINT8 *currentState, TI_UINT8 event, TI_HANDLE hConn)
185{
186   conn_t *pConn = (conn_t *)hConn;
187    TI_STATUS       status;
188    TI_UINT8       nextState;
189
190    status = fsm_GetNextState(pConn->ibss_pFsm, *currentState, event, &nextState);
191    if (status != TI_OK)
192    {
193        TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "IBSS State machine error, failed getting next state\n");
194        return(TI_NOK);
195    }
196
197	TRACE3( pConn->hReport, REPORT_SEVERITY_INFORMATION, "conn_ibssSMEvent: <currentState = %d, event = %d> --> nextState = %d\n", *currentState, event, nextState);
198    status = fsm_Event(pConn->ibss_pFsm, currentState, event, (void *)pConn);
199
200    return status;
201}
202
203
204void connIbss_DisconnectComplete (conn_t *pConn, TI_UINT8  *data, TI_UINT8   dataLength)
205{
206    /* send an DISCONNECT COMPLETE event to the SM */
207    conn_ibssSMEvent(&pConn->state, CONN_IBSS_DISCONN_COMPLETE, (TI_HANDLE) pConn);
208}
209
210/************************************************************************************************************/
211/*      In the following section are listed the callback function used by the IBSS connection state machine */
212/************************************************************************************************************/
213
214/***********************************************************************
215 *                        selfWait_to_rsnWait
216 ***********************************************************************
217DESCRIPTION:
218
219
220INPUT:
221
222OUTPUT:
223
224RETURN:     TI_OK on success, TI_NOK otherwise
225
226************************************************************************/
227static TI_STATUS selfWait_to_rsnWait (void *pData)
228{
229	conn_t      *pConn = (conn_t *)pData;
230    paramInfo_t  param;
231
232    tmr_StopTimer (pConn->hConnTimer);
233
234    param.paramType = RX_DATA_PORT_STATUS_PARAM;
235    param.content.rxDataPortStatus = OPEN_EAPOL;
236    rxData_setParam (pConn->hRxData, &param);
237
238	/* Update TxMgmtQueue SM to enable EAPOL packets. */
239	txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL);
240
241    /*
242     *  Notify that the driver is associated to the supplicant\IP stack.
243     */
244    EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0);
245
246    return rsn_start (pConn->hRsn);
247}
248
249
250/***********************************************************************
251 *                        rsnWait_to_connected
252 ***********************************************************************
253DESCRIPTION:
254
255
256INPUT:
257
258OUTPUT:
259
260RETURN:     TI_OK on success, TI_NOK otherwise
261
262************************************************************************/
263static TI_STATUS rsnWait_to_connected(void *pData)
264{
265    paramInfo_t param;
266
267    conn_t *pConn=(conn_t *)pData;
268
269    TrafficMonitor_Start( pConn->hTrafficMonitor );
270
271    healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_CONNECTED);
272
273    siteMgr_start(pConn->hSiteMgr);
274
275    param.paramType = RX_DATA_PORT_STATUS_PARAM;
276    param.content.rxDataPortStatus = OPEN;
277    rxData_setParam(((conn_t *)pData)->hRxData, &param);
278
279	/* Update TxMgmtQueue SM to open Tx path to all packets. */
280	txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_OPEN);
281
282    /* Update current BSS connection type and mode */
283    currBSS_updateConnectedState(pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
284
285	sme_ReportConnStatus(((conn_t *)pData)->hSmeSm, STATUS_SUCCESSFUL, 0);
286
287    return TI_OK;
288}
289
290static TI_STATUS selfw_merge_rsnw(void *pData)
291{
292    conn_t *pConn=(conn_t *)pData;
293    paramInfo_t param;
294
295	os_printf("IBSS selfw_merge_rsnw!!!!!!!!!!\n");
296
297	tmr_StopTimer (pConn->hConnTimer);
298	siteMgr_join(pConn->hSiteMgr);
299
300    param.paramType = RX_DATA_PORT_STATUS_PARAM;
301    param.content.rxDataPortStatus = OPEN_EAPOL;
302    rxData_setParam (pConn->hRxData, &param);
303
304	/* Update TxMgmtQueue SM to enable EAPOL packets. */
305	txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL);
306
307    /*
308     *  Notify that the driver is associated to the supplicant\IP stack.
309     */
310    EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0);
311
312    return rsn_start (pConn->hRsn);
313
314}
315
316
317static TI_STATUS rsnw_merge_rsnw(void *pData)
318{
319    conn_t *pConn=(conn_t *)pData;
320
321	os_printf("IBSS rsnw_merge_rsnw!!!!!!!!!!\n");
322
323	siteMgr_join(pConn->hSiteMgr);
324
325	return TI_OK;
326}
327
328
329static TI_STATUS conn_merge_conn(void *pData)
330{
331    conn_t *pConn=(conn_t *)pData;
332
333	os_printf("IBSS conn_merge_conn!!!!!!!!!!\n");
334
335	siteMgr_join(pConn->hSiteMgr);
336
337	return TI_OK;
338}
339
340static TI_STATUS waitDisconnToCmplt_to_idle (void *pData)
341{
342	conn_t      *pConn = (conn_t *)pData;
343
344	/* Inform the SME about the connection lost */
345    /* we use this status at SME, if != 0 means that assoc frame sent */
346	sme_ReportConnStatus(pConn->hSmeSm, STATUS_UNSPECIFIED, 1);
347	return TI_OK;
348}
349
350
351
352/***********************************************************************
353 *                        actionUnexpected
354 ***********************************************************************
355DESCRIPTION:
356
357
358INPUT:
359
360OUTPUT:
361
362RETURN:     TI_OK on success, TI_NOK otherwise
363
364************************************************************************/
365static TI_STATUS actionUnexpected(void *pData)
366{
367#ifdef TI_DBG
368    conn_t *pConn = (conn_t *)pData;
369
370    TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "State machine error, unexpected Event\n\n");
371#endif /*TI_DBG*/
372
373    return TI_OK;
374}
375
376/***********************************************************************
377 *                        actionNop
378 ***********************************************************************
379DESCRIPTION:
380
381
382INPUT:
383
384OUTPUT:
385
386RETURN:     TI_OK on success, TI_NOK otherwise
387
388************************************************************************/
389static TI_STATUS actionNop(void *pData)
390{
391    return TI_OK;
392}
393
394
395/***********************************************************************
396 *                        selfWait_to_waitToDisconnCmplt
397 ***********************************************************************
398DESCRIPTION:
399
400
401INPUT:
402
403OUTPUT:
404
405RETURN:     TI_OK on success, TI_NOK otherwise
406
407************************************************************************/
408static TI_STATUS selfWait_to_waitToDisconnCmplt (void *pData)
409{
410	conn_t      *pConn = (conn_t *)pData;
411    paramInfo_t  param;
412
413    tmr_StopTimer (pConn->hConnTimer);
414
415    siteMgr_removeSelfSite(pConn->hSiteMgr);
416
417    /* Update current BSS connection type and mode */
418    currBSS_updateConnectedState(pConn->hCurrBss, TI_FALSE, BSS_INDEPENDENT);
419
420    /* stop beacon generation  */
421    param.paramType = RX_DATA_PORT_STATUS_PARAM;
422    param.content.rxDataPortStatus = CLOSE;
423    rxData_setParam(pConn->hRxData, &param);
424
425	/* Update TxMgmtQueue SM to close Tx path. */
426	txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_CLOSE);
427
428    TWD_CmdFwDisconnect (pConn->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED);
429
430    return TI_OK;
431}
432
433
434
435/***********************************************************************
436 *                        rsnWait_to_waitToDisconnCmplt
437 ***********************************************************************
438DESCRIPTION:
439
440
441INPUT:
442
443OUTPUT:
444
445RETURN:     TI_OK on success, TI_NOK otherwise
446
447************************************************************************/
448static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData)
449{
450    paramInfo_t     param;
451	TI_STATUS		tStatus;
452
453    tStatus = rsn_stop(((conn_t *)pData)->hRsn, TI_FALSE);
454
455    param.paramType = RX_DATA_PORT_STATUS_PARAM;
456    param.content.rxDataPortStatus = CLOSE;
457    rxData_setParam(((conn_t *)pData)->hRxData, &param);
458
459	/* Update TxMgmtQueue SM to close Tx path. */
460	txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_CLOSE);
461
462    /* Update current BSS connection type and mode */
463    currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_FALSE, BSS_INDEPENDENT);
464
465    /* Stop beacon generation */
466    TWD_CmdFwDisconnect (((conn_t *)pData)->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED);
467
468    return tStatus;
469}
470
471
472/***********************************************************************
473 *                        connected_to_waitToDisconnCmplt
474 ***********************************************************************
475DESCRIPTION:
476
477
478INPUT:
479
480OUTPUT:
481
482RETURN:     TI_OK on success, TI_NOK otherwise
483
484************************************************************************/
485static TI_STATUS connected_to_waitToDisconnCmplt(void *pData)
486{
487    conn_t *pConn=(conn_t *)pData;
488
489    TrafficMonitor_Stop(pConn->hTrafficMonitor);
490
491    healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_DISCONNECTED);
492
493    /* The logic of this action is identical to rsnWait_to_idle */
494    return rsnWait_to_waitToDisconnCmplt(pConn);
495}
496
497
498
499
500
501/***********************************************************************
502 *                        idle_to_selfWait
503 ***********************************************************************
504DESCRIPTION:
505
506
507INPUT:
508
509OUTPUT:
510
511RETURN:     TI_OK on success, TI_NOK otherwise
512
513************************************************************************/
514static TI_STATUS idle_to_selfWait (void *pData)
515{
516	conn_t    *pConn = (conn_t *)pData;
517    TI_UINT16  randomTime;
518
519    siteMgr_join (pConn->hSiteMgr);
520
521    /* get a randomTime that is constructed of the lower 13 bits ot the system time to
522       get a MS random time of ~8000 ms */
523    randomTime = os_timeStampMs (pConn->hOs) & 0x1FFF;
524
525    /* Update current BSS connection type and mode */
526    currBSS_updateConnectedState (pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
527
528    tmr_StartTimer (pConn->hConnTimer,
529                    conn_timeout,
530                    (TI_HANDLE)pConn,
531                    pConn->timeout + randomTime,
532                    TI_FALSE);
533
534    return TI_OK;
535}
536
537
538
539/***********************************************************************
540 *                        idle_to_rsnWait
541 ***********************************************************************
542DESCRIPTION:
543
544
545INPUT:
546
547OUTPUT:
548
549RETURN:     TI_OK on success, TI_NOK otherwise
550
551************************************************************************/
552static TI_STATUS idle_to_rsnWait(void *pData)
553{
554    paramInfo_t param;
555
556    siteMgr_join(((conn_t *)pData)->hSiteMgr);
557
558    param.paramType = RX_DATA_PORT_STATUS_PARAM;
559    param.content.rxDataPortStatus = OPEN_EAPOL;
560    rxData_setParam(((conn_t *)pData)->hRxData, &param);
561
562	/* Update TxMgmtQueue SM to enable EAPOL packets. */
563	txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_EAPOL);
564
565    /*
566     *  Notify that the driver is associated to the supplicant\IP stack.
567     */
568    EvHandlerSendEvent(((conn_t *)pData)->hEvHandler, IPC_EVENT_ASSOCIATED, NULL,0);
569
570    /* Update current BSS connection type and mode */
571    currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
572
573    return rsn_start(((conn_t *)pData)->hRsn);
574}
575
576