00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "netif/slipif.h"
00040 #include "lwip/opt.h"
00041 #include "lwip/def.h"
00042 #include "lwip/pbuf.h"
00043 #include "lwip/sys.h"
00044 #include "lwip/stats.h"
00045 #include "lwip/sio.h"
00046
00047 #define SLIP_END 0300
00048 #define SLIP_ESC 0333
00049 #define SLIP_ESC_END 0334
00050 #define SLIP_ESC_ESC 0335
00051
00052 #define MAX_SIZE 1500
00053
00059 err_t
00060 slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
00061 {
00062 struct pbuf *q;
00063 int i;
00064 u8_t c;
00065
00066
00067 sio_send(SLIP_END, netif->state);
00068
00069 for(q = p; q != NULL; q = q->next) {
00070 for(i = 0; i < q->len; i++) {
00071 c = ((u8_t *)q->payload)[i];
00072 switch(c) {
00073 case SLIP_END:
00074 sio_send(SLIP_ESC, netif->state);
00075 sio_send(SLIP_ESC_END, netif->state);
00076 break;
00077 case SLIP_ESC:
00078 sio_send(SLIP_ESC, netif->state);
00079 sio_send(SLIP_ESC_ESC, netif->state);
00080 break;
00081 default:
00082 sio_send(c, netif->state);
00083 break;
00084 }
00085 }
00086 }
00087 sio_send(SLIP_END, netif->state);
00088 return 0;
00089 }
00090
00098 static struct pbuf *
00099 slipif_input( struct netif * netif )
00100 {
00101 u8_t c;
00102 struct pbuf *p, *q;
00103 int recved;
00104 int i;
00105
00106 q = p = NULL;
00107 recved = i = 0;
00108 c = 0;
00109
00110 while(1) {
00111 c = sio_recv(netif->state);
00112 switch(c) {
00113 case SLIP_END:
00114 if(recved > 0) {
00115
00116 pbuf_realloc(q, recved);
00117
00118 #ifdef LINK_STATS
00119 ++lwip_stats.link.recv;
00120 #endif
00121
00122 DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
00123 return q;
00124 }
00125 break;
00126
00127 case SLIP_ESC:
00128 c = sio_recv(netif->state);
00129 switch(c) {
00130 case SLIP_ESC_END:
00131 c = SLIP_END;
00132 break;
00133 case SLIP_ESC_ESC:
00134 c = SLIP_ESC;
00135 break;
00136 }
00137
00138
00139 default:
00140 if(p == NULL) {
00141 DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
00142 p = pbuf_alloc(PBUF_LINK, PBUF_POOL_BUFSIZE, PBUF_POOL);
00143
00144 #ifdef LINK_STATS
00145 if(p == NULL) {
00146 ++lwip_stats.link.drop;
00147 DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
00148 }
00149 #endif
00150
00151 if(q != NULL) {
00152 pbuf_chain(q, p);
00153 } else {
00154 q = p;
00155 }
00156 }
00157 if(p != NULL && recved < MAX_SIZE) {
00158 ((u8_t *)p->payload)[i] = c;
00159 recved++;
00160 i++;
00161 if(i >= p->len) {
00162 i = 0;
00163 p = NULL;
00164 }
00165 }
00166 break;
00167 }
00168
00169 }
00170 return NULL;
00171 }
00172
00178 static void
00179 slipif_loop(void *nf)
00180 {
00181 struct pbuf *p;
00182 struct netif *netif = (struct netif *)nf;
00183
00184 while(1) {
00185 p = slipif_input(netif);
00186 netif->input(p, netif);
00187 }
00188 }
00189
00196 err_t
00197 slipif_init(struct netif *netif)
00198 {
00199
00200 DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%x\n", (int)netif->num));
00201
00202 netif->name[0] = 's';
00203 netif->name[1] = 'l';
00204 netif->output = slipif_output;
00205 netif->mtu = 1500;
00206
00207 netif->state = sio_open(netif->num);
00208 if (!netif->state)
00209 return ERR_IF;
00210
00211 sys_thread_new(slipif_loop, netif, SLIPIF_THREAD_PRIO);
00212 return ERR_OK;
00213 }