summaryrefslogtreecommitdiff
path: root/include/hybbx/circuit.h
blob: c732602aa5f244f052ab5ea6a1f2a9efed858188 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef HYBBX_CIRCUIT_H
#define HYBBX_CIRCUIT_H

/**
 * HBX — Hybrid Bridge eXchange (v1).
 *
 * HyBBX internal framed protocol on the circuit TCP hub. Multiplexes
 * link-layer payloads (AX.25 and future stacks) and application streams
 * (terminal, proxymail, proxychat) between HyBBX processes. Header magic:
 * `H` `B` `X`. Transport is internal TCP/IPv4+IPv6 only — the application
 * core never sees KISS, AX.25 on-air framing, or serial.
 *
 * Short form in docs: **HBX** or **HBX/Circuit** — Circuit = TCP hub
 * (:7323), HBX = framing on top.
 */

#include "hybbx/ax25.h"
#include "hybbx/types.h"

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define HYBBX_CIRCUIT_MAGIC_0 'H'
#define HYBBX_CIRCUIT_MAGIC_1 'B'
#define HYBBX_CIRCUIT_MAGIC_2 'X'
#define HYBBX_CIRCUIT_VERSION  0x01u

#define HYBBX_CIRCUIT_HEADER_SIZE 12u
#define HYBBX_CIRCUIT_MAX_PAYLOAD 4096u
#define HYBBX_CIRCUIT_MAX_FRAME (HYBBX_CIRCUIT_HEADER_SIZE + HYBBX_CIRCUIT_MAX_PAYLOAD)

/** Default internal circuit TCP port (loopback). */
#define HYBBX_CIRCUIT_DEFAULT_PORT 7323u

/**
 * Protocol identifiers — extensible for future link stacks.
 * Values 0x01..0x7F: link-layer payloads; 0x80..0xFF: application streams.
 */
typedef enum hybbx_circuit_proto {
    HYBBX_CIRCUIT_PROTO_AX25 = 0x01,       /**< Raw AX.25 frame incl. FCS */
    HYBBX_CIRCUIT_PROTO_AX25_UI = 0x02,      /**< Masked UI: path + payload */
    HYBBX_CIRCUIT_PROTO_LINK_AUTH = 0x03,    /**< Edge link password auth (no ping) */
    HYBBX_CIRCUIT_PROTO_LINK_AUTH_ACK = 0x04,/**< Central auth response */
    HYBBX_CIRCUIT_PROTO_FLOW_CTRL = 0x05,    /**< Load-balance pause/break/cancel */
    HYBBX_CIRCUIT_PROTO_TERMINAL = 0x10,     /**< BBX / terminal byte stream */
    HYBBX_CIRCUIT_PROTO_PROXY_MAIL = 0x80,   /**< Inter-Main proxymail (service only) */
    HYBBX_CIRCUIT_PROTO_PROXY_CHAT = 0x81,   /**< Inter-Main proxychat (service only) */
    HYBBX_CIRCUIT_PROTO_RESERVED_APRS = 0x20,
    HYBBX_CIRCUIT_PROTO_RESERVED_NETROM = 0x21
} hybbx_circuit_proto_t;

typedef enum hybbx_circuit_flags {
    HYBBX_CIRCUIT_FLAG_NONE = 0x0000,
    HYBBX_CIRCUIT_FLAG_RX = 0x0001,        /**< Frame originated on RF RX */
    HYBBX_CIRCUIT_FLAG_TX = 0x0002,        /**< Frame destined for RF TX */
    HYBBX_CIRCUIT_FLAG_PATH = 0x0004,       /**< AX.25_UI payload carries path */
    HYBBX_CIRCUIT_FLAG_G3RUH_FSK = 0x0008  /**< G3RUH 9600 FSK on-air (vs AFSK) */
} hybbx_circuit_flags_t;

typedef void (*hybbx_circuit_frame_cb)(hybbx_circuit_proto_t proto,
                                       uint16_t flags,
                                       const uint8_t *payload, size_t len,
                                       void *userdata);

typedef struct hybbx_circuit_decoder {
    uint8_t buf[HYBBX_CIRCUIT_MAX_FRAME];
    size_t len;
    size_t need;
    int have_header;
    hybbx_circuit_proto_t proto;
    uint16_t flags;
} hybbx_circuit_decoder_t;

void hybbx_circuit_decoder_init(hybbx_circuit_decoder_t *dec);

void hybbx_circuit_decoder_feed(hybbx_circuit_decoder_t *dec,
                                const uint8_t *data, size_t len,
                                hybbx_circuit_frame_cb cb, void *userdata);

size_t hybbx_circuit_encode(hybbx_circuit_proto_t proto, uint16_t flags,
                            const uint8_t *payload, size_t payload_len,
                            uint8_t *out, size_t out_cap);

size_t hybbx_circuit_encode_ax25(const uint8_t *frame, size_t frame_len,
                                 uint16_t flags,
                                 uint8_t *out, size_t out_cap);

size_t hybbx_circuit_encode_ax25_ui(const hybbx_ax25_path_t *path,
                                    const uint8_t *payload, size_t payload_len,
                                    uint16_t flags,
                                    uint8_t *out, size_t out_cap);

size_t hybbx_circuit_encode_terminal(const char *data, size_t len,
                                     uint8_t *out, size_t out_cap);

/** Encode LINK_AUTH or LINK_AUTH_ACK line-oriented payload. */
size_t hybbx_circuit_encode_link_msg(hybbx_circuit_proto_t proto,
                                   const char *payload, size_t payload_len,
                                   uint8_t *out, size_t out_cap);

/**
 * Unpack AX.25_UI masked payload into path + UI bytes.
 * @return UI payload length or 0 on error.
 */
size_t hybbx_circuit_unpack_ax25_ui(const uint8_t *payload, size_t payload_len,
                                    hybbx_ax25_path_t *path,
                                    uint8_t *ui, size_t ui_cap);

const char *hybbx_circuit_proto_name(hybbx_circuit_proto_t proto);

#ifdef __cplusplus
}
#endif

#endif /* HYBBX_CIRCUIT_H */
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com