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
00040
00041
00042
00043
00044
00045 #include "netif/slipif.h"
00046 #include "lwip/opt.h"
00047
00048 #if LWIP_HAVE_SLIPIF
00049
00050 #include "lwip/def.h"
00051 #include "lwip/pbuf.h"
00052 #include "lwip/sys.h"
00053 #include "lwip/stats.h"
00054 #include "lwip/snmp.h"
00055 #include "lwip/sio.h"
00056
00057 #define SLIP_BLOCK 1
00058 #define SLIP_DONTBLOCK 0
00059
00060 #define SLIP_END 0300
00061 #define SLIP_ESC 0333
00062 #define SLIP_ESC_END 0334
00063 #define SLIP_ESC_ESC 0335
00064
00065 #define SLIP_MAX_SIZE 1500
00066
00067 enum slipif_recv_state {
00068 SLIP_RECV_NORMAL,
00069 SLIP_RECV_ESCAPE,
00070 };
00071
00072 struct slipif_priv {
00073 sio_fd_t sd;
00074
00075 struct pbuf *p, *q;
00076 enum slipif_recv_state state;
00077 u16_t i, recved;
00078 };
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 err_t
00091 slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
00092 {
00093 struct slipif_priv *priv;
00094 struct pbuf *q;
00095 u16_t i;
00096 u8_t c;
00097
00098 LWIP_ASSERT("netif != NULL", (netif != NULL));
00099 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
00100 LWIP_ASSERT("p != NULL", (p != NULL));
00101
00102 LWIP_UNUSED_ARG(ipaddr);
00103
00104 priv = netif->state;
00105
00106
00107 sio_send(SLIP_END, priv->sd);
00108
00109 for (q = p; q != NULL; q = q->next) {
00110 for (i = 0; i < q->len; i++) {
00111 c = ((u8_t *)q->payload)[i];
00112 switch (c) {
00113 case SLIP_END:
00114 sio_send(SLIP_ESC, priv->sd);
00115 sio_send(SLIP_ESC_END, priv->sd);
00116 break;
00117 case SLIP_ESC:
00118 sio_send(SLIP_ESC, priv->sd);
00119 sio_send(SLIP_ESC_ESC, priv->sd);
00120 break;
00121 default:
00122 sio_send(c, priv->sd);
00123 break;
00124 }
00125 }
00126 }
00127 sio_send(SLIP_END, priv->sd);
00128 return ERR_OK;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 static u32_t
00142 slip_sio_read(sio_fd_t fd, u8_t* data, u32_t len, u8_t block)
00143 {
00144 if (block) {
00145 return sio_read(fd, data, len);
00146 } else {
00147 return sio_tryread(fd, data, len);
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 static struct pbuf *
00163 slipif_input(struct netif *netif, u8_t block)
00164 {
00165 struct slipif_priv *priv;
00166 u8_t c;
00167 struct pbuf *t;
00168
00169 LWIP_ASSERT("netif != NULL", (netif != NULL));
00170 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
00171
00172 priv = netif->state;
00173
00174 while (slip_sio_read(priv->sd, &c, 1, block) > 0) {
00175 switch (priv->state) {
00176 case SLIP_RECV_NORMAL:
00177 switch (c) {
00178 case SLIP_END:
00179 if (priv->recved > 0) {
00180
00181
00182 pbuf_realloc(priv->q, priv->recved);
00183
00184 LINK_STATS_INC(link.recv);
00185
00186 LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n"));
00187 t = priv->q;
00188 priv->p = priv->q = NULL;
00189 priv->i = priv->recved = 0;
00190 return t;
00191 }
00192 continue;
00193 case SLIP_ESC:
00194 priv->state = SLIP_RECV_ESCAPE;
00195 continue;
00196 }
00197 break;
00198 case SLIP_RECV_ESCAPE:
00199 switch (c) {
00200 case SLIP_ESC_END:
00201 c = SLIP_END;
00202 break;
00203 case SLIP_ESC_ESC:
00204 c = SLIP_ESC;
00205 break;
00206 }
00207 priv->state = SLIP_RECV_NORMAL;
00208
00209 }
00210
00211
00212 if (priv->p == NULL) {
00213
00214 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
00215 priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL);
00216
00217 if (priv->p == NULL) {
00218 LINK_STATS_INC(link.drop);
00219 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
00220
00221 break;
00222 }
00223
00224 if (priv->q != NULL) {
00225
00226 pbuf_cat(priv->q, priv->p);
00227 } else {
00228
00229 priv->q = priv->p;
00230 }
00231 }
00232
00233
00234 if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
00235 ((u8_t *)priv->p->payload)[priv->i] = c;
00236 priv->recved++;
00237 priv->i++;
00238 if (priv->i >= priv->p->len) {
00239
00240 priv->i = 0;
00241 if (priv->p->next != NULL && priv->p->next->len > 0) {
00242
00243 priv->p = priv->p->next;
00244 } else {
00245
00246
00247 priv->p = NULL;
00248 }
00249 }
00250 }
00251 }
00252
00253 return NULL;
00254 }
00255
00256 #if !NO_SYS
00257
00258
00259
00260
00261
00262
00263
00264 static void
00265 slipif_loop_thread(void *nf)
00266 {
00267 struct pbuf *p;
00268 struct netif *netif = (struct netif *)nf;
00269
00270 while (1) {
00271 p = slipif_input(netif, SLIP_BLOCK);
00272 if (p != NULL) {
00273 if (netif->input(p, netif) != ERR_OK) {
00274 pbuf_free(p);
00275 p = NULL;
00276 }
00277 }
00278 }
00279 }
00280 #endif
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 err_t
00297 slipif_init(struct netif *netif)
00298 {
00299 struct slipif_priv *priv;
00300
00301 LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num));
00302
00303
00304 priv = mem_malloc(sizeof(struct slipif_priv));
00305 if (!priv) {
00306 return ERR_MEM;
00307 }
00308
00309 netif->name[0] = 's';
00310 netif->name[1] = 'l';
00311 netif->output = slipif_output;
00312 netif->mtu = SLIP_MAX_SIZE;
00313 netif->flags |= NETIF_FLAG_POINTTOPOINT;
00314
00315
00316 priv->sd = sio_open(netif->num);
00317 if (!priv->sd) {
00318
00319 mem_free(priv);
00320 return ERR_IF;
00321 }
00322
00323
00324 priv->p = NULL;
00325 priv->q = NULL;
00326 priv->state = SLIP_RECV_NORMAL;
00327 priv->i = 0;
00328 priv->recved = 0;
00329
00330 netif->state = priv;
00331
00332
00333
00334
00335
00336 NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0);
00337
00338
00339 sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
00340 SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
00341 return ERR_OK;
00342 }
00343
00344
00345
00346
00347
00348
00349 void
00350 slipif_poll(struct netif *netif)
00351 {
00352 struct pbuf *p;
00353 struct slipif_priv *priv;
00354
00355 LWIP_ASSERT("netif != NULL", (netif != NULL));
00356 LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
00357
00358 priv = netif->state;
00359
00360 while ((p = slipif_input(netif, SLIP_DONTBLOCK)) != NULL) {
00361 if (netif->input(p, netif) != ERR_OK) {
00362 pbuf_free(p);
00363 }
00364 }
00365 }
00366
00367 #endif