【问题标题】:Cannot initialise wifi_config.ap.ssid with const char * ssid无法使用 const char * ssid 初始化 wifi_config.ap.ssid
【发布时间】:2022-11-23 20:04:49
【问题描述】:

我正在尝试编写一个函数,它将使用 ssid、密码、信道和最大连接设备数来初始化 WLAN AP。下面是我的代码。

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);
    }

问题出在以下部分:

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},
    };

当我像上面那样将 ssid 和 passord 作为字符串常量传递时,它会正确编译和运行。但是,如果我尝试将它们作为变量传递以初始化 wifi_config.ap.ssid,如下所示,它会吐出一个我无法理解的错误。

代码:

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},
        };

错误信息:

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

我没有想出解决办法。在“esp_wifi_types.h”中可以找到wifi_ap_config_t 的成员变量类型如下。

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;

【问题讨论】:

  • 使用上面显示的函数签名,const char * ssid 表示 *ssid 是单个字符。那不是有效的初始值设定项。由于 ssid 是该结构中的一个数组,因此您不能从指针进行初始化。仅来自字符串文字。请改用strcpy
  • @Gerhardh 试过了这次给出了消息:从'const char *'初始化'unsigned char'使指针成为整数而不进行强制转换[-Wint-conversion]
  • 我在您初始化数组时更新了评论
  • 消息是关于哪一行的?初始化 ssid 不会从指针生成整数
  • @Gerhardh 谢谢,解决了这个问题。你让我有了新的认识!我正在用解决方案更新帖子。

标签: c esp32 esp-idf


【解决方案1】:

由于wifi_config_tssid 字段是一个数组,而您的ssid 函数参数是一个指针,因此您不能只将后者分配给前者。您需要的是将指针指向的数据复制到数组中。如果您的 SSID 是一个以 null 结尾的字符串,那么您应该可以使用 strlcpy 函数来做到这一点,如下所示:

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

如果 strlcpy 不可用,您可能需要改用 strncpy,但如果可用,则应使用 strlcpy,因为它保证以 null 终止目标数组中的字符串。如果两者都不可用,则需要使用strlen函数手动找到ssid指向的字符串的长度,然后使用memcpy将这么多字节从ssid复制到wifi_config.ap.ssid,类似于strlcpy 是如何完成的:

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

同样,这一切都假设 ssid 指针指向的字符串以 null 结尾。如果不是,您需要一些其他方法来找出 SSID 字符串的长度。


这是因为赋值 = 不适用于数组。您现在正在使用的值得注意的例外是常量字符串的分配。如果将常量字符串分配给数组,某些编译器会自动将其转换为 memcpy 调用。但是,它不适用于ssid 指针等非常量字符串。在这种情况下,编译器会尝试将指针的值(您的字符串的地址,这是一个类似整数的值)分配给 uint8_t 的数组。可以理解,该操作没有意义,因此编译器会抛出错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多