Example #1
0
/** 
 * \fn     sme_Select
 * \brief  Select a connection candidate from the scan result table
 * 
 * Select a connection candidate from the scan result table.
 * 
 * Connection candidate must match SSID, BSSID, BSS type, RSN and WSC settings, has the best
 * RSSI level from all matching sites, and connection was not attempted to it in this SME cycle
 * (since last scan was completed)
 * 
 * \param  hSme - handle to the SME object
 * \return A pointer to the selected site, NULL if no site macthes the selection criteria
 */ 
TSiteEntry *sme_Select (TI_HANDLE hSme)
{
    TSme            *pSme = (TSme*)hSme;
    TSiteEntry      *pCurrentSite, *pSelectedSite = NULL;
    TI_INT8         iSelectedSiteRssi = -127; /* minimum RSSI */
    TI_BOOL         bWscPbAbort, pWscPbApFound = TI_FALSE;
    int             apFoundCtr =0;

    /* on SG avalanche, select is not needed, send connect event automatically */
    if (TI_TRUE == pSme->bReselect)
    {        
        paramInfo_t *pParam;

        pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t));
        if (!pParam)
        {
            return NULL;
        }

        pSme->bReselect = TI_FALSE;

        /* Get Primary Site */
        pParam->paramType = SITE_MGR_GET_PRIMARY_SITE;
        siteMgr_getParam(pSme->hSiteMgr, pParam);
        pCurrentSite = pParam->content.pPrimarySite;
        os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t));
        return pCurrentSite;

    }

    /* get the first site from the scan result table */
    pCurrentSite = scanResultTable_GetFirst (pSme->hScanResultTable);

    /* check all sites */
    while (NULL != pCurrentSite)
    {
        /* if this site was previously selected in the current SME connection attempt, and conn mode is auto */
        if ((TI_TRUE == pCurrentSite->bConsideredForSelect) && (CONNECT_MODE_AUTO == pSme->eConnectMode)) 
        {
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* check if site matches */
        /* first check SSID match */
        if (TI_FALSE == sme_SelectSsidMatch (hSme, &(pCurrentSite->ssid), &(pSme->tSsid), pSme->eSsidType))
        /* site doesn't match */
        {
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* Now check BSSID match */
        if (TI_FALSE == sme_SelectBssidMatch (&(pCurrentSite->bssid), &(pSme->tBssid)))
        /* site doesn't match */
        {
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* and BSS type match */
        if (TI_FALSE == sme_SelectBssTypeMatch (pCurrentSite->bssType, pSme->eBssType))
        /* site doesn't match */
        {
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

         if (pCurrentSite->WSCSiteMode == TIWLN_SIMPLE_CONFIG_PBC_METHOD)
         {
           apFoundCtr++;
         }
         if (apFoundCtr > 1)
         {
           pWscPbApFound = TI_TRUE;
         }
         
        /* and simple config match */
        if (TI_FALSE == sme_SelectWscMatch (hSme, pCurrentSite, &bWscPbAbort, &pWscPbApFound))
        /* site doesn't match */
        {
            /* also check if abort was indicated */
            if (TI_TRUE == bWscPbAbort)
            {
                /* send event to user mode to indicate this */
                EvHandlerSendEvent (pSme->hEvHandler, IPC_EVENT_WPS_SESSION_OVERLAP, NULL, 0);
                /* select failed - will rescan in time */
                return NULL;
            }
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* and security match */
        if (pCurrentSite->WSCSiteMode == TIWLN_SIMPLE_CONFIG_OFF) /* we don't need to check RSN match while WSC is active */
        {
            if (TI_FALSE == sme_SelectRsnMatch (hSme, pCurrentSite))
            /* site doesn't match */
            {
                pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
                /* get the next site and continue the loop */
                pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
                continue;
            }
        }

        /* and rate match */
        if (TI_FALSE == siteMgr_SelectRateMatch (pSme->hSiteMgr, pCurrentSite))
        /* site doesn't match */
        {
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }
        /* if this site RSSI is higher than current maximum, select it */
        if (pCurrentSite->rssi > iSelectedSiteRssi)
        {
            pSelectedSite = pCurrentSite;
            iSelectedSiteRssi = pCurrentSite->rssi;
        }

        /* and continue to the next site */
        pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
    }

    /* if a matching site was found */
    if (NULL != pSelectedSite)
    {
        /* mark that a connection to this site was (actually is) attempted */
        pSelectedSite->bConsideredForSelect = TI_TRUE;

        /* hope this is the correct place for siteMgr_changeBandParams */
        siteMgr_changeBandParams (pSme->hSiteMgr, pSelectedSite->eBand);

        /*
         * Coordinate between SME module site table and Site module site Table 
         * copy candidate AP to Site module site Table.
         */
        siteMgr_CopyToPrimarySite(pSme->hSiteMgr, pSelectedSite);
    }

    /* return the selected site (or NULL, if no site was selected) */
    return pSelectedSite;
}
/** 
 * \fn     sme_Select
 * \brief  Select a connection candidate from the scan result table
 * 
 * Select a connection candidate from the scan result table.
 * 
 * Connection candidate must match SSID, BSSID, BSS type, RSN and WSC settings, has the best
 * RSSI level from all matching sites, and connection was not attempted to it in this SME cycle
 * (since last scan was completed)
 * 
 * \param  hSme - handle to the SME object
 * \return A pointer to the selected site, NULL if no site macthes the selection criteria
 */ 
TSiteEntry *sme_Select (TI_HANDLE hSme)
{
    TSme            *pSme = (TSme*)hSme;
    TSiteEntry      *pCurrentSite, *pSelectedSite = NULL;
    TI_INT8         iSelectedSiteRssi = -127; /* minimum RSSI */
    TI_BOOL         bWscPbAbort, pWscPbApFound = TI_FALSE;
    int             apFoundCtr =0;
    TIWLN_SIMPLE_CONFIG_MODE eWscMode;

    TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select called\n");

    /* on SG avalanche, select is not needed, send connect event automatically */
    if (TI_TRUE == pSme->bReselect)
    {        
        paramInfo_t *pParam;

        TRACE0(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: reselect flag is on, reselecting the current site\n");

        pParam = (paramInfo_t *)os_memoryAlloc(pSme->hOS, sizeof(paramInfo_t));
        if (!pParam)
        {
            return NULL;
        }

        pSme->bReselect = TI_FALSE;

        /* Get Primary Site */
        pParam->paramType = SITE_MGR_GET_PRIMARY_SITE;
        siteMgr_getParam(pSme->hSiteMgr, pParam);
        pCurrentSite = pParam->content.pPrimarySite;
        os_memoryFree(pSme->hOS, pParam, sizeof(paramInfo_t));
        return pCurrentSite;
    }

    /* get the first site from the scan result table */
    pCurrentSite = scanResultTable_GetFirst (pSme->hScanResultTable);

    /* check all sites */
    while (NULL != pCurrentSite)
    {
        TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: considering BSSID: %02x:%02x:%02x:%02x:%02x:%02x for selection\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);

        /* if this site was previously selected in the current SME connection attempt, and conn mode is auto */
        if (TI_TRUE == pCurrentSite->bConsideredForSelect)
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x was selected previously\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* check if site matches */
        /* first check SSID match */
        if (TI_FALSE == sme_SelectSsidMatch (hSme, &(pCurrentSite->ssid), &(pSme->tSsid), pSme->eSsidType))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match SSID\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* Now check BSSID match */
        if (TI_FALSE == sme_SelectBssidMatch (&(pCurrentSite->bssid), &(pSme->tBssid)))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match SSID\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* and BSS type match */
        if (TI_FALSE == sme_SelectBssTypeMatch (pCurrentSite->bssType, pSme->eBssType))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match BSS type\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

         if (pCurrentSite->WSCSiteMode == TIWLN_SIMPLE_CONFIG_PBC_METHOD)
         {
           apFoundCtr++;
         }
         if (apFoundCtr > 1)
         {
           pWscPbApFound = TI_TRUE;
         }

        /* and simple config match */
        if (TI_FALSE == sme_SelectWscMatch (hSme, pCurrentSite, &bWscPbAbort, &pWscPbApFound))
        /* site doesn't match */
        {
            /* also check if abort was indicated */
            if (TI_TRUE == bWscPbAbort)
            {
                /* send event to user mode to indicate this */
                EvHandlerSendEvent (pSme->hEvHandler, IPC_EVENT_WPS_SESSION_OVERLAP, NULL, 0);
                /* select failed - will rescan in time */
                return NULL;
            }
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match WSC\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* and security match */
        siteMgr_getParamWSC(pSme->hSiteMgr, &eWscMode); 

        /* we don't need to check RSN match while WSC is active */
        if ((pCurrentSite->WSCSiteMode == TIWLN_SIMPLE_CONFIG_OFF) || (pCurrentSite->WSCSiteMode != eWscMode))
        {
            if (TI_FALSE == sme_SelectRsnMatch (hSme, pCurrentSite))
            /* site doesn't match */
            {
                TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match RSN\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
                pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
                /* get the next site and continue the loop */
                pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
                continue;
            }
        }

        /* and rate match */
        if (TI_FALSE == siteMgr_SelectRateMatch (pSme->hSiteMgr, pCurrentSite))
        /* site doesn't match */
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x doesn't match rates\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        if (TI_TRUE == pCurrentSite->bChannelSwitchAnnoncIEFound)
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x has channel switch IE so ignore it \n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pCurrentSite->bConsideredForSelect = TI_TRUE; /* don't try this site again */
            /* get the next site and continue the loop */
            pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
            continue;
        }

        /* if this site RSSI is higher than current maximum, select it */
        if (pCurrentSite->rssi > iSelectedSiteRssi)
        {
            TRACE6(pSme->hReport, REPORT_SEVERITY_INFORMATION , "sme_Select: BSSID: %02x:%02x:%02x:%02x:%02x:%02x match and has highest RSSI so far!\n", pCurrentSite->bssid[ 0 ], pCurrentSite->bssid[ 1 ], pCurrentSite->bssid[ 2 ], pCurrentSite->bssid[ 3 ], pCurrentSite->bssid[ 4 ], pCurrentSite->bssid[ 5 ]);
            pSelectedSite = pCurrentSite;
            iSelectedSiteRssi = pCurrentSite->rssi;
        }

        /* and continue to the next site */
        pCurrentSite = scanResultTable_GetNext (pSme->hScanResultTable);
    }

    /* if a matching site was found */
    if (NULL != pSelectedSite)
    {
        /* mark that a connection to this site was (actually is) attempted */
        pSelectedSite->bConsideredForSelect = TI_TRUE;

        /* hope this is the correct place for siteMgr_changeBandParams */
        siteMgr_changeBandParams (pSme->hSiteMgr, pSelectedSite->eBand);

        /*
         * Coordinate between SME module site table and Site module site Table 
         * copy candidate AP to Site module site Table.
         */
        siteMgr_CopyToPrimarySite(pSme->hSiteMgr, pSelectedSite);

		/* copy the result, rather than returning a pointer to the entry in the scan result table.
		 * This is done since the table might change durring the connection process, and the pointer 
		 * will point to the wrong entry in the table, causing connection/disconnection problems */
		os_memoryCopy(pSme->hOS, &(pSme->tCandidate), pSelectedSite, sizeof(TSiteEntry));

		return &(pSme->tCandidate);
    }

    /* return NULL if no site was selected */
    return NULL;
}