Contiki 2.6
|
00001 /** 00002 * \addtogroup uip 00003 * @{ 00004 */ 00005 00006 /** 00007 * \defgroup slip Serial Line IP (SLIP) protocol 00008 * @{ 00009 * 00010 * The SLIP protocol is a very simple way to transmit IP packets over 00011 * a serial line. It does not provide any framing or error control, 00012 * and is therefore not very widely used today. 00013 * 00014 * This SLIP implementation requires two functions for accessing the 00015 * serial device: slipdev_char_poll() and slipdev_char_put(). These 00016 * must be implemented specifically for the system on which the SLIP 00017 * protocol is to be run. 00018 */ 00019 00020 /** 00021 * \file 00022 * SLIP protocol implementation 00023 * \author Adam Dunkels <adam@dunkels.com> 00024 */ 00025 00026 /* 00027 * Copyright (c) 2001, Adam Dunkels. 00028 * All rights reserved. 00029 * 00030 * Redistribution and use in source and binary forms, with or without 00031 * modification, are permitted provided that the following conditions 00032 * are met: 00033 * 1. Redistributions of source code must retain the above copyright 00034 * notice, this list of conditions and the following disclaimer. 00035 * 2. Redistributions in binary form must reproduce the above copyright 00036 * notice, this list of conditions and the following disclaimer in the 00037 * documentation and/or other materials provided with the distribution. 00038 * 3. The name of the author may not be used to endorse or promote 00039 * products derived from this software without specific prior 00040 * written permission. 00041 * 00042 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00043 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00044 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00045 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00046 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00047 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00048 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00049 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00050 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00051 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00052 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00053 * 00054 * This file is part of the uIP TCP/IP stack. 00055 * 00056 * $Id: slipdev.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ 00057 * 00058 */ 00059 00060 /* 00061 * This is a generic implementation of the SLIP protocol over an RS232 00062 * (serial) device. 00063 * 00064 * Huge thanks to Ullrich von Bassewitz <uz@cc65.org> of cc65 fame for 00065 * and endless supply of bugfixes, insightsful comments and 00066 * suggestions, and improvements to this code! 00067 */ 00068 00069 #include "uip.h" 00070 #include "uip-fw.h" 00071 #include "slipdev.h" 00072 #include <string.h> /* For memcpy() */ 00073 00074 #define SLIP_END 0300 00075 #define SLIP_ESC 0333 00076 #define SLIP_ESC_END 0334 00077 #define SLIP_ESC_ESC 0335 00078 00079 static uint8_t slip_buf[UIP_BUFSIZE]; 00080 00081 static uint16_t len, tmplen; 00082 static uint8_t lastc; 00083 00084 /*-----------------------------------------------------------------------------------*/ 00085 /** 00086 * Send the packet in the uip_buf and uip_appdata buffers using the 00087 * SLIP protocol. 00088 * 00089 * The first 40 bytes of the packet (the IP and TCP headers) are read 00090 * from the uip_buf buffer, and the following bytes (the application 00091 * data) are read from the uip_appdata buffer. 00092 * 00093 * \return This function will always return UIP_FW_OK. 00094 */ 00095 /*-----------------------------------------------------------------------------------*/ 00096 uint8_t 00097 slipdev_send(void) 00098 { 00099 uint16_t i; 00100 uint8_t *ptr; 00101 uint8_t c; 00102 00103 slipdev_char_put(SLIP_END); 00104 00105 ptr = &uip_buf[UIP_LLH_LEN]; 00106 for(i = 0; i < uip_len; ++i) { 00107 if(i == UIP_TCPIP_HLEN) { 00108 ptr = (char *)uip_appdata; 00109 } 00110 c = *ptr++; 00111 switch(c) { 00112 case SLIP_END: 00113 slipdev_char_put(SLIP_ESC); 00114 slipdev_char_put(SLIP_ESC_END); 00115 break; 00116 case SLIP_ESC: 00117 slipdev_char_put(SLIP_ESC); 00118 slipdev_char_put(SLIP_ESC_ESC); 00119 break; 00120 default: 00121 slipdev_char_put(c); 00122 break; 00123 } 00124 } 00125 slipdev_char_put(SLIP_END); 00126 00127 return UIP_FW_OK; 00128 } 00129 /*-----------------------------------------------------------------------------------*/ 00130 /** 00131 * Poll the SLIP device for an available packet. 00132 * 00133 * This function will poll the SLIP device to see if a packet is 00134 * available. It uses a buffer in which all avaliable bytes from the 00135 * RS232 interface are read into. When a full packet has been read 00136 * into the buffer, the packet is copied into the uip_buf buffer and 00137 * the length of the packet is returned. 00138 * 00139 * \return The length of the packet placed in the uip_buf buffer, or 00140 * zero if no packet is available. 00141 */ 00142 /*-----------------------------------------------------------------------------------*/ 00143 uint16_t 00144 slipdev_poll(void) 00145 { 00146 uint8_t c; 00147 00148 while(slipdev_char_poll(&c)) { 00149 switch(c) { 00150 case SLIP_ESC: 00151 lastc = c; 00152 break; 00153 00154 case SLIP_END: 00155 lastc = c; 00156 /* End marker found, we copy our input buffer to the uip_buf 00157 buffer and return the size of the packet we copied. */ 00158 memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len); 00159 tmplen = len; 00160 len = 0; 00161 return tmplen; 00162 00163 default: 00164 if(lastc == SLIP_ESC) { 00165 lastc = c; 00166 /* Previous read byte was an escape byte, so this byte will be 00167 interpreted differently from others. */ 00168 switch(c) { 00169 case SLIP_ESC_END: 00170 c = SLIP_END; 00171 break; 00172 case SLIP_ESC_ESC: 00173 c = SLIP_ESC; 00174 break; 00175 } 00176 } else { 00177 lastc = c; 00178 } 00179 00180 slip_buf[len] = c; 00181 ++len; 00182 00183 if(len > UIP_BUFSIZE) { 00184 len = 0; 00185 } 00186 00187 break; 00188 } 00189 } 00190 return 0; 00191 } 00192 /*-----------------------------------------------------------------------------------*/ 00193 /** 00194 * Initialize the SLIP module. 00195 * 00196 * This function does not initialize the underlying RS232 device, but 00197 * only the SLIP part. 00198 */ 00199 /*-----------------------------------------------------------------------------------*/ 00200 void 00201 slipdev_init(void) 00202 { 00203 lastc = len = 0; 00204 } 00205 /*-----------------------------------------------------------------------------------*/ 00206 00207 /** @} */ 00208 /** @} */