简体   繁体   English

ESP32 原生 ESP-IDF 组件“没有这样的文件或目录”

[英]ESP32 “No such file or directory” for native ESP-IDF component

I'm trying to port the file_serving example to use HTTPS.我正在尝试移植 file_serving 示例以使用 HTTPS。

I've attempted to move the spiff file server functionality to the existing https_server example inside esp-idf but I get the error: httpd_server_init: error in creating ctrl socket (112)我试图将 spiff 文件服务器功能移动到 esp-idf 中现有的 https_server 示例,但出现错误:httpd_server_init:创建 ctrl 套接字时出错 (112)

I realize that this is probably not the easiest way to do it and instead I should work on re-writing the original file_serving example code to use https instead.我意识到这可能不是最简单的方法,相反,我应该重写原始的 file_serving 示例代码以改用 https。 The function to start the server is in the file_server.c:启动服务器的function在file_server.c中:

/* Function to start the file server */
esp_err_t start_file_server(const char *base_path)
{
    static struct file_server_data *server_data = NULL;

    /* Validate file storage base path */
    if (!base_path || strcmp(base_path, "/spiffs") != 0) {
        ESP_LOGE(TAG, "File server presently supports only '/spiffs' as base path");
        return ESP_ERR_INVALID_ARG;
    }

    if (server_data) {
        ESP_LOGE(TAG, "File server already started");
        return ESP_ERR_INVALID_STATE;
    }

    /* Allocate memory for server data */
    server_data = calloc(1, sizeof(struct file_server_data));
    if (!server_data) {
        ESP_LOGE(TAG, "Failed to allocate memory for server data");
        return ESP_ERR_NO_MEM;
    }
    strlcpy(server_data->base_path, base_path,
            sizeof(server_data->base_path));

    httpd_handle_t server = NULL;
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();

    /* Use the URI wildcard matching function in order to
     * allow the same handler to respond to multiple different
     * target URIs which match the wildcard scheme */
    config.uri_match_fn = httpd_uri_match_wildcard;

    ESP_LOGI(TAG, "Starting HTTP Server");
    if (httpd_start(&server, &config) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to start file server!");
        return ESP_FAIL;
    }

    /* URI handler for getting uploaded files */
    httpd_uri_t file_download = {
        .uri       = "/*",  // Match all URIs of type /path/to/file
        .method    = HTTP_GET,
        .handler   = download_get_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_download);

    /* URI handler for uploading files to server */
    httpd_uri_t file_upload = {
        .uri       = "/upload/*",   // Match all URIs of type /upload/path/to/file
        .method    = HTTP_POST,
        .handler   = upload_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_upload);

    /* URI handler for deleting files from server */
    httpd_uri_t file_delete = {
        .uri       = "/delete/*",   // Match all URIs of type /delete/path/to/file
        .method    = HTTP_POST,
        .handler   = delete_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_delete);

    return ESP_OK;
}

The main function references the start_file_server and that is shown below as well:主要的 function 引用了 start_file_server,如下所示:

void app_main(void)
{
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
     * Read "Establishing Wi-Fi or Ethernet Connection" section in
     * examples/protocols/README.md for more information about this function.
     */
    ESP_ERROR_CHECK(example_connect());

    /* Initialize file storage */
    ESP_ERROR_CHECK(init_spiffs());

    /* Start the file server */
    ESP_ERROR_CHECK(start_file_server("/spiffs"));
}

I have the https_server example running and I have https_mbedtls client connecting to it and not authenticating the validity of my self-signed cert.我正在运行 https_server 示例,并且我有 https_mbedtls 客户端连接到它并且没有验证我的自签名证书的有效性。 This same https_mbedtls client would be used to connect the the file_server (https).这个相同的 https_mbedtls 客户端将用于连接 file_server (https)。

the original file_server example includes esp_http_server.h.原始的 file_server 示例包括 esp_http_server.h。 I assume that I need to instead include esp_https_server.h我假设我需要包含 esp_https_server.h

Below are the changes that I have made to it:以下是我对其所做的更改:

/* Function to start the file server */
esp_err_t start_file_server(const char *base_path)
{
    static struct file_server_data *server_data = NULL;

    /* Validate file storage base path */
    if (!base_path || strcmp(base_path, "/spiffs") != 0) {
        ESP_LOGE(TAG, "File server presently supports only '/spiffs' as base path");
        return ESP_ERR_INVALID_ARG;
    }

    if (server_data) {
        ESP_LOGE(TAG, "File server already started");
        return ESP_ERR_INVALID_STATE;
    }

    /* Allocate memory for server data */
    server_data = calloc(1, sizeof(struct file_server_data));
    if (!server_data) {
        ESP_LOGE(TAG, "Failed to allocate memory for server data");
        return ESP_ERR_NO_MEM;
    }
    strlcpy(server_data->base_path, base_path,
            sizeof(server_data->base_path));

    //***********
    httpd_handle_t server = NULL;
    httpd_ssl_config_t config = HTTPD_SSL_CONFIG_DEFAULT(); 
    //***********

    extern const unsigned char cacert_pem_start[] asm("_binary_cacert_pem_start");
    extern const unsigned char cacert_pem_end[]   asm("_binary_cacert_pem_end");
    conf.cacert_pem = cacert_pem_start;
    conf.cacert_len = cacert_pem_end - cacert_pem_start;

    extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
    extern const unsigned char prvtkey_pem_end[]   asm("_binary_prvtkey_pem_end");
    conf.prvtkey_pem = prvtkey_pem_start;
    conf.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
    //***********


    /* Use the URI wildcard matching function in order to
     * allow the same handler to respond to multiple different
     * target URIs which match the wildcard scheme */
    config.uri_match_fn = httpd_uri_match_wildcard;

    ESP_LOGI(TAG, "Starting HTTPS Server");
    //***********
    if (httpd_ssl_start(&server, &config) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to start file server!");
        return ESP_FAIL;
    }

    /* URI handler for getting uploaded files */
    httpd_uri_t file_download = {
        .uri       = "/*",  // Match all URIs of type /path/to/file
        .method    = HTTP_GET,
        .handler   = download_get_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_download);

    /* URI handler for uploading files to server */
    httpd_uri_t file_upload = {
        .uri       = "/upload/*",   // Match all URIs of type /upload/path/to/file
        .method    = HTTP_POST,
        .handler   = upload_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_upload);

    /* URI handler for deleting files from server */
    httpd_uri_t file_delete = {
        .uri       = "/delete/*",   // Match all URIs of type /delete/path/to/file
        .method    = HTTP_POST,
        .handler   = delete_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_delete);

    return ESP_OK;
}

When I go flash through ESP-IDF command line I get the following error:当我通过 ESP-IDF 命令行 go flash 时,我收到以下错误:

../main/file_server.c:22:10: fatal error: esp_https_server.h: No such file or directory #include "esp_https_server.h" ^~~~~~~~~~~~~~~~~~~~ compilation terminated. ../main/file_server.c:22:10: 致命错误: esp_https_server.h: No such file or directory #include "esp_https_server.h" ^~~~~~~~~~~~~~~~~~ ~~ 编译终止。

To fix this, I try to add "REQUIRES esp_https_server" to the CMakeLists.txt in the main directory.为了解决这个问题,我尝试将“REQUIRES esp_https_server”添加到主目录的 CMakeLists.txt 中。 This replaces the previous error with这将先前的错误替换为

../main/main.c:16:10: fatal error: esp_spiffs.h: No such file or directory #include "esp_spiffs.h" ^~~~~~~~~~~~~~ compilation terminated. ../main/main.c:16:10: 致命错误: esp_spiffs.h: 没有这样的文件或目录#include "esp_spiffs.h" ^~~~~~~~~~~~~~ 编译终止。

The same thing happens where it can't find additional requirements until my CMakeLists.txt looks like this:在我的 CMakeLists.txt 看起来像这样之前它无法找到其他要求的地方也会发生同样的事情:

idf_component_register(SRCS "main.c" "file_server.c"
                    INCLUDE_DIRS "."
                    EMBED_FILES "favicon.ico" "upload_script.html"
                    EMBED_TXTFILES "certs/cacert.pem"
                                   "certs/prvtkey.pem"
                    REQUIRES esp_https_server spiffs nvs_flash protocol_examples_common)

And the error I get at this point is once again unable to find esp_https_server.h我此时得到的错误是再次无法找到 esp_https_server.h

../main/file_server.c:22:10: fatal error: esp_https_server.h: No such file or directory #include "esp_https_server.h" ^~~~~~~~~~~~~~~~~~~~ compilation terminated. ../main/file_server.c:22:10: 致命错误: esp_https_server.h: No such file or directory #include "esp_https_server.h" ^~~~~~~~~~~~~~~~~~ ~~ 编译终止。

I hope you understand the frustrating predicament that I'm in and I would greatly appreciate any input on how to fix this "No such file or directory" error or any tips on how to port this example to https as well.我希望你能理解我所处的令人沮丧的困境,我将非常感谢任何关于如何修复这个“没有这样的文件或目录”错误的意见,或者关于如何将此示例移植到 https 的任何提示。 Thank you.谢谢你。

My supervising professor had a look at the problem and found the solution.我的指导教授查看了问题并找到了解决方案。 Here are the changes that were needed to be made:以下是需要进行的更改:

Include the following line in the sdkconfig file: CONFIG_ESP_HTTPS_SERVER_ENABLE=y在 sdkconfig 文件中包含以下行:CONFIG_ESP_HTTPS_SERVER_ENABLE=y

“config” instead of “conf” in the file file_server.c and the configuration for the http server is a subcomponent of the https configuration and needs a "httpd.”文件 file_server.c 中的“config”而不是“conf”,http 服务器的配置是 https 配置的子组件,需要“httpd”。 after the “config.”:在“配置”之后:

 extern const unsigned char cacert_pem_start[] asm("_binary_cacert_pem_start");
    extern const unsigned char cacert_pem_end[]   asm("_binary_cacert_pem_end");
    config.cacert_pem = cacert_pem_start;
    config.cacert_len = cacert_pem_end - cacert_pem_start;

    extern const unsigned char prvtkey_pem_start[] asm("_binary_prvtkey_pem_start");
    extern const unsigned char prvtkey_pem_end[]   asm("_binary_prvtkey_pem_end");
    config.prvtkey_pem = prvtkey_pem_start;
    config.prvtkey_len = prvtkey_pem_end - prvtkey_pem_start;
    //***********


    /* Use the URI wildcard matching function in order to
     * allow the same handler to respond to multiple different
     * target URIs which match the wildcard scheme */
    config.httpd.uri_match_fn = httpd_uri_match_wildcard;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM