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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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, ¶m); 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