Rev Author Line No. Line
3328 povik 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 * $Id: slipdev.c,v 1.1.2.3 2003/10/07 13:23:01 adam Exp $
57 *
58 */
59  
60 /*
61 * This is a generic implementation of the SLIP protocol over an RS232
62 * (serial) device.
63 *
64 * Huge thanks to Ullrich von Bassewitz <uz@cc65.org> of cc65 fame for
65 * and endless supply of bugfixes, insightsful comments and
66 * suggestions, and improvements to this code!
67 */
68  
69 #include "uip.h"
70  
71 #define SLIP_END 0300
72 #define SLIP_ESC 0333
73 #define SLIP_ESC_END 0334
74 #define SLIP_ESC_ESC 0335
75  
76 static u8_t slip_buf[UIP_BUFSIZE];
77  
78 static u16_t len, tmplen;
79 static u8_t lastc;
80  
81 /*-----------------------------------------------------------------------------------*/
82 /**
83 * Send the packet in the uip_buf and uip_appdata buffers using the
84 * SLIP protocol.
85 *
86 * The first 40 bytes of the packet (the IP and TCP headers) are read
87 * from the uip_buf buffer, and the following bytes (the application
88 * data) are read from the uip_appdata buffer.
89 *
90 */
91 /*-----------------------------------------------------------------------------------*/
92 void
93 slipdev_send(void)
94 {
95 u16_t i;
96 u8_t *ptr;
97 u8_t c;
98  
99 slipdev_char_put(SLIP_END);
100  
101 ptr = uip_buf;
102 for(i = 0; i < uip_len; ++i) {
103 if(i == 40) {
104 ptr = (u8_t *)uip_appdata;
105 }
106 c = *ptr++;
107 switch(c) {
108 case SLIP_END:
109 slipdev_char_put(SLIP_ESC);
110 slipdev_char_put(SLIP_ESC_END);
111 break;
112 case SLIP_ESC:
113 slipdev_char_put(SLIP_ESC);
114 slipdev_char_put(SLIP_ESC_ESC);
115 break;
116 default:
117 slipdev_char_put(c);
118 break;
119 }
120 }
121 slipdev_char_put(SLIP_END);
122 }
123 /*-----------------------------------------------------------------------------------*/
124 /**
125 * Poll the SLIP device for an available packet.
126 *
127 * This function will poll the SLIP device to see if a packet is
128 * available. It uses a buffer in which all avaliable bytes from the
129 * RS232 interface are read into. When a full packet has been read
130 * into the buffer, the packet is copied into the uip_buf buffer and
131 * the length of the packet is returned.
132 *
133 * \return The length of the packet placed in the uip_buf buffer, or
134 * zero if no packet is available.
135 */
136 /*-----------------------------------------------------------------------------------*/
137 u16_t
138 slipdev_poll(void)
139 {
140 u8_t c;
141  
142 while(slipdev_char_poll(c)) {
143 switch(c) {
144 case SLIP_ESC:
145 lastc = c;
146 break;
147  
148 case SLIP_END:
149 lastc = c;
150 /* End marker found, we copy our input buffer to the uip_buf
151 buffer and return the size of the packet we copied. */
152 memcpy(uip_buf, slip_buf, len);
153 tmplen = len;
154 len = 0;
155 return tmplen;
156  
157 default:
158 if(lastc == SLIP_ESC) {
159 lastc = c;
160 /* Previous read byte was an escape byte, so this byte will be
161 interpreted differently from others. */
162 switch(c) {
163 case SLIP_ESC_END:
164 c = SLIP_END;
165 break;
166 case SLIP_ESC_ESC:
167 c = SLIP_ESC;
168 break;
169 }
170 } else {
171 lastc = c;
172 }
173  
174 slip_buf[len] = c;
175 ++len;
176  
177 if(len > UIP_BUFSIZE) {
178 len = 0;
179 }
180  
181 break;
182 }
183 }
184 return 0;
185 }
186 /*-----------------------------------------------------------------------------------*/
187 /**
188 * Initialize the SLIP module.
189 *
190 * This function does not initialize the underlying RS232 device, but
191 * only the SLIP part.
192 */
193 /*-----------------------------------------------------------------------------------*/
194 void
195 slipdev_init(void)
196 {
197 lastc = len = 0;
198 }
199 /*-----------------------------------------------------------------------------------*/
200  
201 /** @} */
202 /** @} */