blob: f66405f6e9d7ae7eb33015ee4172521a103972df [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 *
adamdunkelsd9133342003-11-27 15:54:20 +000056 * $Id: slipdev.c,v 1.2 2003/11/27 15:54:20 adamdunkels Exp $
adamdunkelsb489e7a2003-10-14 11:12:50 +000057 *
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"
adamdunkelsd9133342003-11-27 15:54:20 +000070#include "uip-fw.h"
adamdunkelsb489e7a2003-10-14 11:12:50 +000071#include "slipdev.h"
72#include <string.h> /* For memcpy() */
73
74#define SLIP_END 0300
75#define SLIP_ESC 0333
76#define SLIP_ESC_END 0334
77#define SLIP_ESC_ESC 0335
78
79static u8_t slip_buf[UIP_BUFSIZE];
80
81static u16_t len, tmplen;
82static u8_t lastc;
83
84/*-----------------------------------------------------------------------------------*/
85/**
86 * Send the packet in the uip_buf and uip_appdata buffers using the
87 * SLIP protocol.
88 *
89 * The first 40 bytes of the packet (the IP and TCP headers) are read
90 * from the uip_buf buffer, and the following bytes (the application
91 * data) are read from the uip_appdata buffer.
92 *
adamdunkelsd9133342003-11-27 15:54:20 +000093 * \return This function will always return UIP_FW_OK.
adamdunkelsb489e7a2003-10-14 11:12:50 +000094 */
95/*-----------------------------------------------------------------------------------*/
adamdunkelsd9133342003-11-27 15:54:20 +000096u8_t
adamdunkelsb489e7a2003-10-14 11:12:50 +000097slipdev_send(void)
98{
99 u16_t i;
100 u8_t *ptr;
101 u8_t c;
102
103 slipdev_char_put(SLIP_END);
104
105 ptr = &uip_buf[UIP_LLH_LEN];
106 for(i = 0; i < uip_len; ++i) {
107 if(i == UIP_TCPIP_HLEN) {
108 ptr = (char *)uip_appdata;
109 }
110 c = *ptr++;
111 switch(c) {
112 case SLIP_END:
113 slipdev_char_put(SLIP_ESC);
114 slipdev_char_put(SLIP_ESC_END);
115 break;
116 case SLIP_ESC:
117 slipdev_char_put(SLIP_ESC);
118 slipdev_char_put(SLIP_ESC_ESC);
119 break;
120 default:
121 slipdev_char_put(c);
122 break;
123 }
124 }
125 slipdev_char_put(SLIP_END);
adamdunkelsd9133342003-11-27 15:54:20 +0000126
127 return UIP_FW_OK;
adamdunkelsb489e7a2003-10-14 11:12:50 +0000128}
129/*-----------------------------------------------------------------------------------*/
130/**
131 * Poll the SLIP device for an available packet.
132 *
133 * This function will poll the SLIP device to see if a packet is
134 * available. It uses a buffer in which all avaliable bytes from the
135 * RS232 interface are read into. When a full packet has been read
136 * into the buffer, the packet is copied into the uip_buf buffer and
137 * the length of the packet is returned.
138 *
139 * \return The length of the packet placed in the uip_buf buffer, or
140 * zero if no packet is available.
141 */
142/*-----------------------------------------------------------------------------------*/
143u16_t
144slipdev_poll(void)
145{
146 u8_t c;
147
148 while(slipdev_char_poll(&c)) {
149 switch(c) {
150 case SLIP_ESC:
151 lastc = c;
152 break;
153
154 case SLIP_END:
155 lastc = c;
156 /* End marker found, we copy our input buffer to the uip_buf
157 buffer and return the size of the packet we copied. */
158 memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len);
159 tmplen = len;
160 len = 0;
161 return tmplen;
162
163 default:
164 if(lastc == SLIP_ESC) {
165 lastc = c;
166 /* Previous read byte was an escape byte, so this byte will be
167 interpreted differently from others. */
168 switch(c) {
169 case SLIP_ESC_END:
170 c = SLIP_END;
171 break;
172 case SLIP_ESC_ESC:
173 c = SLIP_ESC;
174 break;
175 }
176 } else {
177 lastc = c;
178 }
179
180 slip_buf[len] = c;
181 ++len;
182
183 if(len > UIP_BUFSIZE) {
184 len = 0;
185 }
186
187 break;
188 }
189 }
190 return 0;
191}
192/*-----------------------------------------------------------------------------------*/
193/**
194 * Initialize the SLIP module.
195 *
196 * This function does not initialize the underlying RS232 device, but
197 * only the SLIP part.
198 */
199/*-----------------------------------------------------------------------------------*/
200void
201slipdev_init(void)
202{
203 lastc = len = 0;
204}
205/*-----------------------------------------------------------------------------------*/
206
207/** @} */
208/** @} */