wlan: Fix to select the right country code during roaming

In the current code, with the voting logic for regulatory
in place, during roaming, instead of selecting the
country code of the AP that the STA joins, the STA is
selecting the country code that is decided by the voting
mechanism. This is fixed using this gerrit by using the
country code information from beacon and probe response
for roaming and by using the voting mechanism for other
scenarios.

CRs-Fixed: 676456
Change-Id: I512113fe7ed6b9f85af95b0800f9675add239709
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index 48cd4f5..3d09dfb 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -3127,7 +3127,7 @@
             }
         }
         csrElectedCountryInfo(pMac);
-        csrLearnCountryInformation( pMac, eANI_BOOLEAN_TRUE );
+        csrLearnCountryInformation( pMac, NULL, NULL, eANI_BOOLEAN_TRUE );
     }
 
 end:
@@ -4061,22 +4061,58 @@
 /*
   * 802.11D only: Gather 11d IE via beacon or Probe response and store them in pAdapter->channels11d
 */
-tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tANI_BOOLEAN fForce)
+tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,
+                                         tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce)
 {
     eHalStatus status;
+    tANI_U8 *pCountryCodeSelected;
     tANI_BOOLEAN fRet = eANI_BOOLEAN_FALSE;
     v_REGDOMAIN_t domainId;
+    tDot11fBeaconIEs *pIesLocal = pIes;
+    tANI_BOOLEAN useVoting = eANI_BOOLEAN_FALSE;
 
     if (VOS_STA_SAP_MODE == vos_get_conparam ())
         return eHAL_STATUS_SUCCESS;
 
+    if ((NULL == pSirBssDesc) && (NULL == pIes))
+        useVoting = eANI_BOOLEAN_TRUE;
+
     do
     {
         // check if .11d support is enabled
         if( !csrIs11dSupported( pMac ) ) break;
 
+        if (eANI_BOOLEAN_FALSE == useVoting)
+        {
+            if( !pIesLocal &&
+                (!HAL_STATUS_SUCCESS(csrGetParsedBssDescriptionIEs(pMac,
+                                     pSirBssDesc, &pIesLocal))))
+            {
+                break;
+            }
+            // check if country information element is present
+            if(!pIesLocal->Country.present)
+            {
+                //No country info
+                break;
+            }
+
+            if( HAL_STATUS_SUCCESS(csrGetRegulatoryDomainForCountry
+                (pMac, pIesLocal->Country.country, &domainId,
+                COUNTRY_QUERY)) &&
+                ( domainId == REGDOMAIN_WORLD))
+            {
+                break;
+            }
+        } //useVoting == eANI_BOOLEAN_FALSE
+
+        if (eANI_BOOLEAN_FALSE == useVoting)
+            pCountryCodeSelected = pIesLocal->Country.country;
+        else
+            pCountryCodeSelected = pMac->scan.countryCodeElected;
+
         status = csrGetRegulatoryDomainForCountry(pMac,
-                       pMac->scan.countryCodeElected, &domainId, COUNTRY_IE);
+                       pCountryCodeSelected, &domainId, COUNTRY_IE);
         if ( status != eHAL_STATUS_SUCCESS )
         {
             smsLog( pMac, LOGE, FL("  fail to get regId %d"), domainId );
@@ -4088,7 +4124,7 @@
         if ( domainId != pMac->scan.domainIdCurrent )
         {
             vos_mem_copy(pMac->scan.countryCode11d,
-                                  pMac->scan.countryCodeElected,
+                                  pCountryCodeSelected,
                                   sizeof( pMac->scan.countryCode11d ) );
             /* Set Current Country code and Current Regulatory domain */
             status = csrSetRegulatoryDomain(pMac, domainId, NULL);
@@ -4100,9 +4136,9 @@
             }
             //csrSetRegulatoryDomain will fail if the country doesn't fit our domain criteria.
             vos_mem_copy(pMac->scan.countryCodeCurrent,
-                            pMac->scan.countryCodeElected, WNI_CFG_COUNTRY_CODE_LEN);
+                            pCountryCodeSelected, WNI_CFG_COUNTRY_CODE_LEN);
             //Simply set it to cfg.
-            csrSetCfgCountryCode(pMac, pMac->scan.countryCodeElected);
+            csrSetCfgCountryCode(pMac, pCountryCodeSelected);
 
             /* overwrite the defualt country code */
             vos_mem_copy(pMac->scan.countryCodeDefault,
@@ -4140,7 +4176,12 @@
         fRet = eANI_BOOLEAN_TRUE;
 
     } while( 0 );
-    
+
+    if( !pIes && pIesLocal )
+    {
+        //locally allocated
+        vos_mem_free(pIesLocal);
+    }
 
     return( fRet );
 }