31 |
* Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> |
* Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com> |
32 |
*/ |
*/ |
33 |
|
|
34 |
|
/* |
35 |
|
* This is an arch independent SLIP netif. The specific serial hooks must be provided |
36 |
|
* by another file.They are sio_open, sio_recv and sio_send |
37 |
|
*/ |
38 |
|
|
39 |
#include "netif/slipif.h" |
#include "netif/slipif.h" |
40 |
#include "lwip/debug.h" |
#include "lwip/debug.h" |
41 |
#include "lwip/def.h" |
#include "lwip/def.h" |
42 |
#include "lwip/pbuf.h" |
#include "lwip/pbuf.h" |
43 |
#include "lwip/sys.h" |
#include "lwip/sys.h" |
44 |
#include "lwip/stats.h" |
#include "lwip/stats.h" |
|
#include "netif/sio.h" |
|
45 |
|
|
46 |
#define SLIP_END 0300 |
#define SLIP_END 0300 |
47 |
#define SLIP_ESC 0333 |
#define SLIP_ESC 0333 |
49 |
#define SLIP_ESC_ESC 0335 |
#define SLIP_ESC_ESC 0335 |
50 |
|
|
51 |
#define MAX_SIZE 1500 |
#define MAX_SIZE 1500 |
|
#define SLIPIF_NUM_OF_INTERFACES 2 |
|
|
|
|
|
typedef struct slip_status_t { |
|
|
void *sio; |
|
|
} slip_status_t; |
|
|
|
|
|
/* yes, this is ugly; TODO: should be dynamicaly allocated instead */ |
|
|
static slip_status_t statusar[SLIPIF_NUM_OF_INTERFACES]; |
|
52 |
|
|
53 |
/*-----------------------------------------------------------------------------------*/ |
/** |
54 |
|
* Send a pbuf doing the necessary SLIP encapsulation |
55 |
|
* |
56 |
|
* Uses the serial layer's sio_send() |
57 |
|
*/ |
58 |
err_t |
err_t |
59 |
slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) |
slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) |
60 |
{ |
{ |
|
slip_status_t *slipState = (slip_status_t *)netif->state; |
|
61 |
struct pbuf *q; |
struct pbuf *q; |
62 |
int i; |
int i; |
63 |
u8_t c; |
u8_t c; |
64 |
|
|
65 |
/* Send pbuf out on the serial I/O device. */ |
/* Send pbuf out on the serial I/O device. */ |
66 |
sio_send(SLIP_END, slipState->sio); |
sio_send(SLIP_END, netif->state); |
67 |
|
|
68 |
for(q = p; q != NULL; q = q->next) { |
for(q = p; q != NULL; q = q->next) { |
69 |
for(i = 0; i < q->len; i++) { |
for(i = 0; i < q->len; i++) { |
70 |
c = ((u8_t *)q->payload)[i]; |
c = ((u8_t *)q->payload)[i]; |
71 |
switch(c) { |
switch(c) { |
72 |
case SLIP_END: |
case SLIP_END: |
73 |
sio_send(SLIP_ESC, slipState->sio); |
sio_send(SLIP_ESC, netif->state); |
74 |
sio_send(SLIP_ESC_END, slipState->sio); |
sio_send(SLIP_ESC_END, netif->state); |
75 |
break; |
break; |
76 |
case SLIP_ESC: |
case SLIP_ESC: |
77 |
sio_send(SLIP_ESC, slipState->sio); |
sio_send(SLIP_ESC, netif->state); |
78 |
sio_send(SLIP_ESC_ESC, slipState->sio); |
sio_send(SLIP_ESC_ESC, netif->state); |
79 |
break; |
break; |
80 |
default: |
default: |
81 |
sio_send(c, slipState->sio); |
sio_send(c, netif->state); |
82 |
break; |
break; |
83 |
} |
} |
84 |
} |
} |
85 |
} |
} |
86 |
sio_send(SLIP_END, slipState->sio); |
sio_send(SLIP_END, netif->state); |
87 |
return 0; |
return 0; |
88 |
} |
} |
89 |
/*-----------------------------------------------------------------------------------*/ |
|
90 |
|
/** |
91 |
|
* Handle the incoming SLIP stream character by character |
92 |
|
* |
93 |
|
* Poll the serial layer by calling sio_recv() |
94 |
|
* |
95 |
|
* @return The IP packet when SLIP_END is received |
96 |
|
*/ |
97 |
static struct pbuf * |
static struct pbuf * |
98 |
slipif_input( struct netif * netif ) |
slipif_input( struct netif * netif ) |
99 |
{ |
{ |
|
slip_status_t *slipState = (slip_status_t *)netif->state; |
|
100 |
u8_t c; |
u8_t c; |
101 |
struct pbuf *p, *q; |
struct pbuf *p, *q; |
102 |
int recved; |
int recved; |
107 |
c = 0; |
c = 0; |
108 |
|
|
109 |
while(1) { |
while(1) { |
110 |
c = sio_recv(slipState->sio); |
c = sio_recv(netif->state); |
111 |
switch(c) { |
switch(c) { |
112 |
case SLIP_END: |
case SLIP_END: |
|
if(p == NULL) { |
|
|
return slipif_input(netif); |
|
|
} |
|
113 |
if(recved > 0) { |
if(recved > 0) { |
114 |
/* Received whole packet. */ |
/* Received whole packet. */ |
115 |
pbuf_realloc(q, recved); |
pbuf_realloc(q, recved); |
124 |
break; |
break; |
125 |
|
|
126 |
case SLIP_ESC: |
case SLIP_ESC: |
127 |
c = sio_recv(slipState->sio); |
c = sio_recv(netif->state); |
128 |
switch(c) { |
switch(c) { |
129 |
case SLIP_ESC_END: |
case SLIP_ESC_END: |
130 |
c = SLIP_END; |
c = SLIP_END; |
168 |
} |
} |
169 |
return NULL; |
return NULL; |
170 |
} |
} |
171 |
/*-----------------------------------------------------------------------------------*/ |
|
172 |
|
/** |
173 |
|
* The SLIP input thread |
174 |
|
* |
175 |
|
* Feed the IP layer with incoming packets |
176 |
|
*/ |
177 |
static void |
static void |
178 |
slipif_loop(void *nf) |
slipif_loop(void *nf) |
179 |
{ |
{ |
180 |
struct pbuf *p; |
struct pbuf *p; |
181 |
struct netif *netif = (struct netif *)nf; |
struct netif *netif = (struct netif *)nf; |
|
/* slip_status_t *slipState = (slip_status_t *) netif->state; */ |
|
182 |
|
|
183 |
while(1) { |
while(1) { |
184 |
p = slipif_input(netif); |
p = slipif_input(netif); |
185 |
netif->input(p, netif); |
netif->input(p, netif); |
186 |
} |
} |
187 |
} |
} |
188 |
/*-----------------------------------------------------------------------------------*/ |
|
189 |
|
/** |
190 |
|
* SLIP netif initialization |
191 |
|
* |
192 |
|
* Call the arch specific sio_open and remember |
193 |
|
* the opened device in the state field of the netif. |
194 |
|
*/ |
195 |
void |
void |
196 |
slipif_init(struct netif *netif) |
slipif_init(struct netif *netif) |
197 |
{ |
{ |
|
slip_status_t *slipState; |
|
198 |
|
|
199 |
DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num)); |
DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num)); |
|
if(netif->num >= SLIPIF_NUM_OF_INTERFACES) { |
|
|
DEBUGF( SLIP_DEBUG, ("ERROR: To many slipifs")); |
|
|
return; |
|
|
} |
|
200 |
|
|
|
/* dynamic allocation would be nice */ |
|
|
netif->state = &statusar[netif->num]; |
|
201 |
netif->name[0] = 's'; |
netif->name[0] = 's'; |
202 |
netif->name[1] = 'l'; |
netif->name[1] = 'l'; |
203 |
netif->output = slipif_output; |
netif->output = slipif_output; |
204 |
|
|
205 |
slipState = (slip_status_t *)netif->state; |
netif->state = sio_open(netif->num); |
|
slipState->sio = sio_open(netif->num); |
|
206 |
|
|
207 |
sys_thread_new(slipif_loop, netif); |
sys_thread_new(slipif_loop, netif); |
208 |
} |
} |
|
/*-----------------------------------------------------------------------------------*/ |
|