1 /* 2 * ScanCncnApp.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 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 /* start the scan */ 86 if (SCAN_CRS_SCAN_RUNNING != 87 scanCncn_Start1ShotScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT, pParam->content.pScanParams)) 88 { 89 /* Scan was not started successfully, mark that no app scan is running */ 90 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 91 return TI_NOK; 92 } 93 break; 94 95 case SCAN_CNCN_STOP_APP_SCAN: 96 /* verify that scan is currently running */ 97 if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) 98 { 99 scanCncn_StopScan (hScanCncn, SCAN_SCC_APP_ONE_SHOT); 100 } 101 break; 102 103 case SCAN_CNCN_START_PERIODIC_SCAN: 104 /* verify that scan is not currently running */ 105 if (SCAN_SCC_NO_CLIENT != pScanCncn->eCurrentRunningAppScanClient) 106 { 107 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_WARNING, "scanCncnApp_SetParam: trying to start app periodic scan when client %d is currently running!\n", pScanCncn->eCurrentRunningAppScanClient); 108 /* Scan was not started successfully, send a scan complete event to the user */ 109 return TI_NOK; 110 } 111 112 /* set one-shot scan as running app scan client */ 113 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_PERIODIC; 114 115 /* start the scan */ 116 if (SCAN_CRS_SCAN_RUNNING != 117 scanCncn_StartPeriodicScan (hScanCncn, SCAN_SCC_APP_PERIODIC, pParam->content.pPeriodicScanParams)) 118 { 119 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_CONSOLE , "Scan was not started. Verify scan parametrs or SME mode\n"); 120 WLAN_OS_REPORT (("Scan was not started. Verify scan parametrs or SME mode\n")); 121 122 /* Scan was not started successfully, mark that no app scan is running */ 123 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 124 return TI_NOK; 125 } 126 break; 127 128 case SCAN_CNCN_STOP_PERIODIC_SCAN: 129 /* verify that scan is currently running */ 130 if (pScanCncn->eCurrentRunningAppScanClient != SCAN_SCC_NO_CLIENT) 131 { 132 scanCncn_StopPeriodicScan (hScanCncn, SCAN_SCC_APP_PERIODIC); 133 } 134 break; 135 136 case SCAN_CNCN_BSSID_LIST_SCAN_PARAM: 137 /* check if OID scans are enabled in the registry */ 138 if (0 == pScanCncn->tInitParams.uMinimumDurationBetweenOsScans) 139 { 140 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_SetParam: received OS scan request when OS scans are disabled, quitting...\n"); 141 return TI_NOK; 142 } 143 144 /* check if the last OID scan didn't start at a shorter duration than the configured minimum */ 145 uCurrentTimeStamp = os_timeStampMs (pScanCncn->hOS); 146 if ( (uCurrentTimeStamp - pScanCncn->uOSScanLastTimeStamp) < 147 (pScanCncn->tInitParams.uMinimumDurationBetweenOsScans * 1000) ) /*converted to ms */ 148 { 149 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); 150 return TI_NOK; 151 } 152 153 /* check that no other scan is currently running */ 154 if (SCAN_SCC_NO_CLIENT != pScanCncn->eCurrentRunningAppScanClient) 155 { 156 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnApp_SetParam: received OS scan request when client %d is currently running!\n", pScanCncn->eCurrentRunningAppScanClient); 157 return TI_NOK; 158 } 159 160 /* set one-shot scan as running app scan client */ 161 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_APP_ONE_SHOT; 162 163 /* mark that an OID scan process has started */ 164 pScanCncn->bOSScanRunning = TI_TRUE; 165 pScanCncn->uOSScanLastTimeStamp = uCurrentTimeStamp; 166 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_SetParam: starting OID scan process...\n"); 167 168 if(0 != pParam->content.tScanDesiredSSID.len) 169 { 170 pScanCncn->tOsScanParams.desiredSsid.len = pParam->content.tScanDesiredSSID.len; 171 os_memoryCopy(pScanCncn->hOS, pScanCncn->tOsScanParams.desiredSsid.str, pParam->content.tScanDesiredSSID.str, pParam->content.tScanDesiredSSID.len); 172 } 173 else 174 { 175 pScanCncn->tOsScanParams.desiredSsid.len = 0; 176 pScanCncn->tOsScanParams.desiredSsid.str[ 0 ] = '\0'; /* broadcast scan */ 177 } 178 179 /* and actually start the scan */ 180 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_START_SCAN, hScanCncn); 181 182 break; 183 184 default: 185 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnApp_SetParam: unrecognized param type :%d\n", pParam->paramType); 186 return PARAM_NOT_SUPPORTED; 187 } 188 189 return TI_OK; 190 } 191 192 /** 193 * \fn scanCncnApp_GetParam 194 * \brief Parses and executes a get param command 195 * 196 * Parses and executes a get param command (get BSSID list) 197 * 198 * \param hScanCncn - handle to the scan concentrator object 199 * \param pParam - the param to get 200 * \return operation status (OK / NOK / PARAM_NOT_SUPPORTED) 201 * \sa scanCncnApp_SetParam 202 */ 203 TI_STATUS scanCncnApp_GetParam (TI_HANDLE hScanCncn, paramInfo_t *pParam) 204 { 205 TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; 206 207 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncnApp_GetParam: received request of type %d\n", pParam->paramType); 208 209 switch (pParam->paramType) 210 { 211 case SCAN_CNCN_BSSID_LIST_SIZE_PARAM: 212 /* retrieves the size to allocate for the app scan result taBle BBSID list (see next code) */ 213 pParam->paramLength = sizeof(TI_UINT32); 214 pParam->content.uBssidListSize = 215 scanResultTable_CalculateBssidListSize (pScanCncn->hScanResultTable, TI_FALSE); 216 break; 217 218 case SCAN_CNCN_BSSID_LIST_PARAM: 219 /* retrieve the app scan result table */ 220 return scanResultTable_GetBssidList (pScanCncn->hScanResultTable, pParam->content.pBssidList, 221 &pParam->paramLength, TI_FALSE); 222 break; 223 224 default: 225 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncnApp_GetParam: unrecognized param type :%d\n", pParam->paramType); 226 return PARAM_NOT_SUPPORTED; 227 } 228 229 return TI_OK; 230 } 231 232 /** 233 * \fn scanCncn_AppScanResultCB 234 * \brief Scan result callback for application scan 235 * 236 * Scan result callback for application scan 237 * 238 * \param hScanCncn - handle to the scan concentrator object 239 * \param status - the scan result status (scan complete, result received etc.) 240 * \param frameInfo - a pointer to the structure holding all frame related info (in case a frame was received) 241 * \param SPSStatus - a bitmap indicating on which channels scan was attempted (valid for SPS scan only!) 242 * \return None 243 */ 244 void scanCncn_AppScanResultCB (TI_HANDLE hScanCncn, EScanCncnResultStatus status, 245 TScanFrameInfo* frameInfo, TI_UINT16 SPSStatus) 246 { 247 TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; 248 TI_UINT32 statusData; 249 250 /* forward all data to SME */ 251 sme_AppScanResult (pScanCncn->hSme, status, frameInfo); 252 253 switch (status) 254 { 255 case SCAN_CRS_RECEIVED_FRAME: 256 /* Save the result in the app scan result table */ 257 if (TI_OK != scanResultTable_UpdateEntry (pScanCncn->hScanResultTable, frameInfo->bssId, frameInfo)) 258 { 259 TRACE0(pScanCncn->hReport, REPORT_SEVERITY_WARNING , "scanCncn_AppScanResultCB, scanResultTable_UpdateEntry() failed\n"); 260 } 261 break; 262 263 case SCAN_CRS_SCAN_COMPLETE_OK: 264 265 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_AppScanResultCB, received scan complete with status :%d\n", status); 266 267 /* if OS scan is running */ 268 if (TI_TRUE == pScanCncn->bOSScanRunning) 269 { 270 /* send a scan complete event to the OS scan SM. It will stabliza the table when needed */ 271 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); 272 } 273 else 274 { 275 /* move the scan result table to stable state, clear it if no results were received */ 276 scanResultTable_SetStableState (pScanCncn->hScanResultTable); 277 278 /* mark that no app scan is running */ 279 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 280 /* 281 * The scan was finished, send a scan complete event to the user 282 * (regardless of why the scan was completed) 283 */ 284 statusData = SCAN_STATUS_COMPLETE; /* Completed status */ 285 EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_COMPLETE, (TI_UINT8 *)&statusData, sizeof(TI_UINT32)); 286 } 287 break; 288 289 case SCAN_CRS_SCAN_STOPPED: 290 291 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_AppScanResultCB, received scan complete with status :%d\n", status); 292 293 /* if OS scan is running */ 294 if (TI_TRUE == pScanCncn->bOSScanRunning) 295 { 296 /* send a scan complete event to the OS scan SM. It will stabliza the table when needed */ 297 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); 298 } 299 else 300 { 301 /* move the scan result table to stable state, clear it if no results were received */ 302 scanResultTable_SetStableState (pScanCncn->hScanResultTable); 303 304 /* mark that no app scan is running */ 305 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 306 /* 307 * The scan was finished, send a scan complete event to the user 308 * (regardless of why the scan was completed) 309 */ 310 statusData = SCAN_STATUS_STOPPED; /* Stopped status */ 311 EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_COMPLETE, (TI_UINT8 *)&statusData, sizeof(TI_UINT32)); 312 } 313 break; 314 315 case SCAN_CRS_TSF_ERROR: 316 case SCAN_CRS_SCAN_RUNNING: 317 case SCAN_CRS_SCAN_FAILED: 318 case SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY: 319 case SCAN_CRS_SCAN_ABORTED_FW_RESET: 320 321 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_AppScanResultCB, received scan complete with status :%d\n", status); 322 323 /* if OS scan is running */ 324 if (TI_TRUE == pScanCncn->bOSScanRunning) 325 { 326 /* send a scan complete event to the OS scan SM. It will stabliza the table when needed */ 327 genSM_Event (pScanCncn->hOSScanSm, SCAN_CNCN_OS_SM_EVENT_SCAN_COMPLETE, hScanCncn); 328 } 329 else 330 { 331 /* move the scan result table to stable state, clear it if no results were received */ 332 scanResultTable_SetStableState (pScanCncn->hScanResultTable); 333 334 /* mark that no app scan is running */ 335 pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; 336 /* 337 * The scan was finished, send a scan complete event to the user 338 * (regardless of why the scan was completed) 339 */ 340 statusData = SCAN_STATUS_FAILED; /* Failed status */ 341 EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_COMPLETE, (TI_UINT8 *)&statusData, sizeof(TI_UINT32)); 342 } 343 break; 344 345 case SCAN_CRS_NUM_OF_RES_STATUS: 346 default: 347 TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_AppScanResultCB, received erroneuos scan result with status :%d\n", status); 348 break; 349 } 350 } 351 352