13inline uint64_t
bitReverse(uint64_t value,
unsigned bits) {
16 out = (out << 1) | (value & 1);
23inline uint64_t
bitWindow(uint64_t value,
unsigned offset,
unsigned bits) {
24 uint64_t mask = (bits >= 64) ? ~0ULL : ((1ULL << bits) - 1);
25 return (value >> offset) & mask;
38 virtual int encode(uint32_t words[2], uint8_t ch) {
43 virtual size_t decode(Print& out, uint64_t bits,
unsigned n_bits) = 0;
49 size_t decode(Print& out, uint64_t bits,
unsigned )
override {
50 return out.write((uint8_t)(bits & 0xFF));
57 size_t decode(Print& out, uint64_t bits,
unsigned n_bits)
override {
58 for (
unsigned j = 0; j < n_bits; j++) out.write((bits >> j & 1) +
'0');
76 int encode(uint32_t words[2], uint8_t ch)
override {
78 if (ch >= 0x60)
return 0;
81 if ((
charset & charset_mask) == 0) {
82 if (charset_mask == 0)
return 0;
84 if (charset_mask != 3)
charset = charset_mask;
93 size_t decode(Print& out, uint64_t bits,
unsigned )
override {
94 uint8_t databits = bits & 0x1F;
95 if (databits ==
FIGS) {
99 if (databits ==
LTRS) {
110 static constexpr uint8_t
LTRS = 0x1F;
111 static constexpr uint8_t
FIGS = 0x1B;
112 static constexpr uint8_t
SPACE = 0x04;
119 static const char table[32][3] = {
120 {
'_',
'^',
'^'}, {
'E',
'3',
'3'}, {0xA, 0xA, 0xA},
121 {
'A',
'-',
'-'}, {
' ',
' ',
' '}, {
'S', 0x7,
'\''},
122 {
'I',
'8',
'8'}, {
'U',
'7',
'7'}, {0xD, 0xD, 0xD},
123 {
'D',
'$',
'^'}, {
'R',
'4',
'4'}, {
'J',
'\'', 0x7},
124 {
'N',
',',
','}, {
'F',
'!',
'!'}, {
'C',
':',
':'},
125 {
'K',
'(',
'('}, {
'T',
'5',
'5'}, {
'Z',
'"',
'+'},
126 {
'L',
')',
')'}, {
'W',
'2',
'2'}, {
'H',
'#',
'%'},
127 {
'Y',
'6',
'6'}, {
'P',
'0',
'0'}, {
'Q',
'1',
'1'},
128 {
'O',
'9',
'9'}, {
'B',
'?',
'?'}, {
'G',
'&',
'&'},
129 {
'%',
'%',
'%'}, {
'M',
'.',
'.'}, {
'X',
'/',
'/'},
130 {
'V',
';',
'='}, {
'%',
'%',
'%'},
137 static const uint8_t table[0x60][2] = {
139 {0x00, 3}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
140 {0x05, 2}, {0, 0}, {0, 0}, {0x02, 3}, {0, 0}, {0, 0}, {0x08, 3},
143 {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
144 {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
146 {0x04, 3}, {0x0d, 2}, {0x11, 2}, {0x14, 2}, {0x09, 2}, {0, 0},
147 {0x1a, 2}, {0x0b, 2}, {0x0f, 2}, {0x12, 2}, {0, 0}, {0x12, 2},
148 {0x0c, 2}, {0x03, 2}, {0x1c, 2}, {0x1d, 2},
150 {0x16, 2}, {0x17, 2}, {0x13, 2}, {0x01, 2}, {0x0a, 2}, {0x10, 2},
151 {0x15, 2}, {0x07, 2}, {0x06, 2}, {0x18, 2}, {0x0e, 2}, {0x1e, 2},
152 {0, 0}, {0, 0}, {0, 0}, {0x19, 2},
154 {0, 0}, {0x03, 1}, {0x19, 1}, {0x0e, 1}, {0x09, 1}, {0x01, 1},
155 {0x0d, 1}, {0x1a, 1}, {0x14, 1}, {0x06, 1}, {0x0b, 1}, {0x0f, 1},
156 {0x12, 1}, {0x1c, 1}, {0x0c, 1}, {0x18, 1},
158 {0x16, 1}, {0x17, 1}, {0x0a, 1}, {0x05, 1}, {0x10, 1}, {0x07, 1},
159 {0x1e, 1}, {0x13, 1}, {0x1d, 1}, {0x15, 1}, {0x11, 1}, {0, 0},
160 {0, 0}, {0, 0}, {0, 0}, {0, 0},
178 size_t decode(Print& out, uint64_t bits,
unsigned )
override {
193 unsigned msglen =
buf[1];
194 if (
ndata < msglen + 2)
return 0;
196 size_t n = out.print(
"CALLER-ID\n");
215 static const char* names[] = {
"unknown0:",
"Time:",
"Phone:",
216 "unknown3:",
"Phone:",
"unknown5:",
217 "unknown6:",
"Name:",
"Name:"};
221 static size_t printFmt(Print& out,
const char* fmt, ...) {
225 vsnprintf(tmp,
sizeof(tmp), fmt, args);
227 return out.print(tmp);
231 return printFmt(out,
"%.3s-%.3s-%.4s\n", m, m + 3, m + 6);
235 return printFmt(out,
"%.2s/%.2s %.2s:%.2s\n", m, m + 2, m + 4, m + 6);
241 unsigned msglen =
buf[1];
242 const uint8_t* m =
buf + 2;
244 unsigned type = *m++;
247 if (m + 2 + len >=
buf +
sizeof(
buf))
return n;
249 const char* prdata =
nullptr;
262 prdata = (
const char*)m;
267 if (len == 1 && *m ==
'O') {
270 }
else if (len == 1 && *m ==
'P') {
271 prdata =
"[blocked]";
279 n += out.write((
const uint8_t*)prdata, prlen);
280 n += out.write(
'\n');
290 unsigned msglen =
buf[1];
291 const uint8_t* m =
buf + 2;
294 if (msglen < 8)
return n;
297 unsigned len = msglen - 8;
301 n += out.write(m, len);
302 n += out.write(
'\n');
314 size_t decode(Print& out, uint64_t input,
unsigned )
override {
317 snprintf(tmp,
sizeof(tmp),
318 "Train ID: %X%X%X%X%X%X - Message: %02X (%s)\n",
323 return out.print(tmp);
336 static const Message ground_to_train[] = {
337 {0x00,
"Test"}, {0x02,
"Run slower"},
338 {0x03,
"Extension of telegram"},
339 {0x04,
"Run faster"}, {0x06,
"Written order"},
340 {0x08,
"Speech"}, {0x09,
"Emergency stop"},
341 {0x0C,
"Announcem. by loudspeaker"},
342 {0x55,
"Idle"}, {-1,
nullptr}};
343 static const Message train_to_ground[] = {
344 {0x08,
"Communic. desired"},
345 {0x0A,
"Acknowl. of order"},
348 {0x09,
"Train staff wish to comm."},
349 {0x0C,
"Telephone link desired"},
350 {0x03,
"Extension of telegram"},
352 for (
const Message* m =
train ? train_to_ground : ground_to_train;
353 m->
code != -1; m++) {
354 if (m->code == (
int)code)
return m->meaning;
365 if (
p_out ==
nullptr)
return 0;
366 return p_out->write(isprint(ch) || isspace(ch) ? ch :
'.');
368 size_t write(
const uint8_t* data,
size_t len)
override {
369 for (
size_t j = 0; j < len; j++)
write(data[j]);
ASCII 8-bit data (passthrough).
Definition DataCodecs.h:47
size_t decode(Print &out, uint64_t bits, unsigned) override
Decodes the data bits of a frame: returns the number of written bytes.
Definition DataCodecs.h:49
Baudot (ITA2) 5-bit data.
Definition DataCodecs.h:65
static constexpr uint8_t FIGS
Definition DataCodecs.h:111
static const char * decodeTable(uint8_t idx)
letter, U.S. figs, CCITT No.2 figs (Europe)
Definition DataCodecs.h:118
void resetShift()
Definition DataCodecs.h:74
bool usos
Definition DataCodecs.h:115
int encode(uint32_t words[2], uint8_t ch) override
Converts a character into 0, 1 or 2 data words: returns the count.
Definition DataCodecs.h:76
static const uint8_t * encodeTable(uint8_t idx)
index: ascii char; values: bits, ltrs(1) or figs(2) or both(3)
Definition DataCodecs.h:136
void setUSOS(bool usos)
Unshift on space.
Definition DataCodecs.h:68
void reset() override
resets the internal state (called when the carrier is acquired)
Definition DataCodecs.h:70
static constexpr uint8_t SPACE
Definition DataCodecs.h:112
static constexpr uint8_t LTRS
Definition DataCodecs.h:110
unsigned charset
0 unknown, 1 LTRS, 2 FIGS
Definition DataCodecs.h:114
size_t decode(Print &out, uint64_t bits, unsigned) override
Decodes the data bits of a frame: returns the number of written bytes.
Definition DataCodecs.h:93
Raw N-bit binary data: prints the bits as '0' and '1' followed by newline.
Definition DataCodecs.h:55
size_t decode(Print &out, uint64_t bits, unsigned n_bits) override
Decodes the data bits of a frame: returns the number of written bytes.
Definition DataCodecs.h:57
Caller-ID (USA SDMF/MDMF) decoder. See http://melabs.com/resources/callerid.htm.
Definition DataCodecs.h:171
static constexpr uint8_t DATA_DATETIME
Definition DataCodecs.h:205
static size_t printPhone(Print &out, const uint8_t *m)
Definition DataCodecs.h:230
static constexpr uint8_t DATA_NAME_NA
Definition DataCodecs.h:209
unsigned ndata
Definition DataCodecs.h:211
static size_t printFmt(Print &out, const char *fmt,...)
Definition DataCodecs.h:221
size_t decodeSDMF(Print &out)
Definition DataCodecs.h:288
static constexpr uint8_t MSG_MDMF
Definition DataCodecs.h:203
static constexpr uint8_t DATA_PHONE
Definition DataCodecs.h:206
static size_t printDateTime(Print &out, const uint8_t *m)
Definition DataCodecs.h:234
unsigned msg_type
Definition DataCodecs.h:210
size_t decodeMDMF(Print &out)
Definition DataCodecs.h:238
static constexpr uint8_t DATA_PHONE_NA
Definition DataCodecs.h:207
size_t decode(Print &out, uint64_t bits, unsigned) override
Decodes the data bits of a frame: returns the number of written bytes.
Definition DataCodecs.h:178
static constexpr uint8_t DATA_NAME
Definition DataCodecs.h:208
static const char * typeName(unsigned type)
Definition DataCodecs.h:214
static constexpr uint8_t MSG_SDMF
Definition DataCodecs.h:204
uint8_t buf[256]
Definition DataCodecs.h:212
void reset() override
resets the internal state (called when the carrier is acquired)
Definition DataCodecs.h:173
Converts between characters and the data bits of a frame.
Definition DataCodecs.h:32
virtual size_t decode(Print &out, uint64_t bits, unsigned n_bits)=0
Decodes the data bits of a frame: returns the number of written bytes.
virtual int encode(uint32_t words[2], uint8_t ch)
Converts a character into 0, 1 or 2 data words: returns the count.
Definition DataCodecs.h:38
virtual ~DataCodec()=default
virtual void reset()
resets the internal state (called when the carrier is acquired)
Definition DataCodecs.h:36
Print which replaces non printable characters with '.'.
Definition DataCodecs.h:361
void setOutput(Print *out)
Definition DataCodecs.h:363
size_t write(const uint8_t *data, size_t len) override
Definition DataCodecs.h:368
size_t write(uint8_t ch) override
Definition DataCodecs.h:364
Print * p_out
Definition DataCodecs.h:374
const char * meaning(unsigned code)
Definition DataCodecs.h:335
void setTrainToGround(bool flag)
Definition DataCodecs.h:312
size_t decode(Print &out, uint64_t input, unsigned) override
Decodes the data bits of a frame: returns the number of written bytes.
Definition DataCodecs.h:314
UICCodec(bool trainToGround=false)
Definition DataCodecs.h:311
bool train
Definition DataCodecs.h:327
TinyModem: software audio modems and packets with error correction.
Definition AX25.h:11
uint64_t bitReverse(uint64_t value, unsigned bits)
Reverses the ordering of the bits on an integer.
Definition DataCodecs.h:13
uint64_t bitWindow(uint64_t value, unsigned offset, unsigned bits)
Gets "bits" bits from "value" starting "offset" bits from the start.
Definition DataCodecs.h:23
UIC message code and its meaning.
Definition DataCodecs.h:330
int code
Definition DataCodecs.h:331
const char * meaning
Definition DataCodecs.h:332