Skip to content

marceloalcocer/picohttps

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pico HTTPS request example

An HTTPS client example for the Raspberry Pi Pico W.

Implemented in C, leveraging the Raspberry Pi Pico C/C++ SDK.

Description

There are many excellent examples of HTTP clients for the Raspberry Pi Pico W platform. The extra complexities (viz. cryptography) introduced by the TLS layer of HTTPS, make corresponding HTTPS examples somewhat less common.

This repository contains a simple yet complete example C application which sends a single request to a web server over HTTPS and reads the resulting response.

Requirements

Building

Configuration

The following minimum build-time configuration is required for correct execution;

More detailed documentation of the above (and additional optional) configuration parameters can be found in the source files.

Sample configurations for the lwIP and Mbed TLS libraries used by the example application are provided in lwipopts.h and mbedtls_config.h respectively. These should work 'out-of-the-box', but can be adjusted if necessary/desired.

Invocation

~/picohttps/$ mkdir build
~/picohttps/$ cd build
~/picohttps/build$ PICOHTTPS_WIFI_PASSWORD=mywirelesspassword cmake -D"PICO_BOARD=pico_w" ..
~/picohttps/build$ make

N.b. Whilst the wireless network password can be set in picohttps.h, it is strongly recommended to set this from the build environment instead (as shown above) to minimise the risk of disclosure (e.g. via source code commits).

Internals

Sources

Overview

The example application performs the following actions in sequence;

  1. Initialise Pico W I/O
  2. Initialise Pico W wireless hardware
  3. Connect to wireless network
  4. Resolve server hostname
  5. Connect to server over TCP + TLS
  6. Send HTTP request over TCP + TLS
  7. Read HTTP response over TCP + TLS

The function calls from picohttps.c:main which perform these actions are not deeply nested, and are declared and documented in picohttps.h.

Libraries

Whilst the Raspberry Pi Pico C/C++ SDK is the only requirement for the example application, this is only because it bundles several libraries which together provide the functionality required for HTTPS;

  • cyw43-driver — Driver for the CYW43 wireless hardware on the Pico W
  • lwIP — Network stack. Provides DHCP, DNS and TCP/IP protocols
  • Mbed TLS — Cryptography suite providing cryptographic primitives and certificate handling required for TLS

Library functionality used by the example application:

  • Pico SDK standard I/O (pico_stdio)
    • I/O over USB
  • Pico SDK wireless architecture (pico_cyw43_arch)
    • Initialization of wireless hardware driver (CYW43) and networking stack (lwIP). Leverages the thread_safe_background abstraction for background maintenance of driver and networking stack.
    • Connection to wireless network
  • lwIP DNS 'raw' API
    • Server hostname resolution
  • lwIP ALTCP 'raw' API
    • Sending/receiving data over TCP. Received data handled asynchronously in interrupt context.
  • lwIP ALTCP TLS 'raw' API
    • Transparent addition of TLS to TCP code. Leverages the ALTCP compatible Mbed TLS port bundled with the lwIP code base.
  • Mbed TLS
    • Authentication and cryptography required for TLS. Used indirectly via ALTCP compatible Mbed TLS port bundled with the lwIP code base.

Notes

  • For simplicity, only most basic of error handling is included;
    • All functions return booleans (true on success) — no error codes
    • Errors printed to stdout
  • Functions used as lwIP callbacks are prefixed with callback_ for clarity. No lock acquisition is required when calling into the lwIP API from these.
  • The single common argument passed to lwIP connection callbacks is of type struct altcp_callback_arg and is used for accessing/modifying application state from callbacks. See struct altcp_callback_arg declaration for further documentation.
  • Dynamically allocated variables;
    • TCP + TLS connection configuration (struct altcp_tls_config config): Allocated by lwIP API call (altcp_tls_create_config_client()), freed by lwIP API call (altcp_close())
    • TCP + TLS connection PCB (struct altcp_pcb pcb): Allocated by lwIP API call (altcp_tls_new()), freed by lwIP API call (altcp_tls_free_config())
    • TCP + TLS connection callback common argument (struct altcp_callback_arg arg): Allocated explicitly (malloc()), freed explicitly (free())
    • lwIP packet buffer chain (struct pbuf buf): Allocated by lwIP, freed by lwIP API call (pbuf_free())
  • Server response printed to stdout on reception in callback_altcp_recv()
  • Currently no clear way to cleanly disconnect from wireless networks
  • Hardcoded five second timeout awaiting a response from the server

References

About

An HTTPS client example for the Raspberry Pi Pico W

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published