OpenCPN Partial API docs
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 
42 struct 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 
52 struct 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 
59 unsigned long BuildCanID(int priority, int source, int destination, int pgn);
60 bool IsFastMessagePGN(unsigned pgn);
61 
62 
64 class CanHeader {
65 public:
66  CanHeader();
68  CanHeader(can_frame frame);
69 
71  bool IsFastMessage() const;
72 
73  unsigned char priority;
74  unsigned char source;
75  unsigned char destination;
76  int pgn;
77 };
78 
81 public:
82  class Entry {
83  public:
84  Entry()
85  : time_arrived(wxDateTime::Now()),
86  sid(0), expected_length(0), cursor(0) {}
87 
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),
104  last_gc_run(wxDateTime::Now()) {}
105 
106  Entry operator[](int i) const { return entries[i]; }
107  Entry& operator[](int i) { return entries[i]; }
108 
110  int FindMatchingEntry(const CanHeader header, const unsigned char sid);
111 
113  int AddNewEntry(void);
114 
116  bool InsertEntry(const CanHeader header, const unsigned char* data,
117  int index);
118 
120  bool AppendEntry(const CanHeader hdr, const unsigned char* data, int index);
121 
123  void Remove(int pos);
124 
125  std::vector<Entry> entries;
126 
127 private:
128  bool IsEntryExpired(unsigned int i);
129  int GarbageCollector(void);
130  void CheckGc();
131 
132  int dropped_frames;
133  wxDateTime last_gc_run;
134  wxDateTime dropped_frame_time;
135 };
136 
137 
138 #endif // guard
CAN v2.0 29 bit header as used by NMEA 2000.
Definition: comm_can_util.h:64
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.
Definition: comm_can_util.h:92
unsigned int cursor
cursor into the current position in data.
Definition: comm_can_util.h:99
unsigned int sid
Sequence identifier, used to check if a received message is the next message in the sequence.
Definition: comm_can_util.h:96
unsigned int expected_length
total data length from first frame
Definition: comm_can_util.h:98
wxDateTime time_arrived
time of last fragment.
Definition: comm_can_util.h:89
std::vector< unsigned char > data
Received data.
Track fast message fragments eventually forming complete messages.
Definition: comm_can_util.h:80
int AddNewEntry(void)
Allocate a new, fresh entry and return index to it.
void Remove(int pos)
Remove entry at pos.
Entry & operator[](int i)
Getter.
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.