PageRenderTime 54ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/common/src/Application/Roaming/roamingMngr.c

http://github.com/CyanogenMod/cm-kernel
C | 1674 lines | 988 code | 219 blank | 467 comment | 120 complexity | f2b685a04c18200937d7b92c6aca664a MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.0
  1. /***************************************************************************
  2. **+-----------------------------------------------------------------------+**
  3. **| |**
  4. **| Copyright(c) 1998 - 2008 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. * *
  37. * MODULE: Roaming Manager *
  38. * PURPOSE: *
  39. * Roaming manager is responsible to receive Roaming triggers and try
  40. * to select a better AP.
  41. * The Roaming triggers are: Low RSSI, PER, consecutive No ACK on TX,
  42. * beacon Missed or External request.
  43. * In each Internal Roaming request, scan is performed and selection for
  44. * better AP. Better AP is defined as a different AP with better RSSI,
  45. * and similar SSID and security settings.
  46. * If better AP is found, there is a check for fast-roaming via the
  47. * Supplicant. Then connection to the new AP is invoked.
  48. * *
  49. ****************************************************************************/
  50. #include "osApi.h"
  51. #include "paramOut.h"
  52. #include "report.h"
  53. #include "fsm.h"
  54. #include "utils.h"
  55. #include "scanMngrApi.h"
  56. #include "roamingMngrApi.h"
  57. #include "apConnApi.h"
  58. #include "roamingMngrTypes.h"
  59. #include "bssTypes.h"
  60. /* Constants */
  61. /* Init bits */
  62. #define ROAMING_MNGR_CONTEXT_INIT_BIT 1
  63. #define ROAMING_MNGR_SM_INIT_BIT 2
  64. #define DEFAULT_AP_QUALITY (-70)
  65. #define DEFAULT_LOW_PASS_FILTER (30)
  66. #define DEFAULT_DATA_RETRY_THRESHOLD (20)
  67. #define DEFAULT_LOW_QUALITY_SCAN_COND (-60)
  68. #define DEFAULT_NORMAL_QUALITY_SCAN_COND (-50)
  69. #define DEFAULT_LOW_RSSI (-70)
  70. #define DEFAULT_LOW_SNR (0)
  71. #define DEFAULT_TBTT_4_BSS_LOSS (10)
  72. #define DEFAULT_LOW_TX_RATE (2)
  73. /* Enumerations */
  74. /** state machine states */
  75. typedef enum
  76. {
  77. ROAMING_STATE_IDLE = 0,
  78. ROAMING_STATE_WAIT_4_TRIGGER = 1,
  79. ROAMING_STATE_WAIT_4_CMD = 2,
  80. ROAMING_STATE_SCANNING = 3,
  81. ROAMING_STATE_SELECTING = 4,
  82. ROAMING_STATE_CONNECTING = 5,
  83. ROAMING_STATE_LAST = 6
  84. } roamingMngr_smStates;
  85. /** State machine events */
  86. typedef enum
  87. {
  88. ROAMING_EVENT_START = 0, /* CONNECTED */
  89. ROAMING_EVENT_STOP = 1, /* NOT CONNECTED */
  90. ROAMING_EVENT_ROAM_TRIGGER = 2,
  91. ROAMING_EVENT_SCAN = 3,
  92. ROAMING_EVENT_SELECT = 4,
  93. ROAMING_EVENT_REQ_HANDOVER = 5,
  94. ROAMING_EVENT_ROAM_SUCCESS = 6,
  95. ROAMING_EVENT_FAILURE = 7,
  96. ROAMING_EVENT_LAST = 8
  97. } roamingMngr_smEvents;
  98. /* scan types */
  99. typedef enum
  100. {
  101. ROAMING_NO_SCAN,
  102. ROAMING_PARTIAL_SCAN,
  103. ROAMING_PARTIAL_SCAN_RETRY,
  104. ROAMING_FULL_SCAN,
  105. ROAMING_FULL_SCAN_RETRY
  106. } scan4RoamingType_e;
  107. /* Roaming Trigger groups, according to Roaming Triggers */
  108. typedef enum
  109. {
  110. ROAMING_TRIGGER_BG_SCAN_GROUP = ROAMING_TRIGGER_NORMAL_QUALITY_FOR_BG_SCAN,
  111. ROAMING_TRIGGER_LOW_QUALITY_GROUP = ROAMING_TRIGGER_MAX_TX_RETRIES,
  112. ROAMING_TRIGGER_FAST_CONNECT_GROUP = ROAMING_TRIGGER_SWITCH_CHANNEL,
  113. ROAMING_TRIGGER_FULL_CONNECT_GROUP = ROAMING_TRIGGER_SECURITY_ATTACK
  114. } roamingMngr_connectTypeGroup_e;
  115. #define ROAMING_MNGR_NUM_STATES ROAMING_STATE_LAST
  116. #define ROAMING_MNGR_NUM_EVENTS ROAMING_EVENT_LAST
  117. #define INVALID_CANDIDATE_INDEX 0xFF
  118. #define CURRENT_AP_INDEX 0xFE
  119. /* Typedefs */
  120. typedef struct _roamingMngr_t roamingMngr_t;
  121. /* Structures */
  122. typedef struct
  123. {
  124. UINT8 preAuthBSSList[MAX_SIZE_OF_BSS_TRACK_LIST];
  125. UINT8 numOfPreAuthBSS;
  126. UINT8 neighborBSSList[MAX_SIZE_OF_BSS_TRACK_LIST];
  127. UINT8 numOfNeighborBSS;
  128. UINT8 regularBSSList[MAX_SIZE_OF_BSS_TRACK_LIST];
  129. UINT8 numOfRegularBSS;
  130. } listOfCandidateAps_t;
  131. #define MAX_ROAMING_TRIGGERS ROAMING_TRIGGER_LAST
  132. struct _roamingMngr_t
  133. {
  134. /*** Roaming manager parameters that can be configured externally ***/
  135. roamingMngrConfig_t roamingMngrConfig;
  136. roamingMngrThresholdsConfig_t roamingMngrThresholdsConfig;
  137. UINT32 lowPassFilterRoamingAttemptInMsec;
  138. /*** Internal roaming parameters ***/
  139. /* the roaming trigger type */
  140. apConn_roamingTrigger_e roamingTrigger;
  141. /* Roaming SM current state */
  142. roamingMngr_smStates currentState;
  143. /* Indicate if a trigger is already in process, and therefore the
  144. other triggers will be ignored */
  145. BOOL maskRoamingEvents;
  146. /* TS to filter Too many low Quality roaming triggers */
  147. UINT32 lowQualityTriggerTimestamp;
  148. /* the scan type performed for Roaming */
  149. scan4RoamingType_e scanType;
  150. /* list of BSS received from Scan Manager */
  151. bssList_t *pListOfAPs;
  152. /* Indicating if Neighbor APs exist */
  153. BOOL neighborApsExist;
  154. /* a list of the candiadte APs indexes in pListOfAPs according to
  155. neighbor APs, pre-auth APs and other APs */
  156. listOfCandidateAps_t listOfCandidateAps;
  157. /* The current candidate AP's index to Roam to */
  158. UINT8 candidateApIndex;
  159. /* Indicates whether at least one handover was performed */
  160. BOOL handoverWasPerformed;
  161. /* The station capabilities for the current Connection */
  162. apConn_staCapabilities_t staCapabilities;
  163. /* Roaming manager SM */
  164. fsm_stateMachine_t *pRoamingSm;
  165. /* Roaming manager handles to other objects */
  166. TI_HANDLE hReport;
  167. TI_HANDLE hOs;
  168. TI_HANDLE hScanMngr;
  169. TI_HANDLE hAPConnection;
  170. #ifdef TI_DBG
  171. /* Debug trace for Roaming statistics */
  172. UINT32 roamingTriggerEvents[MAX_ROAMING_TRIGGERS];
  173. UINT32 roamingHandoverEvents[MAX_ROAMING_TRIGGERS];
  174. UINT32 roamingSuccesfulHandoverNum;
  175. UINT32 roamingFailedHandoverNum;
  176. UINT32 roamingTriggerTimestamp;
  177. UINT32 roamingHandoverStartedTimestamp;
  178. UINT32 roamingHandoverCompletedTimestamp;
  179. UINT32 roamingAverageSuccHandoverDuration;
  180. UINT32 roamingAverageRoamingDuration;
  181. #endif
  182. };
  183. /* External data definitions */
  184. /* Local functions definitions */
  185. /* Global variables */
  186. #ifdef REPORT_LOG
  187. static char *roamingMngr_stateDesc[ROAMING_MNGR_NUM_STATES] = {
  188. "STATE_IDLE",
  189. "STATE_WAIT_4_TRIGGER",
  190. "STATE_WAIT_4_CMD",
  191. "STATE_SCANNING",
  192. "STATE_SELECTING",
  193. "CONNECTING"
  194. };
  195. static char *roamingMngr_eventDesc[ROAMING_MNGR_NUM_EVENTS] = {
  196. "EVENT_START",
  197. "EVENT_STOP",
  198. "EVENT_ROAM_TRIGGER",
  199. "EVENT_SCAN",
  200. "EVENT_SELECT",
  201. "EVENT_REQ_HANDOVER",
  202. "EVENT_ROAM_SUCCESS",
  203. "EVENT_FAILURE"
  204. };
  205. #endif
  206. /* Function prototypes */
  207. /* SM functions */
  208. static TI_STATUS roamingMngr_smEvent(UINT8 *currState, UINT8 event, void* data);
  209. static TI_STATUS roamingMngr_smUnexpected(void *pData);
  210. static TI_STATUS roamingMngr_smNop(void *pData);
  211. static TI_STATUS roamingMngr_smStartIdle(void *pData);
  212. static TI_STATUS roamingMngr_smStop(void *pData);
  213. static TI_STATUS roamingMngr_smStopWhileScanning(void *pData);
  214. static TI_STATUS roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr);
  215. static TI_STATUS roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr);
  216. static TI_STATUS roamingMngr_smSelection(TI_HANDLE hRoamingMngr);
  217. static TI_STATUS roamingMngr_smHandover(TI_HANDLE hRoamingMngr);
  218. static TI_STATUS roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr);
  219. static TI_STATUS roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr);
  220. static TI_STATUS roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr);
  221. static TI_STATUS roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr);
  222. /************** callback funtions called by AP Connection **************/
  223. /* called when a trigger for Roaming occurs */
  224. TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData);
  225. /* called when CONN status event occurs */
  226. TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData);
  227. /* called when Neighbor APs is updated */
  228. TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData);
  229. /* internal functions */
  230. static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, UINT32 initVec);
  231. #ifdef TI_DBG
  232. /* debug function */
  233. static void roamingMngr_printStatistics(TI_HANDLE hRoamingMngr);
  234. static void roamingMngr_resetStatistics(TI_HANDLE hRoamingMngr);
  235. #endif
  236. /**
  237. *
  238. * roamingMngr_create
  239. *
  240. * \b Description:
  241. *
  242. * Create the Roaming Manager context.
  243. *
  244. * \b ARGS:
  245. *
  246. * I - hOs - OS handler \n
  247. *
  248. * \b RETURNS:
  249. *
  250. * OK on success, NOK on failure.
  251. *
  252. * \sa
  253. */
  254. TI_HANDLE roamingMngr_create(TI_HANDLE hOs)
  255. {
  256. TI_STATUS status;
  257. roamingMngr_t *pRoamingMngr;
  258. UINT32 initVec;
  259. initVec = 0;
  260. pRoamingMngr = os_memoryAlloc(hOs, sizeof(roamingMngr_t));
  261. if (pRoamingMngr == NULL)
  262. return NULL;
  263. initVec |= (1 << ROAMING_MNGR_CONTEXT_INIT_BIT);
  264. pRoamingMngr->hOs = hOs;
  265. status = fsm_Create(hOs, &pRoamingMngr->pRoamingSm, ROAMING_MNGR_NUM_STATES, ROAMING_MNGR_NUM_EVENTS);
  266. if (status != OK)
  267. {
  268. roamingMngr_releaseModule(pRoamingMngr, initVec);
  269. WLAN_OS_REPORT(("FATAL ERROR: roamingMngr_create(): Error Creating pRoamingSm - Aborting\n"));
  270. return NULL;
  271. }
  272. initVec |= (1 << ROAMING_MNGR_SM_INIT_BIT);
  273. return pRoamingMngr;
  274. }
  275. /**
  276. *
  277. * roamingMngr_releaseModule
  278. *
  279. * \b Description:
  280. *
  281. * Called by the un load function
  282. * Go over the vector, for each bit that is set, release the corresponding module.
  283. *
  284. * \b ARGS:
  285. *
  286. * I - pRoamingMngr - Roaming Manager context \n
  287. * I - initVec - indicates which modules should be released
  288. *
  289. * \b RETURNS:
  290. *
  291. * OK if successful, NOK otherwise.
  292. *
  293. * \sa roamingMngr_create
  294. */
  295. static void roamingMngr_releaseModule(roamingMngr_t *pRoamingMngr, UINT32 initVec)
  296. {
  297. if (pRoamingMngr==NULL)
  298. {
  299. return;
  300. }
  301. if (initVec & (1 << ROAMING_MNGR_SM_INIT_BIT))
  302. {
  303. fsm_Unload(pRoamingMngr->hOs, pRoamingMngr->pRoamingSm);
  304. }
  305. if (initVec & (1 << ROAMING_MNGR_CONTEXT_INIT_BIT))
  306. {
  307. utils_nullMemoryFree(pRoamingMngr->hOs, pRoamingMngr, sizeof(roamingMngr_t));
  308. }
  309. initVec = 0;
  310. }
  311. /**
  312. *
  313. * roamingMngr_unload
  314. *
  315. * \b Description:
  316. *
  317. * Unload Roaming Manager module from memory
  318. *
  319. * \b ARGS:
  320. *
  321. * I - hAdmCtrl - Roaming Manager context \n
  322. *
  323. * \b RETURNS:
  324. *
  325. * OK if successful, NOK otherwise.
  326. *
  327. * \sa roamingMngr_create
  328. */
  329. TI_STATUS roamingMngr_unload(TI_HANDLE hRoamingMngr)
  330. {
  331. UINT32 initVec;
  332. if (hRoamingMngr == NULL)
  333. {
  334. return OK;
  335. }
  336. initVec = 0xFFFF;
  337. roamingMngr_releaseModule(hRoamingMngr, initVec);
  338. return OK;
  339. }
  340. /**
  341. *
  342. * roamingMngr_config
  343. *
  344. * \b Description:
  345. *
  346. * Configure the Roaming Manager module.
  347. *
  348. * \b ARGS:
  349. *
  350. * I - hRoamingMngr - Roaming Manager context \n
  351. * I - hReport - Report context \n
  352. * I - hOs - OS context \n
  353. * I - hSiteMgr - Site Manager context \n
  354. * I - hSmeSm - SME context \n
  355. * I - hCtrlData - Control Data context \n
  356. * I - hPowerMgr - Power Manager context \n
  357. * I - pRoamingParams - init roaming parameters read from the registry \n
  358. *
  359. * \b RETURNS:
  360. *
  361. * OK on success, NOK on failure.
  362. *
  363. * \sa
  364. */
  365. TI_STATUS roamingMngr_init(TI_HANDLE hRoamingMngr,
  366. TI_HANDLE hReport,
  367. TI_HANDLE hScanMngr,
  368. TI_HANDLE hAPConnection)
  369. {
  370. roamingMngr_t *pRoamingMngr;
  371. TI_STATUS status;
  372. #ifdef ENABLE_ROAMING_BY_DEFAULT
  373. roamingMngrConfigParams_t InitRoamingParams;
  374. paramInfo_t param;
  375. #endif
  376. #ifdef TI_DBG
  377. UINT8 index;
  378. #endif
  379. /** Station broadcast key State Machine matrix */
  380. fsm_actionCell_t roamingMngr_matrix[ROAMING_MNGR_NUM_STATES][ROAMING_MNGR_NUM_EVENTS] =
  381. {
  382. /* next state and actions for IDLE state */
  383. { {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smStartIdle}, /* START */
  384. {ROAMING_STATE_IDLE, roamingMngr_smNop}, /* STOP */
  385. {ROAMING_STATE_IDLE, roamingMngr_smNop}, /* ROAM_TRIGGER */
  386. {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* SCAN */
  387. {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* SELECT */
  388. {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
  389. {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
  390. {ROAMING_STATE_IDLE, roamingMngr_smUnexpected} /* FAILURE */
  391. },
  392. /* next state and actions for WAIT_4_TRIGGER state */
  393. { {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* START */
  394. {ROAMING_STATE_IDLE, roamingMngr_smStop}, /* STOP */
  395. {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smRoamTrigger}, /* ROAM_TRIGGER */
  396. {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* SCAN */
  397. {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* SELECT */
  398. {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
  399. {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
  400. {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected} /* FAILURE */
  401. },
  402. /* next state and actions for WAIT_4_CMD state */
  403. { {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* START */
  404. {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* STOP */
  405. {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* ROAM_TRIGGER */
  406. {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan}, /* SCAN */
  407. {ROAMING_STATE_SELECTING, roamingMngr_smSelection}, /* SELECT */
  408. {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
  409. {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
  410. {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected} /* FAILURE */
  411. },
  412. /* next state and actions for SCANNING state */
  413. { {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected}, /* START */
  414. {ROAMING_STATE_IDLE, roamingMngr_smStopWhileScanning}, /* STOP */
  415. {ROAMING_STATE_SCANNING, roamingMngr_smNop}, /* ROAM_TRIGGER */
  416. {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan}, /* SCAN */
  417. {ROAMING_STATE_SELECTING, roamingMngr_smSelection}, /* SELECT */
  418. {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
  419. {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
  420. {ROAMING_STATE_IDLE, roamingMngr_smScanFailure} /* FAILURE */
  421. },
  422. /* next state and actions for SELECTING state */
  423. { {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* START */
  424. {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* STOP */
  425. {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* ROAM_TRIGGER */
  426. {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* SCAN */
  427. {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* SELECT */
  428. {ROAMING_STATE_CONNECTING, roamingMngr_smHandover}, /* REQ_HANDOVER */
  429. {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
  430. {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected} /* FAILURE */
  431. },
  432. /* next state and actions for CONNECTING state */
  433. { {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected}, /* START */
  434. {ROAMING_STATE_IDLE, roamingMngr_smStop}, /* STOP */
  435. {ROAMING_STATE_IDLE, roamingMngr_smDisconnectWhileConnecting}, /* ROAM_TRIGGER */
  436. {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected}, /* SCAN, */
  437. {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected}, /* SELECT */
  438. {ROAMING_STATE_CONNECTING, roamingMngr_smHandover}, /* REQ_HANDOVER */
  439. {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smSuccHandover} , /* ROAM_SUCCESS */
  440. {ROAMING_STATE_IDLE, roamingMngr_smFailHandover} /* FAILURE */
  441. }
  442. };
  443. if (hRoamingMngr == NULL)
  444. {
  445. return NOK;
  446. }
  447. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  448. /* Update handlers */
  449. pRoamingMngr->hReport = hReport;
  450. pRoamingMngr->hScanMngr = hScanMngr;
  451. pRoamingMngr->hAPConnection = hAPConnection;
  452. /* Init intrenal variables */
  453. pRoamingMngr->currentState = ROAMING_STATE_IDLE;
  454. pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
  455. pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
  456. pRoamingMngr->maskRoamingEvents= TRUE;
  457. pRoamingMngr->scanType = ROAMING_NO_SCAN;
  458. pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
  459. pRoamingMngr->handoverWasPerformed = FALSE;
  460. pRoamingMngr->lowQualityTriggerTimestamp = 0;
  461. pRoamingMngr->neighborApsExist = FALSE;
  462. pRoamingMngr->pListOfAPs = NULL;
  463. pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
  464. pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
  465. pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
  466. pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;
  467. #ifdef TI_DBG
  468. /* debug counters */
  469. pRoamingMngr->roamingSuccesfulHandoverNum = 0;
  470. pRoamingMngr->roamingHandoverStartedTimestamp = 0;
  471. pRoamingMngr->roamingHandoverCompletedTimestamp = 0;
  472. pRoamingMngr->roamingAverageSuccHandoverDuration = 0;
  473. pRoamingMngr->roamingAverageRoamingDuration = 0;
  474. pRoamingMngr->roamingFailedHandoverNum = 0;
  475. for (index=ROAMING_TRIGGER_NONE; index<ROAMING_TRIGGER_LAST; index++)
  476. {
  477. pRoamingMngr->roamingTriggerEvents[index] = 0;
  478. pRoamingMngr->roamingHandoverEvents[index] = 0;
  479. }
  480. #endif
  481. /* config the FSM */
  482. status = fsm_Config(pRoamingMngr->pRoamingSm,
  483. &roamingMngr_matrix[0][0],
  484. ROAMING_MNGR_NUM_STATES,
  485. ROAMING_MNGR_NUM_EVENTS,
  486. roamingMngr_smEvent, pRoamingMngr->hOs);
  487. #ifdef ENABLE_ROAMING_BY_DEFAULT
  488. if (status != OK)
  489. {
  490. return status;
  491. }
  492. param.paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
  493. param.content.applicationConfigBuffer.bufferSize = sizeof(roamingMngrConfigParams_t);
  494. param.content.applicationConfigBuffer.buffer = (UINT8 *)&param;
  495. InitRoamingParams.roamingMngrConfig.enableDisable = ROAMING_ENABLED;
  496. InitRoamingParams.roamingMngrConfig.lowPassFilterRoamingAttempt = 30;
  497. InitRoamingParams.roamingMngrConfig.apQualityThreshold = -70;
  498. InitRoamingParams.roamingMngrThresholdsConfig.dataRetryThreshold = 20;
  499. InitRoamingParams.roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss = 10;
  500. InitRoamingParams.roamingMngrThresholdsConfig.txRateThreshold = 2;
  501. InitRoamingParams.roamingMngrThresholdsConfig.lowRssiThreshold = -80;
  502. InitRoamingParams.roamingMngrThresholdsConfig.lowSnrThreshold = 0;
  503. InitRoamingParams.roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition = -60;
  504. InitRoamingParams.roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition = -50;
  505. InitRoamingParams.roamingMngrThresholdsConfig.rssiFilterWeight = 10;
  506. InitRoamingParams.roamingMngrThresholdsConfig.snrFilterWeight = 10;
  507. param.paramType = ROAMING_MNGR_APPLICATION_CONFIGURATION;
  508. param.content.applicationConfigBuffer.bufferSize = sizeof(roamingMngrConfigParams_t);
  509. param.content.applicationConfigBuffer.buffer = (UINT8 *)&InitRoamingParams;
  510. roamingMngr_setParam (hRoamingMngr,&param);
  511. #endif
  512. return status;
  513. }
  514. /* For debug */
  515. extern TI_STATUS apConn_reportRoamingEvent(TI_HANDLE hAPConnection,apConn_roamingTrigger_e roamingEventType,void *pRoamingEventData);
  516. /**
  517. *
  518. * roamingMngr_setParam - Set a specific parameter to the roamingMngr SM
  519. *
  520. * \b Description:
  521. *
  522. * Set a specific parameter to the roamingMngr SM.
  523. *
  524. * \b ARGS:
  525. *
  526. * I - hRoamingMngr - roamingMngr SM context \n
  527. * I/O - pParam - Parameter \n
  528. *
  529. * \b RETURNS:
  530. *
  531. * OK if successful, NOK otherwise.
  532. *
  533. *
  534. */
  535. TI_STATUS roamingMngr_setParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
  536. {
  537. roamingMngr_t *pRoamingMngr;
  538. TI_STATUS status=OK;
  539. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  540. if ((hRoamingMngr == NULL) || (pParam == NULL))
  541. {
  542. return NOK;
  543. }
  544. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  545. ("roamingMngr_setParam %X \n",
  546. pParam->paramType));
  547. switch (pParam->paramType)
  548. {
  549. case ROAMING_MNGR_APPLICATION_CONFIGURATION:
  550. {
  551. roamingMngrConfigParams_t *pRoamingMngrConfigParams;
  552. if (pParam->content.applicationConfigBuffer.bufferSize < sizeof(roamingMngrConfigParams_t))
  553. {
  554. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  555. ("roamingMngr_setParam bad size = %d \n",
  556. pParam->content.applicationConfigBuffer.bufferSize));
  557. return NOK;
  558. }
  559. pRoamingMngrConfigParams = (roamingMngrConfigParams_t*)pParam->content.applicationConfigBuffer.buffer;
  560. /* Configure the Roaming Parmeters */
  561. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,("roamingMngr_setParam Configuration: \n \
  562. enableDisable= %d,\n lowPassFilterRoamingAttempt=%d,\n \
  563. apQualityThreshold=%d\n",
  564. pRoamingMngrConfigParams->roamingMngrConfig.enableDisable,
  565. pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt,
  566. pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold));
  567. pRoamingMngr->roamingMngrConfig.apQualityThreshold = pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold;
  568. pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt;
  569. pRoamingMngr->lowPassFilterRoamingAttemptInMsec = pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt * 1000;
  570. /* Configure the Roaming Trigger thresholds */
  571. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,("roamingMngr_setParam Thresholds: \n \
  572. dataRetryThreshold= %d,\n lowQualityForBackgroungScanCondition=%d,\n \
  573. lowRssiThreshold=%d,\n lowSNRThreshold=%d,\n \
  574. normalQualityForBackgroungScanCondition=%d,\n \
  575. numExpectedTbttForBSSLoss=%d,\n txRateThreshold=%d \n \n",
  576. pRoamingMngrConfigParams->roamingMngrThresholdsConfig.dataRetryThreshold,
  577. pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowQualityForBackgroungScanCondition,
  578. pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowRssiThreshold,
  579. pRoamingMngrConfigParams->roamingMngrThresholdsConfig.lowSnrThreshold, pRoamingMngrConfigParams->roamingMngrThresholdsConfig.normalQualityForBackgroungScanCondition,
  580. pRoamingMngrConfigParams->roamingMngrThresholdsConfig.numExpectedTbttForBSSLoss,
  581. pRoamingMngrConfigParams->roamingMngrThresholdsConfig.txRateThreshold));
  582. os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngr->roamingMngrThresholdsConfig, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));
  583. status = apConn_setRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig);
  584. if (pRoamingMngr->roamingMngrConfig.enableDisable &&
  585. !pRoamingMngrConfigParams->roamingMngrConfig.enableDisable)
  586. { /* disable Roaming Manager */
  587. apConn_unregisterRoamMngrCallb(pRoamingMngr->hAPConnection);
  588. pRoamingMngr->roamingMngrConfig.enableDisable = ROAMING_DISABLED;
  589. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_STOP, pRoamingMngr));
  590. }
  591. else if (!pRoamingMngr->roamingMngrConfig.enableDisable &&
  592. pRoamingMngrConfigParams->roamingMngrConfig.enableDisable)
  593. { /* enable Roaming Manager */
  594. /* Save the Roaming Configuration parameters */
  595. pRoamingMngr->roamingMngrConfig.enableDisable = pRoamingMngrConfigParams->roamingMngrConfig.enableDisable;
  596. /* register Roaming callback */
  597. apConn_registerRoamMngrCallb(pRoamingMngr->hAPConnection,
  598. roamingMngr_triggerRoamingCb,
  599. roamingMngr_connStatusCb,
  600. roamingMngr_updateNeighborApListCb);
  601. }
  602. }
  603. break;
  604. /*********** For Debug Purposes ***********/
  605. case ROAMING_MNGR_TRIGGER_EVENT:
  606. /* Enable/disable Internal Roaming */
  607. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  608. ("roamingMngr_setParam TRIGGER_EVENT= %d \n",
  609. pParam->content.roamingTriggerType));
  610. if ((apConn_roamingTrigger_e)pParam->content.roamingTriggerType == ROAMING_TRIGGER_AP_DISCONNECT)
  611. {
  612. /* DeAuth packet with status code of deauth/disassoc packet equal to 1 */
  613. apConn_reportRoamingEventDisconnect(pRoamingMngr->hAPConnection ,1 ,TRUE);
  614. }
  615. else
  616. {
  617. apConn_reportRoamingEvent(pRoamingMngr->hAPConnection, (apConn_roamingTrigger_e)pParam->content.roamingTriggerType, NULL);
  618. }
  619. break;
  620. case ROAMING_MNGR_CONN_STATUS:
  621. /* External request to connect to BBSID */
  622. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  623. ("roamingMngr_setParam CONN_STATUS= %d \n",
  624. pParam->content.roamingConnStatus));
  625. roamingMngr_connStatusCb(pRoamingMngr, &pParam->content.roamingConnStatus);
  626. break;
  627. default:
  628. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  629. ("roamingMngr_setParam bad param= %X\n",
  630. pParam->paramType));
  631. break;
  632. }
  633. return status;
  634. }
  635. /**
  636. *
  637. * roamingMngr_getParam - Get a specific parameter from the roamingMngr SM
  638. *
  639. * \b Description:
  640. *
  641. * Get a specific parameter from the roamingMngr SM.
  642. *
  643. * \b ARGS:
  644. *
  645. * I - hRoamingMngr - roamingMngr SM context \n
  646. * I/O - pParam - Parameter \n
  647. *
  648. * \b RETURNS:
  649. *
  650. * OK if successful, NOK otherwise.
  651. *
  652. *
  653. */
  654. TI_STATUS roamingMngr_getParam(TI_HANDLE hRoamingMngr, paramInfo_t *pParam)
  655. {
  656. roamingMngr_t *pRoamingMngr;
  657. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  658. if ((hRoamingMngr == NULL) || (pParam == NULL))
  659. {
  660. return NOK;
  661. }
  662. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  663. ("roamingMngr_getParam %X \n",
  664. pParam->paramType));
  665. switch (pParam->paramType)
  666. {
  667. case ROAMING_MNGR_APPLICATION_CONFIGURATION:
  668. {
  669. roamingMngrConfigParams_t *pRoamingMngrConfigParams;
  670. pRoamingMngrConfigParams = (roamingMngrConfigParams_t *)&pParam->content.roamingConfigBuffer;
  671. if (pRoamingMngr->roamingMngrConfig.enableDisable == ROAMING_DISABLED)
  672. {
  673. pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = FALSE;
  674. }
  675. else
  676. {
  677. pRoamingMngrConfigParams->roamingMngrConfig.enableDisable = TRUE;
  678. }
  679. pRoamingMngrConfigParams->roamingMngrConfig.apQualityThreshold = pRoamingMngr->roamingMngrConfig.apQualityThreshold;
  680. pRoamingMngrConfigParams->roamingMngrConfig.lowPassFilterRoamingAttempt = pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt;
  681. apConn_getRoamThresholds(pRoamingMngr->hAPConnection, &pRoamingMngr->roamingMngrThresholdsConfig);
  682. os_memoryCopy(pRoamingMngr->hOs, &pRoamingMngrConfigParams->roamingMngrThresholdsConfig, &pRoamingMngr->roamingMngrThresholdsConfig, sizeof(roamingMngrThresholdsConfig_t));
  683. pParam->paramLength = sizeof(roamingMngrConfigParams_t);
  684. }
  685. break;
  686. case ROAMING_MNGR_CONF_PARAM:
  687. WLAN_OS_REPORT(("Roaming is: %s \n", pRoamingMngr->roamingMngrConfig.enableDisable ? "Enabled" : "Disabled"));
  688. WLAN_OS_REPORT(("lowPassFilterRoamingAttempt = %d msec, apQualityThreshold = %d\n",
  689. pRoamingMngr->roamingMngrConfig.lowPassFilterRoamingAttempt,
  690. pRoamingMngr->roamingMngrConfig.apQualityThreshold));
  691. break;
  692. #ifdef TI_DBG
  693. case ROAMING_MNGR_PRINT_STATISTICS:
  694. roamingMngr_printStatistics(pRoamingMngr);
  695. break;
  696. case ROAMING_MNGR_RESET_STATISTICS:
  697. roamingMngr_resetStatistics(pRoamingMngr);
  698. break;
  699. case ROAMING_MNGR_PRINT_CURRENT_STATUS:
  700. WLAN_OS_REPORT(("Roaming Current State = %s, enableDisable=%d\n, maskRoamingEvents = %d, roamingTrigger=%d \n scanType=%d, handoverWasPerformed=%d \n, candidateApIndex=%d, lowQualityTriggerTimestamp=%d \n",
  701. roamingMngr_stateDesc[pRoamingMngr->currentState],
  702. pRoamingMngr->roamingMngrConfig.enableDisable,
  703. pRoamingMngr->maskRoamingEvents,
  704. pRoamingMngr->roamingTrigger,
  705. pRoamingMngr->scanType,
  706. pRoamingMngr->handoverWasPerformed,
  707. pRoamingMngr->candidateApIndex,
  708. pRoamingMngr->lowQualityTriggerTimestamp));
  709. break;
  710. case ROAMING_MNGR_PRINT_CANDIDATE_TABLE:
  711. {
  712. UINT32 index;
  713. if (pRoamingMngr->pListOfAPs==NULL)
  714. {
  715. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  716. ("Roaming Mngr the candidate AP list is invalid \n") );
  717. break;
  718. }
  719. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  720. ("The number of candidates is %d\n",
  721. pRoamingMngr->pListOfAPs->numOfEntries) );
  722. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  723. ("Roaming Mngr Neighbor AP list, num of candidates = %d\n",
  724. pRoamingMngr->listOfCandidateAps.numOfNeighborBSS) );
  725. for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfNeighborBSS; index++)
  726. {
  727. UINT32 candidateIndex;
  728. bssEntry_t *pBssEntry;
  729. candidateIndex = pRoamingMngr->listOfCandidateAps.neighborBSSList[index];
  730. pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
  731. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  732. ("candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n",
  733. candidateIndex, pBssEntry->BSSID.addr[0],
  734. pBssEntry->BSSID.addr[1], pBssEntry->BSSID.addr[2],
  735. pBssEntry->BSSID.addr[3], pBssEntry->BSSID.addr[4],
  736. pBssEntry->BSSID.addr[5], pBssEntry->RSSI) );
  737. }
  738. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  739. ("Roaming Mngr Pre-Auth AP list, num of candidates = %d\n",
  740. pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS) );
  741. for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS; index++)
  742. {
  743. UINT32 candidateIndex;
  744. bssEntry_t *pBssEntry;
  745. candidateIndex = pRoamingMngr->listOfCandidateAps.preAuthBSSList[index];
  746. pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
  747. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  748. ("candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n",
  749. candidateIndex, pBssEntry->BSSID.addr[0],
  750. pBssEntry->BSSID.addr[1], pBssEntry->BSSID.addr[2],
  751. pBssEntry->BSSID.addr[3], pBssEntry->BSSID.addr[4],
  752. pBssEntry->BSSID.addr[5], pBssEntry->RSSI) );
  753. }
  754. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  755. ("Roaming Mngr Regular AP list, num of candidates = %d\n",
  756. pRoamingMngr->listOfCandidateAps.numOfRegularBSS) );
  757. for (index=0; index<pRoamingMngr->listOfCandidateAps.numOfRegularBSS; index++)
  758. {
  759. UINT32 candidateIndex;
  760. bssEntry_t *pBssEntry;
  761. candidateIndex = pRoamingMngr->listOfCandidateAps.regularBSSList[index];
  762. pBssEntry = &pRoamingMngr->pListOfAPs->BSSList[candidateIndex];
  763. WLAN_REPORT_INFORMATION( pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  764. ("candiate %d, BSSID=%x-%x-%x-%x-%x-%x, RSSI =%d \n",
  765. candidateIndex, pBssEntry->BSSID.addr[0],
  766. pBssEntry->BSSID.addr[1], pBssEntry->BSSID.addr[2],
  767. pBssEntry->BSSID.addr[3], pBssEntry->BSSID.addr[4],
  768. pBssEntry->BSSID.addr[5], pBssEntry->RSSI) );
  769. }
  770. }
  771. break;
  772. #endif /*TI_DBG*/
  773. default:
  774. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  775. ("roamingMngr_getParam bad paramType= %X \n",
  776. pParam->paramType));
  777. return NOK;
  778. }
  779. return OK;
  780. }
  781. /**
  782. *
  783. * roamingMngr_triggerRoamingCb
  784. *
  785. * \b Description:
  786. *
  787. * This procedure is called when Roaming should be triggered
  788. * due to one of apConn_roamingTrigger_e Roaming Reasons.
  789. * Save the trigger and process it only if there's no other Roaming trigger
  790. * in process.
  791. *
  792. * \b ARGS:
  793. *
  794. * I - hRoamingMngr - roamingMngr SM context \n
  795. * I - pData - pointer to roaming trigger
  796. *
  797. * \b RETURNS:
  798. *
  799. * OK if successful, NOK otherwise.
  800. *
  801. *
  802. */
  803. TI_STATUS roamingMngr_triggerRoamingCb(TI_HANDLE hRoamingMngr, void *pData)
  804. {
  805. roamingMngr_t *pRoamingMngr;
  806. apConn_roamingTrigger_e roamingTrigger;
  807. UINT32 curTimestamp;
  808. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  809. if ((pRoamingMngr == NULL) || (pData == NULL))
  810. {
  811. return NOK;
  812. }
  813. roamingTrigger = *(apConn_roamingTrigger_e *)pData;
  814. if (roamingTrigger >= ROAMING_TRIGGER_LAST)
  815. {
  816. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  817. ("roamingMngr_triggerRoamingCb, bad roaming trigger = %d\n", roamingTrigger));
  818. return NOK;
  819. }
  820. #ifdef TI_DBG
  821. /* save parameters for debug*/
  822. pRoamingMngr->roamingTriggerEvents[pRoamingMngr->roamingTrigger]++;
  823. #endif
  824. if (roamingTrigger <= ROAMING_TRIGGER_BG_SCAN_GROUP)
  825. {
  826. BOOL lowQuality = FALSE;
  827. if (roamingTrigger == ROAMING_TRIGGER_LOW_QUALITY_FOR_BG_SCAN)
  828. {
  829. lowQuality = TRUE;
  830. }
  831. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  832. ("roamingMngr_triggerRoamingCb, lowQuality = %d \n",
  833. lowQuality));
  834. scanMngr_qualityChangeTrigger(pRoamingMngr->hScanMngr, lowQuality);
  835. }
  836. else
  837. {
  838. if (roamingTrigger > pRoamingMngr->roamingTrigger)
  839. { /* Save the highest priority roaming trigger */
  840. pRoamingMngr->roamingTrigger = roamingTrigger;
  841. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  842. ("roamingMngr_triggerRoamingCb, higher trigger = %d \n",
  843. roamingTrigger));
  844. }
  845. curTimestamp = os_timeStampMs(pRoamingMngr->hOs);
  846. /* If "No BSS" trigger received, disable count of low pass filter timer */
  847. if (roamingTrigger > ROAMING_TRIGGER_LOW_QUALITY_GROUP)
  848. {
  849. pRoamingMngr->lowQualityTriggerTimestamp = 0;
  850. }
  851. /* Do not invoke a new Roaming Trigger when a previous one is in process */
  852. if (pRoamingMngr->maskRoamingEvents == FALSE)
  853. { /* No Roaming trigger is in process */
  854. /* If the trigger is low quality check the low pass filter */
  855. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  856. ("roamingMngr_triggerRoamingCb, trigger = %d \n",
  857. roamingTrigger));
  858. if (roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
  859. {
  860. UINT32 deltaTs = curTimestamp-pRoamingMngr->lowQualityTriggerTimestamp;
  861. if ((pRoamingMngr->lowQualityTriggerTimestamp != 0) &&
  862. (deltaTs < pRoamingMngr->lowPassFilterRoamingAttemptInMsec))
  863. { /* Ignore the low quality events. till the low pass time elapses */
  864. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  865. ("roamingMngr_triggerRoamingCb, trigger = %d Ignored!!,deltaTs=%d, curTimestamp = %d, lowQualityTriggerTimestamp = %d, lowPassFilterRoamingAttempt=%d\n",
  866. roamingTrigger, deltaTs, curTimestamp, pRoamingMngr->lowQualityTriggerTimestamp, pRoamingMngr->lowPassFilterRoamingAttemptInMsec));
  867. return OK;
  868. }
  869. pRoamingMngr->lowQualityTriggerTimestamp = curTimestamp;
  870. }
  871. /* Mask all future roaming events */
  872. pRoamingMngr->maskRoamingEvents = TRUE;
  873. #ifdef TI_DBG
  874. /* For debug */
  875. pRoamingMngr->roamingTriggerTimestamp = curTimestamp;
  876. #endif
  877. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
  878. }
  879. else if (roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
  880. { /* If the trigger is from the Full Connect group, then stop the connection. */
  881. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_ROAM_TRIGGER, pRoamingMngr));
  882. }
  883. }
  884. return OK;
  885. }
  886. /**
  887. *
  888. * roamingMngr_connStatusCb
  889. *
  890. * \b Description:
  891. *
  892. * This procedure is called when the connection status event
  893. * is triggered.
  894. *
  895. * \b ARGS:
  896. *
  897. * I - hRoamingMngr - roamingMngr SM context \n
  898. * I - pData - pointer to the connection status.
  899. *
  900. * \b RETURNS:
  901. *
  902. * OK if successful, NOK otherwise.
  903. *
  904. *
  905. */
  906. TI_STATUS roamingMngr_connStatusCb(TI_HANDLE hRoamingMngr, void *pData)
  907. {
  908. roamingMngr_t *pRoamingMngr;
  909. apConn_connStatus_e connStatus;
  910. roamingMngr_smEvents roamingEvent;
  911. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  912. if ((pRoamingMngr == NULL) || (pData == NULL))
  913. {
  914. return NOK;
  915. }
  916. connStatus = ((apConn_connStatus_t *)pData)->status;
  917. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  918. ("roamingMngr_connStatusCb, conn status = %d\n", connStatus));
  919. if (!pRoamingMngr->roamingMngrConfig.enableDisable)
  920. {
  921. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  922. ("roamingMngr_connStatusCb, connStatus=%d was received while Roaming is disabled. Stop Roaming \n",
  923. connStatus));
  924. return NOK;
  925. }
  926. switch (connStatus)
  927. {
  928. case CONN_STATUS_CONNECTED: roamingEvent = ROAMING_EVENT_START;
  929. /* Get station capabilities */
  930. apConn_getStaCapabilities(pRoamingMngr->hAPConnection, &pRoamingMngr->staCapabilities);
  931. break;
  932. case CONN_STATUS_NOT_CONNECTED: roamingEvent = ROAMING_EVENT_STOP;
  933. break;
  934. case CONN_STATUS_HANDOVER_SUCCESS: roamingEvent = ROAMING_EVENT_ROAM_SUCCESS;
  935. #ifdef TI_DBG
  936. /* For debug */
  937. pRoamingMngr->roamingSuccesfulHandoverNum++;
  938. pRoamingMngr->roamingHandoverCompletedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
  939. pRoamingMngr->roamingAverageSuccHandoverDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingHandoverStartedTimestamp;
  940. pRoamingMngr->roamingAverageRoamingDuration += os_timeStampMs(pRoamingMngr->hOs)-pRoamingMngr->roamingTriggerTimestamp;
  941. pRoamingMngr->roamingHandoverEvents[pRoamingMngr->roamingTrigger]++;
  942. #endif
  943. break;
  944. case CONN_STATUS_HANDOVER_FAILURE: roamingEvent = ROAMING_EVENT_REQ_HANDOVER;
  945. #ifdef TI_DBG
  946. /* For debug */
  947. pRoamingMngr->roamingFailedHandoverNum++;
  948. #endif
  949. break;
  950. default:
  951. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  952. ("roamingMngr_connStatusCb, bad connStatus = %d\n", connStatus));
  953. return NOK;
  954. /* break; - unreachable */
  955. }
  956. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, roamingEvent, pRoamingMngr));
  957. }
  958. /**
  959. *
  960. * roamingMngr_updateNeighborApListCb
  961. *
  962. * \b Description:
  963. *
  964. * This procedure is called when Neighbor AP list is received from the AP.
  965. * Save the list, and set them in Scan Manager object.
  966. *
  967. * \b ARGS:
  968. *
  969. * I - hRoamingMngr - roamingMngr SM context \n
  970. * I - pData - pointer to the list of Neighbor APs.
  971. *
  972. * \b RETURNS:
  973. *
  974. * OK if successful, NOK otherwise.
  975. *
  976. *
  977. */
  978. TI_STATUS roamingMngr_updateNeighborApListCb(TI_HANDLE hRoamingMngr, void *pData)
  979. {
  980. roamingMngr_t *pRoamingMngr;
  981. neighborAPList_t *pNeighborAPList;
  982. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  983. if ((pRoamingMngr == NULL) || (pData == NULL))
  984. {
  985. return NOK;
  986. }
  987. pNeighborAPList = (neighborAPList_t *)pData;
  988. if (pNeighborAPList->numOfEntries>0)
  989. {
  990. pRoamingMngr->neighborApsExist = TRUE;
  991. }
  992. else
  993. {
  994. pRoamingMngr->neighborApsExist = FALSE;
  995. }
  996. if (pRoamingMngr->roamingMngrConfig.enableDisable)
  997. {
  998. scanMngr_setNeighborAPs (pRoamingMngr->hScanMngr, pNeighborAPList);
  999. }
  1000. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1001. ("roamingMngr_updateNeighborApListCb, numberOfAps = %d, enableDisable=%d\n",
  1002. pNeighborAPList->numOfEntries, pRoamingMngr->roamingMngrConfig.enableDisable));
  1003. return OK;
  1004. }
  1005. /**
  1006. *
  1007. * roamingMngr_immediateScanComplete
  1008. *
  1009. * \b Description:
  1010. *
  1011. * This procedure is called when Scan Manager completed Immediate Scan for Roaming
  1012. * It performs the following:
  1013. * - Partial or Full scan
  1014. * - Re-try Partial or Full scan if the previous scan failed
  1015. * - Full scan if the previous partial scan didn't get any APS
  1016. * - Fail event if all the Scans failed
  1017. *
  1018. * \b ARGS:
  1019. *
  1020. * I - hRoamingMngr - roamingMngr SM context \n
  1021. * I - scanCmpltStatus - the scan result, success or failure with different reasons
  1022. *
  1023. * \b RETURNS:
  1024. *
  1025. * OK if successful, NOK otherwise.
  1026. *
  1027. *
  1028. */
  1029. TI_STATUS roamingMngr_immediateScanComplete(TI_HANDLE hRoamingMngr, scan_mngrResultStatus_e scanCmpltStatus)
  1030. {
  1031. roamingMngr_t *pRoamingMngr;
  1032. roamingMngr_smEvents roamingEvent;
  1033. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  1034. if (pRoamingMngr == NULL)
  1035. {
  1036. return NOK;
  1037. }
  1038. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1039. ("roamingMngr_immediateScanComplete, scanCmpltStatus = %d\n", scanCmpltStatus));
  1040. if (scanCmpltStatus == SCAN_MRS_SCAN_COMPLETE_OK)
  1041. { /* The scan completed OK, get the updated list of APs */
  1042. pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
  1043. if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
  1044. { /* APs were found, start selection */
  1045. pRoamingMngr->scanType = ROAMING_NO_SCAN;
  1046. roamingEvent = ROAMING_EVENT_SELECT;
  1047. }
  1048. else
  1049. { /* There were no APs, if the scan was partial, retry full scan */
  1050. if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
  1051. (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
  1052. {
  1053. pRoamingMngr->scanType = ROAMING_FULL_SCAN;
  1054. roamingEvent = ROAMING_EVENT_SCAN;
  1055. }
  1056. else
  1057. { /* No APs were found in FULL SCAN, report failure */
  1058. roamingEvent = ROAMING_EVENT_SELECT;
  1059. }
  1060. }
  1061. }
  1062. else
  1063. { /* The scan failed, retry scanning according to the current scan type */
  1064. pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
  1065. if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
  1066. { /* APs were found, start selection */
  1067. pRoamingMngr->scanType = ROAMING_NO_SCAN;
  1068. roamingEvent = ROAMING_EVENT_SELECT;
  1069. }
  1070. else
  1071. { /* The scan failed, and there were no APs found.
  1072. Retry scanning according to the current scan type */
  1073. switch (pRoamingMngr->scanType)
  1074. {
  1075. case ROAMING_PARTIAL_SCAN:
  1076. roamingEvent = ROAMING_EVENT_SCAN;
  1077. pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN_RETRY;
  1078. break;
  1079. case ROAMING_PARTIAL_SCAN_RETRY:
  1080. roamingEvent = ROAMING_EVENT_SELECT;
  1081. pRoamingMngr->scanType = ROAMING_NO_SCAN;
  1082. break;
  1083. case ROAMING_FULL_SCAN:
  1084. roamingEvent = ROAMING_EVENT_SCAN;
  1085. pRoamingMngr->scanType = ROAMING_FULL_SCAN_RETRY;
  1086. break;
  1087. case ROAMING_FULL_SCAN_RETRY:
  1088. roamingEvent = ROAMING_EVENT_SELECT;
  1089. pRoamingMngr->scanType = ROAMING_NO_SCAN;
  1090. break;
  1091. default:
  1092. roamingEvent = ROAMING_EVENT_SELECT;
  1093. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1094. ("roamingMngr_immediateScanComplete, pRoamingMngr->scanType = %d\n", pRoamingMngr->scanType));
  1095. pRoamingMngr->scanType = ROAMING_NO_SCAN;
  1096. break;
  1097. }
  1098. }
  1099. }
  1100. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1101. ("roamingMngr_immediateScanComplete, roamingEvent = %d, scanType=%d\n",
  1102. roamingEvent, pRoamingMngr->scanType));
  1103. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, roamingEvent, pRoamingMngr));
  1104. }
  1105. /* called by the Scan Manager when new BSSID was found */
  1106. /**
  1107. *
  1108. * roamingMngr_updateNewBssList
  1109. *
  1110. * \b Description:
  1111. *
  1112. * This procedure is called when Scan Manager finds new BSSIDs.
  1113. * These BSSIDs are sent to RSn to invoke Pre-Auth if allowed.
  1114. *
  1115. * \b ARGS:
  1116. *
  1117. * I - hRoamingMngr - roamingMngr SM context \n
  1118. * I - bssList - list of BSSIDs
  1119. *
  1120. * \b RETURNS:
  1121. *
  1122. * OK if successful, NOK otherwise.
  1123. *
  1124. *
  1125. */
  1126. TI_STATUS roamingMngr_updateNewBssList(TI_HANDLE hRoamingMngr, bssList_t *bssList)
  1127. {
  1128. roamingMngr_t *pRoamingMngr;
  1129. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  1130. if ((pRoamingMngr == NULL) || (bssList == NULL))
  1131. {
  1132. return NOK;
  1133. }
  1134. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1135. ("roamingMngr_updateNewBssList, number of APs = %d\n", bssList->numOfEntries));
  1136. if (pRoamingMngr->currentState != ROAMING_STATE_WAIT_4_TRIGGER)
  1137. {
  1138. WLAN_REPORT_WARNING(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1139. ("roamingMngr_updateNewBssList, ignore APs when not in WAIT_4_TRIGGER state \n"));
  1140. return NOK;
  1141. }
  1142. if (pRoamingMngr->staCapabilities.authMode!=os802_11AuthModeWPA2)
  1143. { /* No Pre-Auth is required */
  1144. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1145. ("roamingMngr_updateNewBssList, No Pre-Auth is required\n"));
  1146. return OK;
  1147. }
  1148. apConn_preAuthenticate(pRoamingMngr->hAPConnection, bssList, bssList->numOfEntries);
  1149. return OK;
  1150. }
  1151. /*****************************************************************************
  1152. ** Private Function section **
  1153. *****************************************************************************/
  1154. /**
  1155. *
  1156. * roamingMngr_smEvent
  1157. *
  1158. * \b Description:
  1159. *
  1160. * Roaming Manager state machine transition function
  1161. *
  1162. * \b ARGS:
  1163. *
  1164. * I/O - currentState - current state in the state machine\n
  1165. * I - event - specific event for the state machine\n
  1166. * I - pData - Data for state machine action function\n
  1167. *
  1168. * \b RETURNS:
  1169. *
  1170. * OK on success, NOK otherwise.
  1171. *
  1172. * \sa
  1173. */
  1174. static TI_STATUS roamingMngr_smEvent(UINT8 *currState, UINT8 event, void* data)
  1175. {
  1176. TI_STATUS status;
  1177. UINT8 nextState;
  1178. roamingMngr_t *pRoamingMngr = (roamingMngr_t*)data;
  1179. status = fsm_GetNextState(pRoamingMngr->pRoamingSm, *currState, event, &nextState);
  1180. if (status != OK)
  1181. {
  1182. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG, ("roamingMngr_smEvent, fsm_GetNextState error\n"));
  1183. return(NOK);
  1184. }
  1185. #ifdef TI_DBG
  1186. WLAN_REPORT_SM(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1187. ("<%s, %s> --> %s\n\n",
  1188. roamingMngr_stateDesc[*currState],
  1189. roamingMngr_eventDesc[event],
  1190. roamingMngr_stateDesc[nextState]));
  1191. #endif
  1192. status = fsm_Event(pRoamingMngr->pRoamingSm, currState, event, (void *)pRoamingMngr);
  1193. #ifdef TI_DBG
  1194. if (status != OK)
  1195. {
  1196. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG, ("roamingMngr_smEvent fsm_Event error\n"));
  1197. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1198. ("<%s, %s> --> %s\n\n",
  1199. roamingMngr_stateDesc[*currState],
  1200. roamingMngr_eventDesc[event],
  1201. roamingMngr_stateDesc[nextState]));
  1202. }
  1203. #endif
  1204. return status;
  1205. }
  1206. /**
  1207. *
  1208. * roamingMngr_smRoamTrigger
  1209. *
  1210. * \b Description:
  1211. *
  1212. * This procedure is called when an Roaming event occurs: BSS LOSS, LOW Quality etc.
  1213. * Performs the following:
  1214. * - If Roaming is disabled, ignore.
  1215. * - Indicate Driver that Roaming process is starting
  1216. * - Get the BSS list from the Scan Manager.
  1217. * - If the list is not empty, start SELECTION
  1218. * - If the list is empty, start SCANNING. The type of scan is decided
  1219. * according to the Neigbor APs existence.
  1220. *
  1221. * \b ARGS:
  1222. *
  1223. * I - hRoamingMngr - roamingMngr SM context \n
  1224. *
  1225. * \b RETURNS:
  1226. *
  1227. * OK if successful, NOK otherwise.
  1228. *
  1229. *
  1230. */
  1231. static TI_STATUS roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr)
  1232. {
  1233. roamingMngr_t *pRoamingMngr;
  1234. roamingMngr_smEvents roamingEvent;
  1235. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  1236. if (pRoamingMngr == NULL)
  1237. {
  1238. return NOK;
  1239. }
  1240. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1241. ("roamingMngr_smRoamTrigger, enableDisable = %d\n",pRoamingMngr->roamingMngrConfig.enableDisable));
  1242. if (!pRoamingMngr->roamingMngrConfig.enableDisable)
  1243. { /* Ignore any other Roaming event when Roaming is disabled */
  1244. WLAN_REPORT_ERROR(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1245. ("roamingMngr_smRoamTrigger, when Roaming is disabled\n"));
  1246. return OK;
  1247. }
  1248. /* Indicate the driver that Roaming process is starting */
  1249. apConn_prepareToRoaming(pRoamingMngr->hAPConnection, pRoamingMngr->roamingTrigger);
  1250. /* Get the current BSSIDs from ScanMngr */
  1251. #if 0
  1252. pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
  1253. #else
  1254. pRoamingMngr->pListOfAPs = NULL; /* force immediate scan */
  1255. #endif
  1256. if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
  1257. { /* No need to SCAN, start SELECTING */
  1258. roamingEvent = ROAMING_EVENT_SELECT;
  1259. }
  1260. else
  1261. { /* check if list of APs exists in order to verify which scan to start */
  1262. roamingEvent = ROAMING_EVENT_SCAN;
  1263. if (pRoamingMngr->neighborApsExist)
  1264. { /* Scan only Neighbor APs */
  1265. pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN;
  1266. }
  1267. else
  1268. { /* Scan all channels */
  1269. pRoamingMngr->scanType = ROAMING_FULL_SCAN;
  1270. }
  1271. }
  1272. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1273. ("roamingMngr_smRoamTrigger, scanType = %d\n", pRoamingMngr->scanType));
  1274. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, roamingEvent, pRoamingMngr));
  1275. }
  1276. /**
  1277. *
  1278. * roamingMngr_smInvokeScan
  1279. *
  1280. * \b Description:
  1281. *
  1282. * This procedure is called when scan should be performed in order
  1283. * to select an AP to roam to.
  1284. * This can be the first scan, a second scan after partail scan,
  1285. * or scan after previous scan was failed.
  1286. * In any case, the scan can either be:
  1287. * partail, on list of channles or
  1288. * full on all channels.
  1289. *
  1290. * \b ARGS:
  1291. *
  1292. * I - hRoamingMngr - roamingMngr SM context \n
  1293. *
  1294. * \b RETURNS:
  1295. *
  1296. * OK if successful, NOK otherwise.
  1297. *
  1298. *
  1299. */
  1300. static TI_STATUS roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr)
  1301. {
  1302. roamingMngr_t *pRoamingMngr;
  1303. scan_mngrResultStatus_e scanResult;
  1304. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  1305. if (pRoamingMngr == NULL)
  1306. {
  1307. return NOK;
  1308. }
  1309. scanMngrClearBSSListEntry(pRoamingMngr->hScanMngr);
  1310. /* check which scan should be performed: Partial on list of channels, or full scan */
  1311. if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
  1312. (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
  1313. {
  1314. scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, TRUE);
  1315. }
  1316. else
  1317. { /* Scan all channels */
  1318. scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, FALSE);
  1319. }
  1320. if (scanResult != SCAN_MRS_SCAN_RUNNING)
  1321. { /* the scan failed, immitate scan complete event */
  1322. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1323. ("roamingMngr_smInvokeScan, scanResult = %d\n", scanResult));
  1324. roamingMngr_immediateScanComplete(pRoamingMngr, scanResult);
  1325. }
  1326. return OK;
  1327. }
  1328. /**
  1329. *
  1330. * roamingMngr_smSelection
  1331. *
  1332. * \b Description:
  1333. *
  1334. * This procedure is called when selection should be performed.
  1335. * It perform the following:
  1336. * Prepare the candidate APs to roam according to:
  1337. * - Priority APs
  1338. * - Pre-Authenticated APs
  1339. * If the candidate AP list is empty, only the current AP can be re-selected
  1340. * Select one AP and trigger REQ_HANDOVER event.
  1341. *
  1342. * \b ARGS:
  1343. *
  1344. * I - hRoamingMngr - roamingMngr SM context \n
  1345. *
  1346. * \b RETURNS:
  1347. *
  1348. * OK if successful, NOK otherwise.
  1349. *
  1350. *
  1351. */
  1352. static TI_STATUS roamingMngr_smSelection(TI_HANDLE hRoamingMngr)
  1353. {
  1354. roamingMngr_t *pRoamingMngr;
  1355. UINT32 index;
  1356. pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
  1357. if (pRoamingMngr == NULL)
  1358. {
  1359. return NOK;
  1360. }
  1361. pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
  1362. pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
  1363. pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;
  1364. pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
  1365. if ((pRoamingMngr->pListOfAPs == NULL) ||
  1366. (pRoamingMngr->pListOfAPs->numOfEntries == 0))
  1367. { /* Error, there cannot be selection */
  1368. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1369. ("roamingMngr_smSelection pListOfAPs is empty \n"));
  1370. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr));
  1371. }
  1372. /* Build the candidate AP list */
  1373. for (index=0; index<pRoamingMngr->pListOfAPs->numOfEntries; index++ )
  1374. {
  1375. if ( (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) &&
  1376. (pRoamingMngr->pListOfAPs->BSSList[index].RSSI < pRoamingMngr->roamingMngrConfig.apQualityThreshold))
  1377. { /* Do not insert APs with low quality to the selection table,
  1378. if the Roaming Trigger was low Quality */
  1379. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1380. ("candidate AP %x-%x-%x-%x-%x-%x with RSSI too low =%d, Quality=%d \n",
  1381. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[0],
  1382. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[1],
  1383. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[2],
  1384. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[3],
  1385. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[4],
  1386. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[5],
  1387. pRoamingMngr->pListOfAPs->BSSList[index].RSSI,
  1388. pRoamingMngr->roamingMngrConfig.apQualityThreshold));
  1389. continue;
  1390. }
  1391. if (apConn_isSiteBanned(pRoamingMngr->hAPConnection, &pRoamingMngr->pListOfAPs->BSSList[index].BSSID) == TRUE)
  1392. {
  1393. WLAN_REPORT_INFORMATION(pRoamingMngr->hReport, ROAMING_MANAGER_MODULE_LOG,
  1394. ("%s: Candidate AP %02X-%02X-%02X-%02X-%02X-%02X is banned!\n", __FUNCTION__,
  1395. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[0],
  1396. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[1],
  1397. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[2],
  1398. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[3],
  1399. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[4],
  1400. pRoamingMngr->pListOfAPs->BSSList[index].BSSID.addr[5]));
  1401. continue;
  1402. }
  1403. if (pRoamingMngr->pListOfAPs->BSSList[index].bNeighborAP)
  1404. { /* The AP is a neighbor AP, insert its index to the neighbor APs list */
  1405. pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS] = index;
  1406. pRoamingMngr->listOfCandidateAps.numOfNeighborBSS++;
  1407. }
  1408. else if (apConn_getPreAuthAPStatus(pRoamingMngr->hAPConnection,
  1409. &pRoamingMngr->pListOfAPs->BSSList[index].BSSID))
  1410. { /* This AP is a pre-auth AP */
  1411. pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS] = index;
  1412. pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS++;
  1413. }
  1414. else
  1415. { /* This AP is not Neighbor nor Pre-Auth */
  1416. pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS] = index;
  1417. pRoamingMngr->listOfCandidateAps.numOfRegularBSS++;
  1418. }
  1419. }
  1420. #ifdef TI_DBG
  1421. { /* for debug */
  1422. paramInfo_t param;
  1423. param.paramType = ROAMING_MNGR_PRINT_CANDIDATE_TABLE;
  1424. roamingMngr_getParam(pRoamingMngr, &param);
  1425. }
  1426. #endif
  1427. return (roamingMngr_smEvent((UINT8*)&pRoamingMngr->currentState, ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr));
  1428. }
  1429. /**
  1430. *
  1431. * roamingMngr_smHandover
  1432. *
  1433. * \b Description:
  1434. *
  1435. * This procedure is called when handover should be invoked.
  1436. * Go over the candidate APs and start handover to each of them.
  1437. * If there's no candidate APs, disconnect.
  1438. * Handover to the current AP is allowed only if the trigger is
  1439. * low quality.
  1440. *
  1441. * \b ARGS:
  1442. *
  1443. * I - hRoamingMngr - roamingMngr SM context \n
  1444. *
  1445. * \b RETURNS:
  1446. *
  1447. * OK if successful, NOK otherwise.
  1448. *
  1449. *
  1450. */
  1451. static TI_STATUS roamingMngr_smHandover(TI_HANDLE hRoamingMngr)
  1452. {
  1453. roamingMngr_t *pRoamingMngr;
  1454. bssEntry_t *pApToConnect;
  1455. apConn_connR