SELKIELogger  1.0.0
N2KRead.c
Go to the documentation of this file.
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 <stdbool.h>
22 #include <stdint.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 
28 #include "SELKIELoggerBase.h"
29 
30 #include "SELKIELoggerN2K.h"
31 
32 #include "version.h"
40 #define BUFSIZE 1024
41 
52 int main(int argc, char *argv[]) {
53  program_state state = {0};
54  state.verbose = 1;
55 
56  char *usage = "Usage: %1$s [-v] [-q] datfile\n"
57  "\t-v\tIncrease verbosity\n"
58  "\t-q\tDecrease verbosity\n"
59  "\nVersion: " GIT_VERSION_STRING "\n";
60 
61  opterr = 0; // Handle errors ourselves
62  int go = 0;
63  bool doUsage = false;
64  while ((go = getopt(argc, argv, "vq")) != -1) {
65  switch (go) {
66  case 'v':
67  state.verbose++;
68  break;
69  case 'q':
70  state.verbose--;
71  break;
72  case '?':
73  log_error(&state, "Unknown option `-%c'", optopt);
74  doUsage = true;
75  }
76  }
77 
78  // Should be 1 spare arguments: The file to convert
79  if (argc - optind != 1) {
80  log_error(&state, "Invalid arguments");
81  doUsage = true;
82  }
83 
84  if (doUsage) {
85  fprintf(stderr, usage, argv[0]);
86  return -1;
87  }
88 
89  FILE *nf = fopen(argv[optind], "r");
90 
91  if (nf == NULL) {
92  log_error(&state, "Unable to open input file \"%s\"", argv[optind]);
93  return -1;
94  }
95 
96  state.started = true;
97  bool processing = true;
98 
99  uint8_t buf[BUFSIZE] = {0};
100  size_t hw = 0;
101  int count = 0;
102  while (processing || hw > 18) {
103  if (processing && (hw < BUFSIZE)) {
104  ssize_t ret = fread(&(buf[hw]), sizeof(uint8_t), BUFSIZE - hw, nf);
105  if (ret < 0) {
106  log_error(&state, "Unable to read data from input");
107  processing = false;
108  } else {
109  hw += ret;
110  }
111  }
112  if (feof(nf)) {
113  log_info(&state, 2, "End of file reached");
114  processing = false;
115  }
116  n2k_act_message *nm = NULL;
117  size_t end = 0;
118  bool r = n2k_act_from_bytes(buf, hw, &nm, &end, (state.verbose > 2));
119  if (r) {
120  log_info(&state, 2, "%d=>%d: PGN %d, Priority %d", nm->src, nm->dst,
121  nm->PGN, nm->priority);
122  switch (nm->PGN) {
123  case 60928:
124  n2k_60928_print(nm);
125  break;
126  case 127250:
127  n2k_127250_print(nm);
128  break;
129  case 127251:
130  n2k_127251_print(nm);
131  break;
132  case 127257:
133  n2k_127257_print(nm);
134  break;
135  case 128267:
136  n2k_128267_print(nm);
137  break;
138  case 129025:
139  n2k_129025_print(nm);
140  break;
141  case 129026:
142  n2k_129026_print(nm);
143  break;
144  case 129029:
145  n2k_129029_print(nm);
146  break;
147  case 129033:
148  n2k_129033_print(nm);
149  break;
150  case 130306:
151  n2k_130306_print(nm);
152  break;
153  case 130311:
154  n2k_130311_print(nm);
155  break;
156  default:
157  n2k_basic_print(nm);
158  break;
159  }
160  count++;
161  } else {
162  log_info(&state, 3, "%zu bytes read, failed to decode message", end);
163  if (!processing && end == 0) {
164  // If we're not making progress and we're at the end of file then
165  // this must be a bad message Force the process to move onwards
166  end = 1;
167  }
168  }
169 
170  if (nm) {
171  if (nm->data) { free(nm->data); }
172  free(nm);
173  nm = NULL;
174  }
175 
176  if ((hw - end) > 0) {
177  memmove(buf, &(buf[end]), hw - end);
178  hw -= end;
179  } else {
180  hw = 0;
181  end = 0;
182  }
183 
184  memset(&(buf[hw]), 0, BUFSIZE - hw);
185  }
186  log_info(&state, 0, "%d messages successfully read from file", count);
187  fclose(nf);
188  return 0;
189 }
int main(int argc, char *argv[])
Definition: N2KRead.c:52
#define BUFSIZE
Allocated read buffer size.
Definition: N2KRead.c:40
void n2k_basic_print(const n2k_act_message *n)
Print basic PGN details to standard output.
Definition: N2KMessages.c:563
void n2k_128267_print(const n2k_act_message *n)
Print PGN 128267 (Water depth) to standard output.
Definition: N2KMessages.c:635
void n2k_129029_print(const n2k_act_message *n)
Print PGN 129029 (GNSS Position) to standard output.
Definition: N2KMessages.c:697
void n2k_130311_print(const n2k_act_message *n)
Print PGN 130311 (Environmental data) to standard output.
Definition: N2KMessages.c:795
void n2k_129026_print(const n2k_act_message *n)
Print PGN 129026 (Course and Speed) to standard output.
Definition: N2KMessages.c:667
void n2k_129025_print(const n2k_act_message *n)
Print PGN 129025 (Device position) to standard output.
Definition: N2KMessages.c:652
void n2k_130306_print(const n2k_act_message *n)
Print PGN 130306 (Wind speed and direction) to standard output.
Definition: N2KMessages.c:759
void n2k_60928_print(const n2k_act_message *n)
Print PGN 60928 (Address claim) to standard output.
Definition: N2KMessages.c:527
void n2k_127250_print(const n2k_act_message *n)
Print PGN 127250 (Vessel Heading) to standard output.
Definition: N2KMessages.c:572
void n2k_127251_print(const n2k_act_message *n)
Print PGN 127251 (Rate of Turn) to standard output.
Definition: N2KMessages.c:604
void n2k_127257_print(const n2k_act_message *n)
Print PGN 127257 (Device orientation) to standard output.
Definition: N2KMessages.c:618
void n2k_129033_print(const n2k_act_message *n)
Print PGN 129033 (Date and Time) to standard output.
Definition: N2KMessages.c:737
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
void log_info(const program_state *s, const int level, const char *format,...)
Output formatted information message at a given level.
Definition: logging.c:125
void log_error(const program_state *s, const char *format,...)
Output formatted error message.
Definition: logging.c:47
uint8_t priority
N2K Message priority value.
Definition: N2KTypes.h:83
uint32_t PGN
24 bit PGN identifier
Definition: N2KTypes.h:84
uint8_t * data
Message payload.
Definition: N2KTypes.h:89
uint8_t dst
Message destination.
Definition: N2KTypes.h:85
uint8_t src
Message source.
Definition: N2KTypes.h:86
Program state and logging information.
Definition: logging.h:40
int verbose
Current log verbosity (console output)
Definition: logging.h:43
bool started
Indicates startup completed.
Definition: logging.h:41
#define GIT_VERSION_STRING
Git version description.
Definition: version.h.in:13