How to call a function outside httpd_ws.c file in esp-idf

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

How to call a function outside httpd_ws.c file in esp-idf

Postby Baldhead » Tue May 18, 2021 7:38 am

Hi,

I implemented a simple keep alive mechanism for my websocket server and i need call a function from "httpd_ws.c" to a file in my project folder, but the compiler show: "fatal error: my_keep_alive.h: No such file or directory".

How can i do this ?

Partial code(last function) from "httpd_ws.c"

Code: Select all

#include "my_keep_alive.h"  // my include


esp_err_t httpd_ws_get_frame_type(httpd_req_t *req)
{
    esp_err_t ret = httpd_ws_check_req(req);
    if (ret != ESP_OK) {
        return ret;
    }

    struct httpd_req_aux *aux = req->aux;
    if (aux == NULL) {
        ESP_LOGW(TAG, LOG_FMT("Invalid Aux pointer"));
        return ESP_ERR_INVALID_ARG;
    }

    /* Read the first byte from the frame to get the FIN flag and Opcode */
    /* Please refer to RFC6455 Section 5.2 for more details */
    uint8_t first_byte = 0;
    if (httpd_recv_with_opt(req, (char *)&first_byte, sizeof(first_byte), false) <= 0) {
        /* If the recv() return code is <= 0, then this socket FD is invalid (i.e. a broken connection) */
        /* Here we mark it as a Close message and close it later. */
        ESP_LOGW(TAG, LOG_FMT("Failed to read header byte (socket FD invalid), closing socket now"));
        aux->ws_final = true;
        aux->ws_type = HTTPD_WS_TYPE_CLOSE;
        return ESP_OK;
    }

    ESP_LOGD(TAG, LOG_FMT("First byte received: 0x%02X"), first_byte);

    /* Decode the FIN flag and Opcode from the byte */
    aux->ws_final = (first_byte & HTTPD_WS_FIN_BIT) != 0;
    aux->ws_type = (first_byte & HTTPD_WS_OPCODE_BITS);

    /* Reply to PING. For PONG and CLOSE, it will be handled elsewhere. */
    if(aux->ws_type == HTTPD_WS_TYPE_PING) {
        ESP_LOGD(TAG, LOG_FMT("Got a WS PING frame, Replying PONG..."));

        /* Read the rest of the PING frame, for PONG to reply back. */
        /* Please refer to RFC6455 Section 5.5.2 for more details */
        httpd_ws_frame_t frame;
        uint8_t frame_buf[128] = { 0 };
        memset(&frame, 0, sizeof(httpd_ws_frame_t));
        frame.payload = frame_buf;

        if(httpd_ws_recv_frame(req, &frame, 126) != ESP_OK) {
            ESP_LOGD(TAG, LOG_FMT("Cannot receive the full PING frame"));
            return ESP_ERR_INVALID_STATE;
        }




// my code
        int sockfd = httpd_req_to_sockfd(req);         
        clear_Keep_Alive_timeout_counter( sockfd );
//




        /* Now turn the frame to PONG */
        frame.type = HTTPD_WS_TYPE_PONG;
        return httpd_ws_send_frame(req, &frame);
    }

    return ESP_OK;
}

Thank's.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby Baldhead » Wed May 19, 2021 5:27 am

Some suggestion of @espressif team will be apreciated.

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby ESP_Sprite » Wed May 19, 2021 8:45 am

Is the http_ws.c thing in a a separate component? If so, you may need to do some CMakeLists.txt of that component to require your project main dir (I think PRIV_REQUIRES "main" might do it). Not sure as a dependency like that is kind-of odd: normally your project depends on everything else and no components explicitly depend onb your project.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby Baldhead » Wed May 19, 2021 10:13 pm

Hi,

I only put this instructions inside "CMakeLists.txt" of "esp_http_server" esp-idf component:
SRCS "C:/esp32Projects/WSS_SERVER_AND_UI_INTEGRATION/components/communication/my_wss_server/src/my_keep_alive.c"
INCLUDE_DIRS "C:/esp32Projects/WSS_SERVER_AND_UI_INTEGRATION/components/communication/my_wss_server/src/include"


"CMakeLists.txt" of "esp_http_server" esp-idf component:

Code: Select all

idf_component_register( SRCS "src/httpd_main.c"
                            	     "src/httpd_parse.c"
                            	     "src/httpd_sess.c"
                                     "src/httpd_txrx.c"
                                     "src/httpd_uri.c"
                                     "src/httpd_ws.c"
                                     "src/util/ctrl_sock.c"					
                                     INCLUDE_DIRS "include"
                                     PRIV_INCLUDE_DIRS "src/port/esp32" "src/util"
                                     REQUIRES nghttp # for http_parser.h
                                     PRIV_REQUIRES lwip mbedtls esp_timer

SRCS "C:/esp32Projects/WSS_SERVER_AND_UI_INTEGRATION/components/communication/my_wss_server/src/my_keep_alive.c"
INCLUDE_DIRS "C:/esp32Projects/WSS_SERVER_AND_UI_INTEGRATION/components/communication/my_wss_server/src/include"					 
)

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby ESP_Sprite » Wed May 19, 2021 11:45 pm

You could try to add 'main' to the list of PRIV_INCLUDES.

But to be honest, all of this has a code smell. As an alternative, it would be nicer to add a keepalive function pointer member to the httpd_config_t configuration struct; you could use that to specify a custom keepalive function at runtime. That stops your code for having this messy upwards dependency.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby Baldhead » Thu May 20, 2021 12:11 am

Yes, good suggestion, but if i update the esp-idf, i will need to update httpd_config_t configuration struct again too.

it would be interesting if espressif definitely created this member within the structure in future releases of esp-idf.

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby ESP_Sprite » Thu May 20, 2021 5:59 am

Baldhead wrote:
Thu May 20, 2021 12:11 am
it would be interesting if espressif definitely created this member within the structure in future releases of esp-idf.
It depends on the use case the capability of having your own keepalive handler (or whatever it is you're trying to do) fullfills. If it's something that can already be done in a different way or something that's only needed in some hyper-specific scenario, it's not likely to go into ESP-IDF. If it's something that can be useful in general, you can make a case for inclusion in an issue on the ESP-IDF Github repo, or (even better) write what you think would work best and use a pull request so we can see if we can pull it in.

ESP_cermak
Posts: 69
Joined: Thu Nov 01, 2018 8:32 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby ESP_cermak » Fri May 21, 2021 4:26 pm

Hi @Baldhead

Have you checked the keep-alive mechanism in the `wss` example (from https_server)?
https://github.com/espressif/esp-idf/tr ... sl-support

It's implemented in the main component and uses only public includes from the ws interface of the http-server. You can directly use the `keep_alive` API here:
https://github.com/espressif/esp-idf/bl ... ep_alive.h

Or you can check how it accessed the required ws payload and the related structures and perhaps use the same approach.

Baldhead
Posts: 468
Joined: Sun Mar 31, 2019 5:16 am

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby Baldhead » Mon May 24, 2021 7:58 pm

Thank's @ESP_cermak and @ESP_Sprite.

su-Koch
Posts: 11
Joined: Sat Jan 25, 2020 1:43 pm

Re: How to call a function outside httpd_ws.c file in esp-idf

Postby su-Koch » Sat Jul 01, 2023 7:42 pm

was so helpfull. had the exact same issue. Checking the example now to get it working.

Who is online

Users browsing this forum: No registered users and 246 guests