ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

slipif.c
Go to the documentation of this file.
00001 
00007 /*
00008  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00009  * All rights reserved. 
00010  *
00011  * Redistribution and use in source and binary forms, with or without 
00012  * modification, are permitted provided that the following conditions 
00013  * are met: 
00014  * 1. Redistributions of source code must retain the above copyright 
00015  *    notice, this list of conditions and the following disclaimer. 
00016  * 2. Redistributions in binary form must reproduce the above copyright 
00017  *    notice, this list of conditions and the following disclaimer in the 
00018  *    documentation and/or other materials provided with the distribution. 
00019  * 3. Neither the name of the Institute nor the names of its contributors 
00020  *    may be used to endorse or promote products derived from this software 
00021  *    without specific prior written permission. 
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
00024  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00026  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
00027  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00028  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00029  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00032  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00033  * SUCH DAMAGE. 
00034  *
00035  * This file is built upon the file: src/arch/rtxc/netif/sioslip.c
00036  *
00037  * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> 
00038  */
00039 
00040 /* 
00041  * This is an arch independent SLIP netif. The specific serial hooks must be
00042  * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send
00043  */
00044 
00045 #include "netif/slipif.h"
00046 #include "lwip/opt.h"
00047 
00048 #if LWIP_HAVE_SLIPIF
00049 
00050 #include "lwip/def.h"
00051 #include "lwip/pbuf.h"
00052 #include "lwip/sys.h"
00053 #include "lwip/stats.h"
00054 #include "lwip/snmp.h"
00055 #include "lwip/sio.h"
00056 
00057 #define SLIP_BLOCK     1
00058 #define SLIP_DONTBLOCK 0
00059 
00060 #define SLIP_END     0300 /* 0xC0 */
00061 #define SLIP_ESC     0333 /* 0xDB */
00062 #define SLIP_ESC_END 0334 /* 0xDC */
00063 #define SLIP_ESC_ESC 0335 /* 0xDD */
00064 
00065 #define SLIP_MAX_SIZE 1500
00066 
00067 enum slipif_recv_state {
00068     SLIP_RECV_NORMAL,
00069     SLIP_RECV_ESCAPE,
00070 };
00071 
00072 struct slipif_priv {
00073   sio_fd_t sd;
00074   /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
00075   struct pbuf *p, *q;
00076   enum slipif_recv_state state;
00077   u16_t i, recved;
00078 };
00079 
00090 err_t
00091 slipif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr)
00092 {
00093   struct slipif_priv *priv;
00094   struct pbuf *q;
00095   u16_t i;
00096   u8_t c;
00097 
00098   LWIP_ASSERT("netif != NULL", (netif != NULL));
00099   LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
00100   LWIP_ASSERT("p != NULL", (p != NULL));
00101 
00102   LWIP_UNUSED_ARG(ipaddr);
00103 
00104   priv = netif->state;
00105 
00106   /* Send pbuf out on the serial I/O device. */
00107   sio_send(SLIP_END, priv->sd);
00108 
00109   for (q = p; q != NULL; q = q->next) {
00110     for (i = 0; i < q->len; i++) {
00111       c = ((u8_t *)q->payload)[i];
00112       switch (c) {
00113       case SLIP_END:
00114         sio_send(SLIP_ESC, priv->sd);
00115         sio_send(SLIP_ESC_END, priv->sd);
00116         break;
00117       case SLIP_ESC:
00118         sio_send(SLIP_ESC, priv->sd);
00119         sio_send(SLIP_ESC_ESC, priv->sd);
00120         break;
00121       default:
00122         sio_send(c, priv->sd);
00123         break;
00124       }
00125     }
00126   }
00127   sio_send(SLIP_END, priv->sd);
00128   return ERR_OK;
00129 }
00130 
00141 static u32_t
00142 slip_sio_read(sio_fd_t fd, u8_t* data, u32_t len, u8_t block)
00143 {
00144   if (block) {
00145     return sio_read(fd, data, len);
00146   } else {
00147     return sio_tryread(fd, data, len);
00148   }
00149 }
00150 
00162 static struct pbuf *
00163 slipif_input(struct netif *netif, u8_t block)
00164 {
00165   struct slipif_priv *priv;
00166   u8_t c;
00167   struct pbuf *t;
00168 
00169   LWIP_ASSERT("netif != NULL", (netif != NULL));
00170   LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
00171 
00172   priv = netif->state;
00173 
00174   while (slip_sio_read(priv->sd, &c, 1, block) > 0) {
00175     switch (priv->state) {
00176     case SLIP_RECV_NORMAL:
00177       switch (c) {
00178       case SLIP_END:
00179         if (priv->recved > 0) {
00180           /* Received whole packet. */
00181           /* Trim the pbuf to the size of the received packet. */
00182           pbuf_realloc(priv->q, priv->recved);
00183 
00184           LINK_STATS_INC(link.recv);
00185 
00186           LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
00187           t = priv->q;
00188           priv->p = priv->q = NULL;
00189           priv->i = priv->recved = 0;
00190           return t;
00191         }
00192         continue;
00193       case SLIP_ESC:
00194         priv->state = SLIP_RECV_ESCAPE;
00195         continue;
00196       }
00197       break;
00198     case SLIP_RECV_ESCAPE:
00199       switch (c) {
00200       case SLIP_ESC_END:
00201         c = SLIP_END;
00202         break;
00203       case SLIP_ESC_ESC:
00204         c = SLIP_ESC;
00205         break;
00206       }
00207       priv->state = SLIP_RECV_NORMAL;
00208       /* FALLTHROUGH */
00209     }
00210 
00211     /* byte received, packet not yet completely received */
00212     if (priv->p == NULL) {
00213       /* allocate a new pbuf */
00214       LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
00215       priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL);
00216 
00217       if (priv->p == NULL) {
00218         LINK_STATS_INC(link.drop);
00219         LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
00220         /* don't process any further since we got no pbuf to receive to */
00221         break;
00222       }
00223 
00224       if (priv->q != NULL) {
00225         /* 'chain' the pbuf to the existing chain */
00226         pbuf_cat(priv->q, priv->p);
00227       } else {
00228         /* p is the first pbuf in the chain */
00229         priv->q = priv->p;
00230       }
00231     }
00232 
00233     /* this automatically drops bytes if > SLIP_MAX_SIZE */
00234     if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
00235       ((u8_t *)priv->p->payload)[priv->i] = c;
00236       priv->recved++;
00237       priv->i++;
00238       if (priv->i >= priv->p->len) {
00239         /* on to the next pbuf */
00240         priv->i = 0;
00241         if (priv->p->next != NULL && priv->p->next->len > 0) {
00242           /* p is a chain, on to the next in the chain */
00243             priv->p = priv->p->next;
00244         } else {
00245           /* p is a single pbuf, set it to NULL so next time a new
00246            * pbuf is allocated */
00247             priv->p = NULL;
00248         }
00249       }
00250     }
00251   }
00252 
00253   return NULL;
00254 }
00255 
00256 #if !NO_SYS
00257 
00264 static void
00265 slipif_loop_thread(void *nf)
00266 {
00267   struct pbuf *p;
00268   struct netif *netif = (struct netif *)nf;
00269 
00270   while (1) {
00271     p = slipif_input(netif, SLIP_BLOCK);
00272     if (p != NULL) {
00273       if (netif->input(p, netif) != ERR_OK) {
00274         pbuf_free(p);
00275         p = NULL;
00276       }
00277     }
00278   }
00279 }
00280 #endif /* !NO_SYS */
00281 
00296 err_t
00297 slipif_init(struct netif *netif)
00298 {
00299   struct slipif_priv *priv;
00300 
00301   LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
00302 
00303   /* Allocate private data */
00304   priv = mem_malloc(sizeof(struct slipif_priv));
00305   if (!priv) {
00306     return ERR_MEM;
00307   }
00308 
00309   netif->name[0] = 's';
00310   netif->name[1] = 'l';
00311   netif->output = slipif_output;
00312   netif->mtu = SLIP_MAX_SIZE;
00313   netif->flags |= NETIF_FLAG_POINTTOPOINT;
00314 
00315   /* Try to open the serial port (netif->num contains the port number). */
00316   priv->sd = sio_open(netif->num);
00317   if (!priv->sd) {
00318     /* Opening the serial port failed. */
00319     mem_free(priv);
00320     return ERR_IF;
00321   }
00322 
00323   /* Initialize private data */
00324   priv->p = NULL;
00325   priv->q = NULL;
00326   priv->state = SLIP_RECV_NORMAL;
00327   priv->i = 0;
00328   priv->recved = 0;
00329 
00330   netif->state = priv;
00331 
00332   /* initialize the snmp variables and counters inside the struct netif
00333    * ifSpeed: no assumption can be made without knowing more about the
00334    * serial line!
00335    */
00336   NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0);
00337 
00338   /* Create a thread to poll the serial line. */
00339   sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
00340     SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
00341   return ERR_OK;
00342 }
00343 
00349 void
00350 slipif_poll(struct netif *netif)
00351 {
00352   struct pbuf *p;
00353   struct slipif_priv *priv;
00354 
00355   LWIP_ASSERT("netif != NULL", (netif != NULL));
00356   LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
00357 
00358   priv = netif->state;
00359 
00360   while ((p = slipif_input(netif, SLIP_DONTBLOCK)) != NULL) {
00361     if (netif->input(p, netif) != ERR_OK) {
00362       pbuf_free(p);
00363     }
00364   }
00365 }
00366 
00367 #endif /* LWIP_HAVE_SLIPIF */

Generated on Fri May 25 2012 04:34:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.