Cannot initialise wifi_config.ap.ssid with const char * ssid

I am trying to write a function that will take ssid, password, channel and maximum connected devices to initialise a WLAN AP. Below is my code.

void wifi_init_softap(const char * ssid, const char *password, uint8_t channel, uint8_t max_conn)
    {
        ESP_ERROR_CHECK(esp_netif_init());                // Initialise ESP Netif, Which manages the DHCP Server
        ESP_ERROR_CHECK(esp_event_loop_create_default()); // Create new event loop
    
        // esp_netif_create_default_wifi_ap();
        esp_netif_t *p_netif = esp_netif_create_default_wifi_ap(); // Create Default Wifi AP
    
        esp_netif_ip_info_t ipInfo; // Stores IP & Gateway & Netmask
    
        // Assignes default values to ip stack
        IP4_ADDR(&ipInfo.ip, 192, 168, 1, 1);
        IP4_ADDR(&ipInfo.gw, 192, 168, 1, 1);
        IP4_ADDR(&ipInfo.netmask, 255, 255, 255, 0);
    
        // Stop DHCP Server on p_netif, assign the new IP stack, and restart it
        esp_netif_dhcps_stop(p_netif);
        esp_netif_set_ip_info(p_netif, &ipInfo);
        esp_netif_dhcps_start(p_netif);
        //----------------------------------------------------------------------------------------//
        ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
                                                            ESP_EVENT_ANY_ID,
                                                            &wifi_event_handler,
                                                            NULL,
                                                            NULL));
    
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));
        //----------------------------------------------------------------------------------------//
    
        // uint8_t *buffer_ssid = (uint8_t *)malloc((strlen(ssid)) * sizeof(char)+1);
        // memcpy(buffer_ssid, ssid, (strlen(ssid)) * sizeof(char) );
    
    
        wifi_config_t wifi_config = {
            .ap = {
                .ssid = "*ssid",
                .ssid_len = strlen(ssid),
                .channel = channel,
                .password = "(*password)",
                .max_connection = max_conn,
                .authmode = WIFI_AUTH_WPA_WPA2_PSK},
        };
        if (strlen(password) == 0)
        {
            wifi_config.ap.authmode = WIFI_AUTH_OPEN;
        }
    
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
        ESP_ERROR_CHECK(esp_wifi_start());
    
        ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
                 ssid, password, max_conn);
    }

The issue is with the following part:

wifi_config_t wifi_config = {
        .ap = {
            .ssid = "*ssid",
            .ssid_len = strlen(ssid),
            .channel = channel,
            .password = "(*password)",
            .max_connection = max_conn,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK},
    };

When I pass ssid and passord as string constants like above, it compiles and functions correctly. However if I try passing them as variables to initialise wifi_config.ap.ssid like below it spits out an error I cannot understand.

Code:

wifi_config_t wifi_config = {
            .ap = {
                .ssid = *ssid,
                .ssid_len = strlen(ssid),
                .channel = channel,
                .password = *password,
                .max_connection = max_conn,
                .authmode = WIFI_AUTH_WPA_WPA2_PSK},
        };

Error Message:

missing braces around initializer [-Werror=missing-braces]

I fail to come up with a solution to this. On "esp_wifi_types.h" the types of member variables to wifi_ap_config_t can be found as below.

typedef struct {
    uint8_t ssid[32];           /**< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */
    uint8_t password[64];       /**< Password of ESP32 soft-AP. */
    uint8_t ssid_len;           /**< Optional length of SSID field. */
    uint8_t channel;            /**< Channel of ESP32 soft-AP */
    wifi_auth_mode_t authmode;  /**< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode */
    uint8_t ssid_hidden;        /**< Broadcast SSID or not, default 0, broadcast the SSID */
    uint8_t max_connection;     /**< Max number of stations allowed to connect in, default 4, max 10 */
    uint16_t beacon_interval;   /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */
    wifi_cipher_type_t pairwise_cipher;   /**< pairwise cipher of SoftAP, group cipher will be derived using this. cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP and WIFI_CIPHER_TYPE_TKIP_CCMP. */
    bool ftm_responder;         /**< Enable FTM Responder mode */
} wifi_ap_config_t;

>Solution :

Since the ssid field of wifi_config_t is an array and your ssid function argument is a pointer, you cannot just assign the latter to the former. What you need is to copy the data pointed by the pointer to the array. If your SSID is a null-terminated string then you should be able to do that with the strlcpy function, like this:

// destination first, source second, max size of buffer last
strlcpy(wifi_config.ap.ssid, ssid, 32);

If strlcpy is not available, you may need to use strncpy instead, although strlcpy should be used if available as it guarantees to null-terminate the string in the destination array. If neither is available, then you need to manually find the length of the string pointed to by ssid using the strlen function and then use memcpy to copy this many bytes from ssid to wifi_config.ap.ssid, similarly to how it is done with strlcpy:

size_t ssid_length = strlen(ssid);
memcpy(wifi_config.ap.ssid, ssid, ssid_length);

Again, this is all assuming the string pointed to by ssid pointer is null-terminated. If it is not, you need some other way of finding out the length of the SSID string.


This is due to the fact that assignment = does not work with arrays. Notable exception, which you are using right now, is assignment of constant strings. If you assign a constant string to an array it will automatically be translated into a memcpy call by some compilers. However, it does not work with non-constant strings like your ssid pointer. In this case, the compiler tries to assign the value of the pointer (address of your string, which is an integer-like value) to an array of uint8_t. Understandably, the operation does not make sense so compiler throws an error.

Leave a Reply