39     if (act == NULL || out == NULL || len == NULL) { 
return false; }
 
   41     (*out) = calloc(5 + act->
length + 2 * act->
datalen, 
sizeof(uint8_t));
 
   51     (*out)[5] = (act->
PGN & 0x0000FF);
 
   52     (*out)[6] = (act->
PGN & 0x00FF00) >> 8;
 
   53     (*out)[7] = (act->
PGN & 0xFF0000) >> 16;
 
   57     (*out)[10] = (act->
timestamp & 0x000000FF);
 
   58     (*out)[11] = (act->
timestamp & 0x0000FF00) >> 8;
 
   59     (*out)[12] = (act->
timestamp & 0x00FF0000) >> 16;
 
   60     (*out)[13] = (act->
timestamp & 0xFF000000) >> 24;
 
   63     for (
int i = 0; i < act->
datalen; i++) {
 
   64         (*out)[ix++] = act->
data[i];
 
   70     (*out)[ix++] = act->
csum;
 
   74     uint8_t *o = realloc((*out), ix * 
sizeof(uint8_t));
 
   99     if (in == NULL || msg == NULL || len < 18 || pos == NULL) { 
return NULL; }
 
  102     while (((*pos) + 18) < len) {
 
  116         if (debug) { fprintf(stderr, 
"N2K: No start marker found\n"); }
 
  119     if ((len - start) < in[start + 3]) {
 
  122         if (debug) { fprintf(stderr, 
"N2K: Insufficient data\n"); }
 
  127     if ((*msg) == NULL) {
 
  128         perror(
"n2k_act_from_bytes");
 
  132     (*msg)->length = in[start + 3];
 
  133     (*msg)->priority = in[start + 4];
 
  134     (*msg)->PGN = in[start + 5] + ((uint32_t)in[start + 6] << 8) + ((uint32_t)in[start + 7] << 16);
 
  138     (*msg)->dst = in[start + 8];
 
  139     (*msg)->src = in[start + 9];
 
  143     (*msg)->timestamp = in[start + 10] + ((uint32_t)in[start + 11] << 8) + ((uint32_t)in[start + 12] << 16) +
 
  144                         ((uint32_t)in[start + 13] << 24);
 
  145     (*msg)->datalen = in[start + 14];
 
  147     volatile ssize_t remaining = len - start - 15;
 
  148     if (remaining <= ((*msg)->datalen + 3)) { 
 
  153         if (debug) { fprintf(stderr, 
"N2K: Insufficient data to read in message content\n"); }
 
  157     (*msg)->data = calloc((*msg)->datalen, 
sizeof(uint8_t));
 
  158     if ((*msg)->data == NULL) {
 
  159         perror(
"n2k_act_from_bytes:data-calloc");
 
  167     for (
int i = 0; i < (*msg)->datalen; i++) {
 
  168         uint8_t c = in[(start + off++)];
 
  171             uint8_t next = in[(start + off++)];
 
  177                 (*pos) = (start + off);
 
  181                 if (debug) { fprintf(stderr, 
"N2K: Premature Termination\n"); }
 
  186                 (*pos) = (start + off - 2);
 
  190                 if (debug) { fprintf(stderr, 
"N2K: Unexpected start of message marker\n"); }
 
  194                 (*pos) = (start + off);
 
  199                     fprintf(stderr, 
"N2K: Bad character escape sequence (ESC + 0x%02x\n", next);
 
  207         if (remaining < ((*msg)->datalen - i + 3)) {
 
  211             if (debug) { fprintf(stderr, 
"N2K: Out of data while parsing\n"); }
 
  216     (*msg)->csum = in[(start + off++)];
 
  218     uint8_t ee = in[(start + off++)];
 
  219     uint8_t et = in[(start + off++)];
 
  221         if (et == 
ACT_ESC && (ssize_t)(start + off) < remaining) {
 
  222             uint8_t next = in[(start + off)];
 
  227                 fprintf(stderr, 
"Unexpected sequence at end of message: 0x%02x 0x%02x\n", ee, et);
 
  232     (*pos) = start + off;
 
  235     if ((*msg)->csum != cs) {
 
  237             fprintf(stderr, 
"Bad checksum (%d => %d\tPGN %d)\n", (*msg)->src, (*msg)->dst, (*msg)->PGN);
 
  252     csum += (msg->
PGN & 0x0000FF);
 
  253     csum += ((msg->
PGN & 0x00FF00) >> 8);
 
  254     csum += ((msg->
PGN & 0xFF0000) >> 16);
 
  258     csum += ((msg->
timestamp & 0x0000FF00) >> 8);
 
  259     csum += ((msg->
timestamp & 0x00FF0000) >> 16);
 
  260     csum += ((msg->
timestamp & 0xFF000000) >> 24);
 
  263     for (
int i = 0; i < msg->
datalen; ++i) {
 
  264         csum += msg->
data[i];
 
  279         fprintf(stdout, 
"N2k ACT Message: ");
 
  280         for (
unsigned int j = 0; j < len; ++j) {
 
  281             fprintf(stdout, 
"%c%02x", j > 0 ? 
':' : 
' ', tmp[j]);
 
  283         fprintf(stdout, 
"\n");
 
  285         fprintf(stdout, 
"N2k ACT Message: [Byte conversion failed]\n");
 
#define ACT_N2K
N2k Message.
 
#define ACT_ESC
Escape character.
 
bool n2k_act_from_bytes(const uint8_t *in, const size_t len, n2k_act_message **msg, size_t *pos, bool debug)
Convert a series of recieved bytes from ACT gateway devices into a message representation.
 
void n2k_act_print(const n2k_act_message *msg)
Print representation of an n2k_act_message to standard output.
 
uint8_t n2k_act_checksum(const n2k_act_message *msg)
Calculate checksum for n2k_act_message.
 
bool n2k_act_to_bytes(const n2k_act_message *act, uint8_t **out, size_t *len)
Convert N2K message to a series of bytes compatible with ACT gateway devices.
 
#define ACT_EOT
End of text.
 
#define ACT_SOT
Start of text.
 
uint8_t priority
N2K Message priority value.
 
uint32_t PGN
24 bit PGN identifier
 
uint8_t * data
Message payload.
 
uint8_t datalen
Length of *data.
 
uint8_t dst
Message destination.
 
uint32_t timestamp
Message timestamp.
 
uint8_t src
Message source.
 
uint8_t length
Counted from priority to csum.