Hahahahahalol I don't even need to calculate an FCS here!

This commit is contained in:
XANTRONIX Development 2015-07-17 20:14:48 -05:00
parent b6f34b8dc4
commit 460bbeea54
2 changed files with 40 additions and 72 deletions

View file

@ -51,12 +51,13 @@ typedef struct _patty_ax25_frame {
enum patty_ax25_frame_type type; enum patty_ax25_frame_type type;
void * payload; uint8_t control;
size_t len; uint8_t proto;
uint8_t control; void * payload;
uint8_t proto; size_t payloadsz;
uint16_t fcs;
size_t size;
} patty_ax25_frame; } patty_ax25_frame;
int patty_ax25_frame_decode(patty_ax25_frame *frame, void *data, size_t len); int patty_ax25_frame_decode(patty_ax25_frame *frame, void *data, size_t len);

View file

@ -4,62 +4,18 @@
#include <patty/ax25.h> #include <patty/ax25.h>
uint16_t fcs_table[256] = { #include "byteorder.h"
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
static inline uint16_t fcs_compute(uint8_t *data, size_t len) {
uint16_t fcs = 0xffff;
while (len--) {
fcs = (fcs >> 8) ^ fcs_table[(fcs ^ ((uint16_t)*data)) & 0x00ff];
data++;
}
return fcs;
}
static ssize_t frame_decode_address(patty_ax25_address *address, void *data, off_t offset) { static ssize_t frame_decode_address(patty_ax25_address *address, void *data, off_t offset) {
int i, space = 0; int i, space = 0;
uint8_t ssid = (((uint8_t *)data) + offset)[6]; uint8_t ssid = ((uint8_t *)data + offset)[6];
/* /*
* First, unpack each callsign octet, ensuring all are within the 7 bit * First, unpack each callsign octet, ensuring all are within the 7 bit
* ASCII space and do not have the extended bit set to 1. * ASCII space and do not have the extended bit set to 1.
*/ */
for (i=0; i<6; i++) { for (i=0; i<6; i++) {
uint8_t b = (((uint8_t *)data) + offset)[i]; uint8_t b = ((uint8_t *)data + offset)[i];
uint8_t c = b >> 1; uint8_t c = b >> 1;
if (!PATTY_AX25_ADDRESS_CHAR_VALID(c) || PATTY_AX25_ADDRESS_OCTET_LAST(b)) { if (!PATTY_AX25_ADDRESS_CHAR_VALID(c) || PATTY_AX25_ADDRESS_OCTET_LAST(b)) {
@ -148,31 +104,27 @@ error:
return -1; return -1;
} }
static ssize_t frame_decode_payload(patty_ax25_frame *frame, void *data, off_t offset) { static ssize_t frame_decode_control(patty_ax25_frame *frame, void *data, off_t offset) {
uint8_t control = ((uint8_t *)data)[0]; uint8_t control = ((uint8_t *)data + offset)[0];
size_t decoded = 0; size_t decoded = 0;
/* int info = 0;
* First, decode the control byte.
*/
frame->control = control; frame->control = control;
decoded++; decoded++;
if (PATTY_AX25_CONTROL_INFO(control)) { if (PATTY_AX25_CONTROL_INFO(control)) {
frame->type = PATTY_AX25_FRAME_INFO; frame->type = PATTY_AX25_FRAME_INFO;
frame->proto = ((uint8_t *)data)[1];
decoded++; info = 1;
} else if (PATTY_AX25_CONTROL_SUPER(control)) { } else if (PATTY_AX25_CONTROL_SUPER(control)) {
frame->type = PATTY_AX25_FRAME_SUPER; frame->type = PATTY_AX25_FRAME_SUPER;
} else if (PATTY_AX25_CONTROL_UNNUMBERED(control)) { } else if (PATTY_AX25_CONTROL_UNNUMBERED(control)) {
frame->type = PATTY_AX25_FRAME_UNNUMBERED; frame->type = PATTY_AX25_FRAME_UNNUMBERED;
if (PATTY_AX25_CONTROL_UNNUMBERED_INFO(control)) { if (PATTY_AX25_CONTROL_UNNUMBERED_INFO(control)) {
frame->proto = ((uint8_t *)data)[1]; info = 1;
decoded++;
} }
} else { } else {
frame->type = PATTY_AX25_FRAME_UNKNOWN; frame->type = PATTY_AX25_FRAME_UNKNOWN;
@ -182,7 +134,20 @@ static ssize_t frame_decode_payload(patty_ax25_frame *frame, void *data, off_t o
goto error; goto error;
} }
fprintf(stderr, "Decoded %lu bytes\n", decoded); /*
* If we've received either an Info or Unnumbered Info frame, then decode
* the Protocol Identifier field, and calculate the location and size of
* the payload as well.
*/
if (info) {
decoded++;
frame->proto = ((uint8_t *)data + offset)[1];
frame->payload = (void *)((uint8_t *)data + offset + decoded);
frame->payloadsz = frame->size - offset - decoded;
decoded += frame->payloadsz;
}
return decoded; return decoded;
@ -190,12 +155,14 @@ error:
return -1; return -1;
} }
int patty_ax25_frame_decode(patty_ax25_frame *frame, void *data, size_t len) { int patty_ax25_frame_decode(patty_ax25_frame *frame, void *data, size_t size) {
ssize_t decoded; ssize_t decoded;
off_t offset = 0; off_t offset = 0;
memset(frame, '\0', sizeof(*frame)); memset(frame, '\0', sizeof(*frame));
frame->size = size;
if ((decoded = frame_decode_address(&frame->dest, data, offset)) < 0) { if ((decoded = frame_decode_address(&frame->dest, data, offset)) < 0) {
goto error_decode; goto error_decode;
} else { } else {
@ -213,8 +180,8 @@ int patty_ax25_frame_decode(patty_ax25_frame *frame, void *data, size_t len) {
} }
/* /*
* Now, if the source address is not the final address in the frame, then * If the source address is not the final address in the frame, begin
* begin decoding repeater addresses. * decoding repeater addresses.
*/ */
if (!frame->src.last) { if (!frame->src.last) {
if ((decoded = frame_decode_hops(frame, data, offset)) < 0) { if ((decoded = frame_decode_hops(frame, data, offset)) < 0) {
@ -224,18 +191,18 @@ int patty_ax25_frame_decode(patty_ax25_frame *frame, void *data, size_t len) {
} }
} }
fprintf(stderr, "Decoded %ld/%lu\n", offset, len);
/* /*
* Time to decode the rest of the payload, including control, PID, and * Now, decode the Control Field, as well as any Protocol Identifier that
* Frame Check Sequence. * may follow.
*/ */
if ((decoded = frame_decode_payload(frame, data, offset)) < 0) { if ((decoded = frame_decode_control(frame, data, offset)) < 0) {
goto error_decode; goto error_decode;
} else { } else {
offset += decoded; offset += decoded;
} }
fprintf(stderr, "Decoded %lld/%lu bytes\n", offset, size);
return offset; return offset;
error_decode: error_decode: