1 /*
2 * connIbss.c
3 *
4 * Copyright(c) 1998 - 2010 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 */
70 static TI_STATUS waitDisconnToCmplt_to_idle (void *pData);
71 static TI_STATUS idle_to_selfWait(void *pData);
72
73 static TI_STATUS idle_to_rsnWait(void *pData);
74
75 static TI_STATUS selfWait_to_waitToDisconnCmplt(void *pData);
76 static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData);
77 static TI_STATUS connected_to_waitToDisconnCmplt(void *pData);
78 static TI_STATUS selfWait_to_rsnWait(void *pData);
79 static TI_STATUS rsnWait_to_connected(void *pData);
80 static TI_STATUS actionUnexpected(void *pData);
81 static TI_STATUS actionNop(void *pData);
82 static TI_STATUS selfw_merge_rsnw(void *pData);
83 static TI_STATUS rsnw_merge_rsnw(void *pData);
84 static TI_STATUS conn_merge_conn(void *pData);
85
86 /********************************************/
87 /* Functions Implementations */
88 /********************************************/
89
90 /***********************************************************************
91 * conn_ibssConfig
92 ***********************************************************************
93 DESCRIPTION: 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
96 INPUT: hConn - Connection handle.
97
98 OUTPUT:
99
100 RETURN: TI_OK on success, TI_NOK otherwise
101
102 ************************************************************************/
conn_ibssConfig(conn_t * pConn)103 TI_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 ***********************************************************************
168 DESCRIPTION: 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
175 INPUT: currentState - Pointer to the connection current state.
176 event - Received event
177 pConn - Connection handle
178
179 OUTPUT:
180
181 RETURN: TI_OK on success, TI_NOK otherwise
182
183 ************************************************************************/
conn_ibssSMEvent(TI_UINT8 * currentState,TI_UINT8 event,TI_HANDLE hConn)184 TI_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
connIbss_DisconnectComplete(conn_t * pConn,TI_UINT8 * data,TI_UINT8 dataLength)204 void 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 ***********************************************************************
217 DESCRIPTION:
218
219
220 INPUT:
221
222 OUTPUT:
223
224 RETURN: TI_OK on success, TI_NOK otherwise
225
226 ************************************************************************/
selfWait_to_rsnWait(void * pData)227 static 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, ¶m);
237
238 /* Update TxMgmtQueue SM to enable EAPOL packets. */
239 txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL);
240
241 return rsn_start (pConn->hRsn);
242 }
243
244
245 /***********************************************************************
246 * rsnWait_to_connected
247 ***********************************************************************
248 DESCRIPTION:
249
250
251 INPUT:
252
253 OUTPUT:
254
255 RETURN: TI_OK on success, TI_NOK otherwise
256
257 ************************************************************************/
rsnWait_to_connected(void * pData)258 static TI_STATUS rsnWait_to_connected(void *pData)
259 {
260 paramInfo_t param;
261
262 conn_t *pConn=(conn_t *)pData;
263
264 TrafficMonitor_Start( pConn->hTrafficMonitor );
265
266 healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_CONNECTED);
267
268 siteMgr_start(pConn->hSiteMgr);
269
270 param.paramType = RX_DATA_PORT_STATUS_PARAM;
271 param.content.rxDataPortStatus = OPEN;
272 rxData_setParam(((conn_t *)pData)->hRxData, ¶m);
273
274 /* Update TxMgmtQueue SM to open Tx path to all packets. */
275 txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_OPEN);
276
277 /* Update current BSS connection type and mode */
278 currBSS_updateConnectedState(pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
279
280 sme_ReportConnStatus(((conn_t *)pData)->hSmeSm, STATUS_SUCCESSFUL, 0);
281
282 return TI_OK;
283 }
284
selfw_merge_rsnw(void * pData)285 static TI_STATUS selfw_merge_rsnw(void *pData)
286 {
287 conn_t *pConn=(conn_t *)pData;
288 paramInfo_t param;
289
290 os_printf("IBSS selfw_merge_rsnw!!!!!!!!!!\n");
291
292 tmr_StopTimer (pConn->hConnTimer);
293 siteMgr_join(pConn->hSiteMgr);
294
295 param.paramType = RX_DATA_PORT_STATUS_PARAM;
296 param.content.rxDataPortStatus = OPEN_EAPOL;
297 rxData_setParam (pConn->hRxData, ¶m);
298
299 /* Update TxMgmtQueue SM to enable EAPOL packets. */
300 txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_EAPOL);
301
302 return rsn_start (pConn->hRsn);
303
304 }
305
306
rsnw_merge_rsnw(void * pData)307 static TI_STATUS rsnw_merge_rsnw(void *pData)
308 {
309 conn_t *pConn=(conn_t *)pData;
310
311 os_printf("IBSS rsnw_merge_rsnw!!!!!!!!!!\n");
312
313 siteMgr_join(pConn->hSiteMgr);
314
315 return TI_OK;
316 }
317
318
conn_merge_conn(void * pData)319 static TI_STATUS conn_merge_conn(void *pData)
320 {
321 conn_t *pConn=(conn_t *)pData;
322
323 os_printf("IBSS conn_merge_conn!!!!!!!!!!\n");
324
325 siteMgr_join(pConn->hSiteMgr);
326
327 return TI_OK;
328 }
329
waitDisconnToCmplt_to_idle(void * pData)330 static TI_STATUS waitDisconnToCmplt_to_idle (void *pData)
331 {
332 conn_t *pConn = (conn_t *)pData;
333
334 /* Inform the SME about the connection lost */
335 /* we use this status at SME, if != 0 means that assoc frame sent */
336 sme_ReportConnStatus(pConn->hSmeSm, STATUS_UNSPECIFIED, 1);
337 return TI_OK;
338 }
339
340
341
342 /***********************************************************************
343 * actionUnexpected
344 ***********************************************************************
345 DESCRIPTION:
346
347
348 INPUT:
349
350 OUTPUT:
351
352 RETURN: TI_OK on success, TI_NOK otherwise
353
354 ************************************************************************/
actionUnexpected(void * pData)355 static TI_STATUS actionUnexpected(void *pData)
356 {
357 #ifdef TI_DBG
358 conn_t *pConn = (conn_t *)pData;
359
360 TRACE0(pConn->hReport, REPORT_SEVERITY_SM, "State machine error, unexpected Event\n\n");
361 #endif /*TI_DBG*/
362
363 return TI_OK;
364 }
365
366 /***********************************************************************
367 * actionNop
368 ***********************************************************************
369 DESCRIPTION:
370
371
372 INPUT:
373
374 OUTPUT:
375
376 RETURN: TI_OK on success, TI_NOK otherwise
377
378 ************************************************************************/
actionNop(void * pData)379 static TI_STATUS actionNop(void *pData)
380 {
381 return TI_OK;
382 }
383
384
385 /***********************************************************************
386 * selfWait_to_waitToDisconnCmplt
387 ***********************************************************************
388 DESCRIPTION:
389
390
391 INPUT:
392
393 OUTPUT:
394
395 RETURN: TI_OK on success, TI_NOK otherwise
396
397 ************************************************************************/
selfWait_to_waitToDisconnCmplt(void * pData)398 static TI_STATUS selfWait_to_waitToDisconnCmplt (void *pData)
399 {
400 conn_t *pConn = (conn_t *)pData;
401 paramInfo_t param;
402
403 tmr_StopTimer (pConn->hConnTimer);
404
405 siteMgr_removeSelfSite(pConn->hSiteMgr);
406
407 /* Update current BSS connection type and mode */
408 currBSS_updateConnectedState(pConn->hCurrBss, TI_FALSE, BSS_INDEPENDENT);
409
410 /* stop beacon generation */
411 param.paramType = RX_DATA_PORT_STATUS_PARAM;
412 param.content.rxDataPortStatus = CLOSE;
413 rxData_setParam(pConn->hRxData, ¶m);
414
415 /* Update TxMgmtQueue SM to close Tx path. */
416 txMgmtQ_SetConnState (pConn->hTxMgmtQ, TX_CONN_STATE_CLOSE);
417
418 TWD_CmdFwDisconnect (pConn->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED);
419
420 return TI_OK;
421 }
422
423
424
425 /***********************************************************************
426 * rsnWait_to_waitToDisconnCmplt
427 ***********************************************************************
428 DESCRIPTION:
429
430
431 INPUT:
432
433 OUTPUT:
434
435 RETURN: TI_OK on success, TI_NOK otherwise
436
437 ************************************************************************/
rsnWait_to_waitToDisconnCmplt(void * pData)438 static TI_STATUS rsnWait_to_waitToDisconnCmplt(void *pData)
439 {
440 paramInfo_t param;
441 TI_STATUS tStatus;
442
443 tStatus = rsn_stop(((conn_t *)pData)->hRsn, TI_FALSE);
444
445 param.paramType = RX_DATA_PORT_STATUS_PARAM;
446 param.content.rxDataPortStatus = CLOSE;
447 rxData_setParam(((conn_t *)pData)->hRxData, ¶m);
448
449 /* Update TxMgmtQueue SM to close Tx path. */
450 txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_CLOSE);
451
452 /* Update current BSS connection type and mode */
453 currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_FALSE, BSS_INDEPENDENT);
454
455 /* Stop beacon generation */
456 TWD_CmdFwDisconnect (((conn_t *)pData)->hTWD, DISCONNECT_IMMEDIATE, STATUS_UNSPECIFIED);
457
458 return tStatus;
459 }
460
461
462 /***********************************************************************
463 * connected_to_waitToDisconnCmplt
464 ***********************************************************************
465 DESCRIPTION:
466
467
468 INPUT:
469
470 OUTPUT:
471
472 RETURN: TI_OK on success, TI_NOK otherwise
473
474 ************************************************************************/
connected_to_waitToDisconnCmplt(void * pData)475 static TI_STATUS connected_to_waitToDisconnCmplt(void *pData)
476 {
477 conn_t *pConn=(conn_t *)pData;
478
479 TrafficMonitor_Stop(pConn->hTrafficMonitor);
480
481 healthMonitor_setState(pConn->hHealthMonitor, HEALTH_MONITOR_STATE_DISCONNECTED);
482
483 /* The logic of this action is identical to rsnWait_to_idle */
484 return rsnWait_to_waitToDisconnCmplt(pConn);
485 }
486
487
488
489
490
491 /***********************************************************************
492 * idle_to_selfWait
493 ***********************************************************************
494 DESCRIPTION:
495
496
497 INPUT:
498
499 OUTPUT:
500
501 RETURN: TI_OK on success, TI_NOK otherwise
502
503 ************************************************************************/
idle_to_selfWait(void * pData)504 static TI_STATUS idle_to_selfWait (void *pData)
505 {
506 conn_t *pConn = (conn_t *)pData;
507 TI_UINT16 randomTime;
508
509 siteMgr_join (pConn->hSiteMgr);
510
511 /* get a randomTime that is constructed of the lower 13 bits ot the system time to
512 get a MS random time of ~8000 ms */
513 randomTime = os_timeStampMs (pConn->hOs) & 0x1FFF;
514
515 /* Update current BSS connection type and mode */
516 currBSS_updateConnectedState (pConn->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
517
518 tmr_StartTimer (pConn->hConnTimer,
519 conn_timeout,
520 (TI_HANDLE)pConn,
521 pConn->timeout + randomTime,
522 TI_FALSE);
523
524 /* Notify that the driver is associated to the supplicant\IP stack. */
525 EvHandlerSendEvent (pConn->hEvHandler, IPC_EVENT_ASSOCIATED, NULL, 0);
526
527 return TI_OK;
528 }
529
530
531
532 /***********************************************************************
533 * idle_to_rsnWait
534 ***********************************************************************
535 DESCRIPTION:
536
537
538 INPUT:
539
540 OUTPUT:
541
542 RETURN: TI_OK on success, TI_NOK otherwise
543
544 ************************************************************************/
idle_to_rsnWait(void * pData)545 static TI_STATUS idle_to_rsnWait(void *pData)
546 {
547 paramInfo_t param;
548
549 siteMgr_join(((conn_t *)pData)->hSiteMgr);
550
551 param.paramType = RX_DATA_PORT_STATUS_PARAM;
552 param.content.rxDataPortStatus = OPEN_EAPOL;
553 rxData_setParam(((conn_t *)pData)->hRxData, ¶m);
554
555 /* Update TxMgmtQueue SM to enable EAPOL packets. */
556 txMgmtQ_SetConnState (((conn_t *)pData)->hTxMgmtQ, TX_CONN_STATE_EAPOL);
557
558 /*
559 * Notify that the driver is associated to the supplicant\IP stack.
560 */
561 EvHandlerSendEvent(((conn_t *)pData)->hEvHandler, IPC_EVENT_ASSOCIATED, NULL,0);
562
563 /* Update current BSS connection type and mode */
564 currBSS_updateConnectedState(((conn_t *)pData)->hCurrBss, TI_TRUE, BSS_INDEPENDENT);
565
566 return rsn_start(((conn_t *)pData)->hRsn);
567 }
568
569