Contiki 2.6

slipdev.c

Go to the documentation of this file.
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 /** @} */