diff options
Diffstat (limited to 'wl1271/stad/src/Sta_Management/ScanCncn.c')
-rw-r--r-- | wl1271/stad/src/Sta_Management/ScanCncn.c | 1508 |
1 files changed, 0 insertions, 1508 deletions
diff --git a/wl1271/stad/src/Sta_Management/ScanCncn.c b/wl1271/stad/src/Sta_Management/ScanCncn.c deleted file mode 100644 index b44da4c..0000000 --- a/wl1271/stad/src/Sta_Management/ScanCncn.c +++ /dev/null @@ -1,1508 +0,0 @@ -/* - * ScanCncn.c - * - * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Texas Instruments nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** \file ScanCncn.c - * \brief Scan concentartor implementation - * - * \see ScanCncnSm.c, ScanCncnSmSpecific.c - */ - - -#define __FILE_ID__ FILE_ID_76 -#include "ScanCncn.h" -#include "report.h" -#include "scrApi.h" -#include "regulatoryDomainApi.h" -#include "siteMgrApi.h" -#include "healthMonitor.h" -#include "TWDriver.h" -#include "DrvMainModules.h" -#include "GenSM.h" -#include "ScanCncnPrivate.h" -#include "ScanCncnOsSm.h" -#include "scanResultTable.h" -#include "smeApi.h" -#include "apConnApi.h" -#include "EvHandler.h" - -/* static functions */ -void scanCncn_SGupdateScanParams (TI_HANDLE hScanCncn, UScanParams *puScanParams, TI_BOOL bPeriodicScan) ; -static void scanCncn_VerifyChannelsWithRegDomain (TI_HANDLE hScanCncn, UScanParams *puScanParams, TI_BOOL bPeriodicScan); -static void scanCncn_Mix1ShotScanChannels (TScanChannelEntry *pChannelArray, TI_UINT32 uValidChannelsCount); -static void scanCncn_MixPeriodicScanChannels (TPeriodicChannelEntry *pChannelArray, TI_UINT32 uValidChannelsCount); - -#define SCAN_CLIENT_FROM_TAG( tag ) tag2Client[ tag ]; -static EScanCncnClient tag2Client[ SCAN_RESULT_TAG_MAX_NUMBER ] = - { SCAN_SCC_NO_CLIENT, SCAN_SCC_APP_ONE_SHOT, SCAN_SCC_DRIVER, SCAN_SCC_APP_PERIODIC, SCAN_SCC_NO_CLIENT, - SCAN_SCC_ROAMING_IMMED, SCAN_SCC_ROAMING_CONT }; - -/** - * \fn scanCncn_Create - * \brief Create the scan concentrator object - * - * Create the scan concentrator object. Allocates system resources and creates the client modules. - * - * \param hOS - handle to the OS object - * \return hanlde to the new scan concentrator object - * \sa scanCncn_Destroy, scanCncn_Init, scanCncn_SetDefaults - */ -TI_HANDLE scanCncn_Create (TI_HANDLE hOS) -{ - TScanCncn *pScanCncn; - TI_UINT32 uIndex; - - /* Allocate scan concentartor object memory */ - pScanCncn = (TScanCncn*)os_memoryAlloc (hOS, sizeof (TScanCncn)); - if (NULL == pScanCncn) - { - WLAN_OS_REPORT (("scanCncn_Create: Unable to allocate memory for scan concentrator object\n")); - return NULL; - } - - /* nullify the new object */ - os_memorySet (hOS, (void*)pScanCncn, 0, sizeof (TScanCncn)); - - /* Store OS handle */ - pScanCncn->hOS = hOS; - - /* Create different clients */ - for (uIndex = 0; uIndex < SCAN_SCC_NUM_OF_CLIENTS; uIndex++) - { - pScanCncn->pScanClients[ uIndex ] = scanCncnSm_Create (hOS); - if (NULL == pScanCncn->pScanClients[ uIndex ]) - { - WLAN_OS_REPORT (("scanCncn_Create: Unable to create client %d object\n", uIndex)); - /* free all resources allocated so far */ - scanCncn_Destroy ((TI_HANDLE)pScanCncn); - return NULL; - } - } - - /* create the OS scan SM */ - pScanCncn->hOSScanSm = scanCncnOsSm_Create ((TI_HANDLE)pScanCncn); - if (NULL == pScanCncn->hOSScanSm) - { - WLAN_OS_REPORT (("scanCncn_Create: Unable to create OS scan SM\n")); - /* free all resources allocated so far */ - scanCncn_Destroy ((TI_HANDLE)pScanCncn); - return NULL; - } - - /* create the app scan result table */ - pScanCncn->hScanResultTable = scanResultTable_Create (hOS, SCAN_CNCN_APP_SCAN_TABLE_ENTRIES); - if (NULL == pScanCncn->hScanResultTable) - { - WLAN_OS_REPORT (("scanCncn_Create: Unable to create application scan result table\n")); - /* free all resources allocated so far */ - scanCncn_Destroy ((TI_HANDLE)pScanCncn); - return NULL; - } - - /* return handle to the new object */ - return (TI_HANDLE)pScanCncn; -} - -/** - * \fn scanCncn_Destroy - * \brief Destroys the scan concentrator object - * - * Destroys the scan concentrator object. Destroys the cleint modules and frees system resources. - * - * \param hScanCncn - handle to the scan concentrator object - * \return None - * \sa scanCncn_Create - */ -void scanCncn_Destroy (TI_HANDLE hScanCncn) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - TI_UINT32 uIndex; - - /* destory the app scan result table */ - scanResultTable_Destroy (pScanCncn->hScanResultTable); - - /* destroy the OS scan SM */ - scanCncnOsSm_Destroy (hScanCncn); - - /* destroy the client objects */ - for (uIndex = 0; uIndex < SCAN_SCC_NUM_OF_CLIENTS; uIndex++) - { - scanCncnSm_Destroy (pScanCncn->pScanClients[ uIndex ]); - } - - /* release the scan concentrator object */ - os_memoryFree (pScanCncn->hOS, hScanCncn, sizeof (TScanCncn)); -} - -/** - * \fn scanCncn_Init - * \brief Initializes the scan concentartor module - * - * Copy handles, register callbacks and initialize client modules - * - * \param pStadHandles - modules handles structure - * \return None - * \sa scanCncn_Create, scanCncn_SetDefaults - */ -void scanCncn_Init (TStadHandlesList *pStadHandles) -{ - TScanCncn *pScanCncn = (TScanCncn*)pStadHandles->hScanCncn; - - /* store handles */ - pScanCncn->hTWD = pStadHandles->hTWD; - pScanCncn->hReport = pStadHandles->hReport; - pScanCncn->hRegulatoryDomain = pStadHandles->hRegulatoryDomain; - pScanCncn->hSiteManager = pStadHandles->hSiteMgr; - pScanCncn->hSCR = pStadHandles->hSCR; - pScanCncn->hAPConn = pStadHandles->hAPConnection; - pScanCncn->hEvHandler = pStadHandles->hEvHandler; - pScanCncn->hMlme = pStadHandles->hMlmeSm; - pScanCncn->hHealthMonitor = pStadHandles->hHealthMonitor; - pScanCncn->hSme = pStadHandles->hSme; - - /* nullify other parameters */ - pScanCncn->eConnectionStatus = STA_NOT_CONNECTED; - pScanCncn->bUseSGParams = TI_FALSE; /* bUseSGParams is TI_TRUE only when SG module is enabled */ - pScanCncn->eCurrentRunningAppScanClient = SCAN_SCC_NO_CLIENT; - pScanCncn->uOSScanLastTimeStamp = 0; - pScanCncn->bOSScanRunning = TI_FALSE; - - /* initialize client objects */ - scanCncnSm_Init (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ], pScanCncn->hReport, pScanCncn->hTWD, - pScanCncn->hSCR, pScanCncn->hAPConn, pScanCncn->hMlme, (TI_HANDLE)pScanCncn, - scanCncnSmImmed1Shot_ScrRequest, scanCncnSmImmed1Shot_ScrRelease, scanCncnSmImmed1Shot_StartScan, - scanCncnSmImmed1Shot_StopScan, scanCncnSmImmed1Shot_Recovery, "Immediate scan SM"); - scanCncnSm_Init (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ], pScanCncn->hReport, pScanCncn->hTWD, - pScanCncn->hSCR, pScanCncn->hAPConn, pScanCncn->hMlme, (TI_HANDLE)pScanCncn, - scanCncnSmCont1Shot_ScrRequest, scanCncnSmCont1Shot_ScrRelease, scanCncnSmCont1Shot_StartScan, - scanCncnSmCont1Shot_StopScan, scanCncnSmCont1Shot_Recovery, "Continuous scan SM"); - scanCncnSm_Init (pScanCncn->pScanClients[ SCAN_SCC_DRIVER ], pScanCncn->hReport, pScanCncn->hTWD, - pScanCncn->hSCR, pScanCncn->hAPConn, pScanCncn->hMlme, (TI_HANDLE)pScanCncn, - scanCncnSmDrvP_ScrRequest, scanCncnSmDrvP_ScrRelease, scanCncnSmDrvP_StartScan, - scanCncnSmDrvP_StopScan, scanCncnSmDrvP_Recovery, "Driver scan SM"); - scanCncnSm_Init (pScanCncn->pScanClients[ SCAN_SCC_APP_PERIODIC ], pScanCncn->hReport, pScanCncn->hTWD, - pScanCncn->hSCR, pScanCncn->hAPConn, pScanCncn->hMlme, (TI_HANDLE)pScanCncn, - scanCncnSmAppP_ScrRequest, scanCncnSmAppP_ScrRelease, scanCncnSmAppP_StartScan, - scanCncnSmAppP_StopScan, scanCncnSmAppP_Recovery, "Periodic application scan SM"); - scanCncnSm_Init (pScanCncn->pScanClients[ SCAN_SCC_APP_ONE_SHOT ], pScanCncn->hReport, pScanCncn->hTWD, - pScanCncn->hSCR, pScanCncn->hAPConn, pScanCncn->hMlme, (TI_HANDLE)pScanCncn, - scanCncnSmApp1Shot_ScrRequest, scanCncnSmApp1Shot_ScrRelease, scanCncnSmApp1Shot_StartScan, - scanCncnSmApp1Shot_StopScan, scanCncnSmApp1Shot_Recovery, "One-shot application scan SM"); - - /* Initialize the OS scan SM */ - scanCncnOsSm_Init ((TI_HANDLE)pScanCncn); - - /* initlaize the application scan result table */ - scanResultTable_Init (pScanCncn->hScanResultTable, pStadHandles, SCAN_RESULT_TABLE_DONT_CLEAR); -} - -/** - * \fn scanCncn_SetDefaults - * \brief Set registry values to scan concentrator - * - * Set registry values to scan concentrator - * - * \param hScanCncn - handle to the scan concentrator object - * \param pScanConcentratorInitParams - pointer to the registry parameters struct - * \return None - * \sa scanCncn_Create, scanCncn_Init - */ -void scanCncn_SetDefaults (TI_HANDLE hScanCncn, TScanCncnInitParams *pScanCncnInitParams) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - /* copy registry values */ - os_memoryCopy (pScanCncn->hOS, - &pScanCncn->tInitParams, - pScanCncnInitParams, - sizeof (TScanCncnInitParams)); - - /* register SCR callbacks */ - scr_registerClientCB (pScanCncn->hSCR, SCR_CID_APP_SCAN, scanCncn_ScrAppCB, (TI_HANDLE)pScanCncn); - scr_registerClientCB (pScanCncn->hSCR, SCR_CID_DRIVER_FG_SCAN, scanCncn_ScrDriverCB, (TI_HANDLE)pScanCncn); - scr_registerClientCB (pScanCncn->hSCR, SCR_CID_CONT_SCAN, scanCncn_ScrRoamingContCB, (TI_HANDLE)pScanCncn); - scr_registerClientCB (pScanCncn->hSCR, SCR_CID_IMMED_SCAN, scanCncn_ScrRoamingImmedCB, (TI_HANDLE)pScanCncn); - - /* register TWD scan complete CB */ - TWD_RegisterScanCompleteCb (pScanCncn->hTWD, scanCncn_ScanCompleteNotificationCB, - (TI_HANDLE)pScanCncn); - /* register and enable periodic scan complete event with TWD */ - TWD_RegisterEvent (pScanCncn->hTWD, TWD_OWN_EVENT_PERIODIC_SCAN_COMPLETE, - (void *)scanCncn_PeriodicScanCompleteCB, (TI_HANDLE)pScanCncn); - TWD_EnableEvent (pScanCncn->hTWD, TWD_OWN_EVENT_PERIODIC_SCAN_COMPLETE); - - /* and periodic scan report */ - TWD_RegisterEvent (pScanCncn->hTWD, TWD_OWN_EVENT_PERIODIC_SCAN_REPORT, - (void *)scanCncn_PeriodicScanReportCB, (TI_HANDLE)pScanCncn); - TWD_EnableEvent (pScanCncn->hTWD, TWD_OWN_EVENT_PERIODIC_SCAN_REPORT); - - /* "register" the application scan result callback */ - scanCncn_RegisterScanResultCB ((TI_HANDLE)pScanCncn, SCAN_SCC_APP_ONE_SHOT, scanCncn_AppScanResultCB, (TI_HANDLE)pScanCncn); - scanCncn_RegisterScanResultCB ((TI_HANDLE)pScanCncn, SCAN_SCC_APP_PERIODIC, scanCncn_AppScanResultCB, (TI_HANDLE)pScanCncn); - - /* set the Scan Result Aging threshold for the scan concentrator's Scan Result Table */ - scanResultTable_SetSraThreshold(pScanCncn->hScanResultTable, pScanCncnInitParams->uSraThreshold); - - /* set to the sme the handler of the scan concentrator Scan Result Table */ - sme_SetScanResultTable(pScanCncn->hSme, pScanCncn->hScanResultTable); -} - -/** - * \fn scanCncn_SwitchToConnected - * \brief Notifies the scan concentratoe the STA has connected to an infrastructure BSS - * - * Notifies the scan concentratoe the STA has connected to an infrastructure BSS - * - * \param hScanCncn - handle to the scan concentrator object - * \return None - * \sa scanCncn_SwitchToNotConnected, scanCncn_SwitchToIBSS - */ -void scanCncn_SwitchToConnected (TI_HANDLE hScanCncn) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_SwitchToConnected: Switching to connected state.\n"); - - /* change connection status to connected */ - pScanCncn->eConnectionStatus = STA_CONNECTED; - - /* Any running scans in other modes will be aborted (if needed) by the SCR (or have already been) */ -} - -/** - * \fn scanCncn_SwitchToNotConnected - * \brief Notifies the scan concentratoe the STA has disconnected from a BSS - * - * Notifies the scan concentratoe the STA has disconnected from a BSS - * - * \param hScanCncn - handle to the scan concentrator object - * \return None - * \sa scanCncn_SwitchToConnected, scanCncn_SwitchToIBSS - */ -void scanCncn_SwitchToNotConnected (TI_HANDLE hScanCncn) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_SwitchToNotConnected: Switching to not connected state.\n"); - - /* change connection status to connected */ - pScanCncn->eConnectionStatus = STA_NOT_CONNECTED; - - /* Any running scans in other modes will be aborted (if needed) by the SCR (or have already been) */ -} - -/** - * \fn scanCncn_SwitchToIBSS - * \brief Notifies the scan concentratoe the STA has connected to an independent BSS - * - * Notifies the scan concentratoe the STA has connected to an independent BSS - * - * \param hScanCncn - handle to the scan concentrator object - * \return None - * \sa scanCncn_SwitchToConnected, scanCncn_SwitchToNotConnected - */ -void scanCncn_SwitchToIBSS (TI_HANDLE hScanCncn) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_SwitchToIBSS: Switching to IBSS state.\n"); - - /* change connection status to connected */ - pScanCncn->eConnectionStatus = STA_IBSS; - - /* Any running scans in other modes will be aborted (if needed) by the SCR (or have already been) */ -} - -EScanCncnResultStatus scanCncn_Start1ShotScan (TI_HANDLE hScanCncn, - EScanCncnClient eClient, - TScanParams* pScanParams) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - paramInfo_t *pParam; - - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_Start1ShotScan: Received scan request from client %d\n", eClient); - - pParam = (paramInfo_t *)os_memoryAlloc(pScanCncn->hOS, sizeof(paramInfo_t)); - if (!pParam) { - return SCAN_CRS_SCAN_FAILED; - } - - /* copy scan parameters to local buffer */ - os_memoryCopy (pScanCncn->hOS, &(pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams), - pScanParams, sizeof(TScanParams)); - - /* - * roaming scans (continuous and immediate) require to set the current SSID, to keep the scan manager - * unaware of it, unless the SSID is broadcast (to allow customers to request broadcast scan) - */ - if ((SCAN_SCC_ROAMING_CONT == eClient) || (SCAN_SCC_ROAMING_IMMED == eClient)) - { - if (0 != pScanParams->desiredSsid.len) - { - /* set the SSID of the current AP */ - pParam->paramType = SME_DESIRED_SSID_ACT_PARAM; - sme_GetParam (pScanCncn->hSme, pParam); - os_memoryCopy (pScanCncn->hOS, - &(pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.desiredSsid), - &(pParam->content.smeDesiredSSID), - sizeof(TSsid)); - } - } - os_memoryFree(pScanCncn->hOS, pParam, sizeof(paramInfo_t)); - - /* ask the reg domain which channels are allowed for the requested scan type */ - scanCncn_VerifyChannelsWithRegDomain (hScanCncn, &(pScanCncn->pScanClients[ eClient ]->uScanParams), TI_FALSE); - - /* if no channels are available for scan, return negative result */ - if (0 == pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.numOfChannels) - { - TRACE0(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_Start1ShotScan: no cahnnels to scan after reg. domain verification, can't scan\n"); - return SCAN_CRS_SCAN_FAILED; - } - - /* Mix the channel order in the 1 Shot Scan channel array */ - scanCncn_Mix1ShotScanChannels (pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.channelEntry, - pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.numOfChannels); - - if (TI_TRUE == pScanCncn->bUseSGParams) - { - scanCncn_SGupdateScanParams (hScanCncn, &(pScanCncn->pScanClients[ eClient ]->uScanParams), TI_FALSE); - } - - /* mark that a scan request is in progress (to avoid client re-entrance if the scan fail) */ - pScanCncn->pScanClients[ eClient ]->bInRequest = TI_TRUE; - - /* mark the scan result as TI_OK (until other status will replace it) */ - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_COMPLETE_OK; - - /* send a start scan event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_START, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - - /* mark that the scan request is no longer in progress */ - pScanCncn->pScanClients[ eClient ]->bInRequest = TI_FALSE; - - /* - * return scan result - if an error occured return the error, otherwise return running - * (complete_ok is set to be returned when scan is complete) - */ - if (SCAN_CRS_SCAN_COMPLETE_OK != pScanCncn->pScanClients[ eClient ]->eScanResult) - { - return pScanCncn->pScanClients[ eClient ]->eScanResult; - } - return SCAN_CRS_SCAN_RUNNING; -} - -void scanCncn_StopScan (TI_HANDLE hScanCncn, EScanCncnClient eClient) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE1( pScanCncn->hReport, REPORT_SEVERITY_INFORMATION, "scanCncn_StopScan: Received stop scan request from client %d\n", eClient); - - /* - * mark that null data should be sent (different from abort, where null dats is not sent - * to reduce abort time) - */ - pScanCncn->pScanClients[ eClient ]->bSendNullDataOnStop = TI_TRUE; - - /* if no previous error has occurred, change the state to stopped */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ eClient ]->eScanResult) - { - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_STOPPED; - } - - /* send a stop scan event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_STOP, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); -} - -/** - * \fn scanCncn_StartPeriodicScan - * \brief Starts a periodic scan operation - * - * Starts a periodic scan operation: - * - copies scan params to scan concentrator object - * - verifies the requested channels with the reg doamin - * - if needed, adjust to SG compensation values - * - send an event to the client SM - * - * \param hScanCncn - handle to the scan concentrator object - * \param eClient - the client requesting the scan operation - * \param pScanParams - scan parameters - * \return Scan opeartion status - * \retval SCAN_CRS_SCAN_RUNNING - scan started successfully and is now running - * \retval SCAN_CRS_SCAN_FAILED - scan failed to start due to an unexpected error - * \sa scanCncn_StopPeriodicScan - */ -EScanCncnResultStatus scanCncn_StartPeriodicScan (TI_HANDLE hScanCncn, - EScanCncnClient eClient, - TPeriodicScanParams *pScanParams) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_startPeriodicScan: Received scan request from client %d\n", eClient); - - /* copy scan parameters to local buffer */ - os_memoryCopy (pScanCncn->hOS, &(pScanCncn->pScanClients[ eClient ]->uScanParams.tPeriodicScanParams), - pScanParams, sizeof(TPeriodicScanParams)); - - /* ask the reg domain which channels are allowed for the requested scan type */ - scanCncn_VerifyChannelsWithRegDomain (hScanCncn, &(pScanCncn->pScanClients[ eClient ]->uScanParams), TI_TRUE); - - /* if no channels are available for scan, return negative result */ - if (0 == pScanCncn->pScanClients[ eClient ]->uScanParams.tPeriodicScanParams.uChannelNum) - { - TRACE0(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_StartPeriodicScan: no cahnnels to scan after reg. domain verification, can't scan\n"); - return SCAN_CRS_SCAN_FAILED; - } - - /* Mix the channel order in the Periodic Scan channel array */ - scanCncn_MixPeriodicScanChannels (pScanCncn->pScanClients[ eClient ]->uScanParams.tPeriodicScanParams.tChannels, - pScanCncn->pScanClients[ eClient ]->uScanParams.tPeriodicScanParams.uChannelNum); - - if (TI_TRUE == pScanCncn->bUseSGParams) - { - scanCncn_SGupdateScanParams (hScanCncn, &(pScanCncn->pScanClients[ eClient ]->uScanParams), TI_TRUE); - } - - /* mark that a scan request is in progress (to avoid client re-entrance if the scan fail) */ - pScanCncn->pScanClients[ eClient ]->bInRequest = TI_TRUE; - - /* mark the scan result as TI_OK (until other status will replace it) */ - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_COMPLETE_OK; - - /* send a start scan event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_START, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - - /* mark that the scan request is no longer in progress */ - pScanCncn->pScanClients[ eClient ]->bInRequest = TI_FALSE; - - /* - * return scan result - if an error occured return the error, otherwise return running - * (complete_ok is set to be returned when scan is complete) - */ - if (SCAN_CRS_SCAN_COMPLETE_OK != pScanCncn->pScanClients[ eClient ]->eScanResult) - { - return pScanCncn->pScanClients[ eClient ]->eScanResult; - } - return SCAN_CRS_SCAN_RUNNING; -} - -/** - * \fn scanCncn_StopPeriodicScan - * \brief Stop an on-going periodic scan operation - * - * Set necessary flags and send a stop scan event to the client SM - * - * \param hScanCncn - handle to the scan concentrator object - * \param eClient - the client requesting to stop the scan operation - * \return None - * \sa scanCncn_StartPeriodicScan - */ -void scanCncn_StopPeriodicScan (TI_HANDLE hScanCncn, EScanCncnClient eClient) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE1( pScanCncn->hReport, REPORT_SEVERITY_INFORMATION, "scanCncn_StopPeriodicScan: Received stop scan request from client %d\n", eClient); - - /* if no previous error has occurred, change the state to stopped */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ eClient ]->eScanResult) - { - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_STOPPED; - } - - /* send a stop scan event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_STOP, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); -} - -void scanCncn_RegisterScanResultCB (TI_HANDLE hScanCncn, EScanCncnClient eClient, - TScanResultCB scanResultCBFunc, TI_HANDLE scanResultCBObj) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - /* save the function and object pointers */ - pScanCncn->pScanClients[ eClient ]->tScanResultCB = scanResultCBFunc; - pScanCncn->pScanClients[ eClient ]->hScanResultCBObj = scanResultCBObj; -} - -/** - * \fn scanCncn_ScanCompleteNotificationCB - * \brief Called when a scan is complete - * - * Update scan status and send a complete event to the SM - * - * \note Must wait for all results to be received before the scan is actually completed - * \param hScanCncn - handle to the scan concentrator object - * \param eTag - the scan type tag - * \param uResoultCount - number of results received during this scan - * \param SPSStatus - which channels were attempted (if this is an SPS scan) - * \param bTSFError - whether a TSF error occurred (if this is an SPS scan) - * \param scanStatus - scan SRV status (OK / NOK) - * \return None - */ -void scanCncn_ScanCompleteNotificationCB (TI_HANDLE hScanCncn, EScanResultTag eTag, - TI_UINT32 uResultCount, TI_UINT16 SPSStatus, - TI_BOOL bTSFError, TI_STATUS scanStatus, - TI_STATUS PSMode) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - EScanCncnClient eClient; - - TRACE6(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScanCompleteNotificationCB: tag: %d, result count: %d, SPS status: %d, TSF Error: %d, scan status: %d, PS mode: %d\n", eTag, uResultCount, SPSStatus, bTSFError, scanStatus, PSMode); - - /* get the scan client value from the scan tag */ - eClient = SCAN_CLIENT_FROM_TAG (eTag); - - /* update scan result if scan SRV reported error (and no error occured so far) */ - if ((TI_OK != scanStatus) && (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ eClient ]->eScanResult)) - { - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_FAILED; - } - - /* for SPS: copy SPS result and update scan status according to TSF error */ - if (SCAN_TYPE_SPS == pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.scanType) - { - pScanCncn->pScanClients[ eClient ]->uSPSScanResult = SPSStatus; - if (TI_TRUE == bTSFError) - { - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_TSF_ERROR; - } - } - - /* update number of frames expected */ - pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber += uResultCount; - - /* check if all frames had been received */ - if (pScanCncn->pScanClients[ eClient ]->uResultCounter >= pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber) - { - TRACE2(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScanCompleteNotificationCB: client %d received %d results, matching scan complete FW indication, sending scan complete event\n", eClient, pScanCncn->pScanClients[ eClient ]->uResultCounter); - - /* all frames had been received, send a scan complete event to the client SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_SCAN_COMPLETE, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - } - else - { - TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScanCompleteNotificationCB: client %d received %d results, FW indicated %d results, waiting for more\n", eClient, pScanCncn->pScanClients[ eClient ]->uResultCounter, pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber); - - /* still waiting for some frames, turn on the scan complete pending flag */ - pScanCncn->pScanClients[ eClient ]->bScanCompletePending = TI_TRUE; - } -} - -/** - * \fn scanCncn_PeriodicScanReportCB - * \brief Called when results are available but periodic scan is not yet complete - * - * Called when results are available but periodic scan is not yet complete - * - * \param hScanCncn - handle to the scan concentrator object - * \param str - event data - * \param strLen - data length - * \return None - * \sa scanCncn_PeriodicScanCompleteCB - */ -void scanCncn_PeriodicScanReportCB (TI_HANDLE hScanCncn, char* str, TI_UINT32 strLen) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - EScanCncnClient eClient; - EScanResultTag eTag = (EScanResultTag)str[ 1 ]; - TI_UINT32 uResultCount = str[ 0 ]; - - TRACE2(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_PeriodicScanReportCB: tag: %d, result count: %d\n", eTag, uResultCount); - - /* get the scan client value from the scan tag */ - eClient = SCAN_CLIENT_FROM_TAG (eTag); - - /* update number of frames expected */ - pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber += uResultCount; -} -/** - * \fn scanCncn_PeriodicScanReportCB - * \brief Called when results are available but the scan is bot yet complete - * - * Called when results are available but the scan is bot yet complete - * - * \param hScanCncn - handle to the scan concentrator object - * \param str - event data - * \param strLen - data length - * \return None - * \sa scanCncn_PeriodicScanReportCB - */ -void scanCncn_PeriodicScanCompleteCB (TI_HANDLE hScanCncn, char* str, TI_UINT32 strLen) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - EScanCncnClient eClient; - EScanResultTag eTag = (EScanResultTag)str[1]; - TI_UINT32 uResultCount = (TI_UINT8)(str[0]); - - TRACE2(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_PeriodicScanCompleteCB: tag: %d, result count: %d\n", eTag, uResultCount); - - /* get the scan client value from the scan tag */ - eClient = SCAN_CLIENT_FROM_TAG (eTag); - - /* update number of frames expected */ - pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber += uResultCount; - - /* check if all frames had been received */ - if (pScanCncn->pScanClients[ eClient ]->uResultCounter >= pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber) - { - TRACE2(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_PeriodicScanCompleteCB: client %d received %d results, matching scan complete FW indication, sending scan complete event\n", eClient, pScanCncn->pScanClients[ eClient ]->uResultCounter); - /* all frames had been received, send a scan complete event to the client SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_SCAN_COMPLETE, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - } - else - { - TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_PeriodicScanCompleteCB: client %d received %d results, FW indicated %d results, waiting for more\n", eClient, pScanCncn->pScanClients[ eClient ]->uResultCounter, pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber); - /* still waiting for some frames, turn on the scan complete pending flag */ - pScanCncn->pScanClients[ eClient ]->bScanCompletePending = TI_TRUE; - } -} - -/** - * \fn scanCncn_MlmeResultCB - * \brief Handles an MLME result (received frame) - * - * Filters the frame for roaming scans and passes it to the appropriate client - * - * \param hScanCncn - handle to the scan concentrator object - * \param bssid - a pointer to the address of the AP sending this frame - * \param frameInfo - the IE in the frame - * \param pRxAttr - a pointer to TNET RX attributes struct - * \param buffer - a pointer to the frame body - * \param bufferLength - the frame body length - * \return None - */ -void scanCncn_MlmeResultCB (TI_HANDLE hScanCncn, TMacAddr* bssid, mlmeFrameInfo_t* frameInfo, - TRxAttr* pRxAttr, TI_UINT8* buffer, TI_UINT16 bufferLength) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - EScanCncnClient eClient; - TScanFrameInfo tScanFrameInfo; - TI_BOOL bValidResult = TI_TRUE; - - /* get the scan client value from the scan tag */ - eClient = SCAN_CLIENT_FROM_TAG (pRxAttr->eScanTag); - - /* increase scan result counter */ - pScanCncn->pScanClients[ eClient ]->uResultCounter++; - - /* - * erroneous results are signaled by NULL pointers and are notified to the scan concentrator to - * update the counter only! - */ - if (NULL == bssid) - { - TRACE0(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: received an empty frame notification from MLME\n"); - - /* invalid resuilt */ - bValidResult = TI_FALSE; - } - /* are results valid so far (TI_TRUE == bValidResult) */ - else - { - TRACE6(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: received frame from BBSID: %02x:%02x:%02x:%02x:%02x:%02x\n", (*bssid)[ 0 ], (*bssid)[ 1 ], (*bssid)[ 2 ], (*bssid)[ 3 ], (*bssid)[ 4 ], (*bssid)[ 5 ]); - - /* If SSID IE is missing, discard the frame */ - if (frameInfo->content.iePacket.pSsid == NULL) - { - TRACE6(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: discarding frame from BSSID: %02x:%02x:%02x:%02x:%02x:%02x, because SSID IE is missing!!\n", (*bssid)[ 0 ], (*bssid)[ 1 ], (*bssid)[ 2 ], (*bssid)[ 3 ], (*bssid)[ 4 ], (*bssid)[ 5 ]); - bValidResult = TI_FALSE; - } - - /* If SSID length is 0 (hidden SSID) */ - else if (frameInfo->content.iePacket.pSsid->hdr[1] == 0) - { - /* Discard the frame unless it is application scan for any SSID - In this case we want to see also the hidden SSIDs*/ - if (!(((SCAN_SCC_APP_ONE_SHOT == eClient) || (SCAN_SCC_APP_PERIODIC == eClient)) && - pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.desiredSsid.len == 0)) - { - TRACE6(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: discarding frame from BSSID: %02x:%02x:%02x:%02x:%02x:%02x, because SSID is hidden (len=0)\n", (*bssid)[ 0 ], (*bssid)[ 1 ], (*bssid)[ 2 ], (*bssid)[ 3 ], (*bssid)[ 4 ], (*bssid)[ 5 ]); - bValidResult = TI_FALSE; - } - } - - /* - * for roaming continuous and immediate, discard frames from current AP, - * or frames with SSID different than desired when the scan is NOT SPS - */ - else if ((SCAN_SCC_ROAMING_CONT == eClient) || (SCAN_SCC_ROAMING_IMMED == eClient)) - { - bssEntry_t *pCurrentAP; - - pCurrentAP = apConn_getBSSParams(pScanCncn->hAPConn); - if(MAC_EQUAL(*bssid, pCurrentAP->BSSID) || - ((os_memoryCompare (pScanCncn->hOS, - (TI_UINT8*)frameInfo->content.iePacket.pSsid->serviceSetId, - (TI_UINT8*)pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.desiredSsid.str, - pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.desiredSsid.len)) && - pScanCncn->pScanClients[ eClient ]->uScanParams.tOneShotScanParams.scanType != SCAN_TYPE_SPS)) - { - TRACE6(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: discarding frame from SSID: , BSSID: %02x:%02x:%02x:%02x:%02x:%02x, because SSID different from desired or from current AP!\n", (*bssid)[ 0 ], (*bssid)[ 1 ], (*bssid)[ 2 ], (*bssid)[ 3 ], (*bssid)[ 4 ], (*bssid)[ 5 ]); - bValidResult = TI_FALSE; - } - - } - - /* if rssi is lower than the Rssi threshold, discard frame */ - if ( pRxAttr->Rssi < pScanCncn->tInitParams.nRssiThreshold ) - { - TRACE7(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: discarding frame from BSSID: %02x:%02x:%02x:%02x:%02x:%02x, because RSSI = %d\n", (*bssid)[ 0 ], (*bssid)[ 1 ], (*bssid)[ 2 ], (*bssid)[ 3 ], (*bssid)[ 4 ], (*bssid)[ 5 ], pRxAttr->Rssi); - bValidResult = TI_FALSE; - } - - if(TI_TRUE == bValidResult) - { - /* build the scan frame info object */ - tScanFrameInfo.bssId = bssid; - tScanFrameInfo.band = (ERadioBand)pRxAttr->band; - tScanFrameInfo.channel = pRxAttr->channel; - tScanFrameInfo.parsedIEs = frameInfo; - tScanFrameInfo.rate = pRxAttr->Rate; - tScanFrameInfo.rssi = pRxAttr->Rssi; - tScanFrameInfo.snr = pRxAttr->SNR; - tScanFrameInfo.staTSF = pRxAttr->TimeStamp; - tScanFrameInfo.buffer = buffer; - tScanFrameInfo.bufferLength = bufferLength; - - if (TI_TRUE == pScanCncn->tInitParams.bPushMode) - { - /* - * The scan found result, send a scan report event to the use with the frame parameters without save the result in the scan table - */ - EvHandlerSendEvent (pScanCncn->hEvHandler, IPC_EVENT_SCAN_REPORT, (TI_UINT8*)&tScanFrameInfo, sizeof(TScanFrameInfo)); - } - else - { - /* call the client result CB */ - pScanCncn->pScanClients[ eClient ]->tScanResultCB (pScanCncn->pScanClients[ eClient ]->hScanResultCBObj, - SCAN_CRS_RECEIVED_FRAME, &tScanFrameInfo, 0xffff ); /* SPS status is only valid on SPS scan complete */ - } - } - } - - /* check if scan complete is pending for this frame for all results */ - if((TI_TRUE == pScanCncn->pScanClients[ eClient ]->bScanCompletePending) && - (pScanCncn->pScanClients[ eClient ]->uResultCounter == pScanCncn->pScanClients[ eClient ]->uResultExpectedNumber)) - { - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_MlmeResultCB: received frame number %d, scan complete pending, sending scan complet event\n", pScanCncn->pScanClients[ eClient ]->uResultCounter); - - /* send a scan complete event to the client SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_SCAN_COMPLETE, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - } -} - -/** - * \fn scanCncn_ScrRoamingImmedCB - * \brief Called by SCR for immediate roaming client status change notification - * - * Handles status change by sending the appropriate SM event - * - * \param hScanCncn - handle to the scan concentrator object - * \param eRrequestStatus - the immediate scan for roaming client status - * \param eResource - the resource for which the CB is issued - * \param ePendreason - The reason for pend status, if the status is pend - * \return None - */ -void scanCncn_ScrRoamingImmedCB (TI_HANDLE hScanCncn, EScrClientRequestStatus eRequestStatus, - EScrResourceId eResource, EScePendReason ePendReason) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScrRoamingImmedCB: status: %d, resource: %d pend reason: %d\n", eRequestStatus, eResource, ePendReason); - - /* act according to the request staus */ - switch (eRequestStatus) - { - case SCR_CRS_RUN: - /* send an SCR run event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]->hGenSM, SCAN_CNCN_SM_EVENT_RUN, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]); - break; - - case SCR_CRS_PEND: - /* if pending reason has changed to different group - send a reject event - (should only happen when pending) */ - if ( SCR_PR_DIFFERENT_GROUP_RUNNING == ePendReason ) - { - /* send an SCR reject event to the SM - would not scan when not performing roaming */ - pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]->eScanResult = SCAN_CRS_SCAN_FAILED; - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]->hGenSM, SCAN_CNCN_SM_EVENT_REJECT, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]); - } - break; - - case SCR_CRS_FW_RESET: - /* if no previous error has occurred, change the state to FW reset */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]->eScanResult) - { - pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]->eScanResult = SCAN_CRS_SCAN_ABORTED_FW_RESET; - } - - /* send a recovery event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]->hGenSM, SCAN_CNCN_SM_EVENT_RECOVERY, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_IMMED ]); - break; - - case SCR_CRS_ABORT: - /* This should never happen, report error */ - default: - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_ScrRoamingImmedCB: Illegal SCR request status: %d.\n", eRequestStatus); - break; - } -} - -/** - * \fn scanCncn_ScrRoamingContCB - * \brief Called by SCR for continuous roaming client status change notification - * - * Handles status change by sending the appropriate SM event - * - * \param hScanCncn - handle to the scan concentrator object - * \param eRrequestStatus - the continuous scan for roaming client status - * \param eResource - the resource for which the CB is issued - * \param ePendreason - The reason for pend status, if the status is pend - * \return None - */ -void scanCncn_ScrRoamingContCB (TI_HANDLE hScanCncn, EScrClientRequestStatus eRequestStatus, - EScrResourceId eResource, EScePendReason ePendReason) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScrRoamingContCB: status: %d, resource: %d pend reason: %d\n", eRequestStatus, eResource, ePendReason); - - /* act according to the request staus */ - switch (eRequestStatus) - { - case SCR_CRS_RUN: - /* send an SCR run event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->hGenSM, SCAN_CNCN_SM_EVENT_RUN, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]); - break; - - case SCR_CRS_PEND: - /* if pending reason has changed to different group - send a reject event (should only happen when pending) */ - if ( SCR_PR_DIFFERENT_GROUP_RUNNING == ePendReason ) - { - pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->eScanResult = SCAN_CRS_SCAN_FAILED; - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->hGenSM, SCAN_CNCN_SM_EVENT_REJECT, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]); - } - break; - - case SCR_CRS_FW_RESET: - /* if no previous error has occurred, change the state to FW reset */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->eScanResult) - { - pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->eScanResult = SCAN_CRS_SCAN_ABORTED_FW_RESET; - } - - /* send a recovery event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->hGenSM, SCAN_CNCN_SM_EVENT_RECOVERY, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]); - break; - - - case SCR_CRS_ABORT: - /* mark not to send NULL data when scan is stopped */ - pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->bSendNullDataOnStop = TI_FALSE; - - /* if no previous error has occurred, change the result to abort */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->eScanResult) - { - pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->eScanResult = SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY; - } - - /* send an abort scan event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]->hGenSM, SCAN_CNCN_SM_EVENT_ABORT, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_ROAMING_CONT ]); - break; - - default: - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_ScrRoamingContCB: Illegal SCR request status: %d.\n", eRequestStatus); - break; - } -} - -/** - * \fn scanCncn_ScrAppCB - * \brief Called by SCR for application scan client status change notification - * - * Handles status change by sending the appropriate SM event - * - * \note this function is used by the SCR for both one-shot and periodic application scan - * \param hScanCncn - handle to the scan concentrator object - * \param eRrequestStatus - the application scan client status - * \param eResource - the resource for which the CB is issued - * \param ePendreason - The reason for pend status, if the status is pend - * \return None - */ -void scanCncn_ScrAppCB (TI_HANDLE hScanCncn, EScrClientRequestStatus eRequestStatus, - EScrResourceId eResource, EScePendReason ePendReason ) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - EScanCncnClient eClient; - - TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScrAppCB: status: %d, resource: %d pend reason: %d\n", eRequestStatus, eResource, ePendReason); - - /* set client according to SCr resource */ - if (SCR_RESOURCE_PERIODIC_SCAN == eResource) - { - eClient = SCAN_SCC_APP_PERIODIC; - } - else - { - eClient = SCAN_SCC_APP_ONE_SHOT; - } - - /* act according to the request staus */ - switch (eRequestStatus) - { - /* - * Note: pend is not handled because application scan cancel its scan request when it receives pend - * as the SCR request result, and thus it is assumed that the application scan request will never be - * pending - */ - case SCR_CRS_RUN: - /* send an SCR run event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_RUN, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - break; - - case SCR_CRS_FW_RESET: - /* if no previous error has occurred, change the state to FW reset */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ eClient ]->eScanResult) - { - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_ABORTED_FW_RESET; - } - - /* send a recovery event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_RECOVERY, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - break; - - case SCR_CRS_ABORT: - /* mark not to send NULL data when scan is stopped */ - pScanCncn->pScanClients[ eClient ]->bSendNullDataOnStop = TI_FALSE; - - /* if no previous error has occurred, change the result to abort */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ eClient ]->eScanResult) - { - pScanCncn->pScanClients[ eClient ]->eScanResult = SCAN_CRS_SCAN_ABORTED_HIGHER_PRIORITY; - } - - /* send an abort scan event to the SM */ - genSM_Event (pScanCncn->pScanClients[ eClient ]->hGenSM, SCAN_CNCN_SM_EVENT_ABORT, - (TI_HANDLE)pScanCncn->pScanClients[ eClient ]); - break; - - default: - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_ScrAppCB: Illegal SCR request status: %d.\n", eRequestStatus); - break; - } -} - -/** - * \fn scanCncn_ScrDriverCB - * \brief Called by SCR for driver scan client status change notification - * - * Handles status change by sending the appropriate SM event - * - * \param hScanCncn - handle to the scan concentrator object - * \param eRrequestStatus - the driver scan client status - * \param eResource - the resource for which the CB is issued - * \param ePendreason - The reason for pend status, if the status is pend - * \return None - */ -void scanCncn_ScrDriverCB (TI_HANDLE hScanCncn, EScrClientRequestStatus eRequestStatus, - EScrResourceId eResource, EScePendReason ePendReason) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - TRACE3(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_ScrDriverCB: status: %d, resource: %d pend reason: %d\n", eRequestStatus, eResource, ePendReason); - - /* act according to the request staus */ - switch (eRequestStatus) - { - case SCR_CRS_RUN: - /* send the next event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]->hGenSM, SCAN_CNCN_SM_EVENT_RUN, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]); - break; - - case SCR_CRS_PEND: - /* if pending reason has changed to different group - send a reject event (should only happen when pending) */ - if ( SCR_PR_DIFFERENT_GROUP_RUNNING == ePendReason ) - { - pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]->eScanResult = SCAN_CRS_SCAN_FAILED; - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]->hGenSM, SCAN_CNCN_SM_EVENT_REJECT, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]); - } - break; - - case SCR_CRS_FW_RESET: - /* if no previous error has occurred, change the state to FW reset */ - if (SCAN_CRS_SCAN_COMPLETE_OK == pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]->eScanResult) - { - pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]->eScanResult = SCAN_CRS_SCAN_ABORTED_FW_RESET; - } - - /* send a recovery event to the SM */ - genSM_Event (pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]->hGenSM, SCAN_CNCN_SM_EVENT_RECOVERY, - (TI_HANDLE)pScanCncn->pScanClients[ SCAN_SCC_DRIVER ]); - break; - - case SCR_CRS_ABORT: - /* This should never happen, report error */ - default: - TRACE1(pScanCncn->hReport, REPORT_SEVERITY_ERROR , "scanCncn_ScrDriverCB: Illegal SCR request status: %d.\n", eRequestStatus); - break; - } -} - -/** - * \fn scanCncn_VerifyChannelsWithRegDomain - * \brief Verifies channel validity and TX power with the reg. domain - * - * Verifies channel validity and TX power with the reg. domain. Removes invalid channels. - * - * \param hScanCncn - handle to the scan concentrator object - * \param puScanParams - a pointer to the scan parmeters union - * \param bPeriodicScan - TRUE if the parameters are for periodic scan, FALSE if for one-shot scan - * \return None - */ -void scanCncn_VerifyChannelsWithRegDomain (TI_HANDLE hScanCncn, UScanParams *puScanParams, TI_BOOL bPeriodicScan) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - paramInfo_t *pParam; - paramInfo_t tDfsParam; - TI_UINT8 i, uChannelNum; - - pParam = (paramInfo_t *)os_memoryAlloc(pScanCncn->hOS, sizeof(paramInfo_t)); - if (!pParam) { - return; - } - - /* get channel number according to scan type */ - if (TI_TRUE == bPeriodicScan) - { - uChannelNum = puScanParams->tPeriodicScanParams.uChannelNum; - } - else - { - uChannelNum = puScanParams->tOneShotScanParams.numOfChannels; - } - - /* check channels */ - for (i = 0; i < uChannelNum; ) - { /* Note that i is only increased when channel is valid - if channel is invalid, another - channel is copied in its place, and thus the same index should be checked again. However, - since the number of channels is decreased, the loop end condition is getting nearer! */ - pParam->paramType = REGULATORY_DOMAIN_GET_SCAN_CAPABILITIES; - if (TI_TRUE == bPeriodicScan) - { - /* set band and scan type for periodic scan */ - pParam->content.channelCapabilityReq.band = puScanParams->tPeriodicScanParams.tChannels[ i ].eBand; - if (puScanParams->tPeriodicScanParams.tChannels[ i ].eScanType == SCAN_TYPE_NORMAL_PASSIVE) - { - pParam->content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; - } - else - { - /* query the reg. domain whether this is a DFS channel */ - tDfsParam.paramType = REGULATORY_DOMAIN_IS_DFS_CHANNEL; - tDfsParam.content.tDfsChannel.eBand = puScanParams->tPeriodicScanParams.tChannels[ i ].eBand; - tDfsParam.content.tDfsChannel.uChannel = puScanParams->tPeriodicScanParams.tChannels[ i ].uChannel; - regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, &tDfsParam); - - /* if this is a DFS channel */ - if (TI_TRUE == tDfsParam.content.tDfsChannel.bDfsChannel) - { - /* - * DFS channels are first scanned passive and than active, so reg. domain can only validate - * these channels for pasiive scanning at the moment - */ - pParam->content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; - - /* set the channel scan type to DFS */ - puScanParams->tPeriodicScanParams.tChannels[ i ].eScanType = SCAN_TYPE_PACTSIVE; - /* passive scan time is passed for all channels to the TWD, and copied there to the FW */ - } - else - { - pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; - } - } - - /* set channel for periodic scan */ - pParam->content.channelCapabilityReq.channelNum = - puScanParams->tPeriodicScanParams.tChannels[ i ].uChannel; - regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, pParam); - if (TI_FALSE == pParam->content.channelCapabilityRet.channelValidity) - { /* channel not allowed - copy the rest of the channel in its place */ - os_memoryCopy (pScanCncn->hOS, &(puScanParams->tPeriodicScanParams.tChannels[ i ]), - &(puScanParams->tPeriodicScanParams.tChannels[ i + 1 ]), - sizeof(TPeriodicChannelEntry) * (puScanParams->tPeriodicScanParams.uChannelNum - i - 1)); - puScanParams->tPeriodicScanParams.uChannelNum--; - uChannelNum--; - } - else - { - /* also set the power level to the minimumm between requested power and allowed power */ - puScanParams->tPeriodicScanParams.tChannels[ i ].uTxPowerLevelDbm = - TI_MIN( pParam->content.channelCapabilityRet.maxTxPowerDbm, - puScanParams->tPeriodicScanParams.tChannels[ i ].uTxPowerLevelDbm ); - - i += 1; - } - } - else - { - /* set band and scan type for one-shot scan */ - pParam->content.channelCapabilityReq.band = puScanParams->tOneShotScanParams.band; - if ((puScanParams->tOneShotScanParams.scanType == SCAN_TYPE_NORMAL_PASSIVE) || - (puScanParams->tOneShotScanParams.scanType == SCAN_TYPE_TRIGGERED_PASSIVE) || - (puScanParams->tOneShotScanParams.scanType == SCAN_TYPE_SPS)) - { - pParam->content.channelCapabilityReq.scanOption = PASSIVE_SCANNING; - } - else - { - pParam->content.channelCapabilityReq.scanOption = ACTIVE_SCANNING; - } - - /* set channel for one-shot scan - SPS */ - if (SCAN_TYPE_SPS == puScanParams->tOneShotScanParams.scanType) - { - pParam->content.channelCapabilityReq.channelNum = - puScanParams->tOneShotScanParams.channelEntry[ i ].SPSChannelEntry.channel; - regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, pParam); - if (TI_FALSE == pParam->content.channelCapabilityRet.channelValidity) - { /* channel not allowed - copy the rest of the channel in its place */ - os_memoryCopy (pScanCncn->hOS, &(puScanParams->tOneShotScanParams.channelEntry[ i ]), - &(puScanParams->tOneShotScanParams.channelEntry[ i + 1 ]), - sizeof(TScanSpsChannelEntry) * (puScanParams->tOneShotScanParams.numOfChannels - i - 1)); - puScanParams->tOneShotScanParams.numOfChannels--; - uChannelNum--; - } - else - { - i += 1; - } - - } - /* set channel for one-shot scan - all other scan types */ - else - { - pParam->content.channelCapabilityReq.channelNum = - puScanParams->tOneShotScanParams.channelEntry[ i ].normalChannelEntry.channel; - regulatoryDomain_getParam (pScanCncn->hRegulatoryDomain, pParam); - if (TI_FALSE == pParam->content.channelCapabilityRet.channelValidity) - { /* channel not allowed - copy the rest of the channel in its place */ - os_memoryCopy (pScanCncn->hOS, &(puScanParams->tOneShotScanParams.channelEntry[ i ]), - &(puScanParams->tOneShotScanParams.channelEntry[ i + 1 ]), - sizeof(TScanNormalChannelEntry) * (puScanParams->tOneShotScanParams.numOfChannels - i - 1)); - puScanParams->tOneShotScanParams.numOfChannels--; - uChannelNum--; - } - else - { - puScanParams->tOneShotScanParams.channelEntry[i].normalChannelEntry.txPowerDbm = - TI_MIN (pParam->content.channelCapabilityRet.maxTxPowerDbm, - puScanParams->tOneShotScanParams.channelEntry[i].normalChannelEntry.txPowerDbm); - i += 1; - } - } - } - } - os_memoryFree(pScanCncn->hOS, pParam, sizeof(paramInfo_t)); -} - -/** - * \fn scanCncn_SGconfigureScanParams - * \brief Configures Bluetooth coexistence compensation paramters - * - * Configures Bluetooth coexistence compensation paramters. - * This function is called when SG is enabled or disabled from the SoftGemini module. - * The compensation is needed since BT Activity holds the antenna and over-ride Scan activity - * - * \param hScanCncn - handle to the scan concentrator object.\n - * \param bUseSGParams - whether to use the new parameters (TI_TRUE when SG is enabled) - * \param probeReqPercent - increasing num probe requests in that percentage - * \param SGcompensationMaxTime - max value from which we won't increase dwelling time - * \param SGcompensationPercent - increasing dwell time in that percentage - * \return None - * \sa scanCncn_SGupdateScanParams - */ -void scanCncn_SGconfigureScanParams (TI_HANDLE hScanCncn, TI_BOOL bUseSGParams, - TI_UINT8 probeReqPercent, TI_UINT32 SGcompensationMaxTime, - TI_UINT32 SGcompensationPercent) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - - pScanCncn->bUseSGParams = bUseSGParams; - pScanCncn->uSGprobeRequestPercent = probeReqPercent; - pScanCncn->uSGcompensationMaxTime = SGcompensationMaxTime; - pScanCncn->uSGcompensationPercent = SGcompensationPercent; - - TRACE4(pScanCncn->hReport, REPORT_SEVERITY_INFORMATION , "scanCncn_SGconfigureScanParams: bUseSGParams=%d, numOfProbeRequest=%d, compensationMaxTime=%d, SGcompensationPercent=%d\n", pScanCncn->bUseSGParams, pScanCncn->uSGprobeRequestPercent, pScanCncn->uSGcompensationMaxTime, pScanCncn->uSGcompensationPercent); -} - -/** - * \fn scanCncn_SGupdateScanParams - * \brief Updates dwell times and probe request number to compensate for bluetooth transmissions - * - * Updates dwell times and probe request number to compensate for bluetooth transmissions - * - * \param hScanCncn - handle to the scan concentrator object - * \param puScanParams - a pointer to the scan parmeters union - * \param bPeriodicScan - TRUE if the parameters are for periodic scan, FALSE if for one-shot scan - * \return None - * \sa scanCncn_SGconfigureScanParams - */ -void scanCncn_SGupdateScanParams (TI_HANDLE hScanCncn, UScanParams *puScanParams, TI_BOOL bPeriodicScan) -{ - TScanCncn *pScanCncn = (TScanCncn*)hScanCncn; - TI_UINT32 i, uTempTime; - - /* one shot scan */ - if (TI_FALSE == bPeriodicScan) - { - /* get a pointer to the one-shot scan params */ - TScanParams *pScanParams = &(puScanParams->tOneShotScanParams); - - /* for each channel increase the min and max dwell time */ - for (i = 0; i < pScanParams->numOfChannels; i++) - { - /* SPS scan */ - if (SCAN_TYPE_SPS == pScanParams->scanType) - { - if (pScanCncn->uSGcompensationMaxTime > - pScanParams->channelEntry[i].SPSChannelEntry.scanDuration) - { - uTempTime = ((pScanParams->channelEntry[i].SPSChannelEntry.scanDuration) * - (100 + pScanCncn->uSGcompensationPercent)) / 100 ; - - if (uTempTime > pScanCncn->uSGcompensationMaxTime) - { - uTempTime = pScanCncn->uSGcompensationMaxTime; - } - pScanParams->channelEntry[i].SPSChannelEntry.scanDuration = uTempTime; - } - } - /* all other scan types */ - else - { - if (pScanCncn->uSGcompensationMaxTime > - pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime) - { - uTempTime = ((pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime) * - (100 + pScanCncn->uSGcompensationPercent)) / 100 ; - - if (uTempTime > pScanCncn->uSGcompensationMaxTime) - { - uTempTime = pScanCncn->uSGcompensationMaxTime; - } - pScanParams->channelEntry[i].normalChannelEntry.minChannelDwellTime = uTempTime; - } - - if (pScanCncn->uSGcompensationMaxTime > - pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime) - { - uTempTime = ((pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime) * - (100 + pScanCncn->uSGcompensationPercent)) / 100 ; - - if (uTempTime > pScanCncn->uSGcompensationMaxTime) - { - uTempTime = pScanCncn->uSGcompensationMaxTime; - } - pScanParams->channelEntry[i].normalChannelEntry.maxChannelDwellTime = uTempTime; - } - } - } - - /* update ProbeReqNumber by SG percantage */ - if (pScanParams->probeReqNumber > 0) - { - pScanParams->probeReqNumber = ((pScanParams->probeReqNumber) * - (100 + pScanCncn->uSGprobeRequestPercent)) / 100 ; - } - } - /* periodic scan */ - else - { - TPeriodicScanParams *pPeriodicScanParams = &(puScanParams->tPeriodicScanParams); - - /* for each channel increase the min and max dwell time */ - for (i = 0; i < pPeriodicScanParams->uChannelNum; i++) - { - if (pScanCncn->uSGcompensationMaxTime > - pPeriodicScanParams->tChannels[ i ].uMinDwellTimeMs) - { - uTempTime = ((pPeriodicScanParams->tChannels[ i ].uMinDwellTimeMs) * - (100 + pScanCncn->uSGcompensationPercent)) / 100 ; - - if (uTempTime > pScanCncn->uSGcompensationMaxTime) - { - uTempTime = pScanCncn->uSGcompensationMaxTime; - } - pPeriodicScanParams->tChannels[ i ].uMinDwellTimeMs = uTempTime; - } - - if (pScanCncn->uSGcompensationMaxTime > - pPeriodicScanParams->tChannels[ i ].uMaxDwellTimeMs) - { - uTempTime = ((pPeriodicScanParams->tChannels[ i ].uMaxDwellTimeMs) * - (100 + pScanCncn->uSGcompensationPercent)) / 100 ; - - if (uTempTime > pScanCncn->uSGcompensationMaxTime) - { - uTempTime = pScanCncn->uSGcompensationMaxTime; - } - pPeriodicScanParams->tChannels[ i ].uMaxDwellTimeMs = uTempTime; - } - } - - /* update ProbeReqNumber by SG percantage */ - if (pPeriodicScanParams->uProbeRequestNum > 0) - { - pPeriodicScanParams->uProbeRequestNum = ((pPeriodicScanParams->uProbeRequestNum) * - (100 + pScanCncn->uSGprobeRequestPercent)) / 100 ; - } - } -} - -/** - * \fn scanCncn_Mix1ShotScanChannels - * \brief Mix the channel order in a 1 Shot Scan channel array. - * - * Mix the channel order in a 1 Shot Scan channel array. - * - * \param pChannelArray - where to store allowed channels information - * \param uValidChannelsCount - Number of allowed channels (that were placed in the given channels array) - * \return None - */ -static void scanCncn_Mix1ShotScanChannels (TScanChannelEntry *pChannelArray, TI_UINT32 uValidChannelsCount) -{ - TI_UINT32 i; - TScanChannelEntry tTempArray[MAX_CHANNEL_IN_BAND_2_4]; - - if (uValidChannelsCount <= MIN_CHANNEL_IN_BAND_2_4) - { - return; - } - - if (uValidChannelsCount > MAX_CHANNEL_IN_BAND_2_4) - { - uValidChannelsCount = MAX_CHANNEL_IN_BAND_2_4; - } - - /* - * Create new Channels Array that will mix the channels - * something like: 1,8,2,9,3,10,4,11,5,12,6,13,7,14 - * For odd number of channels, the last channel will be adjacent, but never mind... - */ - for (i = 0 ; i < uValidChannelsCount - 1 ; i+=2) - { - tTempArray[i] = pChannelArray[i/2]; - tTempArray[i+1] = pChannelArray[(uValidChannelsCount+i)/2]; - } - - /* if this is the last odd channel */ - if ((i + 1) == uValidChannelsCount) - { - tTempArray[i] = tTempArray[i - 1]; - tTempArray[i - 1] = pChannelArray[uValidChannelsCount - 1]; - } - - /* Now copy to the real array */ - for (i = 0 ; i < uValidChannelsCount; i++) - { - pChannelArray[i] = tTempArray[i]; - } -} - - -/** - * \fn scanCncn_MixPeriodicScanChannels - * \brief Mix the channel order in a Periodic Scan channel - * array. - * - * Mix the channel order in a Periodic Scan channel array. - * - * \param pChannelArray - where to store allowed channels information - * \param uValidChannelsCount - Number of allowed channels (that were placed in the given channels array) - * \return None - */ -static void scanCncn_MixPeriodicScanChannels (TPeriodicChannelEntry *pChannelArray, TI_UINT32 uValidChannelsCount) -{ - TI_UINT32 i; - TPeriodicChannelEntry tTempArray[MAX_CHANNEL_IN_BAND_2_4]; - - if (uValidChannelsCount <= MIN_CHANNEL_IN_BAND_2_4) - { - return; - } - - if (uValidChannelsCount > MAX_CHANNEL_IN_BAND_2_4) - { - uValidChannelsCount = MAX_CHANNEL_IN_BAND_2_4; - } - - /* - * Create new Channels Array that will mix the channels - * something like: 1,8,2,9,3,10,4,11,5,12,6,13,7,14 - * For odd number of channels, the last channel will be adjacent, but never mind... - */ - for (i = 0 ; i < uValidChannelsCount - 1 ; i+=2) - { - tTempArray[i] = pChannelArray[i/2]; - tTempArray[i+1] = pChannelArray[(uValidChannelsCount+i)/2]; - } - - /* if this is the last odd channel */ - if ((i + 1) == uValidChannelsCount) - { - tTempArray[i] = tTempArray[i - 1]; - tTempArray[i - 1] = pChannelArray[uValidChannelsCount - 1]; - } - - /* Now copy to the real array */ - for (i = 0 ; i < uValidChannelsCount; i++) - { - pChannelArray[i] = tTempArray[i]; - } -} |