EVE 1.0
slipdev.c
Go to the documentation of this file.
1 /**
2  * \addtogroup uip
3  * @{
4  */
5 
6 /**
7  * \defgroup slip Serial Line IP (SLIP) protocol
8  * @{
9  *
10  * The SLIP protocol is a very simple way to transmit IP packets over
11  * a serial line. It does not provide any framing or error control,
12  * and is therefore not very widely used today.
13  *
14  * This SLIP implementation requires two functions for accessing the
15  * serial device: slipdev_char_poll() and slipdev_char_put(). These
16  * must be implemented specifically for the system on which the SLIP
17  * protocol is to be run.
18  */
19 
20 /**
21  * \file
22  * SLIP protocol implementation
23  * \author Adam Dunkels <adam@dunkels.com>
24  */
25 
26 /*
27  * Copyright (c) 2001, Adam Dunkels.
28  * All rights reserved.
29  *
30  * Redistribution and use in source and binary forms, with or without
31  * modification, are permitted provided that the following conditions
32  * are met:
33  * 1. Redistributions of source code must retain the above copyright
34  * notice, this list of conditions and the following disclaimer.
35  * 2. Redistributions in binary form must reproduce the above copyright
36  * notice, this list of conditions and the following disclaimer in the
37  * documentation and/or other materials provided with the distribution.
38  * 3. The name of the author may not be used to endorse or promote
39  * products derived from this software without specific prior
40  * written permission.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
43  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
46  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
48  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
50  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
51  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53  *
54  * This file is part of the uIP TCP/IP stack.
55  *
56  *
57  */
58 
59 /*
60  * This is a generic implementation of the SLIP protocol over an RS232
61  * (serial) device.
62  *
63  * Huge thanks to Ullrich von Bassewitz <uz@cc65.org> of cc65 fame for
64  * and endless supply of bugfixes, insightsful comments and
65  * suggestions, and improvements to this code!
66  */
67 
68 #include "uip.h"
69 #include "uip-fw.h"
70 #include "slipdev.h"
71 #include <string.h> /* For memcpy() */
72 
73 #define SLIP_END 0300
74 #define SLIP_ESC 0333
75 #define SLIP_ESC_END 0334
76 #define SLIP_ESC_ESC 0335
77 
78 static uint8_t slip_buf[UIP_BUFSIZE];
79 
80 static uint16_t len, tmplen;
81 static uint8_t lastc;
82 
83 /*-----------------------------------------------------------------------------------*/
84 /**
85  * Send the packet in the uip_buf and uip_appdata buffers using the
86  * SLIP protocol.
87  *
88  * The first 40 bytes of the packet (the IP and TCP headers) are read
89  * from the uip_buf buffer, and the following bytes (the application
90  * data) are read from the uip_appdata buffer.
91  *
92  * \return This function will always return UIP_FW_OK.
93  */
94 /*-----------------------------------------------------------------------------------*/
95 uint8_t
97 {
98  uint16_t i;
99  uint8_t *ptr;
100  uint8_t c;
101 
102  slipdev_char_put(SLIP_END);
103 
104  ptr = &uip_buf[UIP_LLH_LEN];
105  for(i = 0; i < uip_len; ++i) {
106  if(i == UIP_TCPIP_HLEN) {
107  ptr = (uint8_t *)uip_appdata;
108  }
109  c = *ptr++;
110  switch(c) {
111  case SLIP_END:
112  slipdev_char_put(SLIP_ESC);
113  slipdev_char_put(SLIP_ESC_END);
114  break;
115  case SLIP_ESC:
116  slipdev_char_put(SLIP_ESC);
117  slipdev_char_put(SLIP_ESC_ESC);
118  break;
119  default:
120  slipdev_char_put(c);
121  break;
122  }
123  }
124  slipdev_char_put(SLIP_END);
125 
126  return UIP_FW_OK;
127 }
128 /*-----------------------------------------------------------------------------------*/
129 /**
130  * Poll the SLIP device for an available packet.
131  *
132  * This function will poll the SLIP device to see if a packet is
133  * available. It uses a buffer in which all avaliable bytes from the
134  * RS232 interface are read into. When a full packet has been read
135  * into the buffer, the packet is copied into the uip_buf buffer and
136  * the length of the packet is returned.
137  *
138  * \return The length of the packet placed in the uip_buf buffer, or
139  * zero if no packet is available.
140  */
141 /*-----------------------------------------------------------------------------------*/
142 uint16_t
144 {
145  uint8_t c;
146 
147  while(slipdev_char_poll(&c)) {
148  switch(c) {
149  case SLIP_ESC:
150  lastc = c;
151  break;
152 
153  case SLIP_END:
154  lastc = c;
155  /* End marker found, we copy our input buffer to the uip_buf
156  buffer and return the size of the packet we copied. */
157  memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len);
158  tmplen = len;
159  len = 0;
160  return tmplen;
161 
162  default:
163  if(lastc == SLIP_ESC) {
164  lastc = c;
165  /* Previous read byte was an escape byte, so this byte will be
166  interpreted differently from others. */
167  switch(c) {
168  case SLIP_ESC_END:
169  c = SLIP_END;
170  break;
171  case SLIP_ESC_ESC:
172  c = SLIP_ESC;
173  break;
174  }
175  } else {
176  lastc = c;
177  }
178 
179  slip_buf[len] = c;
180  ++len;
181 
182  if(len > UIP_BUFSIZE) {
183  len = 0;
184  }
185 
186  break;
187  }
188  }
189  return 0;
190 }
191 /*-----------------------------------------------------------------------------------*/
192 /**
193  * Initialize the SLIP module.
194  *
195  * This function does not initialize the underlying RS232 device, but
196  * only the SLIP part.
197  */
198 /*-----------------------------------------------------------------------------------*/
199 void
201 {
202  lastc = len = 0;
203 }
204 /*-----------------------------------------------------------------------------------*/
205 
206 /** @} */
207 /** @} */
uint8_t slipdev_char_poll(uint8_t *c)
#define UIP_BUFSIZE
Definition: uipopt.h:175
#define UIP_FW_OK
Definition: uip-fw.h:134
uint16_t uip_len
Definition: uip.c:166
#define UIP_LLH_LEN
Definition: uipopt.h:162
uint16_t slipdev_poll(void)
Definition: slipdev.c:143
uint8_t slipdev_send(void)
Definition: slipdev.c:96
void slipdev_init(void)
Definition: slipdev.c:200
void slipdev_char_put(uint8_t c)
void * uip_appdata
Definition: uip.c:154