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