Skip to content

Commit 6f0a1c0

Browse files
committed
add SLIP encoding
1 parent 42e9379 commit 6f0a1c0

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

src/Encoding/SLIP.h

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// =============================================================================
2+
//
3+
// Copyright (c) 2010-2014 Christopher Baker <http://christopherbaker.net>
4+
// 2016 Antoine Villeret added Christopher's ofx/IO/SLIPEncoding.h here
5+
//
6+
// see : https://github.com/bakercp/ofxIO/blob/master/libs/ofxIO/include/ofx/IO/SLIPEncoding.h
7+
//
8+
// Portions:
9+
// Copyright (c) 2011, Jacques Fortier. All rights reserved.
10+
// https://github.com/jacquesf/COBS-Consistent-Overhead-Byte-Stuffing
11+
//
12+
// Permission is hereby granted, free of charge, to any person obtaining a copy
13+
// of this software and associated documentation files (the "Software"), to deal
14+
// in the Software without restriction, including without limitation the rights
15+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16+
// copies of the Software, and to permit persons to whom the Software is
17+
// furnished to do so, subject to the following conditions:
18+
//
19+
// The above copyright notice and this permission notice shall be included in
20+
// all copies or substantial portions of the Software.
21+
//
22+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28+
// THE SOFTWARE.
29+
//
30+
// =============================================================================
31+
32+
33+
#pragma once
34+
35+
36+
#include "Arduino.h"
37+
38+
39+
40+
/// \brief A Serial Line IP (SLIP) Encoder.
41+
///
42+
/// Serial Line IP (SLIP) is a packet framing protocol: SLIP defines a
43+
/// sequence of characters that frame IP packets on a serial line and
44+
/// nothing more. It provides no addressing, packet type identification,
45+
/// error detection/correction or compression mechanisms. Because the
46+
/// protocol does so little, though, it is usually very easy to
47+
/// implement.
48+
///
49+
/// \sa http://tools.ietf.org/html/rfc1055
50+
class SLIP
51+
{
52+
public:
53+
static size_t encode(const uint8_t* buffer, size_t size, uint8_t* encoded)
54+
{
55+
if (size == 0)
56+
return 0;
57+
58+
size_t read_index = 0;
59+
size_t write_index = 0;
60+
61+
// double-ENDed, flush any data that may have accumulated due to line noise
62+
encoded[write_index++] = END;
63+
64+
while (read_index < size)
65+
{
66+
if(buffer[read_index] == END)
67+
{
68+
encoded[write_index++] = ESC;
69+
encoded[write_index++] = ESC_END;
70+
read_index++;
71+
}
72+
else if(buffer[read_index] == ESC)
73+
{
74+
encoded[write_index++] = ESC;
75+
encoded[write_index++] = ESC_ESC;
76+
read_index++;
77+
}
78+
else
79+
{
80+
encoded[write_index++] = buffer[read_index++];
81+
}
82+
}
83+
84+
encoded[write_index++] = END;
85+
86+
return write_index;
87+
}
88+
89+
static size_t decode(const uint8_t* buffer, size_t size, uint8_t* decoded)
90+
{
91+
if (size == 0)
92+
return 0;
93+
94+
size_t read_index = 0;
95+
size_t write_index = 0;
96+
97+
while (read_index < size)
98+
{
99+
if (buffer[read_index] == END)
100+
{
101+
// flush or done
102+
read_index++;
103+
}
104+
else if (buffer[read_index] == ESC)
105+
{
106+
if (buffer[read_index+1] == ESC_END)
107+
{
108+
decoded[write_index++] = END;
109+
read_index += 2;
110+
}
111+
else if (buffer[read_index+1] == ESC_ESC)
112+
{
113+
decoded[write_index++] = ESC;
114+
read_index += 2;
115+
}
116+
else
117+
{
118+
// considered a protocol violation
119+
}
120+
}
121+
else
122+
{
123+
decoded[write_index++] = buffer[read_index++];
124+
}
125+
}
126+
127+
return write_index;
128+
}
129+
130+
/// \brief Get the maximum encoded buffer size needed for a given source size.
131+
///
132+
/// SLIP has a start and a end markers (192 and 219).
133+
/// Marker value is replaced by 2 bytes in the encoded buffer.
134+
/// So in the worst case of sending a buffer with only '192' or '219',
135+
/// the encoded buffer length will be 2 * buffer.size() + 2
136+
/// \param sourceSize The size of the buffer to be encoded.
137+
/// \returns the maximum size of the required encoded buffer.
138+
static size_t getEncodedBufferSize(size_t sourceSize)
139+
{
140+
return sourceSize * 2 + 2;
141+
}
142+
143+
enum
144+
{
145+
END = 0300,
146+
ESC = 0333,
147+
ESC_END = 0334,
148+
ESC_ESC = 0335
149+
};
150+
151+
};

src/PacketSerial.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include <Arduino.h>
2929
#include "Encoding/COBS.h"
30+
#include "Encoding/SLIP.h"
3031

3132

3233
template<typename EncoderType, uint8_t PacketMarker = 0, int BufferSize = 256>
@@ -146,3 +147,4 @@ class PacketSerial_
146147

147148

148149
typedef PacketSerial_<COBS> PacketSerial;
150+
typedef PacketSerial_<SLIP, SLIP::END, 8192> SLIPPacketSerial;

0 commit comments

Comments
 (0)