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

The panel asking GitHub for its newest release, and fetching it. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "fw_image.h"
#include "fw_release.h"
#include "fw_upload.h"
#include "wa_session.h"

Go to the source code of this file.

Data Structures

struct  wa_fetch_t
struct  wa_fetch_res_t
struct  wa_http_head_t
struct  wa_http_t
struct  wa_run_t

Macros

#define WA_FETCH_CHECK_MS   30000u
#define WA_FETCH_JOIN_MS   30000u
#define WA_FETCH_DOWNLOAD_MS   180000u
#define WA_FETCH_OP_MS   10000u

Enumerations

enum  wa_job_t { WA_JOB_CHECK = 0 , WA_JOB_DOWNLOAD }
enum  wa_channel_t { WA_CH_STABLE = 0 , WA_CH_TESTING }
enum  wa_phase_t {
  WA_PH_IDLE = 0 , WA_PH_JOINING , WA_PH_ASKING , WA_PH_SUMS ,
  WA_PH_IMAGE , WA_PH_CHECKING , WA_PH_ENDED
}
enum  wa_got_t {
  WA_GOT_NONE = 0 , WA_GOT_NEWER , WA_GOT_CURRENT , WA_GOT_STAGED ,
  WA_GOT_NO_NET , WA_GOT_BLOCKED , WA_GOT_ABORTED , WA_GOT_JOIN ,
  WA_GOT_RADIO , WA_GOT_TIMEOUT , WA_GOT_CONNECT , WA_GOT_REFUSED ,
  WA_GOT_UNEXPECTED , WA_GOT_SUMS , WA_GOT_HASH , WA_GOT_IMAGE ,
  WA_GOT_MEMORY , WA_GOT_LIMIT , WA_GOT_UNVERSIONED , WA_GOT_PAST_LINE
}
enum  wa_why_t {
  WA_WHY_NONE = 0 , WA_WHY_ARMED , WA_WHY_SUPPLY , WA_WHY_RUN ,
  WA_WHY_STOP , WA_WHY_FILES , WA_WHY_COPROC , WA_WHY_INSTALL ,
  WA_WHY_CANCEL , WA_WHY_BUSY , WA_WHY_DRAWING
}

Functions

void wa_fetch_init (wa_fetch_t *f, fw_version_t running)
wa_why_t wa_fetch_gate (bool armed, bool supply, bool run, bool coproc, bool installing)
wa_why_t wa_fetch_start_gate (wa_why_t gate, bool taken, bool task_alive, bool other)
 The gate a job's start takes, past the bench's own.
wa_got_t wa_fetch_start (wa_fetch_t *f, wa_job_t job, fw_version_t want, wa_channel_t ch, bool have_net, wa_why_t gate, uint32_t now_ms)
bool wa_fetch_offers (const wa_fetch_t *f, wa_channel_t now)
bool wa_fetch_stale (const wa_fetch_t *f, wa_channel_t now)
bool wa_fetch_busy (const wa_fetch_t *f)
bool wa_fetch_has_found (const wa_fetch_t *f)
 Whether the last job names a release in wa_fetch_t.found.
void wa_fetch_tick (wa_fetch_t *f, uint32_t now_ms, wa_why_t abort, const wa_t *w)
void wa_fetch_abort (wa_fetch_t *f, wa_why_t why)
uint32_t wa_fetch_left (const wa_fetch_t *f, uint32_t now_ms)
bool wa_fetch_take_off (wa_fetch_t *f)
bool wa_fetch_take_run (wa_fetch_t *f)
void wa_fetch_on_phase (wa_fetch_t *f, uint32_t gen, wa_phase_t ph)
void wa_fetch_on_bytes (wa_fetch_t *f, uint32_t gen, uint32_t done, uint32_t total)
void wa_fetch_on_end (wa_fetch_t *f, uint32_t gen, const wa_fetch_res_t *r)
void wa_run_check (const wa_run_t *r, wa_fetch_res_t *out)
void wa_run_download (const wa_run_t *r, fw_version_t v, wa_fetch_res_t *out)

Detailed Description

The panel asking GitHub for its newest release, and fetching it.

Two jobs, each on the home network the panel keeps (wa_session.h, WA_MODE_FETCH: no page, no name), each with the radio on only for its length:

CHECK join, then one HTTPS (HTTP over TLS, transport layer security) GET for the newest release of the job's channel. STABLE: FW_REL_LATEST_URL, whose redirect's Location names it (fw_release_parse_tag()); when that release is past the panel's release line and newer than the running build, one request of FW_REL_API_URL more, whose highest release of the line is offered in its place when it is newer than the running build, and which leaves the result as it was when it fails. TESTING: FW_REL_API_URL with GitHub's API headers, whose answer's 10 newest releases by date name it, the highest version among them that is no draft (fw_release_scan_feed()), read up to the 10th release's end and no further, with a Content-Length or in chunks; 403 and 429, GitHub's request limit, end as LIMIT. Where the highest is past the panel's release line, the highest of the line among them stands in for it when it is offered. Either way a release is NEWER only when fw_release_offered() says so; one newer than the running build and past the line is PAST_LINE. Join, address and request take WA_FETCH_CHECK_MS at most, together. DOWNLOAD join within WA_FETCH_JOIN_MS, then SHA256SUMS and the panel image of one release, each through at most FW_REL_HOPS_MAX redirects to the hosts fw_release.h allows, the image into memory; its SHA-256 against its SHA256SUMS line, then every fw_image_check(); WA_FETCH_DOWNLOAD_MS at most from the start. What it leaves is an image staged as an upload would leave it, for the existing installer. No flash is written here.

Two halves. The job (wa_fetch_t) lives with the session under the platform's lock: started and ticked by the UI loop, which holds the budget, the gate and every abort, and told by the radio and by the runner what happened. The runner (wa_run_check(), wa_run_download()) runs on a task of its own against an HTTP client the platform passes in (wa_http_t), so the host suite runs it against a scripted one. A job ended from outside – the budget, STOP, ARMED, the supply, a log run, WI-FI, CANCEL – stays ended: what the runner reports after it is dropped (the job's generation).

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

SPDX-License-Identifier: MIT

Macro Definition Documentation

◆ WA_FETCH_CHECK_MS

#define WA_FETCH_CHECK_MS   30000u

CHECK: join, address and the request, together.

◆ WA_FETCH_DOWNLOAD_MS

#define WA_FETCH_DOWNLOAD_MS   180000u

DOWNLOAD: from the start to a checked image.

◆ WA_FETCH_JOIN_MS

#define WA_FETCH_JOIN_MS   30000u

DOWNLOAD: join and address.

◆ WA_FETCH_OP_MS

#define WA_FETCH_OP_MS   10000u

One connection or one read waits this long at most, and never past the job's budget.

Enumeration Type Documentation

◆ wa_channel_t

Which releases a CHECK looks at: SETUP > UPDATES' RELEASES.

Enumerator
WA_CH_STABLE 

GitHub's latest release: never a pre-release

WA_CH_TESTING 

the newest release, testing or stable

◆ wa_got_t

enum wa_got_t

How a job ended.

Enumerator
WA_GOT_NONE 

under way, or none ran

WA_GOT_NEWER 

CHECK: a newer release, wa_fetch_t.found

WA_GOT_CURRENT 

CHECK: none newer than the running build

WA_GOT_STAGED 

DOWNLOAD: the image waits, checked

WA_GOT_NO_NET 

no home network kept: nothing started

WA_GOT_BLOCKED 

the gate: nothing started; see why

WA_GOT_ABORTED 

ended from outside; see why

WA_GOT_JOIN 

the join failed; see join

WA_GOT_RADIO 

the radio did not come up

WA_GOT_TIMEOUT 

the budget ran out

WA_GOT_CONNECT 

no connection: name, TCP or TLS failed

WA_GOT_REFUSED 

an HTTP status the step does not take

WA_GOT_UNEXPECTED 

an answer out of form; see rel

WA_GOT_SUMS 

SHA256SUMS missing, out of form or without the image's line; see rel

WA_GOT_HASH 

the image's SHA-256 is not SHA256SUMS'

WA_GOT_IMAGE 

the image checks refused it; see img

WA_GOT_MEMORY 

no memory for the image

WA_GOT_LIMIT 

CHECK on TESTING: 403 or 429, GitHub's limit of requests without an account; see status

WA_GOT_UNVERSIONED 

CHECK: the running version did not parse, so nothing is offered; wa_fetch_t.found

WA_GOT_PAST_LINE 

CHECK: the newest release is newer than the running build and past the panel's release line (fw_release_in_line()): not offered; wa_fetch_t.found

◆ wa_phase_t

enum wa_phase_t
Enumerator
WA_PH_IDLE 

no job since the start

WA_PH_JOINING 

the radio joins and takes an address

WA_PH_ASKING 

CHECK: the request to GitHub

WA_PH_SUMS 

DOWNLOAD: SHA256SUMS

WA_PH_IMAGE 

DOWNLOAD: the image

WA_PH_CHECKING 

DOWNLOAD: SHA-256 and the image checks

WA_PH_ENDED 

see wa_fetch_t.got

◆ wa_why_t

enum wa_why_t

Why a job did not start, or was ended from outside.

Enumerator
WA_WHY_ARMED 

ARMED, or an arm waiting

WA_WHY_SUPPLY 

the supply's output on or coming on

WA_WHY_RUN 

a log run open

WA_WHY_FILES 

WI-FI opened: it takes the radio

WA_WHY_COPROC 

the IOmcu's update runs

WA_WHY_INSTALL 

a panel install runs

WA_WHY_CANCEL 

the operator cancelled

WA_WHY_BUSY 

a job runs already

WA_WHY_DRAWING 

a board drawing is fetched or kept: no flash write, so no download either

Function Documentation

◆ wa_fetch_abort()

void wa_fetch_abort ( wa_fetch_t * f,
wa_why_t why )

End the job now for why; nothing when none runs.

◆ wa_fetch_busy()

bool wa_fetch_busy ( const wa_fetch_t * f)

Whether a job runs: joining to checking.

◆ wa_fetch_gate()

wa_why_t wa_fetch_gate ( bool armed,
bool supply,
bool run,
bool coproc,
bool installing )

The gate as wa_gate() takes it, plus the panel's own two.

◆ wa_fetch_has_found()

bool wa_fetch_has_found ( const wa_fetch_t * f)

Whether the last job names a release in wa_fetch_t.found.

Parameters
fthe job; NULL reads as none
Returns
true for a DOWNLOAD, and for a CHECK that ended NEWER, CURRENT, UNVERSIONED or PAST_LINE; false otherwise

◆ wa_fetch_init()

void wa_fetch_init ( wa_fetch_t * f,
fw_version_t running )

No job; running is the build that runs.

◆ wa_fetch_left()

uint32_t wa_fetch_left ( const wa_fetch_t * f,
uint32_t now_ms )

ms of the budget left at now_ms for the phase under way; 0 when it is spent or no job runs.

◆ wa_fetch_offers()

bool wa_fetch_offers ( const wa_fetch_t * f,
wa_channel_t now )

Whether the last job is a CHECK that found a release to offer on channel now: ended NEWER, and run on now. A check on the other channel offers nothing: RELEASES changed after it.

◆ wa_fetch_stale()

bool wa_fetch_stale ( const wa_fetch_t * f,
wa_channel_t now )

Whether the last job is a CHECK that ended on another channel than now: its result is not shown, as if no check had run.

◆ wa_fetch_start()

wa_got_t wa_fetch_start ( wa_fetch_t * f,
wa_job_t job,
fw_version_t want,
wa_channel_t ch,
bool have_net,
wa_why_t gate,
uint32_t now_ms )

Start job at now_ms for release want (DOWNLOAD; ignored by CHECK) on channel ch (CHECK; kept by DOWNLOAD too). WA_GOT_NONE and JOINING: the platform starts the radio in WA_MODE_FETCH. Otherwise the job has ended at once: NO_NET without have_net, BLOCKED for gate or for a job already running (why).

◆ wa_fetch_start_gate()

wa_why_t wa_fetch_start_gate ( wa_why_t gate,
bool taken,
bool task_alive,
bool other )

The gate a job's start takes, past the bench's own.

The radio goes off without waiting for the last job's task: a name lookup under way when the radio goes ends only when lwIP gives up on it, up to about 7s per DNS (Domain Name System) server. Until that task has ended no job starts, so it never runs beside the next job's; a session (WI-FI) starts without waiting for it.

Parameters
gatethe bench's gate (wa_fetch_gate()), or WA_WHY_NONE
takenan image is taken for the install
task_alivethe last job's task has not ended
othera session other than WA_MODE_FETCH asks for the radio
Returns
gate when it is set; WA_WHY_BUSY for any of the other three; WA_WHY_NONE otherwise

◆ wa_fetch_take_off()

bool wa_fetch_take_off ( wa_fetch_t * f)

True once after the job ended: the radio goes off.

◆ wa_fetch_take_run()

bool wa_fetch_take_run ( wa_fetch_t * f)

True once after the join: the runner starts.

◆ wa_fetch_tick()

void wa_fetch_tick ( wa_fetch_t * f,
uint32_t now_ms,
wa_why_t abort,
const wa_t * w )

Once a frame, after wa_tick(): abort as the UI loop sees it now (WA_WHY_NONE for none), w the session. Ends the job for an abort, for the session going off under it and for the budget; moves JOINING on once the session has its address. The platform reads owe_off and owe_run after it.

◆ wa_run_check()

void wa_run_check ( const wa_run_t * r,
wa_fetch_res_t * out )

CHECK, from the join on. NEWER, CURRENT, UNVERSIONED, or why not.

◆ wa_run_download()

void wa_run_download ( const wa_run_t * r,
fw_version_t v,
wa_fetch_res_t * out )

DOWNLOAD of release v, from the join on. STAGED with the image in r->up, or why not with r->up not staged.