OpenCPN Partial API docs
Loading...
Searching...
No Matches
comm_can_util.h
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2024 by David Register *
3 * Copyright (C) 2024 Alec Leamas *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
25#ifndef _COMMCANUTIL_H
26#define _COMMCANUTIL_H
27
28#include <memory>
29#include <string>
30
31#if !defined(_WIN32) && !defined(__APPLE__)
32#include <linux/can.h>
33#include <linux/can/raw.h>
34#endif
35
36#include <wx/datetime.h>
37
38#ifdef __WXMSW__
39#define CAN_MAX_DLEN 8
40
41struct can_frame {
42 uint32_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
43 uint8_t can_dlc; /* frame payload length in byte (0 .. 8) */
44 uint8_t data[CAN_MAX_DLEN];
45};
46#endif
47
48#if defined(__WXMAC__)
49#define CAN_MAX_DLEN 8
50
51struct can_frame {
52 uint32_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
53 uint8_t can_dlc; /* frame payload length in byte (0 .. 8) */
54 uint8_t data[CAN_MAX_DLEN];
55};
56#endif
57
58unsigned long BuildCanID(int priority, int source, int destination, int pgn);
59bool IsFastMessagePGN(unsigned pgn);
60
62class CanHeader {
63public:
64 CanHeader();
66 CanHeader(can_frame frame);
67
69 bool IsFastMessage() const;
70
71 unsigned char priority;
72 unsigned char source;
73 unsigned char destination;
74 int pgn;
75};
76
79public:
80 class Entry {
81 public:
82 Entry()
83 : time_arrived(wxDateTime::Now()),
84 sid(0),
86 cursor(0) {}
87
88 wxDateTime time_arrived;
89
92
95 unsigned int sid;
96
97 unsigned int expected_length;
98 unsigned int cursor;
99 std::vector<unsigned char> data;
100 };
101
102 FastMessageMap() : dropped_frames(0), last_gc_run(wxDateTime::Now()) {}
103
104 Entry operator[](int i) const { return entries[i]; }
105 Entry& operator[](int i) { return entries[i]; }
106
108 int FindMatchingEntry(const CanHeader header, const unsigned char sid);
109
111 int AddNewEntry(void);
112
114 bool InsertEntry(const CanHeader header, const unsigned char* data,
115 int index);
116
118 bool AppendEntry(const CanHeader hdr, const unsigned char* data, int index);
119
121 void Remove(int pos);
122
123 std::vector<Entry> entries;
124
125private:
126 bool IsEntryExpired(unsigned int i);
127 int GarbageCollector(void);
128 void CheckGc();
129
130 int dropped_frames;
131 wxDateTime last_gc_run;
132 wxDateTime dropped_frame_time;
133};
134
135#endif // guard
CAN v2.0 29 bit header as used by NMEA 2000.
CanHeader(can_frame frame)
Construct a CanHeader by parsing a frame.
CanHeader()
CAN v2.0 29 bit header as used by NMEA 2000.
bool IsFastMessage() const
Return true if header reflects a multipart fast message.
CanHeader header
Can header, used to "map" the incoming fast message fragments.
unsigned int cursor
cursor into the current position in data.
unsigned int sid
Sequence identifier, used to check if a received message is the next message in the sequence.
unsigned int expected_length
total data length from first frame
wxDateTime time_arrived
time of last fragment.
std::vector< unsigned char > data
Received data.
Track fast message fragments eventually forming complete messages.
int AddNewEntry(void)
Allocate a new, fresh entry and return index to it.
Entry & operator[](int i)
Getter.
void Remove(int pos)
Remove entry at pos.
bool AppendEntry(const CanHeader hdr, const unsigned char *data, int index)
Append fragment to existing multipart message.
int FindMatchingEntry(const CanHeader header, const unsigned char sid)
Setter.
bool InsertEntry(const CanHeader header, const unsigned char *data, int index)
Insert a new entry, first part of a multipart message.