1 /* 2 * ScanCncnApp.c 3 * 4 * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** \file ScanCncnApp.c 35 * \brief Scan concentrator application scan module implementation 36 * 37 * \see ScanCncn.h, ScanCncn.c 38 */ 39 40 41 #define __FILE_ID__ FILE_ID_77 42 #include "ScanCncnPrivate.h" 43 #include "ScanCncn.h" 44 #include "ScanCncnOsSm.h" 45 #include "EvHandler.h" 46 #include "report.h" 47 #include "GenSM.h" 48 #include "scanResultTable.h" 49 #include "sme.h" 50 #include "smeApi.h" 51 52 /** 53 * \fn scanCncnApp_SetParam 54 * \brief Parses and executes a set param command 55 * 56 * Parses and executes a set param command (start/stop one-shot/periodic/OS scan) 57 * 58 * \param hScanCncn - handle to the scan concentrator object 59 * \param pParam - the param to set 60 * \return operation status (OK / NOK / PARAM_NOT_SUPPORTED) 61 * \sa scanCncnApp_GetParam 62 */ 63 TI_STATUS scanCncnApp_SetParam (TI_HANDLE hScanCncn, paramInfo_t *pParam) 64 { 65 TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; 66 TI_UINT32 uCurrentTimeStamp; 67 68 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_SetParam: recevived request of type 0x%x\n", pParam->paramType); 69 70 switch (pParam->paramType) 71 { 72 case SCAN_CNCN_START_APP_SCAN: 73 74 /* verify that scan is not currently running */ 75 if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) 76 { 77 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_WARNING, "scanCncnApp_SetParam: trying to start app one-shot scan when client %d is currently running!\n", pScanCncn->eCurrentRunningAppScanClient); 78 /* Scan was not started successfully, send a scan complete event to the user */ 79 return TI_NOK; 80 } 81 82 /* set one-shot scan as running app scan client */ 83 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_ONE_SHOT; 84 85 /* Perform aging process before the scan */ 86 scanResultTable_PerformAging(pScanCncn->hScanResultTable); 87 88 /* start the scan */ 89 if (SCAN_CRS_SCAN_RUNNING != 90 scanCncn_Start1ShotScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT, pParam->content.pScanParams)) 91 { 92 /* Scan was not started successfully, mark that no app scan is running */ 93 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 94 return TI_NOK; 95 } 96 break; 97 98 case SCAN_CNCN_STOP_APP_SCAN: 99 /* verify that scan is currently running */ 100 if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) 101 { 102 scanCncn_StopScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT); 103 } 104 break; 105 106 case SCAN_CNCN_START_PERIODIC_SCAN: 107 /* verify that scan is not currently running */ 108 if (SCAN_SCC_NO_CLIENT != pScanCncn->eCurrentRunningAppScanClient) 109 { 110 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_WARNING, "scanCncnApp_SetParam: trying to start app periodic scan when client %d is currently running!\n", pScanCncn->eCurrentRunningAppScanClient); 111 /* Scan was not started successfully, send a scan complete event to the user */ 112 return TI_NOK; 113 } 114 115 /* set one-shot scan as running app scan client */ 116 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_PERIODIC; 117 118 /* Perform aging process before the scan */ 119 scanResultTable_PerformAging(pScanCncn->hScanResultTable); 120 121 /* start the scan */ 122 if (SCAN_CRS_SCAN_RUNNING != 123 scanCncn_StartPeriodicScan (hScanCncn, SCAN_SCC_APP_PERIODIC, pParam->content.pPeriodicScanParams)) 124 { 125 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_CONSOLE , "Scan was not started. Verify scan parametrs or SME mode\n"); 126 WLAN_OS_REPORT (("Scan was not started. Verify scan parametrs or SME mode\n")); 127 128 /* Scan was not started successfully, mark that no app scan is running */ 129 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 130 return TI_NOK; 131 } 132 break; 133 134 case SCAN_CNCN_STOP_PERIODIC_SCAN: 135 /* verify that scan is currently running */ 136 if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) 137 { 138 scanCncn_StopPeriodicScan (hScanCncn, SCAN_SCC_APP_PERIODIC); 139 } 140 break; 141 142 case SCAN_CNCN_BSSID_LIST_SCAN_PARAM: 143 /* check if OID scans are enabled in the registry */ 144 if (0 == pScanCncn->tInitParams.uMinimumDurationBetweenOsScans) 145 { 146 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_SetParam: received OS scan request when OS scans are disabled, quitting...\n"); 147 return TI_NOK; 148 } 149 150 /* check if the last OID scan didn't start at a shorter duration than the configured minimum */ 151 uCurrentTimeStamp = os_timeStampMs (pScanCncn->hOS); 152 if ( (uCurrentTimeStamp - pScanCncn->uOSScanLastTimeStamp) < 153 (pScanCncn->tInitParams.uMinimumDurationBetweenOsScans * 1000) ) /*converted to ms */ 154 { 155 TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_SetParam: last OID scan performed at: %d, now is: %d, min duration is: %d, too early for another scan!\n", pScanCncn->uOSScanLastTimeStamp, uCurrentTimeStamp, pScanCncn->tInitParams.uMinimumDurationBetweenOsScans); 156 return TI_NOK; 157 } 158 159 /* check that no other scan is currently running */ 160 if (SCAN_SCC_NO_CLIENT != pScanCncn->eCurrentRunningAppScanClient) 161 { 162 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnApp_SetParam: received OS scan request when client %d is currently running!\n", pScanCncn->eCurrentRunningAppScanClient); 163 return TI_NOK; 164 } 165 166 /* set one-shot scan as running app scan client */ 167 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_ONE_SHOT; 168 169 /* mark that an OID scan process has started */ 170 pScanCncn->bOSScanRunning = TI_TRUE; 171 pScanCncn->uOSScanLastTimeStamp = uCurrentTimeStamp; 172 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_SetParam: starting OID scan process...\n"); 173 174 if(0 != pParam->content.pScanParams->desiredSsid.len) 175 { 176 pScanCncn->tOsScanParams.desiredSsid.len = pParam->content.pScanParams->desiredSsid.len; 177 os_memoryCopy(pScanCncn->hOS, pScanCncn->tOsScanParams.desiredSsid.str, pParam->content.pScanParams->desiredSsid.str, pParam->content.pScanParams->desiredSsid.len); 178 } 179 else 180 { 181 pScanCncn->tOsScanParams.desiredSsid.len = 0; 182 pScanCncn->tOsScanParams.desiredSsid.str[ 0 ] = '\0'; /* broadcast scan */ 183 } 184 185 pScanCncn->tOsScanParams.scanType = pParam->content.pScanParams->scanType; 186 187 /* and actually start the scan */ 188 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_START_SCAN, hScanCncn); 189 190 break; 191 192 case SCAN_CNCN_SET_SRA: 193 scanResultTable_SetSraThreshold(pScanCncn->hScanResultTable, pParam->content.uSraThreshold); 194 break; 195 196 case SCAN_CNCN_SET_RSSI: 197 pScanCncn->tInitParams.nRssiThreshold = pParam->content.nRssiThreshold; 198 break; 199 200 default: 201 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnApp_SetParam: unrecognized param type :%d\n", pParam->paramType); 202 return PARAM_NOT_SUPPORTED; 203 } 204 205 return TI_OK; 206 } 207 208 /** 209 * \fn scanCncnApp_GetParam 210 * \brief Parses and executes a get param command 211 * 212 * Parses and executes a get param command (get BSSID list) 213 * 214 * \param hScanCncn - handle to the scan concentrator object 215 * \param pParam - the param to get 216 * \return operation status (OK / NOK / PARAM_NOT_SUPPORTED) 217 * \sa scanCncnApp_SetParam 218 */ 219 TI_STATUS scanCncnApp_GetParam (TI_HANDLE hScanCncn, paramInfo_t *pParam) 220 { 221 TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; 222 223 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_GetParam: received request of type %d\n", pParam->paramType); 224 225 switch (pParam->paramType) 226 { 227 228 case SCAN_CNCN_NUM_BSSID_IN_LIST_PARAM: 229 /* retrieve the number of BSSID's in the scan result table*/ 230 pParam->paramLength = sizeof(TI_UINT32); 231 pParam->content.uNumBssidInList = scanResultTable_GetNumOfBSSIDInTheList (pScanCncn->hScanResultTable); 232 break; 233 234 case SCAN_CNCN_BSSID_LIST_SIZE_PARAM: 235 /* retrieves the size to allocate for the app scan result taBle BBSID list (see next code) */ 236 pParam->paramLength = sizeof(TI_UINT32); 237 pParam->content.uBssidListSize = scanResultTable_CalculateBssidListSize (pScanCncn->hScanResultTable, TI_TRUE); 238 break; 239 240 case SCAN_CNCN_BSSID_LIST_PARAM: 241 /* retrieve the app scan result table */ 242 return scanResultTable_GetBssidList (pScanCncn->hScanResultTable, pParam->content.pBssidList, 243 &pParam->paramLength, TI_TRUE); 244 245 case SCAN_CNCN_BSSID_RATE_LIST_PARAM: 246 /* retrieve supported rates list equivalent to the supported rates list 247 in the scan result table, but is extended to include 11n rates as well*/ 248 return scanResultTable_GetBssidSupportedRatesList (pScanCncn->hScanResultTable, pParam->content.pRateList, 249 &pParam->paramLength); 250 251 default: 252 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnApp_GetParam: unrecognized param type :%d\n", pParam->paramType); 253 return PARAM_NOT_SUPPORTED; 254 } 255 256 return TI_OK; 257 } 258 259 /** 260 * \fn scanCncn_AppScanResultCB 261 * \brief Scan result callback for application scan 262 * 263 * Scan result callback for application scan 264 * 265 * \param hScanCncn - handle to the scan concentrator object 266 * \param status - the scan result status (scan complete, result received etc.) 267 * \param frameInfo - a pointer to the structure holding all frame related info (in case a frame was received) 268 * \param SPSStatus - a bitmap indicating on which channels scan was attempted (valid for SPS scan only!) 269 * \return None 270 */ 271 void scanCncn_AppScanResultCB (TI_HANDLE hScanCncn, EScanCncnResultStatus status, 272 TScanFrameInfo* frameInfo, TI_UINT16 SPSStatus) 273 { 274 TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; 275 TI_UINT32 statusData; 276 277 /* Since in Manual Mode the app and the SME use the same table 278 * there is no need to forward data to SME */ 279 280 switch (status) 281 { 282 case SCAN_CRS_RECEIVED_FRAME: 283 /* Save the result in the app scan result table */ 284 if (TI_OK != scanResultTable_UpdateEntry (pScanCncn->hScanResultTable, frameInfo->bssId, frameInfo)) 285 { 286 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_WARNING , "scanCncn_AppScanResultCB, scanResultTable_UpdateEntry() failed\n"); 287 } 288 break; 289 290 case SCAN_CRS_SCAN_COMPLETE_OK: 291 292 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_AppScanResultCB, received scan complete with status :%d\n", status); 293 294 /* if OS scan is running */ 295 if (TI_TRUE == pScanCncn->bOSScanRunning) 296 { 297 /* send a scan complete event to the OS scan SM. It will stabliza the table when needed */ 298 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); 299 } 300 else 301 { 302 /* move the scan result table to stable state */ 303 scanResultTable_SetStableState (pScanCncn->hScanResultTable); 304 305 /* mark that no app scan is running */ 306 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 307 /* 308 * The scan was finished, send a scan complete event to the user 309 * (regardless of why the scan was completed) 310 */ 311 statusData = SCAN_STATUS_COMPLETE; /* Completed status */ 312 EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_COMPLETE, (TI_UINT8 *)&statusData, sizeof(TI_UINT32)); 313 } 314 break; 315 316 case SCAN_CRS_SCAN_STOPPED: 317 318 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_AppScanResultCB, received scan complete with status :%d\n", status); 319 320 /* if OS scan is running */ 321 if (TI_TRUE == pScanCncn->bOSScanRunning) 322 { 323 /* send a scan complete event to the OS scan SM. It will stabliza the table when needed */ 324 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); 325 } 326 else 327 { 328 /* move the scan result table to stable state */ 329 scanResultTable_SetStableState (pScanCncn->hScanResultTable); 330 331 /* mark that no app scan is running */ 332 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 333 /* 334 * The scan was finished, send a scan complete event to the user 335 * (regardless of why the scan was completed) 336 */ 337 statusData = SCAN_STATUS_STOPPED; /* Stopped status */ 338 EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_COMPLETE, (TI_UINT8 *)&statusData, sizeof(TI_UINT32)); 339 } 340 break; 341 342 case SCAN_CRS_TSF_ERROR: 343 case SCAN_CRS_SCAN_RUNNING: 344 case SCAN_CRS_SCAN_FAILED: 345 case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY: 346 case SCAN_CRS_SCAN_ABORTED_FW_RESET: 347 348 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_AppScanResultCB, received scan complete with status :%d\n", status); 349 350 /* if OS scan is running */ 351 if (TI_TRUE == pScanCncn->bOSScanRunning) 352 { 353 /* send a scan complete event to the OS scan SM. It will stabliza the table when needed */ 354 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); 355 } 356 else 357 { 358 /* move the scan result table to stable state */ 359 scanResultTable_SetStableState (pScanCncn->hScanResultTable); 360 361 /* mark that no app scan is running */ 362 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 363 /* 364 * The scan was finished, send a scan complete event to the user 365 * (regardless of why the scan was completed) 366 */ 367 statusData = SCAN_STATUS_FAILED; /* Failed status */ 368 EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_COMPLETE, (TI_UINT8 *)&statusData, sizeof(TI_UINT32)); 369 } 370 break; 371 372 case SCAN_CRS_NUM_OF_RES_STATUS: 373 default: 374 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_AppScanResultCB, received erroneuos scan result with status :%d\n", status); 375 break; 376 } 377 } 378 379