Page 4 of 4
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
Buy from Amazon.
Contents
Preface
- The Pico WiFi Stack
- Introduction To TCP
Extract: Simplest HTTP Client
- More Advanced TCP
- SSL/TLS and HTTPS
Extract: Simplest HTTPS Client
- Details of Cryptography
Extract: Random Numbers
- Servers
Extract: HTTP Server NEW!!
- UDP For Speed
Extract: Basic UDP
- SNTP For Time-Keeping
- SMTP For Email
- MQTT For The IoT
Appendix 1 Getting Started In C
<ASIN:B0C247QJLK>
|