1/*
2 * roamingMngr_manualSM.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 roamingMngr_manualSM.c
35 *  \brief Roaming Manager
36 *
37 *  \see roamingMngr_manualSM.h
38 */
39
40/****************************************************************************
41 *                                                                          *
42 *   MODULE:  Roaming Manager                                               *
43 *   PURPOSE:                                                               *
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.
53 *                                                                          *
54 ****************************************************************************/
55
56#define __FILE_ID__  FILE_ID_136
57#include "osApi.h"
58#include "paramOut.h"
59#include "report.h"
60#include "scanMngrApi.h"
61#include "roamingMngrApi.h"
62#include "roamingMngrTypes.h"
63#include "bssTypes.h"
64#include "DrvMainModules.h"
65#include "TWDriver.h"
66#include "siteMgrApi.h"
67#include "GenSM.h"
68#include "apConnApi.h"
69#include "roamingMngr_manualSM.h"
70#include "EvHandler.h"
71#include "public_types.h"
72
73
74typedef enum
75{
76	REASSOC_RESP_SUCCESS =0,
77	REASSOC_RESP_FAILURE,
78    REASSOC_RESP_REJECT
79} reassociationResp_e;
80
81
82static void roamingMngr_SendReassocEvent(TI_HANDLE hRoamingMngr, reassociationResp_e ReassResp);
83static void roamingMngr_smIdleToStart (TI_HANDLE hRoamingMngr);
84static void roamingMngr_smSTOP (TI_HANDLE hRoamingMngr);
85static void roamingMngr_smConnectedToScan (TI_HANDLE hRoamingMngr);
86static void roamingMngr_smConnectedToHandover(TI_HANDLE hRoamingMngr);
87static void roamingMngr_smScanToConnected(TI_HANDLE hRoamingMngr);
88static void roamingMngr_smHandoverToHandoverConnectEvent (TI_HANDLE hRoamingMngr);
89static void roamingMngr_smHandoverToHandoverFailEvent (TI_HANDLE hRoamingMngr);
90static void roamingMngr_smHandoverToConnectedSuccessEvent(TI_HANDLE hRoamingMngr);
91static void roamingMngr_smHandoverToConnectedRejectEvent(TI_HANDLE hRoamingMngr);
92
93
94/*-----------*/
95/* Constants */
96/*-----------*/
97
98TGenSM_actionCell roamingMngrManual_matrix[ROAMING_MANUAL_NUM_STATES][ROAMING_MANUAL_NUM_EVENTS] =
99{
100    /* next state and actions for IDLE state */
101    {
102        {ROAMING_MANUAL_STATE_CONNECTED, roamingMngr_smIdleToStart},            /* START */
103        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                   /* SCAN  */
104        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                   /*CONNECT*/
105        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                  /* STOP*/
106        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                  /* REJECT*/
107        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                  /* SUCCESS*/
108        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                  /* FAIL*/
109        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                  /* COMPLETE*/
110    },
111    /* next state and actions for CONNECTED state */
112    {
113        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},		                /* START */
114        {ROAMING_MANUAL_STATE_SCAN, roamingMngr_smConnectedToScan},                 /* SCAN  */
115        {ROAMING_MANUAL_STATE_HANDOVER, roamingMngr_smConnectedToHandover},        /*CONNECT*/
116        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smSTOP},                 	        /* STOP*/
117        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                      /* REJECT*/
118        {ROAMING_MANUAL_STATE_CONNECTED, roamingMngr_smNop},                        /* SUCCESS* retain CurrAp called */
119        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                      /* FAIL*/
120        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                      /* COMPLETE*/
121    },
122    /* next state and actions for SCAN state */
123    {
124        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},              /* START */
125        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},            /* SCAN  */
126        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},            /*CONNECT*/
127        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smSTOP},            	    /* STOP*/
128        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},              /* REJECT*/
129        {ROAMING_MANUAL_STATE_SCAN, roamingMngr_smNop},                     /* SUCCESS* retain CurrAp called */
130        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},              /* FAIL*/
131        {ROAMING_MANUAL_STATE_CONNECTED, roamingMngr_smScanToConnected},  /* COMPLETE*/
132    },
133    /* next state and actions for HANDOVER state */
134    {
135        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                      /* START */
136        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected},                    /* SCAN  */
137        {ROAMING_MANUAL_STATE_HANDOVER,roamingMngr_smHandoverToHandoverConnectEvent},    /*CONNECT*/
138        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smSTOP},                            /* STOP*/
139        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smHandoverToConnectedRejectEvent},  /* REJECT*/
140        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smHandoverToConnectedSuccessEvent},  /* SUCCESS*/
141        {ROAMING_MANUAL_STATE_HANDOVER, roamingMngr_smHandoverToHandoverFailEvent},    /* FAIL*/
142        {ROAMING_MANUAL_STATE_IDLE, roamingMngr_smUnexpected },                    /* COMPLETE*/
143    }
144};
145
146TI_INT8*  ManualRoamStateDescription[] =
147{
148    "IDLE",
149    "CONNECTED",
150    "SCAN",
151    "HANDOVER"
152};
153
154TI_INT8*  ManualRoamEventDescription[] =
155{
156    "START",
157    "SCAN",
158    "CONNECT",
159    "STOP",
160    "REJECT",
161    "SUCCESS",
162    "FAIL",
163    "COMPLETE"
164};
165
166static void roamingMngr_smIdleToStart (TI_HANDLE hRoamingMngr)
167{
168    roamingMngr_t* pRoamingMngr;
169
170    pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
171    scanMngr_startManual((TI_HANDLE)pRoamingMngr->hScanMngr);
172}
173
174static void roamingMngr_smSTOP (TI_HANDLE hRoamingMngr)
175{
176    roamingMngr_t* pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
177
178    //if (SCAN_ISS_IDLE != pScanMngr->immedScanState || SCAN_CSS_IDLE!= != pScanMngr->contScanState)
179    {
180        roamingMngr_smStopWhileScanning(hRoamingMngr);
181    }
182
183    scanMngr_stopManual(pRoamingMngr->hScanMngr);
184}
185
186
187static void roamingMngr_smConnectedToScan (TI_HANDLE hRoamingMngr)
188{
189    roamingMngr_t  *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
190    TI_STATUS status = TI_OK;
191
192    status= apConn_prepareToRoaming(pRoamingMngr->hAPConnection, ROAMING_TRIGGER_NONE);
193
194    if (status  == TI_OK)
195    {
196        status = scanMngr_startImmediateScan (pRoamingMngr->hScanMngr,TI_FALSE);
197    }
198    else
199    {
200        roamingMngr_smEvent(ROAMING_MANUAL_EVENT_COMPLETE, hRoamingMngr);
201    }
202}
203
204static void roamingMngr_smConnectedToHandover(TI_HANDLE hRoamingMngr)
205{
206    roamingMngr_t  *pRoamingMngr = (roamingMngr_t*)hRoamingMngr;
207    TI_STATUS status = TI_OK;
208
209    pRoamingMngr->handoverWasPerformed = TI_TRUE;
210    status= apConn_prepareToRoaming(pRoamingMngr->hAPConnection, pRoamingMngr->roamingTrigger);
211
212    if (status  == TI_OK)
213    {
214        apConn_connectToAP(pRoamingMngr->hAPConnection, &(pRoamingMngr->targetAP.newAP), &(pRoamingMngr->targetAP.connRequest), TI_TRUE);
215    }
216    else
217    {
218        roamingMngr_smEvent(ROAMING_MANUAL_EVENT_REJECT, hRoamingMngr);
219    }
220}
221
222static void roamingMngr_smScanToConnected(TI_HANDLE hRoamingMngr)
223{
224    roamingMngr_t  *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
225    apConn_connRequest_t request;
226
227    request.dataBufLength = 0;
228    request.requestType = AP_CONNECT_RETAIN_CURR_AP;
229    apConn_connectToAP(pRoamingMngr->hAPConnection, NULL , &request , TI_FALSE);
230}
231
232static void roamingMngr_smHandoverToHandoverConnectEvent (TI_HANDLE hRoamingMngr)
233{
234	roamingMngr_t  *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
235
236    apConn_connectToAP(pRoamingMngr->hAPConnection, &(pRoamingMngr->targetAP.newAP), &(pRoamingMngr->targetAP.connRequest), TI_TRUE);
237}
238
239static void roamingMngr_smHandoverToHandoverFailEvent (TI_HANDLE hRoamingMngr)
240{
241    roamingMngr_SendReassocEvent(hRoamingMngr, REASSOC_RESP_FAILURE);
242}
243
244static void roamingMngr_smHandoverToConnectedSuccessEvent(TI_HANDLE hRoamingMngr)
245{
246    roamingMngr_SendReassocEvent(hRoamingMngr, REASSOC_RESP_SUCCESS);
247}
248
249static void roamingMngr_smHandoverToConnectedRejectEvent(TI_HANDLE hRoamingMngr)
250{
251    roamingMngr_SendReassocEvent(hRoamingMngr, REASSOC_RESP_REJECT);
252}
253
254static void roamingMngr_SendReassocEvent(TI_HANDLE hRoamingMngr, reassociationResp_e ReassResp)
255{
256	roamingMngr_t  *pRoamingMngr = (roamingMngr_t*) hRoamingMngr;
257
258    TRACE1(pRoamingMngr->hReport, REPORT_SEVERITY_INFORMATION, "roamingMngr_SendReassocEvent(): %d \n", ReassResp);
259    EvHandlerSendEvent(pRoamingMngr->hEvHandler,
260                       IPC_EVENT_REASSOCIATION_RESP,
261                       (TI_UINT8*)(&ReassResp),
262                       sizeof(reassociationResp_e));
263}
264
265
266
267