ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
scp.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#ifndef PROTOCORE_SCP_H
5#define PROTOCORE_SCP_H
6
7#include "protocore_config.h" // the entry point: protocore_types.h for the widths
8
10
11/**
12 * @file scp.h
13 * @brief SCP (RCP) protocol wire codec - the pure, host-testable half of the SCP-over-SSH server
14(PROTOCORE_ENABLE_SSH_SCP).
15 *
16 * SCP transfers a file over an SSH `exec "scp …"` channel using the old rcp line protocol: the source side
17 * sends a control line `C<mode> <size> <name>\n`, the peer acks with a 0 byte, then the file bytes flow,
18 * ended by a 0 byte and another ack. This file parses/builds the command line and the control line and knows
19 * the ack bytes - no filesystem, no SSH, no Arduino, zero heap. The fs::FS sink/source state machine + the
20 * channel glue live in network_drivers/session/scp/ssh_scp.
21 *
22 * @c work is bytes the CALLER holds. This module reads none of them: it carries nothing
23 * between calls, so there is no state to keep and nothing to wipe. The parameter is there so
24 * a caller drives every namespace the same way.
25 *
26 * @author Douglas Quigg (dstroy0)
27 * @date 2026
28 */
29
30// PROTOCORE_SCP_BORROW - the bytes this module runs out of - is stated in protocore_config.h, which sums
31// it into its arena. Its size and its offset are each a static_assert, so a feature
32// combination that does not fit fails to compile rather than overrunning at run time.
33
34// rcp acknowledgement bytes (sent between records).
35#define PROTOCORE_SCP_ACK_OK 0 ///< proceed
36#define PROTOCORE_SCP_ACK_WARN 1 ///< warning: followed by a message + '\n'
37#define PROTOCORE_SCP_ACK_ERROR 2 ///< fatal error: followed by a message + '\n'
38
39/** @brief The role of an `scp` invocation, parsed from the exec command. */
41{
43 SCP_MODE_SINK, ///< `scp -t <path>`: the client sends a file TO the device (device receives)
44 SCP_MODE_SOURCE ///< `scp -f <path>`: the client fetches a file FROM the device (device sends)
46
47/** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */
48typedef struct
49{
50 ScpMode (*parse_cmd)(uint8_t *, const char *, size_t, char *, size_t);
51 proto_bool (*parse_cline)(uint8_t *, const char *, size_t, uint32_t *, uint64_t *, char *, size_t);
52 size_t (*build_cline)(uint8_t *, uint32_t, uint64_t, const char *, char *, size_t);
53} ScpNs;
54PROTOCORE_NS_LAYOUT(ScpNs, parse_cmd, parse_cline, build_cline);
55
56/**
57 * @brief Parse an exec command `scp [-v] [-r] [-p] [-d] -t|-f <path>` into .
58 * @param work PROTOCORE_SCP_BORROW bytes the caller took. Not held past the call.
59 * @param cmd not NUL-terminated (cmd_len bytes). the mode; path_out gets the (NUL-terminated) target,
60 * @param cmd_len Cmd len
61 * @param path_out Path out
62 * @param path_cap Path cap
63 * @return The ScpMode.
64 */
65ScpMode protocore_scp_parse_cmd(uint8_t *work, const char *cmd, size_t cmd_len, char *path_out, size_t path_cap);
66/**
67 * @brief Parse a control line `C<mode> <size> <name>` (a trailing '\n' .
68 * @param work PROTOCORE_SCP_BORROW bytes the caller took. Not held past the call.
69 * @param line Line
70 * @param len Len
71 * @param mode_out Mode out
72 * @param size_out Size out
73 * @param name_out Name out
74 * @param name_cap Name cap
75 * @return PROTO_TRUE on success.
76 */
77proto_bool protocore_scp_parse_cline(uint8_t *work, const char *line, size_t len, uint32_t *mode_out,
78 uint64_t *size_out, char *name_out, size_t name_cap);
79/**
80 * @brief Build a control line `C<mode> <size> <name>\n` for a source .
81 * @param work PROTOCORE_SCP_BORROW bytes the caller took. Not held past the call.
82 * @param mode Mode
83 * @param size Size
84 * @param name Name
85 * @param out Out
86 * @param cap Cap
87 * @return The size_t.
88 */
89size_t protocore_scp_build_cline(uint8_t *work, uint32_t mode, uint64_t size, const char *name, char *out, size_t cap);
90
91/** @brief Module namespace. */
95
97
98#endif // PROTOCORE_SCP_H
PROTO_ENUM_PACKED
Application protocol spoken on a listener port or connection slot.
#define PROTOCORE_NS_LAYOUT(T,...)
Pin every dispatch slot of a table that is nothing but function pointers.
#define PROTOCORE_NS
Storage for a dispatch table. The const is load bearing.
enum PROTO_ENUM_PACKED ScpMode
The role of an scp invocation, parsed from the exec command.
proto_bool protocore_scp_parse_cline(uint8_t *work, const char *line, size_t len, uint32_t *mode_out, uint64_t *size_out, char *name_out, size_t name_cap)
Parse a control line C<mode> <size> <name> (a trailing ' ' .
size_t protocore_scp_build_cline(uint8_t *work, uint32_t mode, uint64_t size, const char *name, char *out, size_t cap)
Build a control line C<mode> <size> <name>\n for a source .
ScpMode protocore_scp_parse_cmd(uint8_t *work, const char *cmd, size_t cmd_len, char *path_out, size_t path_cap)
Parse an exec command scp [-v] [-r] [-p] [-d] -t|-f <path> into .
@ SCP_MODE_SINK
scp -t <path>: the client sends a file TO the device (device receives)
Definition scp.h:43
@ SCP_MODE_SOURCE
scp -f <path>: the client fetches a file FROM the device (device sends)
Definition scp.h:44
@ SCP_MODE_INVALID
Definition scp.h:42
PROTOCORE_NS ScpNs Scp PROTOCORE_UNUSED
Module namespace.
Definition scp.h:92
Dispatch table. Addressed by offset, so the layout is asserted below.
Definition scp.h:49
ScpMode(* parse_cmd)(uint8_t *, const char *, size_t, char *, size_t)
Definition scp.h:50
#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