Arduino KVComm  master
Key-Value pair communication library for Arduino
SLIPStream.cpp
Go to the documentation of this file.
1 #include "SLIPStream.hpp"
2 
4 
5 size_t SLIPStream::writePacket(const uint8_t *data, size_t len) {
6  size_t sent = 0;
7  sent += beginPacket();
8  sent += write(data, len);
9  sent += endPacket();
10  return sent;
11 }
12 
13 size_t SLIPStream::write(const uint8_t *data, size_t len) {
14  return SLIPSender<StreamSender>(stream).write(data, len);
15 }
16 
19 }
20 
23 }
24 
26  while (stream->available()) {
27  size_t packetSize = parser.parse(stream->read());
28  if (packetSize > 0)
29  return packetSize;
30  }
31  return 0;
32 }
33 
34 #if ORIGINAL_RFC1055_SOURCE
35 
36 /* SLIP special character codes
37  */
38 #define END 0300 /* indicates end of packet */
39 #define ESC 0333 /* indicates byte stuffing */
40 #define ESC_END 0334 /* ESC ESC_END means END data byte */
41 #define ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */
42 
43 /* SEND_PACKET: sends a packet of length "len", starting at
44  * location "p".
45  */
46 void send_packet(char *p, int len) {
47 
48  /* send an initial END character to flush out any data that may
49  * have accumulated in the receiver due to line noise
50  */
51  send_char(END);
52 
53  /* for each byte in the packet, send the appropriate character
54  * sequence
55  */
56  while (len--) {
57  switch (*p) {
58  /* if it's the same code as an END character, we send a
59  * special two character code so as not to make the
60  * receiver think we sent an END
61  */
62  case END:
63  send_char(ESC);
64  send_char(ESC_END);
65  break;
66 
67  /* if it's the same code as an ESC character,
68  * we send a special two character code so as not
69  * to make the receiver think we sent an ESC
70  */
71  case ESC:
72  send_char(ESC);
73  send_char(ESC_ESC);
74  break;
75 
76  /* otherwise, we just send the character
77  */
78  default: send_char(*p);
79  }
80 
81  p++;
82  }
83 
84  /* tell the receiver that we're done sending the packet
85  */
86  send_char(END);
87 }
88 
89 /* RECV_PACKET: receives a packet into the buffer located at "p".
90  * If more than len bytes are received, the packet will
91  * be truncated.
92  * Returns the number of bytes stored in the buffer.
93  */
94 int recv_packet(char *p, int len) {
95  char c;
96  int received = 0;
97 
98  /* sit in a loop reading bytes until we put together
99  * a whole packet.
100  * Make sure not to copy them into the packet if we
101  * run out of room.
102  */
103  while (1) {
104  /* get a character to process
105  */
106  c = recv_char();
107 
108  /* handle bytestuffing if necessary
109  */
110  switch (c) {
111 
112  /* if it's an END character then we're done with
113  * the packet
114  */
115  case END:
116  /* a minor optimization: if there is no
117  * data in the packet, ignore it. This is
118  * meant to avoid bothering IP with all
119  * the empty packets generated by the
120  * duplicate END characters which are in
121  * turn sent to try to detect line noise.
122  */
123  if (received)
124  return received;
125  else
126  break;
127 
128  /* if it's the same code as an ESC character, wait
129  * and get another character and then figure out
130  * what to store in the packet based on that.
131  */
132  case ESC:
133  c = recv_char();
134 
135  /* if "c" is not one of these two, then we
136  * have a protocol violation. The best bet
137  * seems to be to leave the byte alone and
138  * just stuff it into the packet
139  */
140  switch (c) {
141  case ESC_END: c = END; break;
142  case ESC_ESC: c = ESC; break;
143  }
144 
145  /* here we fall into the default handler and let
146  * it store the character for us
147  */
148  default:
149  if (received < len)
150  p[received++] = c;
151  }
152  }
153 }
154 
155 #endif
SLIPStream::beginPacket
size_t beginPacket()
Start a packet.
Definition: SLIPStream.cpp:17
SLIPStream::writePacket
size_t writePacket(const uint8_t *data, size_t len)
Sends a packet.
Definition: SLIPStream.cpp:5
SLIPSender
Class for sending SLIP packets.
Definition: SLIPSender.hpp:26
SLIPSender::write
size_t write(const uint8_t *data, size_t len)
Write some data as the body of a packet.
Definition: SLIPSender.ipp:4
SLIPSender::endPacket
size_t endPacket()
Finish the packet.
Definition: SLIPSender.hpp:56
SLIP_Constants::ESC_END
const static uint8_t ESC_END
ESC ESC_END means END data byte.
Definition: SLIP.hpp:12
SLIPStream::parser
SLIPParser parser
Definition: SLIPStream.hpp:67
SLIPStream::stream
Stream * stream
Definition: SLIPStream.hpp:66
SLIPParser::parse
size_t parse(uint8_t c, Callback callback)
Parse the given byte, and call the callback for each data byte.
Definition: SLIPParser.ipp:4
SLIP_Constants::ESC_ESC
const static uint8_t ESC_ESC
ESC ESC_ESC means ESC data byte.
Definition: SLIP.hpp:13
SLIPStream::write
size_t write(const uint8_t *data, size_t len)
Write some data as the body of a packet.
Definition: SLIPStream.cpp:13
SLIP_Constants::ESC
const static uint8_t ESC
indicates byte stuffing
Definition: SLIP.hpp:11
SLIPStream::endPacket
size_t endPacket()
Finish the packet.
Definition: SLIPStream.cpp:21
SLIPSender.hpp
SLIPSender::beginPacket
size_t beginPacket()
Start a packet.
Definition: SLIPSender.hpp:48
SLIPStream.hpp
SLIP_Constants::END
const static uint8_t END
indicates end of packet
Definition: SLIP.hpp:10
SLIPStream::readPacket
size_t readPacket()
Receives a packet into the read buffer.
Definition: SLIPStream.cpp:25