woz_dfu_rx.h
@file…
Overview
Receives a delta patch into the staging partition, application side. Transport-independent on purpose. The DWM3001CDK feeds this from a second L2CAP CoC beside the Aliro one, but nothing here knows that -- it takes frames and returns replies, so the host tests can drive it without a radio. The bootloader half is @ref woz_dfu.h. This side never applies anything: it writes bytes, checks a signature, and reboots.
@file
used by dfu_receiver.c dfu_smp_img.c
API
Cenum woz_dfu_op
Request opcodes, first byte of every frame from the host.
Cenum woz_dfu_rsp
Reply opcodes, first byte of every frame back to the host.
Cenum woz_dfu_err
Why a frame was refused. Deliberately coarse. A peer that has not been let in learns only that it was refused, not how close it got.
##define WOZ_DFU_RSP_MAX 5u
Largest reply this ever produces.
Fvoid woz_dfu_window_open(uint32_t duration_ms)
Open the update window for duration_ms. Until this is called nothing is accepted, and that IS the authorization model. The patch is signed and MCUboot re-verifies the result, so no peer can install code regardless; what the window prevents is an unauthenticated peer in radio range burning flash cycles and forcing reboots. A door lock that anyone nearby can reset in a loop is a real availability attack, and a window the owner has to open is what stops it. Calling it again while open restarts the clock.
Fvoid woz_dfu_window_close(void)
Close the window immediately and discard any transfer in progress.
Fbool woz_dfu_window_is_open(void)
True while the window is open. Transports gate their accept() on this.
Ctypedef void (*woz_dfu_window_cb)(bool open)
Called whenever the window opens or closes. Registered rather than a weak symbol so that it survives LTO without argument, and so a port with no indicator pays nothing.
Fvoid woz_dfu_set_window_cb(woz_dfu_window_cb cb)
Watch the window, so the board can SHOW that it is open. There are three ways in -- SW2, Apple Home's pairing mode, and the bench SWD write -- and none of them is visible from outside the board. An owner who pressed the button has no way to tell whether the press registered, and the five-minute window can expire while they are still looking for the phone. One callback covers every path because they all end at woz_dfu_window_open().
Fint woz_dfu_rx_frame(const uint8_t *frame, size_t len, uint8_t *rsp, size_t *rsp_len)
Handle one frame. @param frame request bytes, opcode first @param len length of frame @param rsp at least @ref WOZ_DFU_RSP_MAX bytes @param rsp_len set to the number of reply bytes produced @retval 0 always; failures are reported to the peer through rsp, because a transport has nothing useful to do with an error code.
Fvoid woz_dfu_rx_reset(void)
Drop any transfer in progress. Transports call this on disconnect.
Fint woz_dfu_rx_upload(uint32_t off, uint32_t total, const uint8_t *data, size_t len, uint32_t *next)
Take one SMP image-upload chunk. The same bytes and the same checks as @ref woz_dfu_rx_frame, reached from CBOR instead of opcodes, so that a stock mcumgr client (nRF Device Manager, mcumgr image upload) can push an update. See src/dfu_smp_img.c. @param off offset the host believes this chunk starts at @param total whole wire length; only read when off is 0 @param data chunk bytes @param len length of data @param[out] next offset to send next. On a mismatched off this comes back as the device's real position and the chunk is discarded -- a resync, which the protocol treats as success. @retval 0 chunk accepted, or a resync was requested @retval -EACCES no update window is open @retval -EINVAL refused; the transfer is discarded and must restart at 0
Fbool woz_dfu_rx_staged(void)
True when a complete, verified update is staged and waiting for a reboot.