4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 /** \file roamingMngr_autoSM.c
35 * \brief Roaming Manager
37 * \see roamingMngr_autoSM.h
40 /****************************************************************************
42 * MODULE: Roaming Manager *
44 * Roaming manager is responsible to receive Roaming triggers and try
45 * to select a better AP.
46 * The Roaming triggers are: Low RSSI, PER, consecutive No ACK on TX,
47 * beacon Missed or External request.
48 * In each Internal Roaming request, scan is performed and selection for
49 * better AP. Better AP is defined as a different AP with better RSSI,
50 * and similar SSID and security settings.
51 * If better AP is found, there is a check for fast-roaming via the
52 * Supplicant. Then connection to the new AP is invoked.
54 ****************************************************************************/
56 #define __FILE_ID__ FILE_ID_135
61 #include "scanMngrApi.h"
62 #include "roamingMngrApi.h"
63 #include "apConnApi.h"
64 #include "roamingMngrTypes.h"
66 #include "DrvMainModules.h"
68 #include "siteMgrApi.h"
70 #include "roamingMngr_autoSM.h"
73 /*****************************************************************************
74 ** Private Function section **
75 *****************************************************************************/
78 static void roamingMngr_smStartIdle(TI_HANDLE hRoamingMngr);
79 static void roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr);
80 static void roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr);
81 static void roamingMngr_smSelection(TI_HANDLE hRoamingMngr);
82 static void roamingMngr_smHandover(TI_HANDLE hRoamingMngr);
83 static void roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr);
84 static void roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr);
85 static void roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr);
86 static void roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr);
88 /*static TI_STATUS roamingMngr_smUnexpected(TI_HANDLE hRoamingMngr);
89 static TI_STATUS roamingMngr_smNop(TI_HANDLE hRoamingMngr);
90 static TI_STATUS roamingMngr_smStopWhileScanning(TI_HANDLE hRoamingMngr);
95 REASSOC_RESP_SUCCESS =0,
98 } reassociationResp_e;
105 TGenSM_actionCell roamingMngrAuto_matrix[ROAMING_MNGR_NUM_STATES][ROAMING_MNGR_NUM_EVENTS] =
107 /* next state and actions for IDLE state */
108 { {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smStartIdle}, /* START */
109 {ROAMING_STATE_IDLE, roamingMngr_smNop}, /* STOP */
110 {ROAMING_STATE_IDLE, roamingMngr_smNop}, /* ROAM_TRIGGER */
111 {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* SCAN */
112 {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* SELECT */
113 {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
114 {ROAMING_STATE_IDLE, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
115 {ROAMING_STATE_IDLE, roamingMngr_smUnexpected} /* FAILURE */
118 /* next state and actions for WAIT_4_TRIGGER state */
119 { {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* START */
120 {ROAMING_STATE_IDLE, roamingMngr_smStop}, /* STOP */
121 {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smRoamTrigger}, /* ROAM_TRIGGER */
122 {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* SCAN */
123 {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* SELECT */
124 {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
125 {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
126 {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smUnexpected} /* FAILURE */
129 /* next state and actions for WAIT_4_CMD state */
130 { {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* START */
131 {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* STOP */
132 {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* ROAM_TRIGGER */
133 {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan}, /* SCAN */
134 {ROAMING_STATE_SELECTING, roamingMngr_smSelection}, /* SELECT */
135 {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
136 {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
137 {ROAMING_STATE_WAIT_4_CMD, roamingMngr_smUnexpected} /* FAILURE */
140 /* next state and actions for SCANNING state */
141 { {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected}, /* START */
142 {ROAMING_STATE_IDLE, roamingMngr_smStopWhileScanning}, /* STOP */
143 {ROAMING_STATE_SCANNING, roamingMngr_smNop}, /* ROAM_TRIGGER */
144 {ROAMING_STATE_SCANNING, roamingMngr_smInvokeScan}, /* SCAN */
145 {ROAMING_STATE_SELECTING, roamingMngr_smSelection}, /* SELECT */
146 {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected}, /* REQ_HANDOVER */
147 {ROAMING_STATE_SCANNING, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
148 {ROAMING_STATE_IDLE, roamingMngr_smScanFailure} /* FAILURE */
152 /* next state and actions for SELECTING state */
153 { {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* START */
154 {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* STOP */
155 {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* ROAM_TRIGGER */
156 {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* SCAN */
157 {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* SELECT */
158 {ROAMING_STATE_CONNECTING, roamingMngr_smHandover}, /* REQ_HANDOVER */
159 {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected}, /* ROAM_SUCCESS */
160 {ROAMING_STATE_SELECTING, roamingMngr_smUnexpected} /* FAILURE */
164 /* next state and actions for CONNECTING state */
165 { {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected}, /* START */
166 {ROAMING_STATE_IDLE, roamingMngr_smStop}, /* STOP */
167 {ROAMING_STATE_IDLE, roamingMngr_smDisconnectWhileConnecting}, /* ROAM_TRIGGER */
168 {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected}, /* SCAN, */
169 {ROAMING_STATE_CONNECTING, roamingMngr_smUnexpected}, /* SELECT */
170 {ROAMING_STATE_CONNECTING, roamingMngr_smHandover}, /* REQ_HANDOVER */
171 {ROAMING_STATE_WAIT_4_TRIGGER, roamingMngr_smSuccHandover} , /* ROAM_SUCCESS */
172 {ROAMING_STATE_IDLE, roamingMngr_smFailHandover} /* FAILURE */
178 TI_INT8* AutoRoamStateDescription[] =
188 TI_INT8* AutoRoamEventDescription[] =
202 * roamingMngr_smRoamTrigger
206 * This procedure is called when an Roaming event occurs: BSS LOSS, LOW Quality etc.
207 * Performs the following:
208 * - If Roaming is disabled, ignore.
209 * - Indicate Driver that Roaming process is starting
210 * - Get the BSS list from the Scan Manager.
211 * - If the list is not empty, start SELECTION
212 * - If the list is empty, start SCANNING. The type of scan is decided
213 * according to the Neigbor APs existence.
217 * I - hRoamingMngr - roamingMngr SM context \n
221 * TI_OK if successful, TI_NOK otherwise.
225 static void roamingMngr_smRoamTrigger(TI_HANDLE hRoamingMngr)
227 roamingMngr_t *pRoamingMngr;
228 roamingMngr_smEvents roamingEvent;
230 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
231 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smRoamTrigger, enableDisable = %d\n",pRoamingMngr->roamingMngrConfig.enableDisable);
233 if (!pRoamingMngr->roamingMngrConfig.enableDisable)
235 /* Ignore any other Roaming event when Roaming is disabled */
236 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_ERROR, "roamingMngr_smRoamTrigger, when Roaming is disabled\n");
239 /* Indicate the driver that Roaming process is starting */
240 apConn_prepareToRoaming(pRoamingMngr->hAPConnection, pRoamingMngr->roamingTrigger);
242 /* Get the current BSSIDs from ScanMngr */
243 pRoamingMngr->pListOfAPs = scanMngr_getBSSList(pRoamingMngr->hScanMngr);
244 if ((pRoamingMngr->pListOfAPs != NULL) && (pRoamingMngr->pListOfAPs->numOfEntries > 0))
245 { /* No need to SCAN, start SELECTING */
246 roamingEvent = ROAMING_EVENT_SELECT;
249 { /* check if list of APs exists in order to verify which scan to start */
250 roamingEvent = ROAMING_EVENT_SCAN;
251 if (pRoamingMngr->neighborApsExist)
252 { /* Scan only Neighbor APs */
253 pRoamingMngr->scanType = ROAMING_PARTIAL_SCAN;
256 { /* Scan all channels */
257 pRoamingMngr->scanType = ROAMING_FULL_SCAN;
260 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smRoamTrigger, scanType = %d\n", pRoamingMngr->scanType);
262 roamingMngr_smEvent(roamingEvent, pRoamingMngr);
267 * roamingMngr_smInvokeScan
271 * This procedure is called when scan should be performed in order
272 * to select an AP to roam to.
273 * This can be the first scan, a second scan after partail scan,
274 * or scan after previous scan was failed.
275 * In any case, the scan can either be:
276 * partail, on list of channles or
277 * full on all channels.
281 * I - hRoamingMngr - roamingMngr SM context \n
285 * TI_OK if successful, TI_NOK otherwise.
289 static void roamingMngr_smInvokeScan(TI_HANDLE hRoamingMngr)
291 roamingMngr_t *pRoamingMngr;
292 scan_mngrResultStatus_e scanResult;
294 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
296 /* check which scan should be performed: Partial on list of channels, or full scan */
297 if ((pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN) ||
298 (pRoamingMngr->scanType == ROAMING_PARTIAL_SCAN_RETRY))
300 scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, TI_TRUE);
303 { /* Scan all channels */
304 scanResult = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr, TI_FALSE);
307 if (scanResult != SCAN_MRS_SCAN_RUNNING)
308 { /* the scan failed, immitate scan complete event */
309 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smInvokeScan, scanResult = %d\n", scanResult);
310 roamingMngr_immediateScanComplete(pRoamingMngr, scanResult);
316 * roamingMngr_smSelection
320 * This procedure is called when selection should be performed.
321 * It perform the following:
322 * Prepare the candidate APs to roam according to:
324 * - Pre-Authenticated APs
325 * If the candidate AP list is empty, only the current AP can be re-selected
326 * Select one AP and trigger REQ_HANDOVER event.
330 * I - hRoamingMngr - roamingMngr SM context \n
334 * TI_OK if successful, TI_NOK otherwise.
338 static void roamingMngr_smSelection(TI_HANDLE hRoamingMngr)
340 roamingMngr_t *pRoamingMngr;
344 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
345 pRoamingMngr->listOfCandidateAps.numOfNeighborBSS = 0;
346 pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS = 0;
347 pRoamingMngr->listOfCandidateAps.numOfRegularBSS = 0;
349 pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
351 if ((pRoamingMngr->pListOfAPs == NULL) ||
352 (pRoamingMngr->pListOfAPs->numOfEntries == 0))
353 { /* Error, there cannot be selection */
354 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smSelection pListOfAPs is empty \n");
355 roamingMngr_smEvent(ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr);
359 /* Build the candidate AP list */
360 for (index=0; index<pRoamingMngr->pListOfAPs->numOfEntries; index++ )
362 if ( (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP) &&
363 (pRoamingMngr->pListOfAPs->BSSList[index].RSSI < pRoamingMngr->roamingMngrConfig.apQualityThreshold))
364 { /* Do not insert APs with low quality to the selection table,
365 if the Roaming Trigger was low Quality */
366 TRACE8(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "candidate AP %x-%x-%x-%x-%x-%x with RSSI too low =%d, Quality=%d \n", pRoamingMngr->pListOfAPs->BSSList[index].BSSID[0], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[1], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[2], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[3], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[4], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[5], pRoamingMngr->pListOfAPs->BSSList[index].RSSI, pRoamingMngr->roamingMngrConfig.apQualityThreshold);
371 if (apConn_isSiteBanned(pRoamingMngr->hAPConnection, &pRoamingMngr->pListOfAPs->BSSList[index].BSSID) == TI_TRUE)
373 TRACE6(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, ": Candidate AP %02X-%02X-%02X-%02X-%02X-%02X is banned!\n", pRoamingMngr->pListOfAPs->BSSList[index].BSSID[0], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[1], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[2], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[3], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[4], pRoamingMngr->pListOfAPs->BSSList[index].BSSID[5]);
377 if (pRoamingMngr->pListOfAPs->BSSList[index].bNeighborAP)
378 { /* The AP is a neighbor AP, insert its index to the neighbor APs list */
379 pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS] = index;
380 pRoamingMngr->listOfCandidateAps.numOfNeighborBSS++;
382 else if (apConn_getPreAuthAPStatus(pRoamingMngr->hAPConnection,
383 &pRoamingMngr->pListOfAPs->BSSList[index].BSSID))
384 { /* This AP is a pre-auth AP */
385 pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS] = index;
386 pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS++;
389 { /* This AP is not Neighbor nor Pre-Auth */
390 pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS] = index;
391 pRoamingMngr->listOfCandidateAps.numOfRegularBSS++;
399 param.paramType = ROAMING_MNGR_PRINT_CANDIDATE_TABLE;
400 roamingMngr_getParam(pRoamingMngr, ¶m);
404 roamingMngr_smEvent(ROAMING_EVENT_REQ_HANDOVER, pRoamingMngr);
410 * roamingMngr_smHandover
414 * This procedure is called when handover should be invoked.
415 * Go over the candidate APs and start handover to each of them.
416 * If there's no candidate APs, disconnect.
417 * Handover to the current AP is allowed only if the trigger is
422 * I - hRoamingMngr - roamingMngr SM context \n
426 * TI_OK if successful, TI_NOK otherwise.
430 static void roamingMngr_smHandover(TI_HANDLE hRoamingMngr)
432 roamingMngr_t *pRoamingMngr;
433 bssEntry_t *pApToConnect;
434 apConn_connRequest_t requestToApConn;
436 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
438 if ((pRoamingMngr->handoverWasPerformed) && (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX))
439 { /* Handover with the current AP already failed, Disconnect */
440 roamingMngr_smEvent(ROAMING_EVENT_FAILURE, pRoamingMngr);
443 if (pRoamingMngr->listOfCandidateAps.numOfNeighborBSS > 0)
444 { /* Neighbor APs are the highest priority to Roam */
445 pRoamingMngr->candidateApIndex =
446 pRoamingMngr->listOfCandidateAps.neighborBSSList[pRoamingMngr->listOfCandidateAps.numOfNeighborBSS-1];
447 pRoamingMngr->listOfCandidateAps.numOfNeighborBSS--;
449 else if (pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS > 0)
450 { /* Pre-Auth APs are the second priority to Roam */
451 pRoamingMngr->candidateApIndex =
452 pRoamingMngr->listOfCandidateAps.preAuthBSSList[pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS-1];
453 pRoamingMngr->listOfCandidateAps.numOfPreAuthBSS--;
455 else if (pRoamingMngr->listOfCandidateAps.numOfRegularBSS > 0)
456 { /* Regular APs are APs that are not pre-authenticated and not Neighbor */
457 pRoamingMngr->candidateApIndex =
458 pRoamingMngr->listOfCandidateAps.regularBSSList[pRoamingMngr->listOfCandidateAps.numOfRegularBSS-1];
459 pRoamingMngr->listOfCandidateAps.numOfRegularBSS--;
462 { /* No Candidate APs */
463 pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
466 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smHandover, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex);
469 if (pRoamingMngr->candidateApIndex == INVALID_CANDIDATE_INDEX)
470 { /* No cnadidate to Roam to, only the current AP is candidate */
471 if (pRoamingMngr->roamingTrigger <= ROAMING_TRIGGER_LOW_QUALITY_GROUP)
472 { /* If the trigger to Roam is low quality, and there are no candidate APs
473 to roam to, retain connected to the current AP */
474 requestToApConn.requestType = (pRoamingMngr->handoverWasPerformed) ? AP_CONNECT_RECONNECT_CURR_AP : AP_CONNECT_RETAIN_CURR_AP;
475 pRoamingMngr->candidateApIndex = CURRENT_AP_INDEX;
478 { /* Disconnect the BSS, there are no more APs to roam to */
479 roamingMngr_smEvent(ROAMING_EVENT_FAILURE, pRoamingMngr);
484 { /* There is a valid candidate AP */
485 if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
486 { /* Full re-connection should be perfromed */
487 requestToApConn.requestType = AP_CONNECT_FULL_TO_AP;
490 { /* Fast re-connection should be perfromed */
491 requestToApConn.requestType = AP_CONNECT_FAST_TO_AP;
496 if (!pRoamingMngr->handoverWasPerformed)
497 { /* Take the time before the first handover started */
498 pRoamingMngr->roamingHandoverStartedTimestamp = os_timeStampMs(pRoamingMngr->hOs);
502 if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
503 { /* get the current AP */
504 pApToConnect = apConn_getBSSParams(pRoamingMngr->hAPConnection);
507 { /* get the candidate AP */
508 pRoamingMngr->handoverWasPerformed = TI_TRUE;
509 pApToConnect = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
511 TRACE3(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smHandover, candidateApIndex=%d, requestType = %d, channel=%d \n", pRoamingMngr->candidateApIndex, requestToApConn.requestType, pApToConnect->channel);
513 requestToApConn.dataBufLength = 0;
514 apConn_connectToAP(pRoamingMngr->hAPConnection, pApToConnect, &requestToApConn, TI_TRUE);
519 * roamingMngr_smDisconnectWhileConnecting
523 * This procedure is called when the Station is in the process of connection,
524 * and the AP disconnects the station.
528 * I - hRoamingMngr - roamingMngr SM context \n
532 * TI_OK if successful, TI_NOK otherwise.
536 static void roamingMngr_smDisconnectWhileConnecting(TI_HANDLE hRoamingMngr)
538 roamingMngr_t *pRoamingMngr;
540 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
542 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smDisconnectWhileConnecting, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex);
544 if (pRoamingMngr->roamingTrigger > ROAMING_TRIGGER_FAST_CONNECT_GROUP)
545 { /* If the trigger is from the Full Connect group, then stop the connection. */
546 /* clean intenal variables */
547 pRoamingMngr->maskRoamingEvents = TI_TRUE;
548 pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
550 scanMngr_stopContScan(pRoamingMngr->hScanMngr);
552 pRoamingMngr->roamingFailedHandoverNum++;
554 apConn_disconnect(pRoamingMngr->hAPConnection);
561 * roamingMngr_smSuccHandover
565 * This procedure is called when handover succeeded.
566 * Inform Scan Manager about the new AP.
567 * UnMask Roaming Triggers.
571 * I - hRoamingMngr - roamingMngr SM context \n
575 * TI_OK if successful, TI_NOK otherwise.
579 static void roamingMngr_smSuccHandover(TI_HANDLE hRoamingMngr)
581 roamingMngr_t *pRoamingMngr;
582 bssEntry_t *pNewConnectedAp;
584 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
586 TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smSuccHandover, candidateApIndex=%d \n", pRoamingMngr->candidateApIndex);
588 if (pRoamingMngr->handoverWasPerformed &&
589 (pRoamingMngr->pListOfAPs != NULL) &&
590 (pRoamingMngr->pListOfAPs->numOfEntries>0))
592 if (pRoamingMngr->candidateApIndex == CURRENT_AP_INDEX)
594 /* get the current AP */
595 pNewConnectedAp = apConn_getBSSParams(pRoamingMngr->hAPConnection);
599 /* get the candidate AP */
600 pNewConnectedAp = &pRoamingMngr->pListOfAPs->BSSList[pRoamingMngr->candidateApIndex];
603 scanMngr_handoverDone(pRoamingMngr->hScanMngr,
604 &pNewConnectedAp->BSSID,
605 pNewConnectedAp->band);
607 pRoamingMngr->maskRoamingEvents = TI_FALSE;
608 pRoamingMngr->candidateApIndex = INVALID_CANDIDATE_INDEX;
609 pRoamingMngr->handoverWasPerformed = TI_FALSE;
610 pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
612 /* Start pre-authentication in order to set PMKID
613 for the current AP */
614 if (pRoamingMngr->staCapabilities.authMode==os802_11AuthModeWPA2)
616 /* No Pre-Auth is required */
619 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smStartIdle, Pre-Auth to cur AP\n");
620 pBssList = os_memoryAlloc(pRoamingMngr->hOs, sizeof(bssList_t));
623 pBssList->numOfEntries = 0;
624 apConn_preAuthenticate(pRoamingMngr->hAPConnection, pBssList);
625 os_memoryFree(pRoamingMngr->hOs, pBssList, sizeof(bssList_t));
631 * roamingMngr_smFailHandover
635 * This procedure is called when handover failed and there are no more
636 * APs to roam to. Disconnect the BSS and retrun to IDLE state.
640 * I - hRoamingMngr - roamingMngr SM context \n
644 * TI_OK if successful, TI_NOK otherwise.
648 static void roamingMngr_smFailHandover(TI_HANDLE hRoamingMngr)
650 roamingMngr_t *pRoamingMngr;
652 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
653 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smFailHandover \n");
655 /* clean intenal variables */
656 pRoamingMngr->maskRoamingEvents = TI_TRUE;
657 pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
659 scanMngr_stopContScan(pRoamingMngr->hScanMngr);
661 pRoamingMngr->roamingFailedHandoverNum++;
663 apConn_disconnect(pRoamingMngr->hAPConnection);
668 * roamingMngr_smScanFailure
672 * This procedure is called when all scan attempts failed.
673 * Send Disconnect event and return to IDLE state.
678 * I - hRoamingMngr - roamingMngr SM context \n
682 * TI_OK if successful, TI_NOK otherwise.
686 static void roamingMngr_smScanFailure(TI_HANDLE hRoamingMngr)
688 roamingMngr_t *pRoamingMngr;
690 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
691 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smScanFailure \n");
693 /* clean intenal variables */
694 pRoamingMngr->maskRoamingEvents = TI_TRUE;
695 pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
697 scanMngr_stopContScan(pRoamingMngr->hScanMngr);
699 apConn_disconnect(pRoamingMngr->hAPConnection);
705 * roamingMngr_smCmdFailure
709 * This procedure is called when all the driver failed to prepare to Roaming.
710 * Mask all future Roaming triggers.
715 * I - hRoamingMngr - roamingMngr SM context \n
719 * TI_OK if successful, TI_NOK otherwise.
723 static void roamingMngr_smCmdFailure(TI_HANDLE hRoamingMngr)
725 roamingMngr_t *pRoamingMngr;
727 pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
728 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smCmdFailure \n");
730 /* clean intenal variables */
731 pRoamingMngr->maskRoamingEvents = TI_TRUE;
732 pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
738 * roamingMngr_smStartIdle - Start event when in Idle state
742 * Start event when in Idle state.
743 * This function is called when the station becomes CONNECTED.
744 * Perform the following:
745 * - The current state becomes WAIT_4_TRIGGER
746 * - Unmask Roaming events
747 * - Set handoverWasPerformed to TI_FALSE
748 * - Start the Scan Manager
752 * I - pData - pointer to the roamingMngr SM context \n
756 * TI_OK if successful, TI_NOK otherwise.
760 static void roamingMngr_smStartIdle(void *pData)
762 roamingMngr_t *pRoamingMngr;
763 bssEntry_t *pCurBssEntry;
765 pRoamingMngr = (roamingMngr_t*)pData;
766 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smStartIdle, Unmask Roaming events and start continuos scan \n");
768 pRoamingMngr->maskRoamingEvents = TI_FALSE;
769 pRoamingMngr->handoverWasPerformed = TI_FALSE;
770 pRoamingMngr->roamingTrigger = ROAMING_TRIGGER_NONE;
772 pCurBssEntry = apConn_getBSSParams(pRoamingMngr->hAPConnection);
773 scanMngr_startContScan(pRoamingMngr->hScanMngr, &pCurBssEntry->BSSID, pCurBssEntry->band);
775 /* Start pre-authentication in order to set PMKID
776 for the current AP */
777 if (pRoamingMngr->staCapabilities.authMode==os802_11AuthModeWPA2)
778 { /* No Pre-Auth is required */
781 TRACE0(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_smStartIdle, Pre-Auth to cur AP\n");
782 pBssList = os_memoryAlloc(pRoamingMngr->hOs, sizeof(bssList_t));
786 pBssList->numOfEntries = 0;
787 apConn_preAuthenticate(pRoamingMngr->hAPConnection, pBssList);
788 os_memoryFree(pRoamingMngr->hOs, pBssList, sizeof(bssList_t));