rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
fw_release.h File Reference

What GitHub says about the panel's releases, read strictly. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "fw_image.h"

Go to the source code of this file.

Data Structures

struct  fw_rel_scan_t
 The scan of the API's answer for the highest release. More...

Macros

#define FW_REL_REPO   "subtilitas/rcbench"
#define FW_REL_LATEST_URL   "https://github.com/" FW_REL_REPO "/releases/latest"
#define FW_REL_TAG_PREFIX   "https://github.com/" FW_REL_REPO "/releases/tag/"
#define FW_REL_DL_PREFIX   "https://github.com/" FW_REL_REPO "/releases/download/"
#define FW_REL_SUMS_NAME   "SHA256SUMS"
#define FW_REL_API_URL
#define FW_REL_API_ACCEPT   "application/vnd.github+json"
#define FW_REL_API_VERSION   "2022-11-28"
#define FW_REL_LINE_CAPPED   0
 Whether a check is held to FW_REL_LINE_MAJOR.FW_REL_LINE_MINOR at start: 0 for the ESP32-P4 panel, which is offered every release newer than its build; 1 for the ESP32-S3 panel's 0.22 line.
#define FW_REL_TAG_MAX   18u
 The longest tag, "v65535.65535.65535", in bytes.
#define FW_REL_VER_TEXT   18u
 The longest version text, "65535.65535.65535", with its terminator.
#define FW_REL_NAME_MAX   40u
 The longest asset name, "rcbench-panel-p4-v65535.65535.65535.bin", with its terminator.
#define FW_REL_URL_MAX   2048u
 A redirect's Location, in bytes; a longer one is refused.
#define FW_REL_HOPS_MAX   3u
#define FW_REL_SUMS_MAX   4096u
#define FW_REL_API_RELEASES   10u
#define FW_REL_API_MAX   262144u
#define FW_REL_SCAN_MAX   FW_REL_API_MAX
#define FW_REL_SCAN_DEPTH   32u
The panel's release line

MAJOR and MINOR of the releases a check held to the line offers: 0.22, the last release line for the ESP32-S3 panel.

#define FW_REL_LINE_MAJOR   0u
#define FW_REL_LINE_MINOR   22u

Enumerations

enum  fw_rel_err_t {
  FW_REL_OK = 0 , FW_REL_MISSING , FW_REL_LONG , FW_REL_CHAR ,
  FW_REL_PLACE , FW_REL_VERSION , FW_REL_STATUS , FW_REL_HOPS ,
  FW_REL_HOST , FW_REL_NO_LENGTH , FW_REL_EMPTY , FW_REL_TOO_BIG ,
  FW_REL_SHORT , FW_REL_OVERRUN , FW_REL_SUMS_BAD , FW_REL_SUMS_NONE ,
  FW_REL_SUMS_TWICE , FW_REL_TAG_NONE , FW_REL_TAG_LONG , FW_REL_TAG_FORM ,
  FW_REL_SCAN_LONG , FW_REL_COUNT
}
enum  fw_rel_status_t { FW_REL_BODY = 0 , FW_REL_REDIRECT , FW_REL_REFUSED }

Functions

const char * fw_rel_err_str (fw_rel_err_t e)
bool fw_release_parse_version (const char *s, size_t n, fw_version_t *out)
fw_rel_err_t fw_release_parse_tag (const char *loc, size_t n, bool cut, fw_version_t *out)
fw_rel_status_t fw_release_status (int status)
fw_rel_err_t fw_release_redirect (const char *loc, size_t n, bool cut, unsigned hops)
fw_rel_err_t fw_release_length (int64_t length, bool chunked, uint32_t cap)
fw_rel_err_t fw_release_parse_sums (const char *text, size_t n, const char *name, uint8_t out[FW_SHA256_BYTES])
void fw_release_scan_init (fw_rel_scan_t *s)
bool fw_release_scan_feed (fw_rel_scan_t *s, const uint8_t *d, size_t n)
fw_rel_err_t fw_release_scan_end (const fw_rel_scan_t *s, fw_version_t *out)
bool fw_release_scan_line (const fw_rel_scan_t *s, fw_version_t *out)
 The highest no-draft release of the panel's release line among those the scan read.
bool fw_release_in_line (fw_version_t v)
 Whether a version is of the panel's release line.
bool fw_release_line_capped (void)
 Whether the panel's release line is capped at FW_REL_LINE_MAJOR.FW_REL_LINE_MINOR.
void fw_release_set_line_capped (bool capped)
 Caps the panel's release line at FW_REL_LINE_MAJOR.FW_REL_LINE_MINOR, or lifts the cap. The panel keeps FW_REL_LINE_CAPPED; the host suite holds both lines.
bool fw_release_offered (fw_version_t found, fw_version_t running, bool running_ok)
 Whether a release is offered to the panel.
void fw_release_version_text (fw_version_t v, char out[FW_REL_VER_TEXT])
void fw_release_image_name (fw_version_t v, char out[FW_REL_NAME_MAX])
 The file name of a release's panel image.
bool fw_release_url (fw_version_t v, const char *file, char *out, size_t cap)

Variables

const char *const FW_REL_HOSTS []

Detailed Description

What GitHub says about the panel's releases, read strictly.

The panel asks GitHub two things over HTTPS (HTTP, hypertext transfer protocol, over TLS, transport layer security). Which release is the newest, by one of two requests, after SETUP > UPDATES' RELEASES:

STABLE a GET of FW_REL_LATEST_URL, answered with a redirect whose Location names the tag (".../releases/tag/v0.20.0"); only that header is read, no body. GitHub's latest release is never a pre-release, so this names a stable release only. TESTING a GET of FW_REL_API_URL, GitHub's REST (representational state transfer) API, answered with a JSON (JavaScript Object Notation) array of the FW_REL_API_RELEASES newest releases by date, testing or stable. fw_release_scan_feed() reads each one's "tag_name" and "draft", a byte at a time, without keeping the answer, and names the highest version among those that are no draft, and the highest of the panel's release line: GitHub's order is by date, not by version.

The panel's release line: 0.22 is the last release for the ESP32-S3 panel, and later releases are for the ESP32-P4 panel. The ESP32-P4 panel's line holds every release: a check offers any release newer than the running build (FW_REL_LINE_CAPPED 0). Held to the ESP32-S3 panel's line (fw_release_set_line_capped()), a check on either channel offers a release of FW_REL_LINE_MAJOR.FW_REL_LINE_MINOR only, a 0.22.x patch release newer than the running build; 0.23.0 and later are never offered. Where STABLE's one tag is past the line and newer than the running build, the check reads the release list once more for the line's newest.

And, for a download, two files of that release: SHA256SUMS and rcbench-panel-p4-vX.Y.Z.bin, each a redirect from github.com to a githubusercontent.com host and then the file.

Every piece of an answer is held to a fixed form here, before anything acts on it:

tag "v" and MAJOR.MINOR.PATCH, digits only, each 0 to 65535, no leading zero (0 itself is fine), nothing after it; the whole Location exactly FW_REL_TAG_PREFIX and the tag redirect "https://", a host of FW_REL_HOSTS exactly, then a path; printable ASCII (American Standard Code for Information Interchange) only, at most FW_REL_URL_MAX bytes, at most FW_REL_HOPS_MAX of them in one fetch length SHA256SUMS and the image: a Content-Length, not chunked, 1 byte to the cap API answer status 200; a Content-Length of 1 to FW_REL_API_MAX bytes, or chunked (Transfer-Encoding: chunked) and its releases read within FW_REL_SCAN_MAX bytes; an array of objects, the first FW_REL_API_RELEASES of them read, each with exactly one "tag_name", a JSON string of at most FW_REL_TAG_MAX bytes without escapes or control bytes, "v" and MAJOR.MINOR.PATCH as a tag, and at most one "draft", true or false; nesting at most FW_REL_SCAN_DEPTH levels, every bracket closed by its own kind. Any release out of this form refuses the whole answer, a draft's included: nothing is offered rather than a release picked around it SHA256SUMS at most FW_REL_SUMS_MAX bytes of lines "<64 lowercase hex>", two spaces or a space and '*', an optional "./", a file name of letters, digits, '.', '-' and '_', and '
'; any other line refuses the whole file; the image's name on exactly one line

Pure C, no ESP-IDF (Espressif Internet-of-Things Development Framework).

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ FW_REL_API_ACCEPT

#define FW_REL_API_ACCEPT   "application/vnd.github+json"

The headers the API request carries besides the User-Agent.

◆ FW_REL_API_MAX

#define FW_REL_API_MAX   262144u

The API's answer at most, by its Content-Length, in bytes. Each release carries its notes and its assets: the 10 newest on 2026-10-18, v0.12.0 to v0.20.0, are 108198 bytes, the largest one 13734.

◆ FW_REL_API_RELEASES

#define FW_REL_API_RELEASES   10u

Releases the API's answer holds, and the scan reads, at most.

◆ FW_REL_API_URL

#define FW_REL_API_URL
Value:
"https://api.github.com/repos/" FW_REL_REPO \
"/releases?per_page=10"

The newest release, testing or stable: GitHub's REST API.

◆ FW_REL_HOPS_MAX

#define FW_REL_HOPS_MAX   3u

Redirects followed in one fetch at most.

◆ FW_REL_LINE_MAJOR

#define FW_REL_LINE_MAJOR   0u

the line's MAJOR

◆ FW_REL_LINE_MINOR

#define FW_REL_LINE_MINOR   22u

the line's MINOR

◆ FW_REL_SCAN_DEPTH

#define FW_REL_SCAN_DEPTH   32u

JSON nesting the scan follows at most, the array included.

◆ FW_REL_SCAN_MAX

#define FW_REL_SCAN_MAX   FW_REL_API_MAX

Bytes of the API's answer scanned at most: the whole of the largest answer taken.

◆ FW_REL_SUMS_MAX

#define FW_REL_SUMS_MAX   4096u

SHA256SUMS at most, in bytes.

Enumeration Type Documentation

◆ fw_rel_err_t

Why an answer is refused; FW_REL_OK is none of them.

Enumerator
FW_REL_MISSING 

no Location, or an empty one

FW_REL_LONG 

over its bound, or cut on the way in

FW_REL_CHAR 

a byte outside printable ASCII

FW_REL_PLACE 

not the expected scheme, host or path

FW_REL_VERSION 

the tag is not v + MAJOR.MINOR.PATCH

FW_REL_STATUS 

an HTTP status this step does not take

FW_REL_HOPS 

more than FW_REL_HOPS_MAX redirects

FW_REL_HOST 

a redirect to a host not in FW_REL_HOSTS

FW_REL_NO_LENGTH 

no Content-Length, or a chunked body where one is needed

FW_REL_EMPTY 

a Content-Length of 0, or an empty chunked API answer

FW_REL_TOO_BIG 

a Content-Length over the cap

FW_REL_SHORT 

the body ended before its Content-Length

FW_REL_OVERRUN 

more body bytes than asked for

FW_REL_SUMS_BAD 

SHA256SUMS has a line out of form

FW_REL_SUMS_NONE 

SHA256SUMS has no line for the file

FW_REL_SUMS_TWICE 

SHA256SUMS names the file on two lines

FW_REL_TAG_NONE 

API: a release without tag_name, no release but drafts, or the answer ended first

FW_REL_TAG_LONG 

API: tag_name over FW_REL_TAG_MAX bytes

FW_REL_TAG_FORM 

API: tag_name not a plain JSON string, or the JSON around it out of form

FW_REL_SCAN_LONG 

API: the releases not read in FW_REL_SCAN_MAX bytes

◆ fw_rel_status_t

What a step does with an HTTP status.

Enumerator
FW_REL_BODY 

200: read the body

FW_REL_REDIRECT 

301, 302, 303, 307, 308: a Location follows

FW_REL_REFUSED 

anything else

Function Documentation

◆ fw_rel_err_str()

const char * fw_rel_err_str ( fw_rel_err_t e)

The English name of e, for the console.

◆ fw_release_image_name()

void fw_release_image_name ( fw_version_t v,
char out[FW_REL_NAME_MAX] )

The file name of a release's panel image.

Writes "rcbench-panel-p4-v0.20.0.bin" for version 0.20.0. The longest name, for 65535.65535.65535, fills FW_REL_NAME_MAX bytes with its terminator.

Parameters
vVersion of the release.
outReceives the name, terminated.

◆ fw_release_in_line()

bool fw_release_in_line ( fw_version_t v)

Whether a version is of the panel's release line.

Parameters
vthe version
Returns
true for every version while the line is not capped (fw_release_line_capped()); once capped, true for MAJOR FW_REL_LINE_MAJOR and MINOR FW_REL_LINE_MINOR, any PATCH

◆ fw_release_length()

fw_rel_err_t fw_release_length ( int64_t length,
bool chunked,
uint32_t cap )

A body's announced size: length as the client read Content-Length, -1 for none, and chunked. FW_REL_OK, or NO_LENGTH, EMPTY or TOO_BIG against cap bytes.

◆ fw_release_line_capped()

bool fw_release_line_capped ( void )

Whether the panel's release line is capped at FW_REL_LINE_MAJOR.FW_REL_LINE_MINOR.

Returns
FW_REL_LINE_CAPPED until fw_release_set_line_capped() sets it

◆ fw_release_offered()

bool fw_release_offered ( fw_version_t found,
fw_version_t running,
bool running_ok )

Whether a release is offered to the panel.

Only one of the panel's release line (fw_release_in_line()) and strictly newer than the running build. Each part counts as a number: 0.22.10 is newer than 0.22.9.

Parameters
foundthe release a check found
runningthe version the panel runs
running_okfalse when the running version did not parse
Returns
true when found is offered; false always when running_ok is false

◆ fw_release_parse_sums()

fw_rel_err_t fw_release_parse_sums ( const char * text,
size_t n,
const char * name,
uint8_t out[FW_SHA256_BYTES] )

The SHA-256 SHA256SUMS gives for name: text of n bytes, not terminated. FW_REL_OK and out, or LONG, SUMS_BAD, SUMS_NONE or SUMS_TWICE.

◆ fw_release_parse_tag()

fw_rel_err_t fw_release_parse_tag ( const char * loc,
size_t n,
bool cut,
fw_version_t * out )

The release a redirect from FW_REL_LATEST_URL names: loc of n bytes, not terminated; cut when the header was longer than the buffer that took it. FW_REL_OK and out, or MISSING, LONG, CHAR, PLACE or VERSION.

◆ fw_release_parse_version()

bool fw_release_parse_version ( const char * s,
size_t n,
fw_version_t * out )

"MAJOR.MINOR.PATCH" in exactly n bytes of s, by the tag's rule: digits only, at most 5 a part, each part 0 to 65535, no leading zero.

◆ fw_release_redirect()

fw_rel_err_t fw_release_redirect ( const char * loc,
size_t n,
bool cut,
unsigned hops )

Whether a download may follow a redirect to loc (n bytes, cut as above) after hops redirects already followed. FW_REL_OK, or MISSING, LONG, CHAR, PLACE (not https://, or no path), HOST or HOPS.

◆ fw_release_scan_end()

fw_rel_err_t fw_release_scan_end ( const fw_rel_scan_t * s,
fw_version_t * out )

The scan's result once the answer is whole: FW_REL_OK and the highest no-draft release in out, or TAG_NONE (a release without a tag, none but drafts, or the answer ended before the array or the FW_REL_API_RELEASES-th release did), TAG_LONG, TAG_FORM, SCAN_LONG or VERSION.

◆ fw_release_scan_feed()

bool fw_release_scan_feed ( fw_rel_scan_t * s,
const uint8_t * d,
size_t n )

n more bytes of the answer. True once the scan has ended: the tag read, or the answer refused; bytes fed after that are not looked at.

◆ fw_release_scan_line()

bool fw_release_scan_line ( const fw_rel_scan_t * s,
fw_version_t * out )

The highest no-draft release of the panel's release line among those the scan read.

Parameters
sthe scan, ended; NULL reads as none
outthe release, when there is one; untouched otherwise; may be NULL
Returns
true once the scan ended with FW_REL_OK and read a no-draft release of the line; false otherwise

◆ fw_release_set_line_capped()

void fw_release_set_line_capped ( bool capped)

Caps the panel's release line at FW_REL_LINE_MAJOR.FW_REL_LINE_MINOR, or lifts the cap. The panel keeps FW_REL_LINE_CAPPED; the host suite holds both lines.

Parameters
cappedtrue for the ESP32-S3 panel's 0.22 line, false for every release

◆ fw_release_url()

bool fw_release_url ( fw_version_t v,
const char * file,
char * out,
size_t cap )

The download URL of file in release v into out of cap bytes; false when it does not fit.

◆ fw_release_version_text()

void fw_release_version_text ( fw_version_t v,
char out[FW_REL_VER_TEXT] )

"0.20.0" into out of FW_REL_VER_TEXT bytes.

Variable Documentation

◆ FW_REL_HOSTS

const char* const FW_REL_HOSTS[]
extern

The hosts a download follows, NULL-terminated.