cryptnox-pos 1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Loading...
Searching...
No Matches
ota.cpp File Reference

Firmware slot handling. See ota.h for the why. More...

#include "ota.h"
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "CW_Utils.h"
#include "esp_app_desc.h"
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "esp_system.h"
#include "ota_version.h"
Include dependency graph for ota.cpp:

Go to the source code of this file.

Macros

#define OTA_MIN_IMAGE   (256U * 1024U)

Functions

static bool lock_ready (void)
 Create the staging lock on first use.
static bool refuse (const char **err, const char *msg)
 Refuse an upload, saying so to the browser AND to the log.
bool ota_begin (size_t len, const char **err)
 Open the idle slot for an image of len bytes.
bool ota_write (const void *buf, size_t n)
 Append n bytes to the open slot.
void ota_abort (void)
 Give up on an upload in progress. Nothing is installed. Safe always.
bool ota_receiving (void)
 Whether an upload is in flight, so a second can be refused.
bool ota_end (char *ver_out, size_t ver_n, const char **err)
 Close and verify the received image, then stage it for the panel.
bool ota_last_update_failed (void)
 Whether the last update was installed and then thrown away.
bool ota_mark_valid (void)
 Confirm the running image, cancelling the rollback armed by the bootloader.
const char * ota_running_version (void)
 The running firmware's version, from the image header.
bool ota_staged (char *version, size_t version_n, bool *older)
 Fetch the version of an image that has been received and verified but not yet installed.
bool ota_commit (bool install)
 Resolve a staged image.

Variables

static const char *const TAG = "ota"
static char s_running_ver [OTA_VERSION_MAX+1] = ""
static SemaphoreHandle_t s_lock = NULL
static bool s_staged = false
static bool s_staged_older = false
static char s_staged_ver [OTA_VERSION_MAX+1] = ""
static volatile bool s_receiving = false
static esp_ota_handle_t s_handle = 0
static const esp_partition_t * s_dst = NULL

Detailed Description

Firmware slot handling. See ota.h for the why.

Definition in file ota.cpp.

Macro Definition Documentation

◆ OTA_MIN_IMAGE

#define OTA_MIN_IMAGE   (256U * 1024U)

Definition at line 45 of file ota.cpp.

Referenced by ota_begin().

Function Documentation

◆ lock_ready()

bool lock_ready ( void )
static

Create the staging lock on first use.

Definition at line 69 of file ota.cpp.

References s_lock.

Referenced by ota_begin().

◆ ota_abort()

void ota_abort ( void )

Give up on an upload in progress. Nothing is installed. Safe always.

Definition at line 156 of file ota.cpp.

References s_handle, s_receiving, and TAG.

Referenced by ota_post(), and prov_stop().

◆ ota_begin()

bool ota_begin ( size_t len,
const char ** err )

Open the idle slot for an image of len bytes.

Erases only the pages that will be written, which on a 1.94 MB slot is a few seconds saved with the operator watching. Refuses a second concurrent upload, a length that is not plausibly firmware, and a device whose partition table has no second app slot at all.

Parameters
[in]lenExact image length, from Content-Length.
[out]errSet to a caller-displayable reason on failure; never NULL on return, points at a string literal.
Returns
true with the slot open — the caller must then reach ota_end or ota_abort, or the slot stays claimed until the next boot.

Definition at line 94 of file ota.cpp.

References lock_ready(), OTA_MIN_IMAGE, refuse(), s_dst, s_handle, s_lock, s_receiving, s_staged, and TAG.

Referenced by ota_post().

◆ ota_commit()

bool ota_commit ( bool install)

Resolve a staged image.

Parameters
[in]installtrue to make the staged slot bootable and reboot into it — this call does not return. false to discard the staging, leaving the running slot untouched.
Returns
false if nothing was staged, or if the slot could not be made bootable. Does not return on success with install true.

Definition at line 291 of file ota.cpp.

References OTA_VERSION_MAX, s_lock, s_staged, s_staged_ver, and TAG.

Referenced by btn_event_cb().

◆ ota_end()

bool ota_end ( char * ver,
size_t ver_n,
const char ** err )

Close and verify the received image, then stage it for the panel.

The gate. Checks the image's own SHA-256, and — on a signed build — its signature against the public key in the running firmware. An image that fails here never becomes bootable, whoever uploaded it. On success the version is read out of the image that was just verified, never out of anything the browser said about it, and the image is staged: written, valid, and still not bootable.

Parameters
[out]verVersion from the image header, may be NULL.
[in]ver_nCapacity of ver.
[out]errDisplayable reason on failure; never NULL on return.
Returns
true if the image is staged and awaiting acceptance on the panel.

Definition at line 167 of file ota.cpp.

References ota_running_version(), ota_version_cmp(), OTA_VERSION_MAX, s_dst, s_handle, s_lock, s_receiving, s_staged, s_staged_older, s_staged_ver, and TAG.

Referenced by ota_post().

◆ ota_last_update_failed()

bool ota_last_update_failed ( void )

Whether the last update was installed and then thrown away.

The failure this exists to name: an image installs, boots, and never reaches ota_mark_valid — because bring-up did not finish, or because somebody power-cycled the terminal during the seconds it takes — so the bootloader reverts to the slot that was working and the panel goes on reading the old version. Correct behaviour, and completely silent: indistinguishable from an update that never happened at all.

Read from the idle slot's state in otadata, so it needs no bookkeeping of its own and clears itself: the next update writes that slot and overwrites the verdict.

Returns
true if the slot an update would go to holds an image the bootloader aborted or marked invalid.

Definition at line 221 of file ota.cpp.

Referenced by build_settings(), and ota_mark_valid().

◆ ota_mark_valid()

bool ota_mark_valid ( void )

Confirm the running image, cancelling the rollback armed by the bootloader.

Call once, and only once the image has proven it can drive its own hardware — panel, card reader and wallet layer all up. Not the uplink: a router or RPC provider that is down during the first boot is the venue's problem, and waiting on it rolled good images back. Until it is called, a freshly installed image is on probation: any reset that happens first (panic, watchdog, brown-out) sends the next boot back to the slot that was working. Calling it early is the same as not having rollback at all.

No-op on a build without CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE, and on a boot that is not the first after an update.

Returns
true if this boot was the first on a freshly installed image, i.e. the probation was real and has just been lifted. The caller uses it to greet the operator once after an update; every later boot returns false.

Definition at line 231 of file ota.cpp.

References ota_last_update_failed(), ota_running_version(), and TAG.

Referenced by pos_boot().

◆ ota_receiving()

bool ota_receiving ( void )

Whether an upload is in flight, so a second can be refused.

Definition at line 165 of file ota.cpp.

References s_receiving.

Referenced by ota_post(), and ui_task().

◆ ota_running_version()

const char * ota_running_version ( void )

The running firmware's version, from the image header.

Returns
Version string ("1.0.0"), never NULL. Valid for the program lifetime.

Definition at line 263 of file ota.cpp.

References s_running_ver.

Referenced by build_ota_confirm(), build_settings(), ota_end(), ota_mark_valid(), pos_boot(), and state_get().

◆ ota_staged()

bool ota_staged ( char * version,
size_t version_n,
bool * older )

Fetch the version of an image that has been received and verified but not yet installed.

Parameters
[out]versionVersion from the staged image's header, may be NULL.
[in]version_nCapacity of version.
[out]olderSet true if the staged version is behind the running one — a downgrade, which the panel must say out loud. May be NULL.
Returns
true if an image is staged and waiting to be accepted.

Definition at line 275 of file ota.cpp.

References s_lock, s_staged, s_staged_older, and s_staged_ver.

Referenced by build_ota_confirm(), ota_post(), and ui_task().

◆ ota_write()

bool ota_write ( const void * buf,
size_t n )

Append n bytes to the open slot.

Returns
false on a write error.

Definition at line 145 of file ota.cpp.

References s_handle, s_receiving, and TAG.

Referenced by ota_post().

◆ refuse()

bool refuse ( const char ** err,
const char * msg )
static

Refuse an upload, saying so to the browser AND to the log.

Five of these refusals used to be silent on the serial side, which left an operator reporting "it says not installed" with nothing to match it against — and the reasons are not interchangeable: a stale staging, a file of the wrong size and a slot that would not erase want three different things done.

Definition at line 87 of file ota.cpp.

References TAG.

Referenced by ota_begin().

Variable Documentation

◆ s_dst

const esp_partition_t* s_dst = NULL
static

Definition at line 66 of file ota.cpp.

Referenced by ota_begin(), and ota_end().

◆ s_handle

esp_ota_handle_t s_handle = 0
static

Definition at line 65 of file ota.cpp.

Referenced by ota_abort(), ota_begin(), ota_end(), and ota_write().

◆ s_lock

SemaphoreHandle_t s_lock = NULL
static

Definition at line 57 of file ota.cpp.

Referenced by lock_ready(), ota_begin(), ota_commit(), ota_end(), and ota_staged().

◆ s_receiving

volatile bool s_receiving = false
static

Definition at line 64 of file ota.cpp.

Referenced by ota_abort(), ota_begin(), ota_end(), ota_receiving(), and ota_write().

◆ s_running_ver

char s_running_ver[OTA_VERSION_MAX+1] = ""
static

Definition at line 51 of file ota.cpp.

Referenced by ota_running_version().

◆ s_staged

bool s_staged = false
static

Definition at line 58 of file ota.cpp.

Referenced by ota_begin(), ota_commit(), ota_end(), and ota_staged().

◆ s_staged_older

bool s_staged_older = false
static

Definition at line 59 of file ota.cpp.

Referenced by ota_end(), and ota_staged().

◆ s_staged_ver

char s_staged_ver[OTA_VERSION_MAX+1] = ""
static

Definition at line 60 of file ota.cpp.

Referenced by ota_commit(), ota_end(), and ota_staged().

◆ TAG

const char* const TAG = "ota"
static

Definition at line 37 of file ota.cpp.