cancel
Showing results for 
Search instead for 
Did you mean: 

WICED Studio Wi-Fi Combo

New Contributor II

We are trying to set the band for AP entries in DCT but the stack seems to be ignoring them.  It finds the network regardless of the band we tell it to look at, implying it is scanning both bands regardless of the setting.

.

We have a configuration file we use to populate an array:

   wifi_list_size = 0;

   cJSON_ArrayForEach(entry, entries)

   {

      cJSON *ssid = cJSON_GetObjectItemCaseSensitive(entry, "SSID");

      cJSON *pw   = cJSON_GetObjectItemCaseSensitive(entry, "PW");

      cJSON *band = cJSON_GetObjectItemCaseSensitive(entry, "Band");

      // Set SSID

      strcpy(wifi_list[wifi_list_size].ssid, ssid->valuestring);

        

      // Set Security

      strcpy(wifi_list[wifi_list_size].password, pw->valuestring);

      wifi_list[wifi_list_size].security = true;

      // Set Band

      if(strncmp("5GHz", band->valuestring, strlen("5GHz")) == 0)

      {

         wifi_list[wifi_list_size].band = WICED_802_11_BAND_5GHZ;

      }

      else if(strncmp("2.4GHz", band->valuestring, strlen("2.4GHz")) == 0)

      {

         wifi_list[wifi_list_size].band = WICED_802_11_BAND_2_4GHZ;

      }

      else

      {

         wifi_list[wifi_list_size].band = WIFI_DEFAULT_BAND;

      }

     

      // increment number of entries

      wifi_list_size++;

   }

Then we update the DCT using that array

   // get the wi-fi config section for modifying, any memory allocation required would be done inside wiced_dct_read_lock()

   wiced_dct_read_lock( (void**) &dct_wifi_config, WICED_TRUE, DCT_WIFI_CONFIG_SECTION, 0, sizeof( *dct_wifi_config ) );

  

   // update top-level parameters

   dct_wifi_config->country_code = GetWifiCountry();

  

   // write the smaller of credentials in wifi.json and what's allowed by the platform

   uint32_t wifiCount = (GetWifiListLength() < CONFIG_AP_LIST_SIZE) ? GetWifiListLength() : CONFIG_AP_LIST_SIZE;

  

   for (uint32_t i=0; i<wifiCount; i++)

   {

      // get the entry from configuration

      entry = GetWifiParameters(i);

     

      // SSID

      dct_wifi_config->stored_ap_list.details.SSID.length = strlen(entry->ssid);

      strlcpy((char *)dct_wifi_config->stored_ap_list.details.SSID.value,

              entry->ssid,

              sizeof(dct_wifi_config->stored_ap_list.details.SSID.value));

      // password

      dct_wifi_config->stored_ap_list.security_key_length = strlen(entry->password);

      strlcpy((char *)dct_wifi_config->stored_ap_list.security_key,

              entry->password,

              sizeof(dct_wifi_config->stored_ap_list.security_key));

      // security type

      dct_wifi_config->stored_ap_list.details.security =

          (entry->security) ? WICED_SECURITY_WPA2_AES_PSK : WICED_SECURITY_OPEN;

         

      // bss type

      dct_wifi_config->stored_ap_list.details.bss_type = WICED_BSS_TYPE_INFRASTRUCTURE;

     

      // band

      dct_wifi_config->stored_ap_list.details.band = entry->band;

     

   }

  

   // write the image back and release the read lock

   wiced_dct_write( (const void*) dct_wifi_config, DCT_WIFI_CONFIG_SECTION, 0, sizeof(platform_dct_wifi_config_t) );

   wiced_dct_read_unlock( dct_wifi_config, WICED_TRUE );

0 Likes
Reply
1 Solution
Moderator
Moderator

Hi,

I've run some searching for you.

I believe the internal function "wiced_join_ap_specific" is the actual function that WICED uses to join the stored APs, which is listed in '43xxx_Wi-Fi/WICED/internal/wifi.c'. I quote it here:

wiced_result_t wiced_join_ap_specific( wiced_ap_info_t* details, uint8_t security_key_length, const char security_key[ 64 ] )

#endif

{

    wiced_result_t      join_result = WICED_STA_JOIN_FAILED;

    wiced_scan_result_t temp_scan_result;

#ifndef WICED_USE_WIFI_TWO_STA_INTERFACE

    wiced_interface_t interface = WICED_STA_INTERFACE;

#endif

    char                ssid_name[SSID_NAME_SIZE + 1];

    memset(ssid_name, 0, sizeof(ssid_name));

    memcpy(ssid_name, details->SSID.value, details->SSID.length);

    WPRINT_WICED_INFO(("Joining : %s\n", ssid_name));

    memcpy( &temp_scan_result, details, sizeof( *details ) );

    /* Try join AP with last know specific details */

    if ( !( NULL_MAC(details->BSSID.octet) ) && details->channel != 0 )

    {

        join_result = (wiced_result_t) wwd_wifi_join_specific( &temp_scan_result, (uint8_t*) security_key, security_key_length, NULL, WICED_TO_WWD_INTERFACE(interface) );

    }

    if ( join_result != WICED_SUCCESS )

    {

        wiced_security_t security;

        security = details->security;

        if (details->bss_type == WICED_BSS_TYPE_ADHOC)

        {

            WPRINT_WICED_INFO(("%s: Network is ADHOC\n", __FUNCTION__));

            security |= IBSS_ENABLED;

        }

        /* If join-specific failed, try scan and join AP */

        join_result = (wiced_result_t) wwd_wifi_join( &details->SSID, security, (uint8_t*) security_key, security_key_length, NULL, WICED_TO_WWD_INTERFACE(interface) );

    }

    if ( join_result == WICED_SUCCESS )

    {

        WPRINT_WICED_INFO( ( "Successfully joined : %s\n", ssid_name) );

#ifdef WICED_USE_WIFI_TWO_STA_INTERFACE

        wiced_sta_link_up[interface]      = WICED_TRUE;

        wiced_sta_security_type[interface] = details->security;

#else

        wiced_sta_link_up      = WICED_TRUE;

        wiced_sta_security_type = details->security;

#endif

        wwd_management_set_event_handler( link_events, wiced_link_events_handler, NULL, WICED_TO_WWD_INTERFACE(interface) );

        return WICED_SUCCESS;

    }

    else

    {

        WPRINT_WICED_INFO(("Failed to join : %s\n", ssid_name));

    }

    return join_result;

}

As you can see, the variable "details" in this piece of code could represent the one named "details" in your code because they are of the same type wiced_ap_info_t. In this code we should see that, though you had setup the band with the line "dct_wifi_config->stored_ap_list.details.band = entry->band; ", it's never used when it actually tries to join a certain AP throughout this function.

So that's why it didn't work because the joining procedure didn't require the field "band". And I believe this is the answer.

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

View solution in original post

3 Replies
Moderator
Moderator

Hi NaFi_2915566​,

Firstly, In your first code block I saw you were on the variant "wifi_list". In your second code block I saw you used a different variant "entry". Have you already verified the two variant do contain the same data you meant? Try to pause on "wiced_dct_write()" to see if "dct_wifi_config" contains the exact data you want while debugging.

Secondly, check the returned Wiced Result of "wiced_dct_write()" to see if the data is successfully written and why.

Besides, when you successfully wrote the data to DCT, you still have to make sure your application reads the updated DCT config the next time you start a scan procedure. It won't notify your application automatically (won't trigger any event like WRITE_COMPLETE that sort of thing).

See the following materials for advices:

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

New Contributor II

Hi ChunleiL_51

wifi_list[] is created by one thread at power up.  Later, the entries are read one at a time using "entry = GetWifiParameters(i);" shown above  I know this part of the code works.

I added checks, none of the three wiced_dct_... calls above returns an error.

I understand what you are saying about using the updated DCT but neither snip/dct_read_write example nor the document you linked above mention how to make sure the code uses the updated DCT.    Do you know how this can be done?

Here is how we update DCT then search for networks.  I know the SSID/PW work because if I change them then wifi searches for new networks the first time I run this code..

   // update the wifi credentials from wifi.json

   update_wifi_credentials();  // NOTE: this is the second piece of code above

  

   // set up callbacks

   wiced_network_register_link_callback(link_up_callback, link_down_callback, WICED_STA_INTERFACE);

  

   do

   {

      result = wiced_network_up(WICED_STA_INTERFACE, WICED_USE_EXTERNAL_DHCP_SERVER, NULL);

      if ( result != WICED_SUCCESS )

      {

         WPRINT_APP_ERROR( ( "***Error: wiced_network_up failed: %u\n", result) );

      }

   } while (result != WICED_SUCCESS);

I also tried several power cycles in case the DCT update only works the next time.  Band selection still does not work.

0 Likes
Reply
Moderator
Moderator

Hi,

I've run some searching for you.

I believe the internal function "wiced_join_ap_specific" is the actual function that WICED uses to join the stored APs, which is listed in '43xxx_Wi-Fi/WICED/internal/wifi.c'. I quote it here:

wiced_result_t wiced_join_ap_specific( wiced_ap_info_t* details, uint8_t security_key_length, const char security_key[ 64 ] )

#endif

{

    wiced_result_t      join_result = WICED_STA_JOIN_FAILED;

    wiced_scan_result_t temp_scan_result;

#ifndef WICED_USE_WIFI_TWO_STA_INTERFACE

    wiced_interface_t interface = WICED_STA_INTERFACE;

#endif

    char                ssid_name[SSID_NAME_SIZE + 1];

    memset(ssid_name, 0, sizeof(ssid_name));

    memcpy(ssid_name, details->SSID.value, details->SSID.length);

    WPRINT_WICED_INFO(("Joining : %s\n", ssid_name));

    memcpy( &temp_scan_result, details, sizeof( *details ) );

    /* Try join AP with last know specific details */

    if ( !( NULL_MAC(details->BSSID.octet) ) && details->channel != 0 )

    {

        join_result = (wiced_result_t) wwd_wifi_join_specific( &temp_scan_result, (uint8_t*) security_key, security_key_length, NULL, WICED_TO_WWD_INTERFACE(interface) );

    }

    if ( join_result != WICED_SUCCESS )

    {

        wiced_security_t security;

        security = details->security;

        if (details->bss_type == WICED_BSS_TYPE_ADHOC)

        {

            WPRINT_WICED_INFO(("%s: Network is ADHOC\n", __FUNCTION__));

            security |= IBSS_ENABLED;

        }

        /* If join-specific failed, try scan and join AP */

        join_result = (wiced_result_t) wwd_wifi_join( &details->SSID, security, (uint8_t*) security_key, security_key_length, NULL, WICED_TO_WWD_INTERFACE(interface) );

    }

    if ( join_result == WICED_SUCCESS )

    {

        WPRINT_WICED_INFO( ( "Successfully joined : %s\n", ssid_name) );

#ifdef WICED_USE_WIFI_TWO_STA_INTERFACE

        wiced_sta_link_up[interface]      = WICED_TRUE;

        wiced_sta_security_type[interface] = details->security;

#else

        wiced_sta_link_up      = WICED_TRUE;

        wiced_sta_security_type = details->security;

#endif

        wwd_management_set_event_handler( link_events, wiced_link_events_handler, NULL, WICED_TO_WWD_INTERFACE(interface) );

        return WICED_SUCCESS;

    }

    else

    {

        WPRINT_WICED_INFO(("Failed to join : %s\n", ssid_name));

    }

    return join_result;

}

As you can see, the variable "details" in this piece of code could represent the one named "details" in your code because they are of the same type wiced_ap_info_t. In this code we should see that, though you had setup the band with the line "dct_wifi_config->stored_ap_list.details.band = entry->band; ", it's never used when it actually tries to join a certain AP throughout this function.

So that's why it didn't work because the joining procedure didn't require the field "band". And I believe this is the answer.

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

View solution in original post