blob: 2c1a229b1a36656b7a18b3e746ada7f8dcced8d5 [file] [log] [blame]
adamdunkelsb489e7a2003-10-14 11:12:50 +00001/**
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 2003/10/14 11:12:50 adamdunkels 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#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
78static u8_t slip_buf[UIP_BUFSIZE];
79
80static u16_t len, tmplen;
81static u8_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 */
93/*-----------------------------------------------------------------------------------*/
94void
95slipdev_send(void)
96{
97 u16_t i;
98 u8_t *ptr;
99 u8_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/*-----------------------------------------------------------------------------------*/
126/**
127 * Poll the SLIP device for an available packet.
128 *
129 * This function will poll the SLIP device to see if a packet is
130 * available. It uses a buffer in which all avaliable bytes from the
131 * RS232 interface are read into. When a full packet has been read
132 * into the buffer, the packet is copied into the uip_buf buffer and
133 * the length of the packet is returned.
134 *
135 * \return The length of the packet placed in the uip_buf buffer, or
136 * zero if no packet is available.
137 */
138/*-----------------------------------------------------------------------------------*/
139u16_t
140slipdev_poll(void)
141{
142 u8_t c;
143
144 while(slipdev_char_poll(&c)) {
145 switch(c) {
146 case SLIP_ESC:
147 lastc = c;
148 break;
149
150 case SLIP_END:
151 lastc = c;
152 /* End marker found, we copy our input buffer to the uip_buf
153 buffer and return the size of the packet we copied. */
154 memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len);
155 tmplen = len;
156 len = 0;
157 return tmplen;
158
159 default:
160 if(lastc == SLIP_ESC) {
161 lastc = c;
162 /* Previous read byte was an escape byte, so this byte will be
163 interpreted differently from others. */
164 switch(c) {
165 case SLIP_ESC_END:
166 c = SLIP_END;
167 break;
168 case SLIP_ESC_ESC:
169 c = SLIP_ESC;
170 break;
171 }
172 } else {
173 lastc = c;
174 }
175
176 slip_buf[len] = c;
177 ++len;
178
179 if(len > UIP_BUFSIZE) {
180 len = 0;
181 }
182
183 break;
184 }
185 }
186 return 0;
187}
188/*-----------------------------------------------------------------------------------*/
189/**
190 * Initialize the SLIP module.
191 *
192 * This function does not initialize the underlying RS232 device, but
193 * only the SLIP part.
194 */
195/*-----------------------------------------------------------------------------------*/
196void
197slipdev_init(void)
198{
199 lastc = len = 0;
200}
201/*-----------------------------------------------------------------------------------*/
202
203/** @} */
204/** @} */