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 ************************************************************************/ 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 ************************************************************************/ 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 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 ************************************************************************/ 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 ************************************************************************/ 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 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 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 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 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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 ************************************************************************/ 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