Prusa MINI Firmware overview
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
slipif.c File Reference
#include "netif/slipif.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/sys.h"
#include "lwip/sio.h"

Classes

struct  slipif_priv
 

Macros

#define SLIP_END   0xC0 /* 0300: start and end of every packet */
 
#define SLIP_ESC   0xDB /* 0333: escape start (one byte escaped data follows) */
 
#define SLIP_ESC_END   0xDC /* 0334: following escape: original byte is 0xC0 (END) */
 
#define SLIP_ESC_ESC   0xDD /* 0335: following escape: original byte is 0xDB (ESC) */
 
#define SLIP_MAX_SIZE   1500
 
#define SLIP_SIO_SPEED(sio_fd)   0
 

Enumerations

enum  slipif_recv_state { SLIP_RECV_NORMAL, SLIP_RECV_ESCAPE }
 

Functions

static err_t slipif_output (struct netif *netif, struct pbuf *p)
 
static struct pbufslipif_rxbyte (struct netif *netif, u8_t c)
 
static void slipif_rxbyte_input (struct netif *netif, u8_t c)
 
err_t slipif_init (struct netif *netif)
 
void slipif_poll (struct netif *netif)
 

Detailed Description

SLIP Interface

Macro Definition Documentation

◆ SLIP_END

#define SLIP_END   0xC0 /* 0300: start and end of every packet */

◆ SLIP_ESC

#define SLIP_ESC   0xDB /* 0333: escape start (one byte escaped data follows) */

◆ SLIP_ESC_END

#define SLIP_ESC_END   0xDC /* 0334: following escape: original byte is 0xC0 (END) */

◆ SLIP_ESC_ESC

#define SLIP_ESC_ESC   0xDD /* 0335: following escape: original byte is 0xDB (ESC) */

◆ SLIP_MAX_SIZE

#define SLIP_MAX_SIZE   1500

Maximum packet size that is received by this netif

◆ SLIP_SIO_SPEED

#define SLIP_SIO_SPEED (   sio_fd)    0

Define this to the interface speed for SNMP (sio_fd is the sio_fd_t returned by sio_open). The default value of zero means 'unknown'.

Enumeration Type Documentation

◆ slipif_recv_state

Enumerator
SLIP_RECV_NORMAL 
SLIP_RECV_ESCAPE 
90  {
93 };

Function Documentation

◆ slipif_output()

static err_t slipif_output ( struct netif netif,
struct pbuf p 
)
static

Send a pbuf doing the necessary SLIP encapsulation

Uses the serial layer's sio_send()

Parameters
netifthe lwip network interface structure for this slipif
pthe pbuf chain packet to send
Returns
always returns ERR_OK since the serial layer does not provide return values
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(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, 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 }
Here is the call graph for this function:

◆ slipif_rxbyte()

static struct pbuf* slipif_rxbyte ( struct netif netif,
u8_t  c 
)
static

Handle the incoming SLIP stream character by character

Parameters
netifthe lwip network interface structure for this slipif
creceived character (multiple calls to this function will return a complete packet, NULL is returned before - used for polling)
Returns
The IP packet when SLIP_END is received
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 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ slipif_rxbyte_input()

static void slipif_rxbyte_input ( struct netif netif,
u8_t  c 
)
static

Like slipif_rxbyte, but passes completed packets to netif->input

Parameters
netifThe lwip network interface structure for this slipif
creceived character
311 {
312  struct pbuf *p;
313  p = slipif_rxbyte(netif, c);
314  if (p != NULL) {
315  if (netif->input(p, netif) != ERR_OK) {
316  pbuf_free(p);
317  }
318  }
319 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ slipif_init()

err_t slipif_init ( struct netif netif)

SLIP netif initialization

Call the arch specific sio_open and remember the opened device in the state field of the netif.

Parameters
netifthe lwip network interface structure for this slipif
Returns
ERR_OK if serial line could be opened, ERR_MEM if no memory could be allocated, ERR_IF is serial line couldn't be opened
Note
netif->num must contain the number of the serial port to open (0 by default). If netif->state is != NULL, it is interpreted as an u8_t pointer pointing to the serial port number instead of netif->num.
362 {
363  struct slipif_priv *priv;
364  u8_t sio_num;
365 
366  LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
367 
368  /* Allocate private data */
369  priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv));
370  if (!priv) {
371  return ERR_MEM;
372  }
373 
374  netif->name[0] = 's';
375  netif->name[1] = 'l';
376 #if LWIP_IPV4
377  netif->output = slipif_output_v4;
378 #endif /* LWIP_IPV4 */
379 #if LWIP_IPV6
380  netif->output_ip6 = slipif_output_v6;
381 #endif /* LWIP_IPV6 */
383 
384  /* netif->state or netif->num contain the port number */
385  if (netif->state != NULL) {
386  sio_num = *(u8_t*)netif->state;
387  } else {
388  sio_num = netif->num;
389  }
390  /* Try to open the serial port. */
391  priv->sd = sio_open(sio_num);
392  if (!priv->sd) {
393  /* Opening the serial port failed. */
394  mem_free(priv);
395  return ERR_IF;
396  }
397 
398  /* Initialize private data */
399  priv->p = NULL;
400  priv->q = NULL;
401  priv->state = SLIP_RECV_NORMAL;
402  priv->i = 0;
403  priv->recved = 0;
404 #if SLIP_RX_FROM_ISR
405  priv->rxpackets = NULL;
406 #endif
407 
408  netif->state = priv;
409 
410  /* initialize the snmp variables and counters inside the struct netif */
411  MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd));
412 
413 #if SLIP_USE_RX_THREAD
414  /* Create a thread to poll the serial line. */
415  sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
417 #endif /* SLIP_USE_RX_THREAD */
418  return ERR_OK;
419 }
Here is the call graph for this function:

◆ slipif_poll()

void slipif_poll ( struct netif netif)

Polls the serial device and feeds the IP layer with incoming packets.

Parameters
netifThe lwip network interface structure for this slipif
428 {
429  u8_t c;
430  struct slipif_priv *priv;
431 
432  LWIP_ASSERT("netif != NULL", (netif != NULL));
433  LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
434 
435  priv = (struct slipif_priv *)netif->state;
436 
437  while (sio_tryread(priv->sd, &c, 1) > 0) {
439  }
440 }
Here is the call graph for this function:
PBUF_POOL
Definition: pbuf.h:123
slipif_priv::recved
u16_t recved
Definition: slipif.c:100
pbuf::len
u16_t len
Definition: pbuf.h:159
PBUF_LINK
Definition: pbuf.h:85
PBUF_LINK_ENCAPSULATION_HLEN
#define PBUF_LINK_ENCAPSULATION_HLEN
Definition: opt.h:1364
SLIP_SIO_SPEED
#define SLIP_SIO_SPEED(sio_fd)
Definition: slipif.c:87
LWIP_ASSERT
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
slipif_priv::i
u16_t i
Definition: slipif.c:100
PBUF_LINK_HLEN
#define PBUF_LINK_HLEN
Definition: opt.h:1355
SLIPIF_THREAD_PRIO
#define SLIPIF_THREAD_PRIO
Definition: opt.h:1599
u16_t
uint16_t u16_t
Definition: arch.h:121
netif::input
netif_input_fn input
Definition: netif.h:244
pbuf::tot_len
u16_t tot_len
Definition: pbuf.h:156
SLIP_ESC
#define SLIP_ESC
Definition: slipif.c:73
netif::state
void * state
Definition: netif.h:279
i
uint8_t i
Definition: screen_test_graph.c:72
pbuf::next
struct pbuf * next
Definition: pbuf.h:144
LINK_STATS_INC
#define LINK_STATS_INC(x)
Definition: stats.h:384
pbuf_free
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:715
sys_thread_new
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:376
netif::mtu
u16_t mtu
Definition: netif.h:299
SLIP_DEBUG
#define SLIP_DEBUG
Definition: opt.h:2821
SLIP_END
#define SLIP_END
Definition: slipif.c:72
SLIP_ESC_ESC
#define SLIP_ESC_ESC
Definition: slipif.c:75
NULL
#define NULL
Definition: usbd_def.h:53
ERR_MEM
Definition: err.h:65
PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE
Definition: opt.h:1373
SLIPIF_THREAD_NAME
#define SLIPIF_THREAD_NAME
Definition: opt.h:1581
netif::num
u8_t num
Definition: netif.h:309
pbuf_alloc
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:248
u8_t
uint8_t u8_t
Definition: arch.h:119
SLIP_MAX_SIZE
#define SLIP_MAX_SIZE
Definition: slipif.c:79
netif
Definition: netif.h:225
MIB2_INIT_NETIF
#define MIB2_INIT_NETIF(netif, type, speed)
Definition: snmp.h:138
SLIP_RECV_NORMAL
Definition: slipif.c:91
pbuf_realloc
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:493
slipif_priv
Definition: slipif.c:95
ERR_IF
Definition: err.h:87
slipif_priv::sd
sio_fd_t sd
Definition: slipif.c:96
netif::name
char name[2]
Definition: netif.h:307
while
while(sofevent)
Definition: USB_HOST_SHIELD.h:456
pbuf_cat
void pbuf_cat(struct pbuf *h, struct pbuf *t)
Definition: pbuf.c:840
sio_tryread
u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len)
U16_F
#define U16_F
Definition: arch.h:143
ERR_OK
Definition: err.h:63
slipif_priv::p
struct pbuf * p
Definition: slipif.c:98
sio_open
sio_fd_t sio_open(u8_t devnum)
slipif_rxbyte_input
static void slipif_rxbyte_input(struct netif *netif, u8_t c)
Definition: slipif.c:310
slipif_priv::q
struct pbuf * q
Definition: slipif.c:98
mem_malloc
void * mem_malloc(mem_size_t size)
Definition: mem.c:603
SLIPIF_THREAD_STACKSIZE
#define SLIPIF_THREAD_STACKSIZE
Definition: opt.h:1590
sio_send
void sio_send(u8_t c, sio_fd_t fd)
mem_free
void mem_free(void *rmem)
Definition: mem.c:419
slipif_priv::state
u8_t state
Definition: slipif.c:99
slipif_rxbyte
static struct pbuf * slipif_rxbyte(struct netif *netif, u8_t c)
Definition: slipif.c:207
SLIP_ESC_END
#define SLIP_ESC_END
Definition: slipif.c:74
pbuf
Definition: pbuf.h:142
LWIP_DEBUGF
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:164
SLIP_RECV_ESCAPE
Definition: slipif.c:92
pbuf::payload
void * payload
Definition: pbuf.h:147