Article Index

Program Listings

Master the Raspberry Pi Pico in C:

WiFi with lwIP & mbedtls

picomaster360

 

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans or VS Code project. 

The only downside is that you have to create a project to paste the code into.

To do this follow the instructions in the book.

All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.

Also notice that you will find complete listings of programs that are only slighly modified in the book and therefore not includes as a complete listing.The CMakeLists and other configuration files are also included here for completeness.

If anything you consider important is missing or if you have any requests or comments  contact:

This email address is being protected from spambots. You need JavaScript enabled to view it.


CHAPTER 1

Page 20 WiFi Simple Connect  Main program 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

int setup(uint32_t country, const char *ssid, const char *pass,  uint32_t auth)
{
   if (cyw43_arch_init_with_country(country))
  {
    return 1;
  }
  cyw43_arch_enable_sta_mode();
  if (cyw43_arch_wifi_connect_blocking(ssid, pass, auth))
  {
    return 2;
  }
}

char ssid[] = "myhost";
char pass[] = "mypassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;

int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth);
    while (true)
    {
        sleep_ms(1);
    }
}

Page 21 WiFi Connect  CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()


add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background )
pico_add_extra_outputs(main)

Page 21 WiFi Connect lwiopts.h  - basic configuration file not listed in book

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H 

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#endif /* __LWIPOPTS_H__ */

 

 

Page 25 WiFi Connect setupWifi.h - used in most examples to connect to the AP.

int setup(uint32_t country, const char *ssid, const char *pass,
          uint32_t auth, const char *hostname, ip_addr_t *ip,
          ip_addr_t *mask, ip_addr_t *gw)
{

    if (cyw43_arch_init_with_country(country))
    {
        return 1;
    }

    cyw43_arch_enable_sta_mode();
    if (hostname != NULL)
    {
        netif_set_hostname(netif_default, hostname);
    }
    if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
    {
        return 2;
    }
    int flashrate = 1000;
    int status = CYW43_LINK_UP + 1;
    while (status >= 0 && status != CYW43_LINK_UP)
    {
        int new_status = cyw43_tcpip_link_status(&cyw43_state,
                                                 CYW43_ITF_STA);
        if (new_status != status)
        {
            status = new_status;
            flashrate = flashrate / (status + 1);
            printf("connect status: %d %d\n", status, flashrate);
        }
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(flashrate);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(flashrate);
    }
    if (status < 0)
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
    }
    else
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        if (ip != NULL)
        {
            netif_set_ipaddr(netif_default, ip);
        }
        if (mask != NULL)
        {
            netif_set_netmask(netif_default, mask);
        }
        if (gw != NULL)
        {
            netif_set_gw(netif_default, gw);
        }

        printf("IP: %s\n",
               ip4addr_ntoa(netif_ip_addr4(netif_default)));
        printf("Mask: %s\n",
               ip4addr_ntoa(netif_ip_netmask4(netif_default)));
        printf("Gateway: %s\n",
               ip4addr_ntoa(netif_ip_gw4(netif_default)));
        printf("Host Name: %s\n",
               netif_get_hostname(netif_default));
    }
    return status;
}

int connect()
{
    char ssid[] = "ssid";
    char pass[] = "password";
    uint32_t country = CYW43_COUNTRY_code;
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    return  setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
}

Page 28 Scan main program  

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

static int scan_result(void *env, const cyw43_ev_scan_result_t *result)
{
    if (result)
    {
        printf("ssid: %-32s rssi: %4d chan: %3d mac: %02x:%02x:%02x:%02x:%02x:%02x sec: %u\n",
               result->ssid, result->rssi, result->channel,
               result->bssid[0], result->bssid[1], result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5],
               result->auth_mode);
    }
    return 0;
}

int main()
{
    stdio_init_all();

    if (cyw43_arch_init())
    {
        printf("failed to initialise\n");
        return 1;
    }

    cyw43_arch_enable_sta_mode();
    cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, CYW43_COUNTRY_UK);
    cyw43_wifi_scan_options_t scan_options = {0};
    int err = cyw43_wifi_scan(&cyw43_state, &scan_options, NULL, scan_result);

    while (true)
    {
        if (!cyw43_wifi_scan_active(&cyw43_state))
            break;
        sleep_ms(1000);
        printf("Scan in progress \n");
    }
    printf("Scan Complete\n");
    cyw43_arch_deinit();
    return 0;
}

Page 29 Get RSSI main program

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "setupWifi.h"

int main()
{
    stdio_init_all();
    connect();
    int32_t rssi;
    while (true)
    {
        sleep_ms(1000);
        cyw43_wifi_get_rssi(&cyw43_state, &rssi);
        printf("rssi: %d \n", rssi);
    }
}
 

Chapter 2

Page 38 Python HTTP Server

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):

    def sendResponse(self, cmd):
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        self.send_response(200)
        self.end_headers()
        response = BytesIO()
        response.write(b'This is a '+bytes(cmd, 'utf-8')+
                                               b' request. ')
        response.write(b'Received: ')
        response.write(body)
        self.wfile.write(response.getvalue())

    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'Hello, world!')


    def do_HEAD(self):
        self.send_response(200)
        self.end_headers()

    def do_POST(self):
        self.sendResponse("POST")

    def do_PUT(self):
        self.sendResponse("PUT")

    def do_DELETE(self):
        self.sendResponse("DELETE")

    def do_PATCH(self):
        self.sendResponse("PATCH")


httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 42  Simple HTTP Client using standard  lwipopts.h and cmakelists.txt 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/tcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\nConnection: close\r\n\r\n";

err_t recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
 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);
 tcp_recved(pcb, p->tot_len);
 pbuf_free(p);
 }
 return ERR_OK;
}

static err_t connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
 err = tcp_write(pcb, header, strlen(header), 0);
 err = tcp_output(pcb);
 return ERR_OK;
}

int main()
{

 stdio_init_all();
 connect();

    struct tcp_pcb *pcb = tcp_new();
    tcp_recv(pcb, recv);
    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = tcp_connect(pcb, &ip, 80, connected);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 44 Simple HTTP Client Using ALTCP

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    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);
    }
    return ERR_OK;
}

static err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    err = altcp_write(pcb, header, strlen(header), 0);
    err = altcp_output(pcb);
    return ERR_OK;
}

int main()
{

    stdio_init_all();
    connect();

    struct altcp_pcb *pcb = altcp_new(NULL);
    altcp_recv(pcb, recv);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 80, altcp_client_connected);
    cyw43_arch_lwip_end();

    while (true)
    {
        sleep_ms(500);
    }
}
 

Add to the end of lwipopts.h

#define LWIP_ALTCP 1
 

 

Page 45 Not listed in full in book
Final Practical HTTP Client main.c - standard cmakelists.txt and lwipopts.h with  #define LWIP_ALTCP 1

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
                if ((p->tot_len) > 2)
        {
        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);
    }    else
    {
        printf("Connection Closed");
        altcp_close(pcb);
    }
    return ERR_OK;
}

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    err = altcp_write(pcb, header, strlen(header), 0);
    err = altcp_output(pcb);

    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb){
        printf("Connection Closed");
        altcp_close(pcb);
}


int main()
{

    stdio_init_all();
    connect();

    struct altcp_pcb *pcb = altcp_new(NULL);
    altcp_recv(pcb, recv);
    altcp_sent(pcb, sent);
    altcp_err(pcb, err);
    altcp_poll(pcb, poll,10);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 80, altcp_client_connected);
    cyw43_arch_lwip_end();

    while (true)
    {
        sleep_ms(500);
    }
}

 


 

Chapter 3

Page 54 Not listed in full in book

Simple integer state request

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, myBuff, p->tot_len, 0);
            myBuff[p->tot_len] = 0;
            *(int *)arg = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        printf("Connection Closed \n");
        altcp_close(pcb);
        *(int *)arg = 6;
    }
    return ERR_OK;
}

static err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    *(int *)arg = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    *(int *)arg = 6;
    altcp_close(pcb);
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

int main()
{
    stdio_init_all();
    connect();

    int state = 0;
    struct altcp_pcb *pcb = altcp_new(NULL);

    altcp_recv(pcb, recv);
    altcp_sent(pcb, sent);
    altcp_err(pcb, err);
    altcp_poll(pcb, poll, 10);
    altcp_arg(pcb, &state);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 80, altcp_client_connected);
    cyw43_arch_lwip_end();
    state = 1;

    while (state != 0)
    {
        switch (state)
        {
        case 0:
        case 1:
        case 3:
            break;

        case 2:
            state = 3;
            cyw43_arch_lwip_begin();
            err = altcp_write(pcb, header, strlen(header), 0);
            err = altcp_output(pcb);
            cyw43_arch_lwip_end();
            break;
        case 4:
            state = 5;
            break;
        case 6:
            printf("Buffer= %s\n", myBuff);
            state = 0;
            break;
        default:
            sleep_ms(1000);
            printf("LED Flash\n");
        }
    }
    printf("Data Transfered\n");
}

Page 59 State use a struct

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *myBuff;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->myBuff) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->myBuff[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        printf("Connection Closed\n");
        altcp_close(pcb);
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
    altcp_close(pcb);
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

err_t newConnection(struct connectionState *cs, char *buf)
{
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->myBuff = buf;
    cs->start = 0;
    return ERR_OK;
}

int pollConnection(struct connectionState *cs)
{

    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
    case 6:
        break;
    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, header, strlen(header), 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    }
    return cs->state;
}

int main()
{
    stdio_init_all();
    connect();

    struct connectionState cs;
    newConnection(&cs, myBuff);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs.pcb, &ip, 80, connected);
    cyw43_arch_lwip_end();
    cs.state = 1;
    while (true)
    {
        if (pollConnection(&cs) == 6)
        {
            printf("Buffer= %s\n", cs.myBuff);
            cs.state = 0;
            break;
        }
        sleep_ms(1000);
        printf("LED Flash\n");
    }
    printf("Data Transfered\n");
}

 

Page 65 Non blocking general Request.h

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *sendData;
    char *recvData;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->recvData) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->recvData[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {            
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

struct connectionState *newConnection(char *sendData, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *doRequest(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, char *recvData)
{
    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n%s";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    char *requestData = malloc(len + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    struct connectionState *cs = newConnection(requestData, recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

int pollRequest(struct connectionState **pcs)
{
    if(*pcs==NULL) return 0;
    struct connectionState *cs=*pcs;
    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
        break;

    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, cs->sendData, strlen(cs->sendData), 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    case 6:
        cyw43_arch_lwip_begin();
        altcp_close(cs->pcb);
        cyw43_arch_lwip_end();
        free(cs);
        *pcs = NULL;
        return 0;
    }
    return cs->state;
}
 

Page 27 Non blocking Request main program downloading two requests.

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "lwip/altcp.h"
#include "setupWifi.h"
#include "request.h"
#define BUF_SIZE 2048
char myBuff1[BUF_SIZE];
char myBuff2[BUF_SIZE];

int main()
{
    stdio_init_all();
    connect();

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    struct connectionState *cs1 = doRequest(&ip, "example.com", 80, "GET", "/", NULL, myBuff1);
    IP4_ADDR(&ip, 192, 168, 11, 101);
    struct connectionState *cs2 = doRequest(&ip, "192.168.11.101", 8080, "PUT", "/", "Hello PUT world", myBuff2);

    while (pollRequest(&cs1) + pollRequest(&cs2))
    {
        sleep_ms(100);
    }
    printf("Both complete\n");
    printf("Buffer 1 = \n%s\n\n", myBuff1);
    printf("Buffer 2 = \n%s\n\n", myBuff2);

    printf("Data Transferred\n");
    cyw43_arch_deinit();
    return 0;
}
 
 

Page 70 Temperature PUT client main program

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#include "request.h"

#define BUF_SIZE 4096
char myBuff1[BUF_SIZE];

int readTemp()
{
    return 33;
}

int main()
{
    char ssid[] = "laribina";
    char pass[] = "hawkhawk";
    uint32_t country = CYW43_COUNTRY_UK;
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);

    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);

    while (true)
    {
        int t = readTemp();
        int len = snprintf(NULL, 0, "%d", t);
        char *requestData = malloc(len + 1);
        snprintf(requestData, len + 1, "%d", t);
        printf("%s\n",requestData);
        struct connectionState *cs1 = doRequest(&ip, "192.168.11.101", 8080, "PUT", "/", requestData, myBuff1);
        while (pollRequest(&cs1) )
        {
            sleep_ms(200);
        }
        printf("%s\n",myBuff1);
        sleep_ms(5000);
    }
    return 0;
}
 
 
 

Page 71 Custom Sever For the PUT Temperature Client

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def log_message(self,*args, **kwargs):
        pass

    def do_PUT(self):
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        bodyString= body.decode(encoding="utf-8")
        temp=float(bodyString)
        print(temp,"C")
        self.send_response(200)
        self.end_headers()

httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 72 full listing not in book

Binary request version of request.h

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *sendData;
    int bytes;
    char *recvData;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->recvData) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->recvData[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

struct connectionState *newConnection(char *sendData, int bytes, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->bytes=bytes;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *doRequest(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, char *recvData)
{
    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n%s";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    char *requestData = malloc(len + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    struct connectionState *cs = newConnection(requestData, strlen(requestData),recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

struct connectionState *doRequestBinary(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, int bytes, char *recvData)
{

    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, bytes);
    char *requestData = malloc(len + bytes + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, bytes);
    memcpy(requestData + len, sendData, bytes);
    struct connectionState *cs = newConnection(requestData, len + bytes, recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

int pollRequest(struct connectionState **pcs)
{
    if (*pcs == NULL)
        return 0;
    struct connectionState *cs = *pcs;
    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
        break;

    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, cs->sendData, cs->bytes, 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    case 6:
        cyw43_arch_lwip_begin();
        altcp_close(cs->pcb);
        cyw43_arch_lwip_end();
        free(cs);
        *pcs = NULL;
        return 0;
    }
    return cs->state;
}

Page 74 Binary request main program

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#include "request.h"

#define BUF_SIZE 4096
char myBuff1[BUF_SIZE];

int main()
{
    char ssid[] = "laribina";
    char pass[] = "hawkhawk";
    uint32_t country = CYW43_COUNTRY_UK;
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);

    char randdata[500];
    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);
    for (int p = 0; p < 500; p++)
    {
        randdata[p] = (uint8_t)rand();
    }
    struct connectionState *cs1 = doRequestBinary(&ip, "192.168.11.101", 8080, "PUT", "/", randdata, 500, myBuff1);
    while (pollRequest(&cs1))
    {
        sleep_ms(200);
    }
    printf("%s\n", myBuff1);

    return 0;
}

Page 75 Python Custom server for Binary request

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def log_message(self,*args, **kwargs):
        pass

    def do_PUT(self):  
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        print(content_length)      
        with open("data.bin",mode="wb") as f:
            f.write(body)  
        self.send_response(200)
        self.end_headers()
        response = BytesIO()
        response.write(b'Received:' )      
        self.wfile.write(response.getvalue())

httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 77 full listing not in book

DNS Main Program needs requests.h 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "lwip/altcp.h"
#include "lwip/dns.h"
#include "setupWifi.h"
#include "request.h"
#define BUF_SIZE 2048
char myBuff1[BUF_SIZE];

void dns_found(const char *name, const ip_addr_t *ip, void *arg)
{
    ip_addr_t *ipResult = (ip_addr_t *)arg;
    if (ip)
    {
        ip4_addr_copy(*ipResult, *ip);
    }
    else
    {
        ip4_addr_set_loopback(ipResult);
    }
    return;
}

err_t getIP(char *URL, ip_addr_t *ipResult)
{
    cyw43_arch_lwip_begin();
    err_t err = dns_gethostbyname(URL, ipResult, dns_found, ipResult);
    cyw43_arch_lwip_end();
    return err;
}

int main()
{
    stdio_init_all();
    connect();

    ip_addr_t ip;
    ip4_addr_set_zero(&ip);
    getIP("example.com", &ip);
    while (!ip_addr_get_ip4_u32(&ip))
    {
        sleep_ms(100);
    };
    if (ip4_addr_isloopback(&ip))
    {
        printf("address not found");
    }
    struct connectionState *cs1 = doRequest(&ip, "example.com", 80, "GET", "/", NULL, myBuff1);

    while (pollRequest(&cs1))
    {
        sleep_ms(100);
    }
    printf("Buffer 1 = \n%s\n\n", myBuff1);

    printf("Data Transferred\n");
    cyw43_arch_deinit();
    return 0;
}


Chapter 4

Page 90  Simple TLS Client  main.c

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"

#include "setupWifi.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    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);
    }
    return ERR_OK;
}

static err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    err = altcp_write(pcb, header, strlen(header), 0);
    err = altcp_output(pcb);

    return ERR_OK;
}

int main()
{

    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    struct altcp_pcb *pcb = altcp_tls_new(tls_config, IPADDR_TYPE_ANY);
    mbedtls_ssl_set_hostname(altcp_tls_context(pcb), "example.com");
    altcp_recv(pcb, recv);



    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 443, altcp_client_connected);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 90 Simple TLS Client cmakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()


add_executable(main
 main.c
)


target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mbedtls
pico_mbedtls)
pico_add_extra_outputs(main)

Page 88 Simple TLS Client mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
 #define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C
//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 90 full listing not in book

Simple TLS Client lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1
#define LWIP_ALTCP_TLS           1
#define LWIP_ALTCP_TLS_MBEDTLS   1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG  LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */

Page 92 Full listing not in book

TLS Request.h

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *sendData;
    int bytes;
    char *recvData;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->recvData) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->recvData[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

struct connectionState *newConnection(char *sendData, int bytes, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->bytes=bytes;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *newTLSConnection(char* host, char *sendData, int bytes, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    cs->pcb = altcp_tls_new(tls_config, IPADDR_TYPE_ANY);    
    mbedtls_ssl_set_hostname(altcp_tls_context(cs->pcb), host);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->bytes=bytes;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *doRequest(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, char *recvData)
{
    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n%s";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    char *requestData = malloc(len + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    struct connectionState *cs = newConnection(requestData, strlen(requestData),recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

struct connectionState *doRequestBinary(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, int bytes, char *recvData)
{

    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, bytes);
    char *requestData = malloc(len + bytes + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, bytes);
    memcpy(requestData + len, sendData, bytes);
    struct connectionState *cs = newConnection(requestData, len + bytes, recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}


struct connectionState *doTLSRequestBinary(ip_addr_t *ip, char *host, u16_t port, char *request, char *file,  char *sendData,int bytes, char *recvData)
{

    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, bytes);
    char *requestData = malloc(len + bytes+1);
    snprintf(requestData, len+1, headerTemplate, request, file, host, port, bytes);
    memcpy(requestData+len,sendData,bytes);  
    struct connectionState *cs = newTLSConnection(host,requestData,len+bytes ,recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}


int pollRequest(struct connectionState **pcs)
{
    if (*pcs == NULL)
        return 0;
    struct connectionState *cs = *pcs;
    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
        break;

    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, cs->sendData, cs->bytes, 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    case 6:
        cyw43_arch_lwip_begin();
        altcp_close(cs->pcb);
        cyw43_arch_lwip_end();
        free(cs);
        *pcs = NULL;
        return 0;
    }
    return cs->state;
}

Page 94 RequestTLS Client Main.c

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/altcp_tcp.h"
#include "lwip/altcp_tls.h"
#include "setupWifi.h"

#include "request.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];

int main()
{

    stdio_init_all();
    connect();

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);

    struct connectionState *cs1 = doTLSRequestBinary(&ip, "example.com", 443, "GET", "/", NULL, 0, myBuff);
    while (pollRequest(&cs1))
    {
        sleep_ms(200);
    }
    printf("%s\n", myBuff);

    return 0;
}

Chapter 5

Page 105 RandomByte function

uint8_t randomByte()
{
    uint32_t random = 0;
    uint32_t bit = 0;
    for (int k = 0; k < 8; k++)
    {
        while (true)
        {
            bit = rosc_hw->randombit;
            sleep_us(10);
            if (bit != rosc_hw->randombit)
                break;
        }

        random = (random << 1) | bit;
    }

    return (uint8_t)random;
}

Page 111 Full listing not in book

Adding EC and GCM to mbedtls_config.h in Client and server mode

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C



//EC KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C

/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

#define MBEDTLS_SSL_SRV_C

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 115 AES ECB Mode Main Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "mbedtls/cipher.h"

#include "pico/rand.h"

int main()
{
    stdio_init_all();
    int ret;


    mbedtls_cipher_context_t cipher_ctx;
    mbedtls_cipher_init(&cipher_ctx);

    const mbedtls_cipher_info_t *cipher_info;
    cipher_info = mbedtls_cipher_info_from_string("AES-128-ECB");
    ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info);

    unsigned char key[16];
    get_rand_128((rng_128_t*)key );


    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_ENCRYPT);
    ret = mbedtls_cipher_reset(&cipher_ctx);

    char buffer[16] = "Hello World";
    char output[16];
    int olen;
    ret = mbedtls_cipher_update(&cipher_ctx, buffer, 16, output, &olen);
    printf("cipher text ");
    for (int i = 0; i < olen; i++)
    {
        printf("%02X", output[i]);
    }
    printf("\n");

    char plaintext[16];  
    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_DECRYPT);
    ret = mbedtls_cipher_reset(&cipher_ctx);
    mbedtls_cipher_update(&cipher_ctx, output, 16, plaintext, &olen);
    printf("plain text %.16s\n", plaintext);
    return 0;
}

Page 116 AES ECB mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES

#define MBEDTLS_CIPHER_C

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 116 AES ECB Mode CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

 add_executable(main

   main.c
)
target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_mbedtls)
pico_add_extra_outputs(main)

Page 118 Full listing not in book

AES CBC Mode Main Program including list of available encryptions.

#include <stdio.h>
#include "pico/stdlib.h"
#include "mbedtls/cipher.h"

#include "pico/rand.h"

int main()
{
    stdio_init_all();
    int ret;

    const mbedtls_cipher_info_t *cipher_info1;
    const int *list;
    printf("Available ciphers:\n");
    list = mbedtls_cipher_list();
    while (*list)
    {
        cipher_info1 = mbedtls_cipher_info_from_type(*list);
        printf("  %s\n", cipher_info1->name);
        list++;
    }

    mbedtls_cipher_context_t cipher_ctx;
    mbedtls_cipher_init(&cipher_ctx);

    const mbedtls_cipher_info_t *cipher_info;
    cipher_info = mbedtls_cipher_info_from_string("AES-128-CBC");
    ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info);

    unsigned char key[16];
    get_rand_128((rng_128_t *)key);
    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_ENCRYPT);

    unsigned char IV[16];
    get_rand_128((rng_128_t *)IV);
    ret = mbedtls_cipher_set_iv(&cipher_ctx, IV, 16);

    ret = mbedtls_cipher_reset(&cipher_ctx);

    char buffer[16] = "Hello World";
    char output[16];
    int olen;
    ret = mbedtls_cipher_update(&cipher_ctx, buffer, 16, output, &olen);

    printf("cipher text ");
    for (int i = 0; i < olen; i++)
    {
        printf("%02X", output[i]);
    }
    printf("\n");

    char plaintext[16];
    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_DECRYPT);   
    ret = mbedtls_cipher_set_iv(&cipher_ctx, IV, 16);
    ret = mbedtls_cipher_reset(&cipher_ctx);
    ret = mbedtls_cipher_update(&cipher_ctx, output, 16, plaintext, &olen);
    printf("plain text %.16s\n", plaintext);
    return 0;
}

Chapter 6

Page 130 Simple HTTP Server Main Program 

#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\nContent-Type: text/html;charset=UTF-8\r\nServer: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);
    }
}

Page 133 Full listing not in book

Simple HTTP Server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1

#define LWIP_DEBUG 1
#define TCP_LISTEN_BACKLOG       1
#endif /* __LWIPOPTS_H__ */

Page 113 Full listing not in book

Simple HTTP Server CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background hardware_rtc)
pico_add_extra_outputs(main)

Page 136 Python program to convert certificate to C code

import binascii

with open("iopress.key", 'rb') as f:
    lines = f.readlines()
lines = b"".join(lines[1:-1])
key = binascii.a2b_base64(lines)

res = ""

for b in key:
    res += "0x%02x," % b

res="u8_t key[]={"+res[:-1]+"};"
print(res)

with open("iopress.crt", 'rb') as f:
    lines = f.readlines()
lines = b"".join(lines[1:-1])
cert = binascii.a2b_base64(lines)
res = ""
for b in cert:
    res += "0x%02x," % b

res="u8_t cert[]={"+res[:-1]+"};"
print()
print(res)

Page 137 Full listing not in book

Simple HTTPS Server Main Program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/altcp_tcp.h"

#include "lwip/altcp_tls.h"
#include "hardware/structs/rosc.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\nContent-Type: text/html;charset=UTF-8\r\nServer: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();

    u8_t key[] = {0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x1e, 0x04, 0x4b, 0xc5, 0xa4, 0xa0, 0x8b, 0x1a, 0xfd, 0x3d, 0xbb, 0xce, 0x74, 0x6d, 0xdc, 0x8a, 0xc4, 0x8a, 0x7b, 0x49, 0xae, 0x98, 0xc8, 0xf2, 0xbc, 0xae, 0xd4, 0xd8, 0xa4, 0x61, 0x14, 0x03, 0x2c, 0xd9, 0xea, 0xb6, 0xae, 0xe5, 0xbc, 0xc8, 0x35, 0x11, 0x04, 0x9c, 0x41, 0xc2, 0x47, 0xd4, 0x2c, 0x9c, 0x0c, 0xdc, 0x1f, 0x8f, 0xc5, 0xa9, 0xd7, 0xb8, 0xd1, 0xb4, 0x12, 0xf2, 0x44, 0x71, 0x22, 0x69, 0x83, 0x47, 0x84, 0x04, 0x8c, 0x23, 0x37, 0x98, 0xf0, 0xbe, 0x7a, 0x67, 0x48, 0xd7, 0x32, 0xd2, 0xf5, 0x8d, 0xf1, 0xf1, 0x6e, 0xf4, 0x4b, 0xa5, 0x48, 0x1c, 0xcc, 0x7d, 0xe0, 0xa9, 0xee, 0x9d, 0xf3, 0x39, 0x77, 0x64, 0x91, 0x07, 0x70, 0x27, 0xf0, 0x34, 0xa2, 0x21, 0xd8, 0xec, 0xd0, 0xe7, 0xeb, 0x43, 0xc3, 0x6a, 0x20, 0x23, 0x10, 0xfe, 0x42, 0x02, 0x6b, 0xda, 0x89, 0xf4, 0x41, 0x96, 0x64, 0x32, 0x52, 0x20, 0x05, 0x0d, 0x5b, 0xf3, 0x67, 0x51, 0xb7, 0x7d, 0xd1, 0x24, 0x0b, 0x2c, 0x33, 0x84, 0x5b, 0xf9, 0xed, 0x66, 0xe6, 0x3c, 0x4d, 0xdf, 0x09, 0x3e, 0xd5, 0xe5, 0x1c, 0x27, 0x2c, 0x81, 0xee, 0x03, 0x91, 0x8d, 0xc0, 0x2b, 0x3e, 0xd9, 0x37, 0x8e, 0x3d, 0xd1, 0x30, 0xd6, 0x97, 0x7b, 0x98, 0xfb, 0x80, 0x13, 0x5a, 0x84, 0x08, 0x90, 0x0d, 0x5c, 0x99, 0x51, 0x4f, 0x8f, 0xab, 0x0c, 0x39, 0x69, 0x76, 0xf8, 0xf4, 0xfd, 0xa7, 0x04, 0x8d, 0x72, 0x27, 0xa6, 0x1e, 0xbd, 0xff, 0x10, 0x43, 0xe8, 0x53, 0xe7, 0x08, 0xb8, 0xbd, 0x55, 0xb4, 0x7a, 0xa2, 0x44, 0xe9, 0xe7, 0x78, 0xf7, 0x11, 0x49, 0x01, 0x70, 0x60, 0xdf, 0xe8, 0xd1, 0xb0, 0x8c, 0xa2, 0x3d, 0x98, 0x07, 0x9b, 0x66, 0xff, 0xe8, 0x68, 0x33, 0x82, 0xe3, 0x75, 0x3d, 0x37, 0x8d, 0xf2, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe8, 0xc0, 0x12, 0x7f, 0x02, 0x98, 0x75, 0x23, 0xa6, 0x32, 0x92, 0x4e, 0x11, 0x27, 0xad, 0xda, 0x5b, 0x9e, 0xec, 0x9c, 0xa4, 0xb4, 0x26, 0x2b, 0x2b, 0xd4, 0xdb, 0x1a, 0x9e, 0xd5, 0xd3, 0xa8, 0xb4, 0x29, 0x58, 0x79, 0x96, 0x9f, 0x1a, 0xff, 0xdc, 0xef, 0x4c, 0xb3, 0x1b, 0x79, 0x36, 0xd3, 0x03, 0x4d, 0x08, 0x15, 0x54, 0xa7, 0x84, 0x2d, 0xc3, 0xb2, 0x44, 0x75, 0x15, 0x9f, 0x57, 0xae, 0x25, 0x64, 0xcc, 0x5f, 0xdf, 0x7d, 0xd3, 0xe9, 0xb7, 0xbc, 0xeb, 0x01, 0x92, 0xda, 0x9f, 0x7e, 0xc3, 0xc6, 0xce, 0xd9, 0xc2, 0x16, 0x5a, 0x52, 0x0c, 0x1e, 0xe2, 0x92, 0x4a, 0xf2, 0x33, 0x13, 0x78, 0x5f, 0xa3, 0xa8, 0x0d, 0x99, 0x75, 0x8d, 0x33, 0xd5, 0x71, 0xc6, 0x3c, 0x86, 0xf9, 0x36, 0xbf, 0x86, 0x2e, 0xc3, 0xfe, 0x63, 0x7d, 0x50, 0x94, 0xb6, 0x71, 0x7f, 0x9f, 0xb6, 0x55, 0xa5, 0x02, 0x81, 0x81, 0x00, 0xd0, 0xa6, 0xcd, 0xaf, 0x92, 0x3b, 0x7a, 0x2f, 0x17, 0xfd, 0xd1, 0x05, 0x6b, 0x9c, 0x95, 0xb7, 0x7b, 0x39, 0x0c, 0xa5, 0xde, 0xb1, 0xa4, 0x86, 0x87, 0x39, 0x73, 0xb0, 0x22, 0xb3, 0x7c, 0x6a, 0x14, 0xdc, 0x19, 0x98, 0xa7, 0xe7, 0x02, 0xdb, 0x54, 0xa0, 0xc3, 0xbc, 0x80, 0x54, 0x60, 0xb6, 0xa6, 0xf4, 0xc5, 0x01, 0xe1, 0xc3, 0xf7, 0xc3, 0xd2, 0xdb, 0xe7, 0x1f, 0xc9, 0xcc, 0x51, 0x66, 0x66, 0xd0, 0xce, 0x31, 0x5a, 0x31, 0x76, 0xb7, 0x98, 0x52, 0xda, 0x82, 0xe8, 0x33, 0xc8, 0xf0, 0x1a, 0x8f, 0x95, 0x46, 0x7f, 0x48, 0x72, 0x47, 0x1e, 0x33, 0x3c, 0x0f, 0xd7, 0x55, 0x21, 0xc3, 0xea, 0x10, 0x8e, 0xae, 0xbc, 0x18, 0xa5, 0xcc, 0x85, 0xf1, 0x09, 0x3d, 0x15, 0x82, 0xa0, 0x49, 0x55, 0xd6, 0x7f, 0x64, 0xe0, 0xb0, 0xf0, 0x17, 0x75, 0xbd, 0x92, 0xc7, 0x83, 0xe3, 0x59, 0x09, 0x02, 0x81, 0x81, 0x00, 0x88, 0x6b, 0xd4, 0x2b, 0x87, 0xcc, 0xee, 0x93, 0xe7, 0x9d, 0x2a, 0xae, 0x01, 0x56, 0x1d, 0x8b, 0xa8, 0x3a, 0x1d, 0x7b, 0xae, 0xfa, 0x3c, 0x88, 0xff, 0x56, 0xf2, 0xd9, 0xc6, 0x91, 0x94, 0x4f, 0x04, 0xd2, 0x5b, 0x1e, 0x61, 0x4f, 0x7e, 0x96, 0xcb, 0xdb, 0xa3, 0x3c, 0x33, 0xf5, 0x37, 0x52, 0x35, 0x54, 0x18, 0x51, 0xd0, 0x5d, 0xa3, 0x96, 0xe3, 0x66, 0x80, 0xc3, 0x93, 0xd9, 0xe2, 0x9d, 0x9b, 0x23, 0x5a, 0xbb, 0x33, 0x16, 0xe0, 0x77, 0xd4, 0x0f, 0x32, 0x3b, 0xa8, 0xe4, 0xe5, 0xa9, 0x7a, 0x7c, 0xf3, 0xcf, 0x24, 0xf8, 0xcf, 0x15, 0xda, 0x2e, 0xdc, 0x24, 0x5d, 0x33, 0x5b, 0x06, 0xa5, 0x7e, 0x81, 0x41, 0x46, 0x3f, 0x55, 0x6c, 0x5f, 0x1e, 0x53, 0x62, 0x9b, 0x25, 0x8d, 0xbb, 0x2e, 0x45, 0x2a, 0xf2, 0x0c, 0x10, 0x2a, 0x6a, 0x69, 0xd0, 0x09, 0xf4, 0x81, 0x1b, 0x71, 0x55, 0x02, 0x81, 0x80, 0x66, 0x63, 0x74, 0x4b, 0xd3, 0xd6, 0x9b, 0xfe, 0xc0, 0x27, 0x2d, 0x8b, 0x1b, 0x63, 0x9b, 0x94, 0x8e, 0x43, 0x50, 0x91, 0x94, 0xd6, 0x57, 0x86, 0x2c, 0x95, 0x64, 0xcf, 0xea, 0x37, 0x69, 0xb6, 0x24, 0xc6, 0x5d, 0x49, 0x2c, 0x1b, 0x90, 0xab, 0x50, 0xbc, 0x13, 0x51, 0x4d, 0x28, 0x1a, 0xcd, 0x86, 0xe0, 0x56, 0x4c, 0xb6, 0x1d, 0x14, 0x58, 0x64, 0x00, 0xc5, 0x4a, 0x34, 0x1c, 0xaf, 0x55, 0x30, 0xdf, 0x06, 0x4f, 0xf1, 0x92, 0x94, 0x4f, 0x43, 0xd0, 0x64, 0xaa, 0x18, 0x88, 0x50, 0xf2, 0x82, 0x16, 0x33, 0x8a, 0x84, 0xab, 0x68, 0x68, 0xbd, 0xc9, 0x26, 0x90, 0x1f, 0x7b, 0x07, 0x36, 0xbc, 0x85, 0xa3, 0x7e, 0xdb, 0x8e, 0xbc, 0xcd, 0xc0, 0x6c, 0xa7, 0xbb, 0xf1, 0xf2, 0x47, 0xf5, 0xb4, 0xc9, 0xad, 0x7a, 0x33, 0x48, 0xa0, 0x88, 0xe2, 0x9e, 0x44, 0x88, 0xe3, 0x8f, 0x8d, 0x01, 0x02, 0x81, 0x80, 0x04, 0xa3, 0xe0, 0xb3, 0x7e, 0xdd, 0x12, 0x94, 0x27, 0xb0, 0xac, 0x4b, 0x26, 0xfd, 0xb2, 0x5f, 0x2b, 0x91, 0x29, 0x5a, 0x0b, 0x2b, 0x9a, 0xeb, 0x08, 0x21, 0xde, 0x15, 0x79, 0x8a, 0x55, 0x0c, 0xec, 0xac, 0x85, 0x72, 0x11, 0xb6, 0x1d, 0x51, 0xf1, 0xa6, 0x28, 0xa0, 0x86, 0xae, 0x23, 0x7c, 0x4c, 0x2c, 0xfe, 0xce, 0xd4, 0xd3, 0xf2, 0x67, 0x47, 0x6c, 0xa7, 0xfd, 0xe6, 0x80, 0x4f, 0x8d, 0x54, 0xa9, 0x8a, 0xb8, 0x80, 0xc5, 0xbc, 0x6b, 0x7e, 0xe1, 0xc2, 0xa1, 0x24, 0xcf, 0x2d, 0xe1, 0x0c, 0x9f, 0x7b, 0x71, 0xcf, 0x75, 0xb2, 0x04, 0xf8, 0x51, 0xac, 0x07, 0x10, 0x56, 0x93, 0x46, 0x92, 0xdd, 0x1d, 0x5b, 0x1f, 0x94, 0x87, 0xcf, 0xe2, 0x99, 0x36, 0x89, 0xe7, 0xc2, 0x8a, 0x0a, 0x9e, 0x0d, 0x30, 0x17, 0xd5, 0x6d, 0xde, 0x10, 0x94, 0x47, 0x35, 0x89, 0x10, 0xe6, 0x8c, 0x0e};

    u8_t cert[] = {0x30, 0x82, 0x03, 0x6b, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x72, 0x8e, 0xfd, 0x0e, 0x52, 0x0a, 0x87, 0xdd, 0x55, 0x25, 0xee, 0x05, 0x11, 0x1d, 0x0d, 0xf7, 0xc8, 0x64, 0x5b, 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5b, 0x91, 0x51, 0xe1, 0x89, 0x20, 0xf5, 0xdf, 0x02, 0x94, 0x59, 0x76, 0x9e, 0xdc, 0x53, 0xf3, 0x17, 0x8f, 0x96, 0x17, 0xd1, 0x2f, 0x65, 0x36, 0xd4, 0x56, 0x7e, 0xd8, 0x0d, 0x7e, 0x59, 0x79, 0xab, 0x47, 0x67, 0x01, 0xb6, 0x9e, 0xf6, 0x7a, 0x0d, 0x20, 0xd2, 0xb2, 0x2d, 0x87, 0x84, 0x07, 0x40, 0x2d, 0x83, 0x1e, 0x16, 0x4f, 0x2d, 0x20, 0xaf, 0xf2, 0xca, 0xde, 0x10, 0x73, 0x41, 0xb9, 0x48, 0x3c, 0x4f, 0x9d, 0x55, 0xbc, 0xee, 0x68, 0xae, 0x66, 0x4d, 0x5d, 0x41, 0xa9, 0xbc, 0x51, 0x6d, 0xe2, 0x37, 0x0c, 0x0f, 0xf4, 0x43, 0xa0, 0x84, 0xf9, 0x40, 0xbc, 0x89, 0xaa, 0xcd, 0x14, 0xb4, 0xd5, 0xda, 0xd1, 0xb3, 0x2c, 0x4a, 0x56, 0x7e, 0x86, 0x2c, 0x71, 0xaa, 0x75, 0x86, 0x48, 0x14, 0x2a, 0xbc, 0x05, 0xab, 0x14, 0x72, 0x72, 0x01, 0xc8, 0xff, 0x02, 0x3d, 0x2e, 0xe9, 0xef, 0x21, 0x4d, 0x71, 0xf3, 0x0c, 0xba, 0x40, 0xfd, 0x9f, 0xb1, 0x40, 0xea, 0x47, 0x65, 0x3d, 0xb7, 0x52, 0xd8, 0xbb, 0x13, 0x30, 0x38, 0xb4, 0x3c, 0xbf, 0x76, 0x06, 0xe2, 0xb3, 0x3f, 0xf7, 0x7b, 0xdd, 0xdf, 0x54, 0x7b, 0x8d, 0x0c, 0x4d, 0x4a, 0x96, 0xcd, 0x14, 0x5c, 0x7d, 0xed, 0xb3, 0x2f, 0xbd, 0x27, 0xc8, 0x52, 0x6e, 0x58, 0x8e, 0x9c, 0x07, 0xa1, 0x52, 0xe2, 0x49, 0x8c, 0x04, 0x3f, 0x84, 0x32, 0x7b, 0xff, 0x5f, 0xf4, 0xf2, 0xdf, 0x3c, 0x73, 0xff, 0x9f, 0x63, 0x0e, 0xe5, 0x7f, 0xdf, 0xa8, 0x7e, 0x4d, 0xf3, 0x29, 0xd8, 0x2b, 0x41, 0x25, 0xbc, 0x73, 0x41, 0x3b, 0x1f, 0x39, 0x64, 0x48, 0x85, 0xe5, 0x66, 0x90, 0x8c, 0xd3, 0x8a, 0xce, 0xdc, 0xb5, 0x0d, 0x93, 0xb0, 0xd0, 0x8a, 0xef, 0x74, 0x8f, 0x28, 0x2f, 0x2c, 0x96, 0x4a, 0x4f, 0xc3, 0xf1, 0xde, 0x25, 0xff, 0xd4};
    struct altcp_tls_config *tls_config = altcp_tls_create_config_server_privkey_cert(key, sizeof(key), NULL, 0, cert, sizeof(cert));
    struct altcp_pcb *pcb = altcp_tls_new(tls_config, IPADDR_TYPE_ANY);

    altcp_accept(pcb, accept);

    altcp_bind(pcb, IP_ADDR_ANY, 443);
    cyw43_arch_lwip_begin();
    pcb = altcp_listen_with_backlog(pcb, 3);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 137 Full listing not in book

Simple HTTPS Server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1
#define LWIP_ALTCP_TLS           1
#define LWIP_ALTCP_TLS_MBEDTLS   1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG  LWIP_DBG_ON
#define TCP_LISTEN_BACKLOG       1
#endif /* __LWIPOPTS_H__ */

Page 137 Full listing not in book

Simple HTTPS Server mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

#define MBEDTLS_SSL_SRV_C

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 137 Full listing not in book

Simple HTTPS Server CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background hardware_rtc pico_lwip_mbedtls pico_mbedtls)
pico_add_extra_outputs(main)

Page 140 Simple HTTP Bultin Server Main Program  

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/apps/httpd.h"
#include "setupWifi.h"

int main()
{
    stdio_init_all();
    connect();

    httpd_init();

    while (true)
    {
        sleep_ms(500);
    }
}

Page 140 Full listing not in book

Simple HTTP Bultin Server Cmakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_http)
pico_add_extra_outputs(main)

Page 140 Full listing not in book

Simple HTTP Bultin Server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384

#define LWIP_ALTCP 1

#define LWIP_DEBUG 1
#define TCP_LISTEN_BACKLOG 1

#endif /* __LWIPOPTS_H__ */

Page 141 Linux Cmakelists.txt for htmlgen

cmake_minimum_required(VERSION 3.13)
project(makefsdata C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

add_executable(htmlgen
 makefsdata.c
)

target_include_directories(htmlgen
         PRIVATE ../../../../src/include/
         PRIVATE ../../../../contrib/ports/unix/port/include/
         PRIVATE ${CMAKE_CURRENT_LIST_DIR})

Page 141 Windows Cmakelists.txt for htmlgen

cmake_minimum_required(VERSION 3.13)

project(makefsdata C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

add_executable(htmlgen
 makefsdata.c
)

target_include_directories(htmlgen
         PRIVATE ../../../../src/include/

         PRIVATE ../../../../contrib/ports/win32/include/

         PRIVATE ${CMAKE_CURRENT_LIST_DIR})

Page 151

Simple HTTPS Bultin Server Main Program TLS and SSI

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/altcp_tls.h"

#include "lwip/apps/httpd.h"
#include "hardware/structs/rosc.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 setRTC()
{
    datetime_t t = {
        .year = 2023,
        .month = 02,
        .day = 05,
        .dotw = 0,
        .hour = 6,
        .min = 14,
        .sec = 00};
    rtc_init();
    rtc_set_datetime(&t);
}

const char *ssitags[] = {"temp", "hum"};

u16_t mySSIHandler(int iIndex, char *pcInsert, int iInsertLen)
{
    switch(iIndex){
        case 0:
            snprintf(pcInsert, iInsertLen, "42 C");
            break;
        case 1:
            snprintf(pcInsert, iInsertLen, "80%%");
            break;
    }
}

int main()
{
    stdio_init_all();
    setRTC();
    connect();


    u8_t key[] = {0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x1e, 0x04, 0x4b, 0xc5, 0xa4, 0xa0, 0x8b, 0x1a, 0xfd, 0x3d, 0xbb, 0xce, 0x74, 0x6d, 0xdc, 0x8a, 0xc4, 0x8a, 0x7b, 0x49, 0xae, 0x98, 0xc8, 0xf2, 0xbc, 0xae, 0xd4, 0xd8, 0xa4, 0x61, 0x14, 0x03, 0x2c, 0xd9, 0xea, 0xb6, 0xae, 0xe5, 0xbc, 0xc8, 0x35, 0x11, 0x04, 0x9c, 0x41, 0xc2, 0x47, 0xd4, 0x2c, 0x9c, 0x0c, 0xdc, 0x1f, 0x8f, 0xc5, 0xa9, 0xd7, 0xb8, 0xd1, 0xb4, 0x12, 0xf2, 0x44, 0x71, 0x22, 0x69, 0x83, 0x47, 0x84, 0x04, 0x8c, 0x23, 0x37, 0x98, 0xf0, 0xbe, 0x7a, 0x67, 0x48, 0xd7, 0x32, 0xd2, 0xf5, 0x8d, 0xf1, 0xf1, 0x6e, 0xf4, 0x4b, 0xa5, 0x48, 0x1c, 0xcc, 0x7d, 0xe0, 0xa9, 0xee, 0x9d, 0xf3, 0x39, 0x77, 0x64, 0x91, 0x07, 0x70, 0x27, 0xf0, 0x34, 0xa2, 0x21, 0xd8, 0xec, 0xd0, 0xe7, 0xeb, 0x43, 0xc3, 0x6a, 0x20, 0x23, 0x10, 0xfe, 0x42, 0x02, 0x6b, 0xda, 0x89, 0xf4, 0x41, 0x96, 0x64, 0x32, 0x52, 0x20, 0x05, 0x0d, 0x5b, 0xf3, 0x67, 0x51, 0xb7, 0x7d, 0xd1, 0x24, 0x0b, 0x2c, 0x33, 0x84, 0x5b, 0xf9, 0xed, 0x66, 0xe6, 0x3c, 0x4d, 0xdf, 0x09, 0x3e, 0xd5, 0xe5, 0x1c, 0x27, 0x2c, 0x81, 0xee, 0x03, 0x91, 0x8d, 0xc0, 0x2b, 0x3e, 0xd9, 0x37, 0x8e, 0x3d, 0xd1, 0x30, 0xd6, 0x97, 0x7b, 0x98, 0xfb, 0x80, 0x13, 0x5a, 0x84, 0x08, 0x90, 0x0d, 0x5c, 0x99, 0x51, 0x4f, 0x8f, 0xab, 0x0c, 0x39, 0x69, 0x76, 0xf8, 0xf4, 0xfd, 0xa7, 0x04, 0x8d, 0x72, 0x27, 0xa6, 0x1e, 0xbd, 0xff, 0x10, 0x43, 0xe8, 0x53, 0xe7, 0x08, 0xb8, 0xbd, 0x55, 0xb4, 0x7a, 0xa2, 0x44, 0xe9, 0xe7, 0x78, 0xf7, 0x11, 0x49, 0x01, 0x70, 0x60, 0xdf, 0xe8, 0xd1, 0xb0, 0x8c, 0xa2, 0x3d, 0x98, 0x07, 0x9b, 0x66, 0xff, 0xe8, 0x68, 0x33, 0x82, 0xe3, 0x75, 0x3d, 0x37, 0x8d, 0xf2, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe8, 0xc0, 0x12, 0x7f, 0x02, 0x98, 0x75, 0x23, 0xa6, 0x32, 0x92, 0x4e, 0x11, 0x27, 0xad, 0xda, 0x5b, 0x9e, 0xec, 0x9c, 0xa4, 0xb4, 0x26, 0x2b, 0x2b, 0xd4, 0xdb, 0x1a, 0x9e, 0xd5, 0xd3, 0xa8, 0xb4, 0x29, 0x58, 0x79, 0x96, 0x9f, 0x1a, 0xff, 0xdc, 0xef, 0x4c, 0xb3, 0x1b, 0x79, 0x36, 0xd3, 0x03, 0x4d, 0x08, 0x15, 0x54, 0xa7, 0x84, 0x2d, 0xc3, 0xb2, 0x44, 0x75, 0x15, 0x9f, 0x57, 0xae, 0x25, 0x64, 0xcc, 0x5f, 0xdf, 0x7d, 0xd3, 0xe9, 0xb7, 0xbc, 0xeb, 0x01, 0x92, 0xda, 0x9f, 0x7e, 0xc3, 0xc6, 0xce, 0xd9, 0xc2, 0x16, 0x5a, 0x52, 0x0c, 0x1e, 0xe2, 0x92, 0x4a, 0xf2, 0x33, 0x13, 0x78, 0x5f, 0xa3, 0xa8, 0x0d, 0x99, 0x75, 0x8d, 0x33, 0xd5, 0x71, 0xc6, 0x3c, 0x86, 0xf9, 0x36, 0xbf, 0x86, 0x2e, 0xc3, 0xfe, 0x63, 0x7d, 0x50, 0x94, 0xb6, 0x71, 0x7f, 0x9f, 0xb6, 0x55, 0xa5, 0x02, 0x81, 0x81, 0x00, 0xd0, 0xa6, 0xcd, 0xaf, 0x92, 0x3b, 0x7a, 0x2f, 0x17, 0xfd, 0xd1, 0x05, 0x6b, 0x9c, 0x95, 0xb7, 0x7b, 0x39, 0x0c, 0xa5, 0xde, 0xb1, 0xa4, 0x86, 0x87, 0x39, 0x73, 0xb0, 0x22, 0xb3, 0x7c, 0x6a, 0x14, 0xdc, 0x19, 0x98, 0xa7, 0xe7, 0x02, 0xdb, 0x54, 0xa0, 0xc3, 0xbc, 0x80, 0x54, 0x60, 0xb6, 0xa6, 0xf4, 0xc5, 0x01, 0xe1, 0xc3, 0xf7, 0xc3, 0xd2, 0xdb, 0xe7, 0x1f, 0xc9, 0xcc, 0x51, 0x66, 0x66, 0xd0, 0xce, 0x31, 0x5a, 0x31, 0x76, 0xb7, 0x98, 0x52, 0xda, 0x82, 0xe8, 0x33, 0xc8, 0xf0, 0x1a, 0x8f, 0x95, 0x46, 0x7f, 0x48, 0x72, 0x47, 0x1e, 0x33, 0x3c, 0x0f, 0xd7, 0x55, 0x21, 0xc3, 0xea, 0x10, 0x8e, 0xae, 0xbc, 0x18, 0xa5, 0xcc, 0x85, 0xf1, 0x09, 0x3d, 0x15, 0x82, 0xa0, 0x49, 0x55, 0xd6, 0x7f, 0x64, 0xe0, 0xb0, 0xf0, 0x17, 0x75, 0xbd, 0x92, 0xc7, 0x83, 0xe3, 0x59, 0x09, 0x02, 0x81, 0x81, 0x00, 0x88, 0x6b, 0xd4, 0x2b, 0x87, 0xcc, 0xee, 0x93, 0xe7, 0x9d, 0x2a, 0xae, 0x01, 0x56, 0x1d, 0x8b, 0xa8, 0x3a, 0x1d, 0x7b, 0xae, 0xfa, 0x3c, 0x88, 0xff, 0x56, 0xf2, 0xd9, 0xc6, 0x91, 0x94, 0x4f, 0x04, 0xd2, 0x5b, 0x1e, 0x61, 0x4f, 0x7e, 0x96, 0xcb, 0xdb, 0xa3, 0x3c, 0x33, 0xf5, 0x37, 0x52, 0x35, 0x54, 0x18, 0x51, 0xd0, 0x5d, 0xa3, 0x96, 0xe3, 0x66, 0x80, 0xc3, 0x93, 0xd9, 0xe2, 0x9d, 0x9b, 0x23, 0x5a, 0xbb, 0x33, 0x16, 0xe0, 0x77, 0xd4, 0x0f, 0x32, 0x3b, 0xa8, 0xe4, 0xe5, 0xa9, 0x7a, 0x7c, 0xf3, 0xcf, 0x24, 0xf8, 0xcf, 0x15, 0xda, 0x2e, 0xdc, 0x24, 0x5d, 0x33, 0x5b, 0x06, 0xa5, 0x7e, 0x81, 0x41, 0x46, 0x3f, 0x55, 0x6c, 0x5f, 0x1e, 0x53, 0x62, 0x9b, 0x25, 0x8d, 0xbb, 0x2e, 0x45, 0x2a, 0xf2, 0x0c, 0x10, 0x2a, 0x6a, 0x69, 0xd0, 0x09, 0xf4, 0x81, 0x1b, 0x71, 0x55, 0x02, 0x81, 0x80, 0x66, 0x63, 0x74, 0x4b, 0xd3, 0xd6, 0x9b, 0xfe, 0xc0, 0x27, 0x2d, 0x8b, 0x1b, 0x63, 0x9b, 0x94, 0x8e, 0x43, 0x50, 0x91, 0x94, 0xd6, 0x57, 0x86, 0x2c, 0x95, 0x64, 0xcf, 0xea, 0x37, 0x69, 0xb6, 0x24, 0xc6, 0x5d, 0x49, 0x2c, 0x1b, 0x90, 0xab, 0x50, 0xbc, 0x13, 0x51, 0x4d, 0x28, 0x1a, 0xcd, 0x86, 0xe0, 0x56, 0x4c, 0xb6, 0x1d, 0x14, 0x58, 0x64, 0x00, 0xc5, 0x4a, 0x34, 0x1c, 0xaf, 0x55, 0x30, 0xdf, 0x06, 0x4f, 0xf1, 0x92, 0x94, 0x4f, 0x43, 0xd0, 0x64, 0xaa, 0x18, 0x88, 0x50, 0xf2, 0x82, 0x16, 0x33, 0x8a, 0x84, 0xab, 0x68, 0x68, 0xbd, 0xc9, 0x26, 0x90, 0x1f, 0x7b, 0x07, 0x36, 0xbc, 0x85, 0xa3, 0x7e, 0xdb, 0x8e, 0xbc, 0xcd, 0xc0, 0x6c, 0xa7, 0xbb, 0xf1, 0xf2, 0x47, 0xf5, 0xb4, 0xc9, 0xad, 0x7a, 0x33, 0x48, 0xa0, 0x88, 0xe2, 0x9e, 0x44, 0x88, 0xe3, 0x8f, 0x8d, 0x01, 0x02, 0x81, 0x80, 0x04, 0xa3, 0xe0, 0xb3, 0x7e, 0xdd, 0x12, 0x94, 0x27, 0xb0, 0xac, 0x4b, 0x26, 0xfd, 0xb2, 0x5f, 0x2b, 0x91, 0x29, 0x5a, 0x0b, 0x2b, 0x9a, 0xeb, 0x08, 0x21, 0xde, 0x15, 0x79, 0x8a, 0x55, 0x0c, 0xec, 0xac, 0x85, 0x72, 0x11, 0xb6, 0x1d, 0x51, 0xf1, 0xa6, 0x28, 0xa0, 0x86, 0xae, 0x23, 0x7c, 0x4c, 0x2c, 0xfe, 0xce, 0xd4, 0xd3, 0xf2, 0x67, 0x47, 0x6c, 0xa7, 0xfd, 0xe6, 0x80, 0x4f, 0x8d, 0x54, 0xa9, 0x8a, 0xb8, 0x80, 0xc5, 0xbc, 0x6b, 0x7e, 0xe1, 0xc2, 0xa1, 0x24, 0xcf, 0x2d, 0xe1, 0x0c, 0x9f, 0x7b, 0x71, 0xcf, 0x75, 0xb2, 0x04, 0xf8, 0x51, 0xac, 0x07, 0x10, 0x56, 0x93, 0x46, 0x92, 0xdd, 0x1d, 0x5b, 0x1f, 0x94, 0x87, 0xcf, 0xe2, 0x99, 0x36, 0x89, 0xe7, 0xc2, 0x8a, 0x0a, 0x9e, 0x0d, 0x30, 0x17, 0xd5, 0x6d, 0xde, 0x10, 0x94, 0x47, 0x35, 0x89, 0x10, 0xe6, 0x8c, 0x0e};
    u8_t cert[] = {0x30, 0x82, 0x03, 0x6b, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x72, 0x8e, 0xfd, 0x0e, 0x52, 0x0a, 0x87, 0xdd, 0x55, 0x25, 0xee, 0x05, 0x11, 0x1d, 0x0d, 0xf7, 0xc8, 0x64, 0x5b, 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5b, 0x91, 0x51, 0xe1, 0x89, 0x20, 0xf5, 0xdf, 0x02, 0x94, 0x59, 0x76, 0x9e, 0xdc, 0x53, 0xf3, 0x17, 0x8f, 0x96, 0x17, 0xd1, 0x2f, 0x65, 0x36, 0xd4, 0x56, 0x7e, 0xd8, 0x0d, 0x7e, 0x59, 0x79, 0xab, 0x47, 0x67, 0x01, 0xb6, 0x9e, 0xf6, 0x7a, 0x0d, 0x20, 0xd2, 0xb2, 0x2d, 0x87, 0x84, 0x07, 0x40, 0x2d, 0x83, 0x1e, 0x16, 0x4f, 0x2d, 0x20, 0xaf, 0xf2, 0xca, 0xde, 0x10, 0x73, 0x41, 0xb9, 0x48, 0x3c, 0x4f, 0x9d, 0x55, 0xbc, 0xee, 0x68, 0xae, 0x66, 0x4d, 0x5d, 0x41, 0xa9, 0xbc, 0x51, 0x6d, 0xe2, 0x37, 0x0c, 0x0f, 0xf4, 0x43, 0xa0, 0x84, 0xf9, 0x40, 0xbc, 0x89, 0xaa, 0xcd, 0x14, 0xb4, 0xd5, 0xda, 0xd1, 0xb3, 0x2c, 0x4a, 0x56, 0x7e, 0x86, 0x2c, 0x71, 0xaa, 0x75, 0x86, 0x48, 0x14, 0x2a, 0xbc, 0x05, 0xab, 0x14, 0x72, 0x72, 0x01, 0xc8, 0xff, 0x02, 0x3d, 0x2e, 0xe9, 0xef, 0x21, 0x4d, 0x71, 0xf3, 0x0c, 0xba, 0x40, 0xfd, 0x9f, 0xb1, 0x40, 0xea, 0x47, 0x65, 0x3d, 0xb7, 0x52, 0xd8, 0xbb, 0x13, 0x30, 0x38, 0xb4, 0x3c, 0xbf, 0x76, 0x06, 0xe2, 0xb3, 0x3f, 0xf7, 0x7b, 0xdd, 0xdf, 0x54, 0x7b, 0x8d, 0x0c, 0x4d, 0x4a, 0x96, 0xcd, 0x14, 0x5c, 0x7d, 0xed, 0xb3, 0x2f, 0xbd, 0x27, 0xc8, 0x52, 0x6e, 0x58, 0x8e, 0x9c, 0x07, 0xa1, 0x52, 0xe2, 0x49, 0x8c, 0x04, 0x3f, 0x84, 0x32, 0x7b, 0xff, 0x5f, 0xf4, 0xf2, 0xdf, 0x3c, 0x73, 0xff, 0x9f, 0x63, 0x0e, 0xe5, 0x7f, 0xdf, 0xa8, 0x7e, 0x4d, 0xf3, 0x29, 0xd8, 0x2b, 0x41, 0x25, 0xbc, 0x73, 0x41, 0x3b, 0x1f, 0x39, 0x64, 0x48, 0x85, 0xe5, 0x66, 0x90, 0x8c, 0xd3, 0x8a, 0xce, 0xdc, 0xb5, 0x0d, 0x93, 0xb0, 0xd0, 0x8a, 0xef, 0x74, 0x8f, 0x28, 0x2f, 0x2c, 0x96, 0x4a, 0x4f, 0xc3, 0xf1, 0xde, 0x25, 0xff, 0xd4};
    struct altcp_tls_config *tls_config = altcp_tls_create_config_server_privkey_cert(key, sizeof(key), NULL, 0, cert, sizeof(cert));
    http_set_ssi_handler(mySSIHandler, ssitags, 2);
    httpd_inits(tls_config);
    while (true)
    {
        sleep_ms(500);
    }
}

Page 151 Simple HTTPS Bultin Server TLS and SSI CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background hardware_rtc pico_lwip_mbedtls pico_mbedtls pico_lwip_http)
pico_add_extra_outputs(main)

Page 151 Full listing not in book

Simple HTTPS Bultin Server LWIPOPTS.H TLS and SSI

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1
#define LWIP_ALTCP_TLS           1
#define LWIP_ALTCP_TLS_MBEDTLS   1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG  LWIP_DBG_ON
#define TCP_LISTEN_BACKLOG       1



#define HTTPD_ENABLE_HTTPS   1
#undef MEM_SIZE
#define MEM_SIZE                    8000
#define LWIP_HTTPD_SSI   1

#endif /* __LWIPOPTS_H__ */

Page 144 Full listing not in book

Simple HTTPS Bultin Server mbedtls_config.h TLS and SSI

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION
#define MBEDTLS_SSL_SRV_C

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"



Chapter 7

Page 157 Simple UDP server

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"

int main()
{
    stdio_init_all();
    connect();

    struct udp_pcb *pcb = udp_new();
    udp_bind(pcb, IP_ADDR_ANY, 8080);

    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);

    udp_connect(pcb, &ip, 8080);

    char message[] = "Hello UDP World";
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, strlen(message) + 1, PBUF_RAM);

    snprintf(p->payload, strlen(message) + 1, "%s", message);

    err_t er = udp_send(pcb, p);
    pbuf_free(p);
    while (true)
    {
        sleep_ms(500);
    }
}

Page 157 Full listing not in book

Simple UDP server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_DEBUG 1
#endif /* __LWIPOPTS_H__ */

Page 158 Full listing not in book

Simple UDP server Cmakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background)
pico_add_extra_outputs(main)

Page 158 Python UDP Client

import asyncio
class ClientDatagramProtocol(asyncio.DatagramProtocol):
    def datagram_received(self, data, addr):
        message = data.decode("utf8")
        print("Received",message,"from", addr)

async def main():
    loop = asyncio.get_running_loop()
    transport, protocol = await loop.create_datagram_endpoint(
          lambda: ClientDatagramProtocol(),
                    local_addr=('0.0.0.0', 8080))
    await asyncio.sleep(100000)
    transport.close()

asyncio.run(main())

Page 161 Full listing not in book

Simple UDP client

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"

#define BUF_SIZE 1024

void recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    char myBuff[BUF_SIZE];
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d \n", p->tot_len, p->len, p->next);
        printf("From %s:%d\n", ipaddr_ntoa(addr), port);
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;
        printf("Buffer= %s\n", myBuff);
        pbuf_free(p);
    }
}

int main()
{
    stdio_init_all();
    connect();

    struct udp_pcb *pcb = udp_new();
    udp_recv(pcb, recv, NULL);

    udp_bind(pcb, IP_ADDR_ANY, 8080);

    //   ip_addr_t ip;
    //  IP4_ADDR(&ip, 192, 168, 11, 101);
    // IP4_ADDR(&ip, 192, 168, 11, 255);
    // udp_connect(pcb, &ip, 8080);

    while (true)
    {
        sleep_ms(500);
    }
}

Page 162 Python UDP Server

import asyncio

async def main():  
    loop = asyncio.get_running_loop()
    transport, protocol = await loop.create_datagram_endpoint(
                             lambda: asyncio.DatagramProtocol(),
                             local_addr=('0.0.0.0',8080))
    data=b"Hello UDP World"
    for i in range(20):
        transport.sendto(data,addr=("192.168.11.255",8080))
        await asyncio.sleep(1)
    transport.close()  
asyncio.run(main())

Chapter 8

Page 176 SNTP RTC main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"
#include "hardware/rtc.h"
#include "time.h"
#include "lwip/dns.h"

bool getDateNow(struct tm *t)
{
    datetime_t rtc;
    bool state = rtc_get_datetime(&rtc);
    if (state)
    {

        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;
    }
    return state;
}

void setRTC(struct tm *datetime)
{
    datetime_t t;
    t.year = datetime->tm_year + 1900;
    t.month = datetime->tm_mon + 1;
    t.day = datetime->tm_mday;
    t.dotw = datetime->tm_wday;
    t.hour = datetime->tm_hour;
    t.min = datetime->tm_min;
    t.sec = datetime->tm_sec;
    rtc_init();
    rtc_set_datetime(&t);
}
struct timeStatus
{
    bool ready;
    struct udp_pcb *pcb;
};

void recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    struct timeStatus *tstatus = (struct timeStatus *)arg;
    printf("SNTP responded\n");
    if (p != NULL)
    {
        uint8_t seconds_buf[4];
        pbuf_copy_partial(p, seconds_buf, sizeof(seconds_buf), 40);
        uint32_t seconds_since_1900 = seconds_buf[0] << 24 | seconds_buf[1] << 16 | seconds_buf[2] << 8 | seconds_buf[3];
        time_t seconds_since_1970 = seconds_since_1900 - 2208988800;
        struct tm *datetime = gmtime(&seconds_since_1970);
        setRTC(datetime);
        pbuf_free(p);
        udp_remove(pcb);
        tstatus->pcb=NULL;
        tstatus->ready = true;
    }
}

bool pollSNTP(struct timeStatus *tstatus)
{
    if (tstatus == NULL)
        return true;
    if (tstatus->ready)
    {
        free(tstatus);
        tstatus = NULL;
        return true;
    }
    return false;
}

void dns_found(const char *name, const ip_addr_t *ip, void *arg)
{
    struct timeStatus *tstatus = (struct timeStatus *)arg;
    printf("DNS %s\n", ipaddr_ntoa(ip));
    struct udp_pcb *pcb = udp_new();
    tstatus->pcb = pcb;
    udp_recv(pcb, recv, arg);
    udp_bind(pcb, IP_ADDR_ANY, 123);
    udp_connect(pcb, ip, 123);
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 48, PBUF_RAM);
    uint8_t *payload = (uint8_t *)p->payload;
    memset(payload, 0, 48);
    *payload = 0x1b;
    err_t er = udp_send(pcb, p);
    pbuf_free(p);
}

struct timeStatus *getSNTP()
{
    struct timeStatus *tstatus = malloc(sizeof(struct timeStatus));
    tstatus->ready = false;
    tstatus->pcb=NULL;
    ip_addr_t ip;
    cyw43_arch_lwip_begin();
    err_t err = dns_gethostbyname("time.nist.gov", &ip, dns_found, tstatus);
    cyw43_arch_lwip_end();
    if (err == ERR_OK)
    {
        printf("DNS cache %s\n", ipaddr_ntoa(&ip));
        dns_found("", &ip, tstatus);
    }
    return tstatus;
}

void cancelSNTP(struct timeStatus *tstatus)
{
    if (tstatus != NULL)
    {
        udp_remove(tstatus->pcb);
        free(tstatus);
        tstatus = NULL;
        printf("canceled\n");
    }
}

int main()
{
    stdio_init_all();
    connect();

    while (true)
    {
        struct timeStatus *tstatus = getSNTP();
        sleep_ms(500);
        if (pollSNTP(tstatus))
            break;
        cancelSNTP(tstatus);
    }

    while (true)
    {
        struct tm t;
        getDateNow(&t);
        char Date[100];
        strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);
        printf("%s\n", Date);
        sleep_ms(5000);
    }
}

Page 182 SNTP RTC App main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "hardware/rtc.h"
#include <time.h>
#include "lwip/apps/sntp.h"

void SNTPSetRTC(u32_t t, u32_t us)
{
    printf("updating RTC\n");
    time_t seconds_since_1970 = t - 2208988800;
    struct tm *datetime = gmtime(&seconds_since_1970);
    datetime_t dt;
    dt.year = datetime->tm_year + 1900;
    dt.month = datetime->tm_mon + 1;
    dt.day = datetime->tm_mday;
    dt.dotw = datetime->tm_wday;
    dt.hour = datetime->tm_hour;
    dt.min = datetime->tm_min;
    dt.sec = datetime->tm_sec;
    rtc_init();
    rtc_set_datetime(&dt);
}

bool getDateNow(struct tm *t)
{
    datetime_t rtc;
    bool state = rtc_get_datetime(&rtc);
    if (state)
    {
        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;
    }
    return state;
}

int main()
{
    stdio_init_all();
    connect();

    sntp_setoperatingmode(SNTP_OPMODE_POLL);
    sntp_setservername(0, "pool.ntp.org");
    sntp_init();

    while (true)
    {
        struct tm t;
        if (getDateNow(&t))        {
            char Date[100];
            strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);
            printf("%s\n", Date);
        }
        sleep_ms(5000);
    }
}

Page 183 Full listing not in book

SNTP RTC app lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define SNTP_SERVER_DNS              1
#define SNTP_SUPPORT                 1
#define SNTP_UPDATE_DELAY       60*1000

#define SNTP_SET_SYSTEM_TIME_NTP(sec, us) \
 void SNTPSetRTC(u32_t, u32_t); \
  SNTPSetRTC(sec, us)

#define LWIP_DEBUG 1
#endif /* __LWIPOPTS_H__ */

Page 184 Full listing not in book

SNTP RTC app CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_sntp hardware_rtc)
pico_add_extra_outputs(main)

Chapter 9

Page 190 SMTP  main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "setupWifi.h"

#include "lwip/apps/smtp.h"

void mailsent(void *arg, u8_t smtp_result, u16_t srv_err, err_t err)
{
    printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg,
           smtp_result, srv_err, err);
}

int main()
{
    stdio_init_all();
    connect();

    smtp_set_server_addr("iopress.info");
    smtp_set_server_port(25);  
    smtp_set_auth(NULL, NULL);
  smtp_send_mail("This email address is being protected from spambots. You need JavaScript enabled to view it.", "This email address is being protected from spambots. You need JavaScript enabled to view it.", "subject", "body", mailsent, NULL);
    while (true)
    {
        sleep_ms(10);
    }
}

Page 191 Full listing not in book

SMTP  CMakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_smtp)  
pico_add_extra_outputs(main)

Page 192 Full listing not in book

SMTP lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#define LWIP_DEBUG 1
#define SMTP_DEBUG LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */

Page 193 SMTPS main

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "setupWifi.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/smtp.h"

void mailsent(void *arg, u8_t smtp_result, u16_t srv_err, err_t err)
{
    printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg,
           smtp_result, srv_err, err);
}

int main()
{
    stdio_init_all();
    connect();
    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    smtp_set_tls_config(tls_config);

    smtp_set_server_addr("smtp.gmail.com");
    smtp_set_server_port(465);
    smtp_set_auth("gmailUSER", "App Password");

    smtp_send_mail("gmailUSER", "email address", "subject", "body", mailsent, NULL);
    while (true)
    {
        sleep_ms(10);
    }
}

Page 194 Full listing not in book

SMTPS mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//EC KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C

/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//ECDHE-RSA-AES256-GCM-SHA384
//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 194 Full listing not in book

SMTPS lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384
#undef MEM_SIZE
#define MEM_SIZE 8000

#define LWIP_ALTCP 1
#define LWIP_ALTCP_TLS 1
#define LWIP_ALTCP_TLS_MBEDTLS 1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON
#define SMTP_DEBUG LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */

Page 194 Full listing not in book

SMTPS CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mbedtls
pico_mbedtls pico_lwip_smtp)
pico_add_extra_outputs(main)



Chapter 10

Page 203 MQTT main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/ip_addr.h"
#include "setupWifi.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/mqtt.h"

int mqttStatus = 0;

void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    if (status == MQTT_CONNECT_ACCEPTED)
    {
        mqttStatus = 1;
    }
}

static void pub_request_cb(void *arg, err_t result)
{
    printf("Publish result: %d\n", result);
    mqtt_client_t *client = (mqtt_client_t *)arg;
}

void sub_request_cb(void *arg, err_t result)
{
    printf("Subscribe result: %d\n", result);
    mqttStatus = 2;
}

static void incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Topic %s. %d\n", topic, tot_len);
}

static void incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
    char *payload = (char *)data;
    printf("payload\n%.*s\n", len, payload);
}

int main()
{
    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);

    mqtt_client_t *client = mqtt_client_new();

    struct mqtt_connect_client_info_t ci;
    memset(&ci, 0, sizeof(ci));
    ci.client_id = "MyPicoW";
    ci.keep_alive = 10;

    ci.tls_config = tls_config;

    ip_addr_t ip;
    IP4_ADDR(&ip, 137, 135, 83, 217);
    // IP4_ADDR(&ip, 20, 79, 70, 109);

    err_t err = mqtt_client_connect(client, &ip, 8883, mqtt_connection_cb, 0, &ci);

    char payload[] = "Hello MQTT World";
    u8_t qos = 2;
    u8_t retain = 0;
    while (true)
    {
        switch (mqttStatus)
        {
        case 0:
            break;
        case 1:
            mqtt_set_inpub_callback(client, incoming_publish_cb, incoming_data_cb, NULL);
            err = mqtt_subscribe(client, "MyTopic", 1, sub_request_cb, NULL);
            break;

        case 2:
            err = mqtt_publish(client, "MyTopic", payload, strlen(payload), qos, retain, pub_request_cb, client);
            break;
        }
        sleep_ms(2000);
    }
}

Page 205 Full listing not in book

MQTT lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384
#undef MEM_SIZE
#define MEM_SIZE 8000

#define LWIP_ALTCP 1
//#define LWIP_ALTCP_TLS 1
//#define LWIP_ALTCP_TLS_MBEDTLS 1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON
#define MQTT_DEBUG LWIP_DBG_ON
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 1)
#define MQTT_REQ_MAX_IN_FLIGHT (5)

#endif /* __LWIPOPTS_H__ */

Page 205 Full listing not in book

MQTT Cmakelist.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mqtt)
pico_add_extra_outputs(main)

Page 205 Full listing not in book

MQTT TLS  main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/ip_addr.h"
#include "setupWifi.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/mqtt.h"

int mqttStatus = 0;

void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    if (status == MQTT_CONNECT_ACCEPTED)
    {
        mqttStatus = 1;
    }
}

static void pub_request_cb(void *arg, err_t result)
{
    printf("Publish result: %d\n", result);
    mqtt_client_t *client = (mqtt_client_t *)arg;
}

void sub_request_cb(void *arg, err_t result)
{
    printf("Subscribe result: %d\n", result);
    mqttStatus = 2;
}

static void incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Topic %s. %d\n", topic, tot_len);
}

static void incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
    char *payload = (char *)data;
    printf("payload\n%.*s\n", len, payload);
}

int main()
{
    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);

    mqtt_client_t *client = mqtt_client_new();

    struct mqtt_connect_client_info_t ci;
    memset(&ci, 0, sizeof(ci));
    ci.client_id = "MyPicoW";
    ci.keep_alive = 10;

    ci.tls_config = tls_config;

    ip_addr_t ip;
    IP4_ADDR(&ip, 137, 135, 83, 217);
    // IP4_ADDR(&ip, 20, 79, 70, 109);

    err_t err = mqtt_client_connect(client, &ip, 8883, mqtt_connection_cb, 0, &ci);

    char payload[] = "Hello MQTT World";
    u8_t qos = 2;
    u8_t retain = 0;
    while (true)
    {
        switch (mqttStatus)
        {
        case 0:
            break;
        case 1:
            mqtt_set_inpub_callback(client, incoming_publish_cb, incoming_data_cb, NULL);
            err = mqtt_subscribe(client, "MyTopic", 1, sub_request_cb, NULL);
            break;

        case 2:
            err = mqtt_publish(client, "MyTopic", payload, strlen(payload), qos, retain, pub_request_cb, client);
            break;
        }
        sleep_ms(2000);
    }
}

Page 205 Full listing not in book

MQTT TLS lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384
#undef MEM_SIZE
#define MEM_SIZE 8000

#define LWIP_ALTCP 1
#define LWIP_ALTCP_TLS 1
#define LWIP_ALTCP_TLS_MBEDTLS 1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON
#define MQTT_DEBUG LWIP_DBG_ON
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 1)
#define MQTT_REQ_MAX_IN_FLIGHT (5)

#endif /* __LWIPOPTS_H__ */

Page 205 Full listing not in book

MQTT TLS mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//EC KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C

/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//ECDHE-RSA-AES256-GCM-SHA384
//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 205 Full listing not in book

MQTT TLS CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mqtt pico_lwip_mbedtls
pico_mbedtls)
pico_add_extra_outputs(main)

Page 207  MQTT HiveMQ main program Note works with modified mqtt.h and mqtt.c

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/ip_addr.h"
#include "setupWifi.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/mqtt.h"

int mqttStatus = 0;

void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    if (status == MQTT_CONNECT_ACCEPTED)
    {
        mqttStatus = 1;
    }
}

static void pub_request_cb(void *arg, err_t result)
{
    printf("Publish result: %d\n", result);
    mqtt_client_t *client = (mqtt_client_t *)arg;
}

void sub_request_cb(void *arg, err_t result)
{
    printf("Subscribe result: %d\n", result);
    mqttStatus = 2;
}

static void incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Topic %s. %d\n", topic, tot_len);
}

static void incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
    char *payload = (char *)data;
    printf("payload\n%.*s\n", len, payload);
}

int main()
{
    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    mqtt_client_t *client = mqtt_client_new();

    struct mqtt_connect_client_info_t ci;
    memset(&ci, 0, sizeof(ci));
    ci.client_id = "MyPicoW";
    ci.client_user = "username";
    ci.client_pass = "password";
    ci.keep_alive = 10;
    ci.tls_config = tls_config;
    strncpy(ci.domName, "1a6d2dccd35744888e4b7c6f8e65f613.s2.eu.hivemq.cloud", 100);
    ip_addr_t ip;
    // IP4_ADDR(&ip, 137, 135, 83, 217);
    IP4_ADDR(&ip, 20, 79, 70, 109);

    err_t err = mqtt_client_connect(client, &ip, 8883, mqtt_connection_cb, 0, &ci);

    char payload[] = "Hello MQTT World";
    u8_t qos = 2;
    u8_t retain = 0;
    while (true)
    {
        switch (mqttStatus)
        {
        case 0:
            break;
        case 1:
            mqtt_set_inpub_callback(client, incoming_publish_cb, incoming_data_cb, NULL);
            err = mqtt_subscribe(client, "MyTopic", 1, sub_request_cb, NULL);
            break;

        case 2:
            err = mqtt_publish(client, "MyTopic", payload, strlen(payload), qos, retain, pub_request_cb, client);
            break;
        }
        sleep_ms(2000);
    }
}