ReactOS 0.4.16-dev-340-g0540c21
slipif.c
Go to the documentation of this file.
1
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 * Simon Goldschmidt
39 */
40
41
62#include "netif/slipif.h"
63#include "lwip/opt.h"
64
65#include "lwip/def.h"
66#include "lwip/pbuf.h"
67#include "lwip/stats.h"
68#include "lwip/snmp.h"
69#include "lwip/sys.h"
70#include "lwip/sio.h"
71
72#define SLIP_END 0xC0 /* 0300: start and end of every packet */
73#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */
74#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */
75#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */
76
78#ifndef SLIP_MAX_SIZE
79#define SLIP_MAX_SIZE 1500
80#endif
81
86#ifndef SLIP_SIO_SPEED
87#define SLIP_SIO_SPEED(sio_fd) 0
88#endif
89
93};
94
97 /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
98 struct pbuf *p, *q;
101#if SLIP_RX_FROM_ISR
102 struct pbuf *rxpackets;
103#endif
104};
105
115static err_t
116slipif_output(struct netif *netif, struct pbuf *p)
117{
118 struct slipif_priv *priv;
119 struct pbuf *q;
120 u16_t i;
121 u8_t c;
122
123 LWIP_ASSERT("netif != NULL", (netif != NULL));
124 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
125 LWIP_ASSERT("p != NULL", (p != NULL));
126
127 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output: sending %"U16_F" bytes\n", p->tot_len));
128 priv = (struct slipif_priv *)netif->state;
129
130 /* Send pbuf out on the serial I/O device. */
131 /* Start with packet delimiter. */
132 sio_send(SLIP_END, priv->sd);
133
134 for (q = p; q != NULL; q = q->next) {
135 for (i = 0; i < q->len; i++) {
136 c = ((u8_t *)q->payload)[i];
137 switch (c) {
138 case SLIP_END:
139 /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */
140 sio_send(SLIP_ESC, priv->sd);
141 sio_send(SLIP_ESC_END, priv->sd);
142 break;
143 case SLIP_ESC:
144 /* need to escape this byte (0xDB -> 0xDB, 0xDD) */
145 sio_send(SLIP_ESC, priv->sd);
146 sio_send(SLIP_ESC_ESC, priv->sd);
147 break;
148 default:
149 /* normal byte - no need for escaping */
150 sio_send(c, priv->sd);
151 break;
152 }
153 }
154 }
155 /* End with packet delimiter. */
156 sio_send(SLIP_END, priv->sd);
157 return ERR_OK;
158}
159
160#if LWIP_IPV4
171static err_t
172slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
173{
174 LWIP_UNUSED_ARG(ipaddr);
175 return slipif_output(netif, p);
176}
177#endif /* LWIP_IPV4 */
178
179#if LWIP_IPV6
190static err_t
191slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
192{
193 LWIP_UNUSED_ARG(ipaddr);
194 return slipif_output(netif, p);
195}
196#endif /* LWIP_IPV6 */
197
206static struct pbuf *
208{
209 struct slipif_priv *priv;
210 struct pbuf *t;
211
212 LWIP_ASSERT("netif != NULL", (netif != NULL));
213 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
214
215 priv = (struct slipif_priv *)netif->state;
216
217 switch (priv->state) {
218 case SLIP_RECV_NORMAL:
219 switch (c) {
220 case SLIP_END:
221 if (priv->recved > 0) {
222 /* Received whole packet. */
223 /* Trim the pbuf to the size of the received packet. */
224 pbuf_realloc(priv->q, priv->recved);
225
226 LINK_STATS_INC(link.recv);
227
228 LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved));
229 t = priv->q;
230 priv->p = priv->q = NULL;
231 priv->i = priv->recved = 0;
232 return t;
233 }
234 return NULL;
235 case SLIP_ESC:
236 priv->state = SLIP_RECV_ESCAPE;
237 return NULL;
238 default:
239 break;
240 } /* end switch (c) */
241 break;
242 case SLIP_RECV_ESCAPE:
243 /* un-escape END or ESC bytes, leave other bytes
244 (although that would be a protocol error) */
245 switch (c) {
246 case SLIP_ESC_END:
247 c = SLIP_END;
248 break;
249 case SLIP_ESC_ESC:
250 c = SLIP_ESC;
251 break;
252 default:
253 break;
254 }
255 priv->state = SLIP_RECV_NORMAL;
256 break;
257 default:
258 break;
259 } /* end switch (priv->state) */
260
261 /* byte received, packet not yet completely received */
262 if (priv->p == NULL) {
263 /* allocate a new pbuf */
264 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
266
267 if (priv->p == NULL) {
268 LINK_STATS_INC(link.drop);
269 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
270 /* don't process any further since we got no pbuf to receive to */
271 return NULL;
272 }
273
274 if (priv->q != NULL) {
275 /* 'chain' the pbuf to the existing chain */
276 pbuf_cat(priv->q, priv->p);
277 } else {
278 /* p is the first pbuf in the chain */
279 priv->q = priv->p;
280 }
281 }
282
283 /* this automatically drops bytes if > SLIP_MAX_SIZE */
284 if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
285 ((u8_t *)priv->p->payload)[priv->i] = c;
286 priv->recved++;
287 priv->i++;
288 if (priv->i >= priv->p->len) {
289 /* on to the next pbuf */
290 priv->i = 0;
291 if (priv->p->next != NULL && priv->p->next->len > 0) {
292 /* p is a chain, on to the next in the chain */
293 priv->p = priv->p->next;
294 } else {
295 /* p is a single pbuf, set it to NULL so next time a new
296 * pbuf is allocated */
297 priv->p = NULL;
298 }
299 }
300 }
301 return NULL;
302}
303
309static void
311{
312 struct pbuf *p;
314 if (p != NULL) {
315 if (netif->input(p, netif) != ERR_OK) {
316 pbuf_free(p);
317 }
318 }
319}
320
321#if SLIP_USE_RX_THREAD
329static void
330slipif_loop_thread(void *nf)
331{
332 u8_t c;
333 struct netif *netif = (struct netif *)nf;
334 struct slipif_priv *priv = (struct slipif_priv *)netif->state;
335
336 while (1) {
337 if (sio_read(priv->sd, &c, 1) > 0) {
339 }
340 }
341}
342#endif /* SLIP_USE_RX_THREAD */
343
359err_t
361{
362 struct slipif_priv *priv;
363 u8_t sio_num;
364
365 LWIP_ASSERT("slipif needs an input callback", netif->input != NULL);
366
367 /* netif->state contains serial port number */
369
370 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)sio_num));
371
372 /* Allocate private data */
373 priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv));
374 if (!priv) {
375 return ERR_MEM;
376 }
377
378 netif->name[0] = 's';
379 netif->name[1] = 'l';
380#if LWIP_IPV4
381 netif->output = slipif_output_v4;
382#endif /* LWIP_IPV4 */
383#if LWIP_IPV6
384 netif->output_ip6 = slipif_output_v6;
385#endif /* LWIP_IPV6 */
387
388 /* Try to open the serial port. */
389 priv->sd = sio_open(sio_num);
390 if (!priv->sd) {
391 /* Opening the serial port failed. */
392 mem_free(priv);
393 return ERR_IF;
394 }
395
396 /* Initialize private data */
397 priv->p = NULL;
398 priv->q = NULL;
399 priv->state = SLIP_RECV_NORMAL;
400 priv->i = 0;
401 priv->recved = 0;
402#if SLIP_RX_FROM_ISR
403 priv->rxpackets = NULL;
404#endif
405
406 netif->state = priv;
407
408 /* initialize the snmp variables and counters inside the struct netif */
409 MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd));
410
411#if SLIP_USE_RX_THREAD
412 /* Create a thread to poll the serial line. */
413 sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
415#endif /* SLIP_USE_RX_THREAD */
416 return ERR_OK;
417}
418
425void
427{
428 u8_t c;
429 struct slipif_priv *priv;
430
431 LWIP_ASSERT("netif != NULL", (netif != NULL));
432 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
433
434 priv = (struct slipif_priv *)netif->state;
435
436 while (sio_tryread(priv->sd, &c, 1) > 0) {
438 }
439}
440
441#if SLIP_RX_FROM_ISR
448void
449slipif_process_rxqueue(struct netif *netif)
450{
451 struct slipif_priv *priv;
452 SYS_ARCH_DECL_PROTECT(old_level);
453
454 LWIP_ASSERT("netif != NULL", (netif != NULL));
455 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
456
457 priv = (struct slipif_priv *)netif->state;
458
459 SYS_ARCH_PROTECT(old_level);
460 while (priv->rxpackets != NULL) {
461 struct pbuf *p = priv->rxpackets;
462#if SLIP_RX_QUEUE
463 /* dequeue packet */
464 struct pbuf *q = p;
465 while ((q->len != q->tot_len) && (q->next != NULL)) {
466 q = q->next;
467 }
468 priv->rxpackets = q->next;
469 q->next = NULL;
470#else /* SLIP_RX_QUEUE */
471 priv->rxpackets = NULL;
472#endif /* SLIP_RX_QUEUE */
473 SYS_ARCH_UNPROTECT(old_level);
474 if (netif->input(p, netif) != ERR_OK) {
475 pbuf_free(p);
476 }
477 SYS_ARCH_PROTECT(old_level);
478 }
479 SYS_ARCH_UNPROTECT(old_level);
480}
481
487static void
488slipif_rxbyte_enqueue(struct netif *netif, u8_t data)
489{
490 struct pbuf *p;
491 struct slipif_priv *priv = (struct slipif_priv *)netif->state;
492 SYS_ARCH_DECL_PROTECT(old_level);
493
495 if (p != NULL) {
496 SYS_ARCH_PROTECT(old_level);
497 if (priv->rxpackets != NULL) {
498#if SLIP_RX_QUEUE
499 /* queue multiple pbufs */
500 struct pbuf *q = p;
501 while (q->next != NULL) {
502 q = q->next;
503 }
504 q->next = p;
505 } else {
506#else /* SLIP_RX_QUEUE */
507 pbuf_free(priv->rxpackets);
508 }
509 {
510#endif /* SLIP_RX_QUEUE */
511 priv->rxpackets = p;
512 }
513 SYS_ARCH_UNPROTECT(old_level);
514 }
515}
516
527void
528slipif_received_byte(struct netif *netif, u8_t data)
529{
530 LWIP_ASSERT("netif != NULL", (netif != NULL));
531 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
532 slipif_rxbyte_enqueue(netif, data);
533}
534
546void
547slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len)
548{
549 u8_t i;
550 u8_t *rxdata = data;
551 LWIP_ASSERT("netif != NULL", (netif != NULL));
552 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
553
554 for (i = 0; i < len; i++, rxdata++) {
555 slipif_rxbyte_enqueue(netif, *rxdata);
556 }
557}
558#endif /* SLIP_RX_FROM_ISR */
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
const WCHAR * link
Definition: db.cpp:997
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
switch(r->id)
Definition: btrfs.c:3046
#define SYS_ARCH_UNPROTECT(lev)
Definition: cc.h:39
#define SYS_ARCH_PROTECT(lev)
Definition: cc.h:38
#define SYS_ARCH_DECL_PROTECT(lev)
Definition: cc.h:37
#define U16_F
Definition: cc.h:19
void * mem_malloc(mem_size_t size_in)
Definition: mem.c:831
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
sio_fd_t sio_open(u8_t devnum)
void sio_send(u8_t c, sio_fd_t fd)
u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len)
u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
#define MIB2_INIT_NETIF(netif, type, speed)
Definition: snmp.h:138
#define ERR_MEM
Definition: fontsub.h:52
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint8_t u8_t
Definition: arch.h:125
#define LWIP_PTR_NUMERIC_CAST(target_type, val)
Definition: arch.h:252
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
s8_t err_t
Definition: err.h:96
@ ERR_IF
Definition: err.h:79
@ ERR_OK
Definition: err.h:55
#define SLIP_DEBUG
Definition: opt.h:3519
#define PBUF_LINK_HLEN
Definition: opt.h:1581
#define PBUF_LINK_ENCAPSULATION_HLEN
Definition: opt.h:1590
#define PBUF_POOL_BUFSIZE
Definition: opt.h:1599
#define SLIPIF_THREAD_PRIO
Definition: opt.h:1867
#define SLIPIF_THREAD_STACKSIZE
Definition: opt.h:1858
#define SLIPIF_THREAD_NAME
Definition: opt.h:1849
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:402
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:855
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
@ PBUF_POOL
Definition: pbuf.h:167
@ PBUF_LINK
Definition: pbuf.h:102
err_t slipif_init(struct netif *netif)
Definition: slipif.c:360
void slipif_poll(struct netif *netif)
Definition: slipif.c:426
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:275
#define c
Definition: ke_i.h:80
#define SLIP_SIO_SPEED(sio_fd)
Definition: slipif.c:87
#define SLIP_ESC
Definition: slipif.c:73
#define SLIP_ESC_END
Definition: slipif.c:74
#define SLIP_ESC_ESC
Definition: slipif.c:75
static void slipif_rxbyte_input(struct netif *netif, u8_t c)
Definition: slipif.c:310
static struct pbuf * slipif_rxbyte(struct netif *netif, u8_t c)
Definition: slipif.c:207
static err_t slipif_output(struct netif *netif, struct pbuf *p)
Definition: slipif.c:116
#define SLIP_END
Definition: slipif.c:72
#define SLIP_MAX_SIZE
Definition: slipif.c:79
slipif_recv_state
Definition: slipif.c:90
@ SLIP_RECV_NORMAL
Definition: slipif.c:91
@ SLIP_RECV_ESCAPE
Definition: slipif.c:92
#define LINK_STATS_INC(x)
Definition: stats.h:384
struct define * next
Definition: compiler.c:65
Definition: netif.h:269
char name[2]
Definition: netif.h:356
void * state
Definition: netif.h:332
netif_input_fn input
Definition: netif.h:297
u16_t mtu
Definition: netif.h:344
Definition: pbuf.h:186
struct pbuf * p
Definition: slipif.c:98
u16_t recved
Definition: slipif.c:100
struct pbuf * q
Definition: slipif.c:98
sio_fd_t sd
Definition: slipif.c:96
u8_t state
Definition: slipif.c:99
u16_t i
Definition: slipif.c:100