Skip to main content
Explorer
February 13, 2024
Solved

Where to find LwIP incoming payload data for webserver?

  • February 13, 2024
  • 8 replies
  • 5434 views

STM32CubeIDE Version: 1.12.0
Build: 14980_20230301_1550 (UTC)

I have a STM32F407 Discovery board running a web server.  I have a simple webpage with a single button that when clicked, displays a text message below the button. I had issues with the server at first due to the const keywords that were in the fsdata.c file, but it is working fine now.

Where is the buffer for the incoming button click and the text message located? Is there a weak callback function somewhere that handles incoming data? I want to intercept the message and take action based on the incoming data.

I used STM32CubeIDE to create the server and accepted all of the default settings.

 

 

    This topic has been closed for replies.
    Best answer by Raymond Buck

    LCE, thank you for pointing me to the correct place to get the data. I see the button request data at line 2021 in the http_parse_request function. The statements at that point are these:

    if (!strncmp(data, "GET ", 4)) {
    sp1 = data + 3;

    spi has the message that the button click sends. It looks exactly like the data that Wireshark logs. Unfortunately, there are no sections for user code to be placed there. I will make a note in my main.c file to remind me that I had to put code there to retrieve the incoming data. Out of curiosity, I ran the IOC tool to regenerate code and it did overwrite my code at that point. So I will have to include the code that I added in the note that I make.

    Problem solved. Thank you again. I had spent a few hours searching and not finding the solution..

    8 replies

    Super User
    February 14, 2024

    Is there any incoming data due to the button click? You have not provided enough details on your "simple web page".

    For example the button click can be completely handled on the client side (in your browser) so nothing is sent back to the server on click.  If you don't feel confident in web programming and client-server communication, look for a consultant?

     

    Explorer
    February 14, 2024

    When the button is clicked, this is the data I send out:

    button_request?data=test4,button_4,ON

    In Wireshark I see this data: GET /button_request?data=test4%2Cbutton_4%2CON HTTP/1.1

    I can make it work using UDP and I know where that data comes in. I am looking for the function (probably a weak one) that handles the TCP data coming in.

    I am not using an OS and don't want to use one.

    Graduate II
    February 14, 2024

    Check http_parse_request() in httpd.c in ..\Middlewares\Third_Party\LwIP\src\apps\http\httpd.c

    At least that's a starting point... As all else in lwip, it's totally "nested" in bazillions of functions with crazy pbuf pointering (I renamed many of these from "p" to "pPbufIn", "pPbufWork" .... to keep better control).

    But that's where incoming data is checked for GET, I put the PUT option in there. 

    Data in the incoming p->payload.

    Raymond BuckAuthorAnswer
    Explorer
    February 14, 2024

    LCE, thank you for pointing me to the correct place to get the data. I see the button request data at line 2021 in the http_parse_request function. The statements at that point are these:

    if (!strncmp(data, "GET ", 4)) {
    sp1 = data + 3;

    spi has the message that the button click sends. It looks exactly like the data that Wireshark logs. Unfortunately, there are no sections for user code to be placed there. I will make a note in my main.c file to remind me that I had to put code there to retrieve the incoming data. Out of curiosity, I ran the IOC tool to regenerate code and it did overwrite my code at that point. So I will have to include the code that I added in the note that I make.

    Problem solved. Thank you again. I had spent a few hours searching and not finding the solution..

    Super User
    February 14, 2024

    Have you tried the LwIP User mailing List?

    https://savannah.nongnu.org/mail/?group=lwip

     

    Explorer
    February 14, 2024

    Andrew, No I did not check there as I felt this was the first place to ask for help. I'm sure ST heavily modifies the LwIP code to match their development environment. If I didn't get answers here, I would have checked there next.

    Super User
    February 14, 2024

    In Wireshark I see this data: GET /button_request?data=test4%2Cbutton_4%2CON HTTP/1.1

    Then it looks like your web page does a new http get request, with the parameters encoded in the URL. There's a standard for this: the parameters start with ? after the URL and are separated by & and there can be something else. Then, the httpd "core" will call the handler function and pass the parsed parameters to it. It supports few kinds of handlers, called via user-provided  httpd_cgi_handler(). So you likely need to implement this to get the URL-encoded parameters.

    Sending another page request is not an efficient way to communicate with a server, as it causes complete reloading the entire page in both server and client.

     

    Super User
    February 14, 2024

     I'm sure ST heavily modifies the LwIP code to match their development environment.

    Hm, not quite so. They modify only the low level ethernetif code related to the STM32 ETH controller, its capabilities, supported offloads and so on. They also provide complete working examples, including the http server/client. The examples are very simple, with the only purpose to demonstrate the hardware operation. ST also has to touch the FreeRTOS related glue code in LwIP/system/arch, LwIP/system/OS. And the mandatory SSL support & crypto. Nothing other fancy in the software. 

     

     

    Explorer
    February 15, 2024

    I am not sending another page request in my application. I had set that up just to confirm the website was working. All I will be sending to the server are button press notifications. I do have to figure how how to send an ACK back from the server. I currently get the message "Server request failed with status: 0" back when I click a button. This is the error message I put in a textbox if I don't get an OK message back from the server.

    I also will probably have to check the board to confirm that the I/O that I toggled on or off actually worked and send that information back to the web page.

    When you mention the server/client examples, are you referring to the echo examples of some other example?

    Super User
    February 26, 2024

    @Raymond Buck Yes I refer to the HTTP server and client examples in Cube lib. package (by the way Cube packages for more recent MCU families can have more interesting examples).

    As I tried to say earlier the web server/client stuff is complex - more complex than one wishes to know. These complications are crucial for efficient, reliable and secure communication. The ST examples are just as simple as possible to demonstrate the hardware operation. People are lured to use ST boards because of low price and seemingly "easy" tools - but then intimidated by need to implement a lot of software, from the app layer down to network drivers below L2. Of course, efficient solutions do exist, but people do not like them.

    Graduate II
    February 15, 2024

    @Raymond Buck I recommend to stop using CubeMX after the initial setup, because of overwriting stuff.

    I always start a 2nd project with the same settings, and if there's a new peripheral I need, I copy stuff from the new 2nd project.

    When I started with CubeMX that really cost me some time and nerves...

    lwIP: as @Pavel A. said, I think ST doesn't touch the lwip files in ..\Middlewares\Third_Party\LwIP/.
    All the STM32 specific stuff is done in the  in the lower "LWIP" /App and /Target folders, e.g. with lwipopts.h making the "regular" opts.h kinda weak file or so.

    I actually had to edit the lwip files for my application:
    - PUT method into httpd
    - some extra pbuf ACK handling in the TCP files

    Feels somehow bad, but I couldn't handle some stuff with external functions.

    Super User
    February 15, 2024

     some extra pbuf ACK handling in the TCP files

    Could you tell more about this please?

     

    Graduate II
    February 15, 2024

    @Pavel A. 

    For a ~50 Mbit/s audio over TCP application which needs 100% reliability, no dropouts allowed,
    I made the following changes :

    - added a pointer pA2IpCtl (to my "audio to IP control struct" in DTCM) to the pbuf struct, which holds the control data (pointer to next control, pointer to audio buffer, buffer state, errors) for the actual audio data buffer (incl. own header)

    - I copied and edited tcp_write() to a  tcp_write_a2ip() version which adds the pointer pA2IpCtl to the TCP pbuf

    - in pbuf.c / pbuf_free() that pointer pA2IpCtl is checked if != NULL the audio buffer state is changed to free

     

    I had no other idea how to accomplish that.

    But at least it's working...

    Graduate II
    February 27, 2024

    If you need ACK from any side, keep using TCP.

    I have the STM as the webserver with 3 html pages, including some buttons, text fields and drop down menus.

    All this is handled with SSI / CGI stuff, there are "tags" in html, these are checked in httpd.c, then a user SSI / CGI handler must be implemented.

    I think there is an ST example, incl. a html page with buttons - without OS.