OpenCPN Partial API docs
Loading...
Searching...
No Matches
comm_can_util.h
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: Low-level utility functions for socketcan support.
5 * Author: David Register, Alec Leamas
6 *
7 ***************************************************************************
8 * Copyright (C) 2024 by David Register, Alec Leamas *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25
26#ifndef _COMMCANUTIL_H
27#define _COMMCANUTIL_H
28
29#include <memory>
30#include <string>
31
32#include <wx/datetime.h>
33
34#if !defined(__WXMSW__) && !defined(__WXMAC__)
35#include <linux/can.h>
36#include <linux/can/raw.h>
37#endif
38
39#ifdef __WXMSW__
40#define CAN_MAX_DLEN 8
41
42struct can_frame {
43 uint32_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
44 uint8_t can_dlc; /* frame payload length in byte (0 .. 8) */
45 uint8_t data[CAN_MAX_DLEN];
46};
47#endif
48
49#if defined(__WXMAC__)
50#define CAN_MAX_DLEN 8
51
52struct can_frame {
53 uint32_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
54 uint8_t can_dlc; /* frame payload length in byte (0 .. 8) */
55 uint8_t data[CAN_MAX_DLEN];
56};
57#endif
58
59unsigned long BuildCanID(int priority, int source, int destination, int pgn);
60bool IsFastMessagePGN(unsigned pgn);
61
63class CanHeader {
64public:
65 CanHeader();
67 CanHeader(can_frame frame);
68
70 bool IsFastMessage() const;
71
72 unsigned char priority;
73 unsigned char source;
74 unsigned char destination;
75 int pgn;
76};
77
80public:
81 class Entry {
82 public:
83 Entry()
84 : time_arrived(wxDateTime::Now()),
85 sid(0),
87 cursor(0) {}
88
89 wxDateTime time_arrived;
90
93
96 unsigned int sid;
97
98 unsigned int expected_length;
99 unsigned int cursor;
100 std::vector<unsigned char> data;
101 };
102
103 FastMessageMap() : dropped_frames(0), last_gc_run(wxDateTime::Now()) {}
104
105 Entry operator[](int i) const { return entries[i]; }
106 Entry& operator[](int i) { return entries[i]; }
107
109 int FindMatchingEntry(const CanHeader header, const unsigned char sid);
110
112 int AddNewEntry(void);
113
115 bool InsertEntry(const CanHeader header, const unsigned char* data,
116 int index);
117
119 bool AppendEntry(const CanHeader hdr, const unsigned char* data, int index);
120
122 void Remove(int pos);
123
124 std::vector<Entry> entries;
125
126private:
127 bool IsEntryExpired(unsigned int i);
128 int GarbageCollector(void);
129 void CheckGc();
130
131 int dropped_frames;
132 wxDateTime last_gc_run;
133 wxDateTime dropped_frame_time;
134};
135
136#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.