SELKIELogger  1.0.0
N2KConnection.c
1 /*
2  * Copyright (C) 2023 Swansea University
3  *
4  * This file is part of the SELKIELogger suite of tools.
5  *
6  * SELKIELogger is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation, either version 3 of the License, or (at your option)
9  * any later version.
10  *
11  * SELKIELogger is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this SELKIELogger product.
18  * If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <errno.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include "N2KConnection.h"
28 
29 #include "SELKIELoggerBase.h"
30 
38 int n2k_openConnection(const char *device, const int baud) {
39  if (device == NULL) { return -1; }
40  return openSerialConnection(device, baud);
41 }
42 
46 void n2k_closeConnection(int handle) {
47  errno = 0;
48  close(handle);
49 }
50 
61 bool n2k_act_readMessage(int handle, n2k_act_message *out) {
62  static uint8_t buf[N2K_BUFF];
63  static size_t index = 0; // Current read position
64  static size_t hw = 0; // Current array end
65  return n2k_act_readMessage_buf(handle, out, buf, &index, &hw);
66 }
67 
85 bool n2k_act_readMessage_buf(int handle, n2k_act_message *out, uint8_t buf[N2K_BUFF], size_t *index, size_t *hw) {
86  int ti = 0;
87  if ((*hw) < N2K_BUFF - 1) {
88  errno = 0;
89  ti = read(handle, &(buf[(*hw)]), N2K_BUFF - (*hw));
90  if (ti >= 0) {
91  (*hw) += ti;
92  } else {
93  if (errno != EAGAIN) {
94  fprintf(stderr, "Unexpected error while reading from serial port (handle ID: 0x%02x)\n",
95  handle);
96  fprintf(stderr, "read returned \"%s\" in readMessage\n", strerror(errno));
97  out->priority = 0xAA;
98  return false;
99  }
100  }
101  }
102  if (((*hw) == N2K_BUFF) && (*index) > 0 && (*index) > ((*hw) - 25)) {
103  // Full buffer, very close to the fill limit
104  // Assume we're full of garbage before index
105  memmove(buf, &(buf[(*index)]), N2K_BUFF - (*index));
106  (*hw) -= (*index);
107  (*index) = 0;
108  out->priority = 0xFF;
109  if (ti == 0) { out->priority = 0xFD; }
110  return false;
111  }
112 
113  n2k_act_message *t = NULL;
114  bool r = n2k_act_from_bytes(buf, *hw, &t, index, false);
115  if (t) {
116  (*out) = (*t);
117  free(t); // Shallow copied into out, so don't free ->data
118  t = NULL;
119  } else {
120  out->priority = 0xEE;
121  }
122 
123  if (!r) { out->priority = 0xEE; }
124 
125  if ((*hw) > 0 && ((*hw) >= (*index))) {
126  // Move data from index back to zero position
127  memmove(buf, &(buf[(*index)]), N2K_BUFF - (*index));
128  (*hw) -= (*index);
129  (*index) = 0;
130  }
131  return r;
132 }
#define N2K_BUFF
Default serial buffer allocation size.
Definition: N2KConnection.h:35
bool n2k_act_readMessage(int handle, n2k_act_message *out)
Static wrapper around n2k_readMessage_buf.
Definition: N2KConnection.c:61
void n2k_closeConnection(int handle)
Close N2K serial connection.
Definition: N2KConnection.c:46
int n2k_openConnection(const char *device, const int baud)
Open connection to an N2K serial device.
Definition: N2KConnection.c:38
bool n2k_act_readMessage_buf(int handle, n2k_act_message *out, uint8_t buf[N2K_BUFF], size_t *index, size_t *hw)
Read data from handle, and parse message if able.
Definition: N2KConnection.c:85
int openSerialConnection(const char *port, const int baudRate)
Open a serial connection at a given baud rate.
Definition: serial.c:44
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.
Definition: N2KTypes.c:98
uint8_t priority
N2K Message priority value.
Definition: N2KTypes.h:83