Master The Pico WiFi: HTTP Server
Written by Mike James & Harry Fairhead   
Monday, 13 May 2024
Article Index
Master The Pico WiFi: HTTP Server
The Response
Content Length
A Simple Server

The complete C program is:

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/altcp_tcp.h"
#include "hardware/rtc.h"
#include "time.h"
#include "setupWifi.h"
#define BUF_SIZE 2048

void getDateNow(struct tm *t)
{
datetime_t rtc;
rtc_get_datetime(&rtc);
t->tm_sec = rtc.sec;
t->tm_min = rtc.min;
t->tm_hour = rtc.hour;
t->tm_mday = rtc.day;
t->tm_mon = rtc.month - 1;
t->tm_year = rtc.year - 1900;
t->tm_wday = rtc.dotw;
t->tm_yday = 0;
t->tm_isdst = -1;
}
void sendData(struct altcp_pcb *pcb)
{
err_t err;
char html[] = "<html><head><title>Temperature
</title></head>
<body><p>{\"humidity\":81%,\"airtemperature\":23.5C}
</p></body></html>\r\n";
char headers[1024] = {0};
char Status[] = "HTTP/1.1 200 OK\r\n
Content-Type: text/html;charset=UTF-8\r\n
Server:Picow\r\n";
struct tm t;
getDateNow(&t);
char Date[100];
strftime(Date, sizeof(Date),
"Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);
char ContLen[100] = {0};
snprintf(ContLen, sizeof ContLen,
"Content-Length:%d \r\n",
strlen(html));
snprintf(headers, sizeof headers, "%s%s%s\r\n",
Status, Date, ContLen);
char data[2048] = {0};
snprintf(data, sizeof data, "%s%s", headers, html);
err = altcp_write(pcb, data, strlen(data), 0);
err = altcp_output(pcb);
}
err_t recv(void *arg, struct altcp_pcb *pcb,
struct pbuf *p, err_t err)
{
char myBuff[BUF_SIZE];
if (p != NULL)
{
printf("recv total %d this buffer %d next %d err %d\n",
p->tot_len, p->len, p->next, err);
pbuf_copy_partial(p, myBuff, p->tot_len, 0);
myBuff[p->tot_len] = 0;
printf("Buffer= %s\n", myBuff);
altcp_recved(pcb, p->tot_len);
pbuf_free(p);
sendData(pcb);
}
return ERR_OK;
}
static err_t sent(void *arg, struct altcp_pcb *pcb,
u16_t len)
{
altcp_close(pcb);
}
static err_t accept(void *arg, struct altcp_pcb *pcb,
err_t err)
{
altcp_recv(pcb, recv);
altcp_sent(pcb, sent);
printf("connect!\n");
return ERR_OK;
}
void setRTC()
{
datetime_t t = {
.year = 2023,
.month = 02,
.day = 03,
.dotw = 5,
.hour = 11,
.min = 10,
.sec = 00};
rtc_init();
rtc_set_datetime(&t);
}
int main()
{
stdio_init_all();
setRTC();
connect();
struct altcp_pcb *pcb = altcp_new(NULL);
altcp_accept(pcb, accept);
altcp_bind(pcb, IP_ADDR_ANY, 80);
cyw43_arch_lwip_begin();
pcb = altcp_listen_with_backlog(pcb,3);
cyw43_arch_lwip_end();
while (true)
{
sleep_ms(500);
}
}

You also need to change the target_link_libraries in the CmakeLists.txt file to read:

target_link_libraries(main pico_stdlib 
pico_cyw43_arch_lwip_threadsafe_background hardware_rtc)

i.e. add hardware_rtc.

And for the backlog queue to work you need to add:

#define TCP_LISTEN_BACKLOG       1 

in your lwipopts.h.

In chapter but not in this extract:

  • A Polling Server
  • Certificates
  • Adding HTTPS
  • A Practical Web Server
  • A Custom Website
  • Adding HTTPS to the Server App
  • A Dynamic Web Page – Server Side Includes
  • Listing
  • DIY or pico_lwip_http

Summary

  • The only difference between a server and a client is the ability to accept a connection. A client actively seeks a connection with a server, but a server has to just sit waiting patiently for a client to connect.

  • A server has to listen on a specified IP/Port and when a client tries to connect it has to accept the connection. Each client opens a new TCP connection in addition to the one used for listening.

  • HTTP needs the date and time to be set to supply information for the date header.

  • We also need to work out the number of bytes in the response and use this to set the Content-Length header.

  • Polling isn’t an appropriate approach to implementing a server, which is inherently asynchronous. Callbacks need to be kept short as they block the handing of other clients.

  • To extend the HTTP server to HTTPS we need to include a certificate as a string of bytes.

  • In most cases a self-signed certificate can be created using OPENSSL and used for testing.

  • The lwIP library includes a server module which supports a range of more advanced features including SSI, Server Side Includes.

  • To use the server module you have to compile the HTML pages you want to serve into a C program using the htmlgen utility.

  • The server module can also implement HTTPS using altcp.

Master the Raspberry Pi Pico in C:
WiFiwith lwIP & mbedtls

By Harry Fairhead & Mike James

picomaster360

Buy from Amazon.

Contents

       Preface

  1. The Pico WiFi Stack
  2. Introduction To TCP
          Extract:
    Simplest HTTP Client
  3. More Advanced TCP
  4. SSL/TLS and HTTPS
          Extract:
    Simplest HTTPS Client
  5. Details of Cryptography
          Extract:
    Random Numbers
  6. Servers
          Extract: HTTP Server NEW!!
  7. UDP For Speed
          Extract: 
    Basic UDP
  8. SNTP For Time-Keeping
  9. SMTP For Email
  10. MQTT For The IoT

    Appendix 1 Getting Started In C

<ASIN:B0C247QJLK>

 

espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 



Last Updated ( Monday, 13 May 2024 )