NMEA2000 Library  0.1
Library to handle NMEA 2000 Communication written in C++
ActisenseReader.cpp
Go to the documentation of this file.
1/*
2ActisenseReader.cpp
3
4Copyright (c) 2015-2024 Timo Lappalainen, Kave Oy, www.kave.fi
5
6Permission is hereby granted, free of charge, to any person obtaining a copy of
7this software and associated documentation files (the "Software"), to deal in
8the Software without restriction, including without limitation the rights to use,
9copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10Software, and to permit persons to whom the Software is furnished to do so,
11subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
17INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
18PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23
24This is class for reading Actisense format messages from given stream.
25*/
26#include "ActisenseReader.h"
27#include <string.h>
28#include "N2kTimer.h"
29
30//*****************************************************************************
33 ReadStream=0;
35}
36
37//*****************************************************************************
40 byteSum=0;
42 MsgIsComing=false;
43 EscapeReceived=false;
44}
45
46//*****************************************************************************
48 if (MsgWritePos>=MAX_STREAM_MSG_BUF_LEN) return false;
49
50 MsgBuf[MsgWritePos]=NewByte;
52 if ( MsgBuf[1]+3!=MsgWritePos ) byteSum+=NewByte; // !Do not add CRC to byteSum
53 return true;
54}
55
56#define Escape 0x10
57#define StartOfText 0x02
58#define EndOfText 0x03
59#define MsgTypeN2kData 0x93
60#define MsgTypeN2kRequest 0x94
61
62//*****************************************************************************
64
65 N2kMsg.Clear();
66
67 if (MsgWritePos!=MsgBuf[1]+3) {
68 return false; // Length does not match. Add type, length and crc
69 }
70
71 uint8_t CheckSum = (uint8_t)((byteSum == 0) ? 0 : (256 - byteSum));
72 if ( CheckSum!=MsgBuf[MsgWritePos-1] ) {
73 return false; // Checksum does not match
74 }
75
76 int i=2;
77 N2kMsg.Priority=MsgBuf[i++];
78 N2kMsg.PGN=GetBuf3ByteUInt(i,MsgBuf);
79 N2kMsg.Destination=MsgBuf[i++];
80 if ( MsgBuf[0]==MsgTypeN2kData ) {
81 N2kMsg.Source=MsgBuf[i++];
83 } else {
84 N2kMsg.Source=DefaultSource;
85 N2kMsg.MsgTime=N2kMillis();
86 }
87 N2kMsg.DataLen=MsgBuf[i++];
88
89 if ( N2kMsg.DataLen>tN2kMsg::MaxDataLen ) {
90 N2kMsg.Clear();
91 return false; // Too long data
92 }
93
94 for (int j=0; i<MsgWritePos-1; i++, j++) N2kMsg.Data[j]=MsgBuf[i];
95
96 return true;
97}
98
99//*****************************************************************************
101 return (ch==Escape);
102}
103
104//*****************************************************************************
105// Read Actisense formatted NMEA2000 message from stream
106// Actisense Format:
107// <10><02><93><length (1)><priority (1)><PGN (3)><destination (1)><source (1)><time (4)><len (1)><data (len)><CRC (1)><10><03>
108// or
109// <10><02><94><length (1)><priority (1)><PGN (3)><destination (1)><len (1)><data (len)><CRC (1)><10><03>
111 bool result=false;
112
113 if (ReadStream==0) return false;
114
115 int NewByte;
116 bool ContinueLoopAvailable=true;
117
118 while ((NewByte = ReadStream->peek()) != -1 && !result && ContinueLoopAvailable) {
119// Serial.println((char)NewByte,HEX);
120 if (MsgIsComing) {
121 ReadStream->read();
122 if (EscapeReceived) {
123 switch (NewByte) {
124 case Escape: // Escaped Escape
125 EscapeReceived=false;
126 if (!AddByteToBuffer(NewByte)) ClearBuffer();
127 break;
128 case EndOfText: // Message ready
129 switch (MsgBuf[0]) {
130 case MsgTypeN2kData:
132 result=CheckMessage(N2kMsg);
133 break;
134 default:
135 result=false;
136 }
137 ClearBuffer();
138 break;
139 case StartOfText: // Start new message
140 ClearBuffer();
142 break;
143 default: // Error
144 ClearBuffer();
145 }
146 } else {
147 if (NewByte==Escape) {
148 EscapeReceived=true;
149 } else {
150 if (!AddByteToBuffer(NewByte)) ClearBuffer();
151 }
152 }
153 } else {
154 switch (NewByte) {
155 case StartOfText:
157 if (EscapeReceived) {
158 ReadStream->read(); // Read ch out
159 ClearBuffer();
161 }
162 break;
163 default:
164 EscapeReceived=(NewByte==Escape);
166 ReadStream->read(); // Read ch out
168 MsgIsComing=true;
169 AddByteToBuffer(NewByte);
170 } else {
171 if ( EscapeReceived || ReadOut ) ReadStream->read(); // Read ch out
172 }
173 }
174 }
175
176 ContinueLoopAvailable=ReadOut || Handling();
177 }
178
179 return result;
180}
181
182//*****************************************************************************
184 tN2kMsg N2kMsg;
185
186 while (GetMessageFromStream(N2kMsg)) {
187 if (MsgHandler!=0) MsgHandler(N2kMsg);
188 }
189}
190
191
#define MsgTypeN2kRequest
#define MsgTypeN2kData
#define StartOfText
#define EndOfText
#define Escape
File contains declaration for tActisenseReader class for reading Actisense format messages from strea...
#define MAX_STREAM_MSG_BUF_LEN
Maximum length of the stream message buffer.
uint32_t GetBuf4ByteUInt(int &index, const unsigned char *buf)
Extracts 4 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:640
uint32_t GetBuf3ByteUInt(int &index, const unsigned char *buf)
Extracts 3 bytes out of the given buffer and converts it to an integer value.
Definition: N2kMsg.cpp:635
uint32_t N2kMillis()
Definition: N2kTimer.cpp:48
The file contains function and classes for best timing performance.
virtual int peek()=0
reads a byte from the file without advancing to the next one
virtual int read()=0
reads characters from an incoming stream to the buffer
bool EscapeReceived
Escape character has been received.
bool Handling() const
Indicates if still message handling is needed.
bool GetMessageFromStream(tN2kMsg &N2kMsg, bool ReadOut=true)
Read Actisense formatted NMEA2000 message from stream.
tActisenseReader()
Constructor for the class Initialize all class attributes and clear the buffer.
int byteSum
Sum of all bytes is used as kind of check sum.
bool IsStart(char ch)
Checks if character is start of Actisense format.
void ParseMessages()
Parse messages from stream.
unsigned char DefaultSource
Default source of the N2k message.
bool AddByteToBuffer(char NewByte)
Adds a new Byte to the buffer.
void ClearBuffer()
Clears the buffer.
unsigned char MsgBuf[MAX_STREAM_MSG_BUF_LEN]
Buffer for incoming messages from stream.
int MsgWritePos
Current write position inside the buffer.
bool CheckMessage(tN2kMsg &N2kMsg)
Checks is Actisense message read from stream valid and builds tN2kMsg message from it.
bool MsgIsComing
A Message is coming.
bool StartOfTextReceived
Start of text has been received.
void(* MsgHandler)(const tN2kMsg &N2kMsg)
N2kStream * ReadStream
Stream to read from.
This class contains all the data of an NMEA2000 message.
Definition: N2kMsg.h:656
unsigned char Data[MaxDataLen]
Byte array which carries all the data of the NMEA2000 message.
Definition: N2kMsg.h:675
unsigned char Source
Source of the NMEA2000 message.
Definition: N2kMsg.h:669
static const int MaxDataLen
Maximum number of bytes that can be stored in the data buffer With fast packet the first frame can ha...
Definition: N2kMsg.h:663
unsigned char Priority
Priority of the NMEA2000 message.
Definition: N2kMsg.h:665
virtual void Clear()
Clears the content of the N2kMsg object The method sets the PGN, DataLen and MsgTime to zero.
Definition: N2kMsg.cpp:94
unsigned long MsgTime
timestamp (ms since start [max 49days]) of the NMEA2000 message
Definition: N2kMsg.h:677
int DataLen
Number of bytes already stored in tN2kMsg::Data of this message.
Definition: N2kMsg.h:673
unsigned long PGN
Parameter Group Number (PGN) of the NMEA2000 message.
Definition: N2kMsg.h:667
unsigned char Destination
Destination of the NMEA2000 message.
Definition: N2kMsg.h:671