OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [ethernet/] [lwIP_130/] [src/] [netif/] [slipif.c] - Blame information for rev 606

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 606 jeremybenn
/**
2
 * @file
3
 * SLIP Interface
4
 *
5
 */
6
 
7
/*
8
 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions and the following disclaimer.
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in the
18
 *    documentation and/or other materials provided with the distribution.
19
 * 3. Neither the name of the Institute nor the names of its contributors
20
 *    may be used to endorse or promote products derived from this software
21
 *    without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
 * SUCH DAMAGE.
34
 *
35
 * This file is built upon the file: src/arch/rtxc/netif/sioslip.c
36
 *
37
 * Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com>
38
 */
39
 
40
/*
41
 * This is an arch independent SLIP netif. The specific serial hooks must be
42
 * provided by another file. They are sio_open, sio_recv and sio_send
43
 */
44
 
45
#include "netif/slipif.h"
46
#include "lwip/opt.h"
47
#include "lwip/def.h"
48
#include "lwip/pbuf.h"
49
#include "lwip/sys.h"
50
#include "lwip/stats.h"
51
#include "lwip/snmp.h"
52
#include "lwip/sio.h"
53
 
54
#define SLIP_END     0300 /* 0xC0 */
55
#define SLIP_ESC     0333 /* 0xDB */
56
#define SLIP_ESC_END 0334 /* 0xDC */
57
#define SLIP_ESC_ESC 0335 /* 0xDD */
58
 
59
#define MAX_SIZE     1500
60
 
61
/**
62
 * Send a pbuf doing the necessary SLIP encapsulation
63
 *
64
 * Uses the serial layer's sio_send()
65
 *
66
 * @param netif the lwip network interface structure for this slipif
67
 * @param p the pbuf chaing packet to send
68
 * @param ipaddr the ip address to send the packet to (not used for slipif)
69
 * @return always returns ERR_OK since the serial layer does not provide return values
70
 */
71
err_t
72
slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
73
{
74
  struct pbuf *q;
75
  u16_t i;
76
  u8_t c;
77
 
78
  LWIP_ASSERT("netif != NULL", (netif != NULL));
79
  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
80
  LWIP_ASSERT("p != NULL", (p != NULL));
81
 
82
  LWIP_UNUSED_ARG(ipaddr);
83
 
84
  /* Send pbuf out on the serial I/O device. */
85
  sio_send(SLIP_END, netif->state);
86
 
87
  for (q = p; q != NULL; q = q->next) {
88
    for (i = 0; i < q->len; i++) {
89
      c = ((u8_t *)q->payload)[i];
90
      switch (c) {
91
      case SLIP_END:
92
        sio_send(SLIP_ESC, netif->state);
93
        sio_send(SLIP_ESC_END, netif->state);
94
        break;
95
      case SLIP_ESC:
96
        sio_send(SLIP_ESC, netif->state);
97
        sio_send(SLIP_ESC_ESC, netif->state);
98
        break;
99
      default:
100
        sio_send(c, netif->state);
101
        break;
102
      }
103
    }
104
  }
105
  sio_send(SLIP_END, netif->state);
106
  return ERR_OK;
107
}
108
 
109
/**
110
 * Handle the incoming SLIP stream character by character
111
 *
112
 * Poll the serial layer by calling sio_recv()
113
 *
114
 * @param netif the lwip network interface structure for this slipif
115
 * @return The IP packet when SLIP_END is received
116
 */
117
static struct pbuf *
118
slipif_input(struct netif *netif)
119
{
120
  u8_t c;
121
  /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
122
  struct pbuf *p, *q;
123
  u16_t recved;
124
  u16_t i;
125
 
126
  LWIP_ASSERT("netif != NULL", (netif != NULL));
127
  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
128
 
129
  q = p = NULL;
130
  recved = i = 0;
131
  c = 0;
132
 
133
  while (1) {
134
    c = sio_recv(netif->state);
135
    switch (c) {
136
    case SLIP_END:
137
      if (recved > 0) {
138
        /* Received whole packet. */
139
        /* Trim the pbuf to the size of the received packet. */
140
        pbuf_realloc(q, recved);
141
 
142
        LINK_STATS_INC(link.recv);
143
 
144
        LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
145
        return q;
146
      }
147
      break;
148
 
149
    case SLIP_ESC:
150
      c = sio_recv(netif->state);
151
      switch (c) {
152
      case SLIP_ESC_END:
153
        c = SLIP_END;
154
        break;
155
      case SLIP_ESC_ESC:
156
        c = SLIP_ESC;
157
        break;
158
      }
159
      /* FALLTHROUGH */
160
 
161
    default:
162
      /* byte received, packet not yet completely received */
163
      if (p == NULL) {
164
        /* allocate a new pbuf */
165
        LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
166
        p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
167
 
168
        if (p == NULL) {
169
          LINK_STATS_INC(link.drop);
170
          LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
171
          /* don't process any further since we got no pbuf to receive to */
172
          break;
173
        }
174
 
175
        if (q != NULL) {
176
          /* 'chain' the pbuf to the existing chain */
177
          pbuf_cat(q, p);
178
        } else {
179
          /* p is the first pbuf in the chain */
180
          q = p;
181
        }
182
      }
183
 
184
      /* this automatically drops bytes if > MAX_SIZE */
185
      if ((p != NULL) && (recved <= MAX_SIZE)) {
186
        ((u8_t *)p->payload)[i] = c;
187
        recved++;
188
        i++;
189
        if (i >= p->len) {
190
          /* on to the next pbuf */
191
          i = 0;
192
          if (p->next != NULL && p->next->len > 0) {
193
            /* p is a chain, on to the next in the chain */
194
            p = p->next;
195
          } else {
196
            /* p is a single pbuf, set it to NULL so next time a new
197
             * pbuf is allocated */
198
            p = NULL;
199
          }
200
        }
201
      }
202
      break;
203
    }
204
  }
205
  return NULL;
206
}
207
 
208
#if !NO_SYS
209
/**
210
 * The SLIP input thread.
211
 *
212
 * Feed the IP layer with incoming packets
213
 *
214
 * @param nf the lwip network interface structure for this slipif
215
 */
216
static void
217
slipif_loop(void *nf)
218
{
219
  struct pbuf *p;
220
  struct netif *netif = (struct netif *)nf;
221
 
222
  while (1) {
223
    p = slipif_input(netif);
224
    if (p != NULL) {
225
      if (netif->input(p, netif) != ERR_OK) {
226
        pbuf_free(p);
227
        p = NULL;
228
      }
229
    }
230
  }
231
}
232
#endif /* !NO_SYS */
233
 
234
/**
235
 * SLIP netif initialization
236
 *
237
 * Call the arch specific sio_open and remember
238
 * the opened device in the state field of the netif.
239
 *
240
 * @param netif the lwip network interface structure for this slipif
241
 * @return ERR_OK if serial line could be opened,
242
 *         ERR_IF is serial line couldn't be opened
243
 *
244
 * @note netif->num must contain the number of the serial port to open
245
 *       (0 by default)
246
 */
247
err_t
248
slipif_init(struct netif *netif)
249
{
250
 
251
  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
252
 
253
  netif->name[0] = 's';
254
  netif->name[1] = 'l';
255
  netif->output = slipif_output;
256
  netif->mtu = MAX_SIZE;
257
  netif->flags = NETIF_FLAG_POINTTOPOINT;
258
 
259
  /* Try to open the serial port (netif->num contains the port number). */
260
  netif->state = sio_open(netif->num);
261
  if (!netif->state) {
262
    /* Opening the serial port failed. */
263
    return ERR_IF;
264
  }
265
 
266
  /* initialize the snmp variables and counters inside the struct netif
267
   * ifSpeed: no assumption can be made without knowing more about the
268
   * serial line!
269
   */
270
  NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0);
271
 
272
  /* Create a thread to poll the serial line. */
273
  sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop, netif, SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
274
  return ERR_OK;
275
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.