ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
ftp_session.h
Go to the documentation of this file.
1// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file ftp_session.h
6 * @brief FTP client session driver: the two sockets the ftp.h codec deliberately does not own.
7 *
8 * ftp.h is pure bytes-on-the-wire. This is the other half: it drives a real control connection
9 * (`protocore_client_*`) through the RFC 959 login -> TYPE I -> passive-mode -> transfer -> QUIT
10 * sequence, opens the second (data) connection the server names, and streams a payload across it.
11 *
12 * The payload is **pulled**, not pushed: the caller supplies a `protocore_ftp_source` that fills a chunk at
13 * a given offset. So the bytes can come from anywhere - a file, a sensor log, or the core-dump
14 * partition (`protocore_exc_coredump_read`) - without this owner knowing about any of them, and nothing
15 * ever has to fit in RAM at once.
16 *
17 * Non-blocking: a call advances the sequence as far as the sockets allow, then reports
18 * ::PROTOCORE_FTP_BUSY. A reply is bounded by PROTOCORE_FTP_TIMEOUT_MS.
19 *
20 * @author Douglas Quigg (dstroy0)
21 * @date 2026
22 */
23
24#ifndef PROTOCORE_FTP_SESSION_H
25#define PROTOCORE_FTP_SESSION_H
26
27#include "protocore_config.h" // the entry point: protocore_types.h for the widths
28
29#if PROTOCORE_ENABLE_FTP_SESSION
30
32
33// PROTOCORE_FTP_SESSION_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
34// it into its arena. A caller takes them once and passes the pointer to every call. How they
35// are carved is this module's and is never named here.
36
37/** @brief Where a transfer stands. */
38typedef enum PROTO_ENUM_PACKED
39{
40 PROTOCORE_FTP_READY = 0, ///< the server confirmed the completed transfer
41 PROTOCORE_FTP_BUSY, ///< the sockets have no more to give; ask again on the next tick
42 PROTOCORE_FTP_FAILED, ///< the sequence broke, or a reply passed its deadline
43} protocore_ftp_state;
44
45/** @brief Where to connect and who to log in as. */
46typedef struct
47{
48 const char *host; ///< server hostname or dotted-quad
49 uint16_t port; ///< control port, or 0 for the default 21
50 const char *user; ///< username, or nullptr for "anonymous"
51 const char *pass; ///< password, or nullptr for "" (anonymous)
52} FtpTarget;
53
54/**
55 * @brief Fill up to @p cap bytes of the payload starting at @p offset.
56 *
57 * Called repeatedly with ascending offsets until the declared total is sent. Returning fewer than
58 * @p cap bytes ends the transfer early and fails it, so a source that cannot satisfy a chunk should
59 * return 0 rather than pad.
60 *
61 * @return bytes written into @p buf.
62 */
63typedef size_t (*protocore_ftp_source)(void *ctx, size_t offset, uint8_t *buf, size_t cap);
64
65/** @brief What store takes: target, remote_path, total, ... */
66typedef struct
67{
68 const FtpTarget *target;
69 const char *remote_path;
70 size_t total;
71 protocore_ftp_source src;
72 void *ctx;
73} FtpSessionStoreArgs;
74
75/**
76 * @brief FTP client session driver: the two sockets the ftp.h codec deliberately does not own. ftp.h is pure
77 * bytes-on-the-wire.
78 *
79 * A caller sets the members a call takes, invokes it through ::FtpSession with the bytes it runs
80 * out of, and reads the outcome off the same handle.
81 *
82 * FtpSession.store_args.target = ...;
83 * FtpSession.store_args.remote_path = ...;
84 * FtpSession.store_args.total = ...;
85 * FtpSession.store_args.src = ...;
86 * FtpSession.store_args.ctx = ...;
87 * FtpSession.store(work);
88 * // FtpSession.value is what the call reports
89 *
90 * @var FtpSessionNs::store_args what store takes: target, remote_path, total,
91 * @var FtpSessionNs::ok a call's true/false outcome
92 * @var FtpSessionNs::value ::PROTOCORE_FTP_READY only if the server confirmed the completed ...
93 * @var FtpSessionNs::store upload total bytes pulled from src to remote_path (RFC 959 STOR). ...
94 *
95 * @c work is PROTOCORE_FTP_SESSION_BORROW bytes the CALLER took, at an address it knows. It is not held past the call,
96 * so nothing here aliases it. How those bytes are carved is this module's and is never named here.
97 */
98typedef struct
99{
100 FtpSessionStoreArgs store_args;
101 proto_bool ok;
102 protocore_ftp_state value;
103} FtpSessionVars;
104
105/** @brief The operands and the outcome. */
106extern FtpSessionVars FtpSessionV;
107
108/** @brief The entries. */
109typedef struct
110{
111 void (*const store)(uint8_t *work);
112} FtpSessionNs;
113
114// What the table binds, defined once in the .c and taking one parameter each: everything
115// else an entry needs is an operand in FtpSessionV or a region of the borrow at a fixed offset.
116void protocore_ftp_session_store(uint8_t *work);
117
118// `static const`, initialised HERE rather than `extern` against a definition in the .c: a
119// const object whose initializer every translation unit can see is a COMPILE-TIME FACT, so
120// `FtpSession.store(work)` resolves to a named function and becomes a DIRECT call. An extern table
121// leaves the call indirect and the symbol live at every level, -O2 -flto included.
122static const FtpSessionNs FtpSession __attribute__((unused)) = {
123 .store = protocore_ftp_session_store,
124};
125
126/**
127 * @brief The PROTOCORE_FTP_SESSION_BORROW bytes this module's state lives in.
128 *
129 * Stated beside the namespace rather than on it: an entry takes a borrow, and this is where
130 * that borrow comes from. Taken once from the end of the pool, which no mark and no release
131 * walks, so the state lasts the life of the program.
132 *
133 * @return the span.
134 */
135uint8_t *protocore_ftp_session_span(void);
136
138
139#endif // PROTOCORE_ENABLE_FTP_SESSION
140
141#endif // PROTOCORE_FTP_SESSION_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
#define PROTOCORE_BEGIN_DECLS
Give a header's declarations C linkage, so their symbol names carry no parameter types.
Definition types.h:96
_Bool proto_bool
The truth value.
Definition types.h:64
#define PROTOCORE_END_DECLS
Definition types.h:97