ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_net_c6link.c
Go to the documentation of this file.
1
9
10#include "mdl_net_c6link.h"
11
12#include <stddef.h>
13#include <stdint.h>
14#include <string.h>
15
16#include "mdl_net_internal.h"
17#include "ra8_attributes.h"
18
24
33
34static_assert((uint32_t)k_mdl_retry_after_max == (uint32_t)k_ra8_mdl_retry_after_max,
35 "C6 and downloader Retry-After capacities must match");
36static_assert((uint32_t)k_mdl_etag_max == (uint32_t)k_ra8_mdl_etag_max,
37 "C6 and downloader ETag capacities must match");
38static_assert((uint32_t)k_mdl_last_mod_max == (uint32_t)k_ra8_mdl_http_date_max,
39 "C6 and downloader HTTP-date capacities must match");
40static_assert((uint32_t)k_mdl_content_type_max == (uint32_t)k_ra8_mdl_content_type_max,
41 "C6 and downloader Content-Type capacities must match");
42
59RA8_INTERNAL static ra8_err_t internal_c6_output_begin(void* ctx, const char* destination)
60{
61 mdl_c6_output_t* output = (mdl_c6_output_t*)ctx;
62 if ((output == nullptr) || (destination == nullptr) || (destination[0] == '\0')) {
64 }
65 output->length = 0U;
66 if (output->kind == k_mdl_c6_output_buffer) {
67 output->buffer[0] = '\0';
68 }
69 return k_ra8_ok;
70}
71
92internal_c6_output_write(void* ctx, const uint8_t* data, uint16_t len, uint16_t* written)
93{
94 mdl_c6_output_t* output = (mdl_c6_output_t*)ctx;
95 *written = 0U;
96 if (output->kind == k_mdl_c6_output_buffer) {
97 if ((output->length >= output->cap) || ((size_t)len > (output->cap - output->length - 1U))) {
98 return k_ra8_err_no_mem;
99 }
100 (void)memcpy(&output->buffer[output->length], data, len);
101 } else {
102 uint32_t accepted = 0U;
103 const ra8_err_t sink_result = output->sink->write(output->sink->ctx, data, len, &accepted);
104 if (sink_result != k_ra8_ok) {
105 return sink_result;
106 }
107 if (accepted != len) {
109 }
110 }
111 output->length += len;
112 *written = len;
113 return k_ra8_ok;
114}
115
131{
132 mdl_c6_output_t* output = (mdl_c6_output_t*)ctx;
133 if (output->kind == k_mdl_c6_output_buffer) {
134 output->buffer[output->length] = '\0';
135 }
136 return k_ra8_ok;
137}
138
154{
155 mdl_c6_output_t* output = (mdl_c6_output_t*)ctx;
156 ra8_err_t result = k_ra8_ok;
157 if (output->kind == k_mdl_c6_output_buffer) {
158 output->buffer[0] = '\0';
159 } else {
160 result = output->sink->reset(output->sink->ctx);
161 }
162 if (result == k_ra8_ok) {
163 output->length = 0U;
164 }
165 return result;
166}
167
191 const char* url,
192 const mdl_net_req_t* req,
193 mdl_c6_output_t* output,
194 size_t* out_len,
195 mdl_net_resp_t* resp)
196{
197 const ra8_mdl_transfer_config_t config = {
198 .storage = {.begin = internal_c6_output_begin,
200 .validate = nullptr,
203 .ctx = output},
204 .sha256 = backend->sha256,
205 .format = k_mdl_format_loose,
206 .http = {.user_agent = req->user_agent,
207 .referer = req->referer,
208 .if_none_match = req->if_none_match,
209 .if_modified_since = req->if_modified_since,
210 .timeout_ms = req->timeout_ms},
211 .chunk_bytes = backend->chunk_bytes,
212 .max_chunks = backend->max_chunks,
213 };
214 ra8_mdl_transfer_result_t transfer = {};
215 const ra8_err_t result =
216 ra8_c6link_mdl_transfer(backend->link, url, "c6-response", &config, &transfer);
217 if (result == k_ra8_ok) {
218 if (transfer.bytes_stored > SIZE_MAX) {
220 }
221 if (resp != nullptr) {
222 resp->status = transfer.response.status;
223 (void)memcpy(resp->retry_after, transfer.response.retry_after, sizeof(resp->retry_after));
224 (void)memcpy(resp->etag, transfer.response.etag, sizeof(resp->etag));
225 (void)memcpy(resp->last_modified,
226 transfer.response.last_modified,
227 sizeof(resp->last_modified));
228 (void)memcpy(resp->content_type, transfer.response.content_type, sizeof(resp->content_type));
229 }
230 const ra8_err_t classified = priv_mdl_net_classify_http(transfer.response.status);
231 if (classified != k_ra8_ok) {
232 (void)internal_c6_output_abort(output);
233 return classified;
234 }
235 if (out_len != nullptr) {
236 *out_len = (size_t)transfer.bytes_stored;
237 }
238 }
239 return result;
240}
241
244 const char* url,
245 const mdl_net_req_t* req,
246 char* buf,
247 size_t cap,
248 size_t* out_len,
249 mdl_net_resp_t* resp)
250{
251 mdl_c6_output_t output = {
253 .buffer = buf,
254 .cap = cap,
255 };
256 return internal_c6_get((mdl_net_c6link_t*)ctx, url, req, &output, out_len, resp);
257}
258
261 const char* url,
262 const mdl_net_req_t* req,
264 size_t* out_len,
265 mdl_net_resp_t* resp)
266{
267 mdl_c6_output_t output = {
268 .kind = k_mdl_c6_output_sink,
269 .sink = sink,
270 };
271 return internal_c6_get((mdl_net_c6link_t*)ctx, url, req, &output, out_len, resp);
272}
273
275RA8_INTERNAL static void internal_c6_destroy(void* ctx)
276{
277 (void)ctx;
278}
279
281 mdl_net_c6link_t* backend,
282 ra8_c6link_t* link,
283 const ra8_mdl_sha256_iface_t* sha256,
284 uint16_t chunk_bytes,
285 uint32_t max_chunks)
286{
287 if ((net == nullptr) || (backend == nullptr)) {
288 return k_ra8_err_null_ptr;
289 }
290 *net = (mdl_net_iface_t){};
291 *backend = (mdl_net_c6link_t){};
292 if ((link == nullptr) || (sha256 == nullptr) || (sha256->init == nullptr) ||
293 (sha256->update == nullptr) || (sha256->final == nullptr) || (sha256->ctx == nullptr)) {
294 return k_ra8_err_null_ptr;
295 }
296 if ((chunk_bytes == 0U) || (chunk_bytes > k_ra8_mdl_chunk_data_max) || (max_chunks == 0U)) {
298 }
299 *backend = (mdl_net_c6link_t){
300 .link = link,
301 .sha256 = *sha256,
302 .chunk_bytes = chunk_bytes,
303 .max_chunks = max_chunks,
304 };
306 static const mdl_net_vtable_t k_c6_vtable = {
307 .get_buf = internal_c6_get_buf,
308 .get_body = internal_c6_get_body,
309 .destroy = internal_c6_destroy,
310 };
311 *net = (mdl_net_iface_t){.vtable = &k_c6_vtable, .ctx = backend};
312 return k_ra8_ok;
313}
@ k_mdl_format_loose
Leave loose page images.
Definition mdl_format.h:36
ra8_err_t priv_mdl_net_classify_http(long status)
Classify one observed HTTP response status.
Definition mdl_net.c:31
@ k_mdl_last_mod_max
Raw Last-Modified header value buffer bytes.
Definition mdl_net.h:95
@ k_mdl_content_type_max
Raw Content-Type header value buffer bytes.
Definition mdl_net.h:96
@ k_mdl_retry_after_max
Raw Retry-After header value buffer bytes.
Definition mdl_net.h:93
@ k_mdl_etag_max
Raw ETag header value buffer bytes.
Definition mdl_net.h:94
Private HTTP classification shared by downloader network backends.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
@ k_ra8_mdl_chunk_data_max
Maximum raw body bytes in one chunk.
@ k_ra8_mdl_http_date_max
Maximum HTTP-date size, including NUL.
@ k_ra8_mdl_etag_max
Maximum ETag size, including NUL.
@ k_ra8_mdl_content_type_max
Maximum Content-Type size, including NUL.
@ k_ra8_mdl_retry_after_max
Maximum Retry-After size, including NUL.
Transaction state that turns one C6 body into a network response.
size_t cap
Text-buffer capacity.
mdl_net_body_sink_t * sink
Streaming sink or null.
size_t length
Bytes accepted so far.
char * buffer
Text buffer or null.
mdl_c6_output_kind_t kind
Selected output union member.
Caller-owned lifecycle and write seam for one response body.
Definition mdl_net.h:162
mdl_net_body_write_fn write
Consume one response chunk.
Definition mdl_net.h:164
void * ctx
Caller-owned callback state.
Definition mdl_net.h:165
mdl_net_body_reset_fn reset
Clear/abort prior attempt state.
Definition mdl_net.h:163
A network backend handle: an immutable method table plus its state.
Per-request session parameters.
Definition mdl_net.h:43
const char * referer
Referer header value, or NULL to omit.
Definition mdl_net.h:45
const char * if_none_match
If-None-Match conditional header (ETag), or NULL.
Definition mdl_net.h:46
const char * if_modified_since
If-Modified-Since header (Last-Modified), or NULL.
Definition mdl_net.h:47
const char * user_agent
Session User-Agent; never per-request random.
Definition mdl_net.h:44
uint32_t timeout_ms
Whole-request time budget, milliseconds.
Definition mdl_net.h:48
Per-transfer response metadata surfaced to the politeness governor.
Definition mdl_net.h:120
long status
Finished transfer's HTTP status, 0 if none.
Definition mdl_net.h:121
char retry_after[k_mdl_retry_after_max]
Raw Retry-After value, "" when absent.
Definition mdl_net.h:122
char etag[k_mdl_etag_max]
Raw ETag value, "" when absent.
Definition mdl_net.h:123
char last_modified[k_mdl_last_mod_max]
Raw Last-Modified value, "" when absent.
Definition mdl_net.h:124
char content_type[k_mdl_content_type_max]
Raw Content-Type value, "" when absent.
Definition mdl_net.h:125
Method table one network backend registers (Dependency Inversion).
Definition mdl_net.h:186
char last_modified[k_ra8_mdl_http_date_max]
Last-Modified or empty.
int32_t status
Final HTTP status.
char retry_after[k_ra8_mdl_retry_after_max]
Retry-After or empty.
char content_type[k_ra8_mdl_content_type_max]
Content-Type or empty.
char etag[k_ra8_mdl_etag_max]
ETag or empty.
ra8_err_t(* update)(void *ctx, const uint8_t *data, uint16_t len)
Feed one ordered byte span to the running hash.
ra8_err_t(* init)(void *ctx)
Reset the caller-owned context for a SHA-256 operation.
void * ctx
Hash context passed to every function.
ra8_err_t(* final)(void *ctx, uint8_t out[k_ra8_mdl_sha256_bytes])
Finalise the hash into the caller-provided digest.
ra8_mdl_http_response_t response
Proven terminal HTTP metadata.
uint64_t bytes_stored
Bytes atomically committed.