source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/apps/shell/shell.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 39.5 KB
Line 
1/*
2 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25 * OF SUCH DAMAGE.
26 *
27 * This file is part of the lwIP TCP/IP stack.
28 *
29 * Author: Adam Dunkels <adam@sics.se>
30 *
31 */
32
33#include "shell.h"
34
35#include "lwip/opt.h"
36
37#if LWIP_NETCONN && LWIP_TCP
38
39#include <string.h>
40#include <stdio.h>
41
42#include "lwip/mem.h"
43#include "lwip/debug.h"
44#include "lwip/def.h"
45#include "lwip/api.h"
46#include "lwip/stats.h"
47
48#if LWIP_SOCKET
49#include "lwip/errno.h"
50#include "lwip/if_api.h"
51#endif
52
53#if 1 /* WIN32 TOPPERS */
54#define NEWLINE "\r\n"
55#else /* WIN32 */
56#define NEWLINE "\n"
57#endif /* WIN32 */
58
59/** Define this to 1 if you want to echo back all received characters
60 * (e.g. so they are displayed on a remote telnet)
61 */
62#ifndef SHELL_ECHO
63#define SHELL_ECHO 0
64#endif
65
66#define BUFSIZE 1024
67static unsigned char buffer[BUFSIZE];
68
69struct command {
70 struct netconn *conn;
71 s8_t (* exec)(struct command *);
72 u8_t nargs;
73 char *args[10];
74};
75
76#include <stdio.h>
77#include <stdlib.h>
78#include <limits.h>
79
80/*
81 * TELNET state
82 */
83#define TELNET_STATE_DATA 0
84#define TELNET_STATE_CR 1
85#define TELNET_STATE_IAC 2
86#define TELNET_STATE_WILL 3
87#define TELNET_STATE_WONT 4
88#define TELNET_STATE_DO 5
89#define TELNET_STATE_DONT 6
90#define TELNET_STATE_SB 7
91#define TELNET_STATE_SE 8
92
93/*
94 * TELNET control command
95 */
96#define TELNET_SE 240
97#define TELNET_NOP 241
98#define TELNET_DM 242
99#define TELNET_BRK 243
100#define TELNET_IP 244
101#define TELNET_AO 245
102#define TELNET_AYT 246
103#define TELNET_EC 247
104#define TELNET_EL 248
105#define TELNET_GA 249
106#define TELNET_SB 250
107#define TELNET_WILL 251
108#define TELNET_WONT 252
109#define TELNET_DO 253
110#define TELNET_DONT 254
111#define TELNET_IAC 255
112
113#define ESUCCESS 0
114#define ESYNTAX -1
115#define ETOOFEW -2
116#define ETOOMANY -3
117#define ECLOSED -4
118
119#define NCONNS 10
120static struct netconn *conns[NCONNS];
121
122/* help_msg is split into 3 strings to prevent exceeding the C89 maximum length of 509 per string */
123static char help_msg1[] = "Available commands:"NEWLINE"\
124open [IP address] [TCP port]: opens a TCP connection to the specified address."NEWLINE"\
125lstn [TCP port]: sets up a server on the specified port."NEWLINE"\
126acpt [connection #]: waits for an incoming connection request."NEWLINE"\
127send [connection #] [message]: sends a message on a TCP connection."NEWLINE"\
128udpc [local UDP port] [IP address] [remote port]: opens a UDP \"connection\"."NEWLINE"\
129udpl [local UDP port] [IP address] [remote port]: opens a UDP-Lite \"connection\"."NEWLINE"";
130static char help_msg2[] = "udpn [local UDP port] [IP address] [remote port]: opens a UDP \"connection\" without checksums."NEWLINE"\
131udpb [local port] [remote port]: opens a UDP broadcast \"connection\"."NEWLINE"\
132usnd [connection #] [message]: sends a message on a UDP connection."NEWLINE"\
133recv [connection #]: recieves data on a TCP or UDP connection."NEWLINE"\
134clos [connection #]: closes a TCP or UDP connection."NEWLINE"\
135stat: prints out lwIP statistics."NEWLINE"\
136idxtoname [index]: outputs interface name from index."NEWLINE"\
137nametoidx [name]: outputs interface index from name."NEWLINE;
138static char help_msg3[] =
139"gethostnm [name]: outputs IP address of host."NEWLINE"\
140quit: quits"NEWLINE"";
141
142#if LWIP_STATS
143static char padding_10spaces[] = " ";
144
145#define PROTOCOL_STATS (LINK_STATS && ETHARP_STATS && IPFRAG_STATS && IP_STATS && ICMP_STATS && UDP_STATS && TCP_STATS)
146
147#if PROTOCOL_STATS
148static const char* shell_stat_proto_names[] = {
149#if LINK_STATS
150 "LINK ",
151#endif
152#if ETHARP_STATS
153 "ETHARP ",
154#endif
155#if IPFRAG_STATS
156 "IP_FRAG ",
157#endif
158#if IP_STATS
159 "IP ",
160#endif
161#if ICMP_STATS
162 "ICMP ",
163#endif
164#if UDP_STATS
165 "UDP ",
166#endif
167#if TCP_STATS
168 "TCP ",
169#endif
170 "last"
171};
172
173static struct stats_proto* shell_stat_proto_stats[] = {
174#if LINK_STATS
175 &lwip_stats.link,
176#endif
177#if ETHARP_STATS
178 &lwip_stats.etharp,
179#endif
180#if IPFRAG_STATS
181 &lwip_stats.ip_frag,
182#endif
183#if IP_STATS
184 &lwip_stats.ip,
185#endif
186#if ICMP_STATS
187 &lwip_stats.icmp,
188#endif
189#if UDP_STATS
190 &lwip_stats.udp,
191#endif
192#if TCP_STATS
193 &lwip_stats.tcp,
194#endif
195};
196const size_t num_protostats = sizeof(shell_stat_proto_stats)/sizeof(struct stats_proto*);
197
198static const char *stat_msgs_proto[] = {
199 " * transmitted ",
200 " * received ",
201 " forwarded ",
202 " * dropped ",
203 " * checksum errors ",
204 " * length errors ",
205 " * memory errors ",
206 " routing errors ",
207 " protocol errors ",
208 " option errors ",
209 " * misc errors ",
210 " cache hits "
211};
212#endif /* PROTOCOL_STATS */
213#endif /* LWIP_STATS */
214
215/*-----------------------------------------------------------------------------------*/
216static void
217sendstr(const char *str, struct netconn *conn)
218{
219 netconn_write(conn, (const void *)str, strlen(str), NETCONN_NOCOPY);
220}
221/*-----------------------------------------------------------------------------------*/
222static s8_t
223com_open(struct command *com)
224{
225 ip_addr_t ipaddr;
226 u16_t port;
227 int i;
228 err_t err;
229 long tmp;
230
231 if (ipaddr_aton(com->args[0], &ipaddr) == -1) {
232 sendstr(strerror(errno), com->conn);
233 return ESYNTAX;
234 }
235 tmp = strtol(com->args[1], NULL, 10);
236 if((tmp < 0) || (tmp > 0xffff)) {
237 sendstr("Invalid port number."NEWLINE, com->conn);
238 return ESUCCESS;
239 }
240 port = (u16_t)tmp;
241
242 /* Find the first unused connection in conns. */
243 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
244
245 if (i == NCONNS) {
246 sendstr("No more connections available, sorry."NEWLINE, com->conn);
247 return ESUCCESS;
248 }
249
250 sendstr("Opening connection to ", com->conn);
251 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
252 sendstr(":", com->conn);
253 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
254 sendstr(NEWLINE, com->conn);
255
256 conns[i] = netconn_new(NETCONN_TCP);
257 if (conns[i] == NULL) {
258 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
259 return ESUCCESS;
260 }
261 err = netconn_connect(conns[i], &ipaddr, port);
262 if (err != ERR_OK) {
263 fprintf(stderr, "error %s"NEWLINE, lwip_strerr(err));
264 sendstr("Could not connect to remote host: ", com->conn);
265#ifdef LWIP_DEBUG
266 sendstr(lwip_strerr(err), com->conn);
267#else
268 sendstr("(debugging must be turned on for error message to appear)", com->conn);
269#endif /* LWIP_DEBUG */
270 sendstr(NEWLINE, com->conn);
271 netconn_delete(conns[i]);
272 conns[i] = NULL;
273 return ESUCCESS;
274 }
275
276 sendstr("Opened connection, connection identifier is ", com->conn);
277 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
278 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
279
280 return ESUCCESS;
281}
282/*-----------------------------------------------------------------------------------*/
283static s8_t
284com_lstn(struct command *com)
285{
286 u16_t port;
287 int i;
288 err_t err;
289 long tmp;
290
291 tmp = strtol(com->args[0], NULL, 10);
292 if((tmp < 0) || (tmp > 0xffff)) {
293 sendstr("Invalid port number."NEWLINE, com->conn);
294 return ESUCCESS;
295 }
296 port = (u16_t)tmp;
297
298 /* Find the first unused connection in conns. */
299 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
300
301 if (i == NCONNS) {
302 sendstr("No more connections available, sorry."NEWLINE, com->conn);
303 return ESUCCESS;
304 }
305
306 sendstr("Opening a listening connection on port ", com->conn);
307 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
308 sendstr(NEWLINE, com->conn);
309
310 conns[i] = netconn_new(NETCONN_TCP);
311 if (conns[i] == NULL) {
312 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
313 return ESUCCESS;
314 }
315
316 err = netconn_bind(conns[i], IP_ADDR_ANY, port);
317 if (err != ERR_OK) {
318 netconn_delete(conns[i]);
319 conns[i] = NULL;
320 sendstr("Could not bind: ", com->conn);
321#ifdef LWIP_DEBUG
322 sendstr(lwip_strerr(err), com->conn);
323#else
324 sendstr("(debugging must be turned on for error message to appear)", com->conn);
325#endif /* LWIP_DEBUG */
326 sendstr(NEWLINE, com->conn);
327 return ESUCCESS;
328 }
329
330 err = netconn_listen(conns[i]);
331 if (err != ERR_OK) {
332 netconn_delete(conns[i]);
333 conns[i] = NULL;
334 sendstr("Could not listen: ", com->conn);
335#ifdef LWIP_DEBUG
336 sendstr(lwip_strerr(err), com->conn);
337#else
338 sendstr("(debugging must be turned on for error message to appear)", com->conn);
339#endif /* LWIP_DEBUG */
340 sendstr(NEWLINE, com->conn);
341 return ESUCCESS;
342 }
343
344 sendstr("Opened connection, connection identifier is ", com->conn);
345 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
346 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
347
348 return ESUCCESS;
349}
350/*-----------------------------------------------------------------------------------*/
351/*-----------------------------------------------------------------------------------*/
352static s8_t
353com_clos(struct command *com)
354{
355 int i;
356 err_t err;
357
358 i = strtol(com->args[0], NULL, 10);
359
360 if (i > NCONNS) {
361 sendstr("Connection identifier too high."NEWLINE, com->conn);
362 return ESUCCESS;
363 }
364 if (conns[i] == NULL) {
365 sendstr("Connection identifier not in use."NEWLINE, com->conn);
366 return ESUCCESS;
367 }
368
369 err = netconn_close(conns[i]);
370 if (err != ERR_OK) {
371 sendstr("Could not close connection: ", com->conn);
372#ifdef LWIP_DEBUG
373 sendstr(lwip_strerr(err), com->conn);
374#else
375 sendstr("(debugging must be turned on for error message to appear)", com->conn);
376#endif /* LWIP_DEBUG */
377 sendstr(NEWLINE, com->conn);
378 return ESUCCESS;
379 }
380
381 sendstr("Connection closed."NEWLINE, com->conn);
382 netconn_delete(conns[i]);
383 conns[i] = NULL;
384 return ESUCCESS;
385}
386/*-----------------------------------------------------------------------------------*/
387static s8_t
388com_acpt(struct command *com)
389{
390 int i, j;
391 err_t err;
392
393 /* Find the first unused connection in conns. */
394 for(j = 0; j < NCONNS && conns[j] != NULL; j++);
395
396 if (j == NCONNS) {
397 sendstr("No more connections available, sorry."NEWLINE, com->conn);
398 return ESUCCESS;
399 }
400
401 i = strtol(com->args[0], NULL, 10);
402
403 if (i > NCONNS) {
404 sendstr("Connection identifier too high."NEWLINE, com->conn);
405 return ESUCCESS;
406 }
407 if (conns[i] == NULL) {
408 sendstr("Connection identifier not in use."NEWLINE, com->conn);
409 return ESUCCESS;
410 }
411
412 err = netconn_accept(conns[i], &conns[j]);
413
414 if (err != ERR_OK) {
415 sendstr("Could not accept connection: ", com->conn);
416#ifdef LWIP_DEBUG
417 sendstr(lwip_strerr(err), com->conn);
418#else
419 sendstr("(debugging must be turned on for error message to appear)", com->conn);
420#endif /* LWIP_DEBUG */
421 sendstr(NEWLINE, com->conn);
422 return ESUCCESS;
423 }
424
425 sendstr("Accepted connection, connection identifier for new connection is ", com->conn);
426 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, j);
427 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
428
429 return ESUCCESS;
430}
431/*-----------------------------------------------------------------------------------*/
432#if LWIP_STATS
433static void
434com_stat_write_mem(struct netconn *conn, struct stats_mem *elem, int i)
435{
436 u16_t len;
437 char buf[100];
438 size_t slen;
439
440#ifdef LWIP_DEBUG
441 LWIP_UNUSED_ARG(i);
442 slen = strlen(elem->name);
443 netconn_write(conn, elem->name, slen, NETCONN_COPY);
444#else /* LWIP_DEBUG */
445 len = (u16_t)sprintf(buf, "%d", i);
446 slen = strlen(buf);
447 netconn_write(conn, buf, slen, NETCONN_COPY);
448#endif /* LWIP_DEBUG */
449 if(slen < 10) {
450 netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY);
451 }
452
453 len = (u16_t)sprintf(buf, " * available %"MEM_SIZE_F NEWLINE, elem->avail);
454 netconn_write(conn, buf, len, NETCONN_COPY);
455 len = (u16_t)sprintf(buf, " * used %"MEM_SIZE_F NEWLINE, elem->used);
456 netconn_write(conn, buf, len, NETCONN_COPY);
457 len = (u16_t)sprintf(buf, " * high water mark %"MEM_SIZE_F NEWLINE, elem->max);
458 netconn_write(conn, buf, len, NETCONN_COPY);
459 len = (u16_t)sprintf(buf, " * errors %"STAT_COUNTER_F NEWLINE, elem->err);
460 netconn_write(conn, buf, len, NETCONN_COPY);
461 len = (u16_t)sprintf(buf, " * illegal %"STAT_COUNTER_F NEWLINE, elem->illegal);
462 netconn_write(conn, buf, len, NETCONN_COPY);
463}
464static void
465com_stat_write_sys(struct netconn *conn, struct stats_syselem *elem, const char *name)
466{
467 u16_t len;
468 char buf[100];
469 size_t slen = strlen(name);
470
471 netconn_write(conn, name, slen, NETCONN_COPY);
472 if(slen < 10) {
473 netconn_write(conn, padding_10spaces, 10-slen, NETCONN_COPY);
474 }
475
476 len = (u16_t)sprintf(buf, " * used %"STAT_COUNTER_F NEWLINE, elem->used);
477 netconn_write(conn, buf, len, NETCONN_COPY);
478 len = (u16_t)sprintf(buf, " * high water mark %"STAT_COUNTER_F NEWLINE, elem->max);
479 netconn_write(conn, buf, len, NETCONN_COPY);
480 len = (u16_t)sprintf(buf, " * errors %"STAT_COUNTER_F NEWLINE, elem->err);
481 netconn_write(conn, buf, len, NETCONN_COPY);
482}
483static s8_t
484com_stat(struct command *com)
485{
486#if PROTOCOL_STATS || MEMP_STATS
487 size_t i;
488#endif /* PROTOCOL_STATS || MEMP_STATS */
489#if PROTOCOL_STATS
490 size_t k;
491 char buf[100];
492 u16_t len;
493
494 /* protocol stats, @todo: add IGMP */
495 for(i = 0; i < num_protostats; i++) {
496 size_t s = sizeof(struct stats_proto)/sizeof(STAT_COUNTER);
497 STAT_COUNTER *c = &shell_stat_proto_stats[i]->xmit;
498 LWIP_ASSERT("stats not in sync", s == sizeof(stat_msgs_proto)/sizeof(char*));
499 netconn_write(com->conn, shell_stat_proto_names[i], strlen(shell_stat_proto_names[i]), NETCONN_COPY);
500 for(k = 0; k < s; k++) {
501 len = (u16_t)sprintf(buf, "%s%"STAT_COUNTER_F NEWLINE, stat_msgs_proto[k], c[k]);
502 netconn_write(com->conn, buf, len, NETCONN_COPY);
503 }
504 }
505#endif /* PROTOCOL_STATS */
506#if MEM_STATS
507 com_stat_write_mem(com->conn, &lwip_stats.mem, -1);
508#endif /* MEM_STATS */
509#if MEMP_STATS
510 for(i = 0; i < MEMP_MAX; i++) {
511 com_stat_write_mem(com->conn, lwip_stats.memp[i], -1);
512 }
513#endif /* MEMP_STATS */
514#if SYS_STATS
515 com_stat_write_sys(com->conn, &lwip_stats.sys.sem, "SEM ");
516 com_stat_write_sys(com->conn, &lwip_stats.sys.mutex, "MUTEX ");
517 com_stat_write_sys(com->conn, &lwip_stats.sys.mbox, "MBOX ");
518#endif /* SYS_STATS */
519
520 return ESUCCESS;
521}
522#endif
523/*-----------------------------------------------------------------------------------*/
524static s8_t
525com_send(struct command *com)
526{
527 int i;
528 err_t err;
529 size_t len;
530
531 i = strtol(com->args[0], NULL, 10);
532
533 if (i > NCONNS) {
534 sendstr("Connection identifier too high."NEWLINE, com->conn);
535 return ESUCCESS;
536 }
537
538 if (conns[i] == NULL) {
539 sendstr("Connection identifier not in use."NEWLINE, com->conn);
540 return ESUCCESS;
541 }
542
543 len = strlen(com->args[1]);
544 com->args[1][len] = '\r';
545 com->args[1][len + 1] = '\n';
546 com->args[1][len + 2] = 0;
547
548 err = netconn_write(conns[i], com->args[1], len + 3, NETCONN_COPY);
549 if (err != ERR_OK) {
550 sendstr("Could not send data: ", com->conn);
551#ifdef LWIP_DEBUG
552 sendstr(lwip_strerr(err), com->conn);
553#else
554 sendstr("(debugging must be turned on for error message to appear)", com->conn);
555#endif /* LWIP_DEBUG */
556 sendstr(NEWLINE, com->conn);
557 return ESUCCESS;
558 }
559
560 sendstr("Data enqueued for sending."NEWLINE, com->conn);
561 return ESUCCESS;
562}
563/*-----------------------------------------------------------------------------------*/
564static s8_t
565com_recv(struct command *com)
566{
567 int i;
568 err_t err;
569 struct netbuf *buf;
570 u16_t len;
571
572 i = strtol(com->args[0], NULL, 10);
573
574 if (i > NCONNS) {
575 sendstr("Connection identifier too high."NEWLINE, com->conn);
576 return ESUCCESS;
577 }
578
579 if (conns[i] == NULL) {
580 sendstr("Connection identifier not in use."NEWLINE, com->conn);
581 return ESUCCESS;
582 }
583
584 err = netconn_recv(conns[i], &buf);
585 if (err == ERR_OK) {
586
587 netbuf_copy(buf, buffer, BUFSIZE);
588 len = netbuf_len(buf);
589 sendstr("Reading from connection:"NEWLINE, com->conn);
590 netconn_write(com->conn, buffer, len, NETCONN_COPY);
591 netbuf_delete(buf);
592 } else {
593 sendstr("EOF."NEWLINE, com->conn);
594 }
595 err = netconn_err(conns[i]);
596 if (err != ERR_OK) {
597 sendstr("Could not receive data: ", com->conn);
598#ifdef LWIP_DEBUG
599 sendstr(lwip_strerr(err), com->conn);
600#else
601 sendstr("(debugging must be turned on for error message to appear)", com->conn);
602#endif /* LWIP_DEBUG */
603 sendstr(NEWLINE, com->conn);
604 return ESUCCESS;
605 }
606 return ESUCCESS;
607}
608/*-----------------------------------------------------------------------------------*/
609static s8_t
610com_udpc(struct command *com)
611{
612 ip_addr_t ipaddr;
613 u16_t lport, rport;
614 int i;
615 err_t err;
616 long tmp;
617
618 tmp = strtol(com->args[0], NULL, 10);
619 if((tmp < 0) || (tmp > 0xffff)) {
620 sendstr("Invalid port number."NEWLINE, com->conn);
621 return ESUCCESS;
622 }
623 lport = (u16_t)tmp;
624 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
625 sendstr(strerror(errno), com->conn);
626 return ESYNTAX;
627 }
628 tmp = strtol(com->args[2], NULL, 10);
629 if((tmp < 0) || (tmp > 0xffff)) {
630 sendstr("Invalid port number."NEWLINE, com->conn);
631 return ESUCCESS;
632 }
633 rport = (u16_t)tmp;
634
635 /* Find the first unused connection in conns. */
636 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
637
638 if (i == NCONNS) {
639 sendstr("No more connections available, sorry."NEWLINE, com->conn);
640 return ESUCCESS;
641 }
642
643 sendstr("Setting up UDP connection from port ", com->conn);
644 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
645 sendstr(" to ", com->conn);
646 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
647 sendstr(":", com->conn);
648 netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
649 sendstr(NEWLINE, com->conn);
650
651 conns[i] = netconn_new(NETCONN_UDP);
652 if (conns[i] == NULL) {
653 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
654 return ESUCCESS;
655 }
656
657 err = netconn_connect(conns[i], &ipaddr, rport);
658 if (err != ERR_OK) {
659 netconn_delete(conns[i]);
660 conns[i] = NULL;
661 sendstr("Could not connect to remote host: ", com->conn);
662#ifdef LWIP_DEBUG
663 sendstr(lwip_strerr(err), com->conn);
664#else
665 sendstr("(debugging must be turned on for error message to appear)", com->conn);
666#endif /* LWIP_DEBUG */
667 sendstr(NEWLINE, com->conn);
668 return ESUCCESS;
669 }
670
671 err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
672 if (err != ERR_OK) {
673 netconn_delete(conns[i]);
674 conns[i] = NULL;
675 sendstr("Could not bind: ", com->conn);
676#ifdef LWIP_DEBUG
677 sendstr(lwip_strerr(err), com->conn);
678#else
679 sendstr("(debugging must be turned on for error message to appear)", com->conn);
680#endif /* LWIP_DEBUG */
681 sendstr(NEWLINE, com->conn);
682 return ESUCCESS;
683 }
684
685 sendstr("Connection set up, connection identifier is ", com->conn);
686 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
687 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
688
689 return ESUCCESS;
690}
691/*-----------------------------------------------------------------------------------*/
692static s8_t
693com_udpl(struct command *com)
694{
695 ip_addr_t ipaddr;
696 u16_t lport, rport;
697 int i;
698 err_t err;
699 long tmp;
700
701 tmp = strtol(com->args[0], NULL, 10);
702 if((tmp < 0) || (tmp > 0xffff)) {
703 sendstr("Invalid port number."NEWLINE, com->conn);
704 return ESUCCESS;
705 }
706 lport = (u16_t)tmp;
707 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
708 sendstr(strerror(errno), com->conn);
709 return ESYNTAX;
710 }
711 tmp = strtol(com->args[2], NULL, 10);
712 if((tmp < 0) || (tmp > 0xffff)) {
713 sendstr("Invalid port number."NEWLINE, com->conn);
714 return ESUCCESS;
715 }
716 rport = (u16_t)tmp;
717
718 /* Find the first unused connection in conns. */
719 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
720
721 if (i == NCONNS) {
722 sendstr("No more connections available, sorry."NEWLINE, com->conn);
723 return ESUCCESS;
724 }
725
726 sendstr("Setting up UDP-Lite connection from port ", com->conn);
727 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
728 sendstr(" to ", com->conn);
729 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
730 sendstr(":", com->conn);
731 netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
732 sendstr(NEWLINE, com->conn);
733
734 conns[i] = netconn_new(NETCONN_UDPLITE);
735 if (conns[i] == NULL) {
736 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
737 return ESUCCESS;
738 }
739
740 err = netconn_connect(conns[i], &ipaddr, rport);
741 if (err != ERR_OK) {
742 netconn_delete(conns[i]);
743 conns[i] = NULL;
744 sendstr("Could not connect to remote host: ", com->conn);
745#ifdef LWIP_DEBUG
746 sendstr(lwip_strerr(err), com->conn);
747#else
748 sendstr("(debugging must be turned on for error message to appear)", com->conn);
749#endif /* LWIP_DEBUG */
750 sendstr(NEWLINE, com->conn);
751 return ESUCCESS;
752 }
753
754 err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
755 if (err != ERR_OK) {
756 netconn_delete(conns[i]);
757 conns[i] = NULL;
758 sendstr("Could not bind: ", com->conn);
759#ifdef LWIP_DEBUG
760 sendstr(lwip_strerr(err), com->conn);
761#else
762 sendstr("(debugging must be turned on for error message to appear)", com->conn);
763#endif /* LWIP_DEBUG */
764 sendstr(NEWLINE, com->conn);
765 return ESUCCESS;
766 }
767
768 sendstr("Connection set up, connection identifier is ", com->conn);
769 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
770 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
771
772 return ESUCCESS;
773}
774/*-----------------------------------------------------------------------------------*/
775static s8_t
776com_udpn(struct command *com)
777{
778 ip_addr_t ipaddr;
779 u16_t lport, rport;
780 int i;
781 err_t err;
782 long tmp;
783
784 tmp = strtol(com->args[0], NULL, 10);
785 if((tmp < 0) || (tmp > 0xffff)) {
786 sendstr("Invalid port number."NEWLINE, com->conn);
787 return ESUCCESS;
788 }
789 lport = (u16_t)tmp;
790 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
791 sendstr(strerror(errno), com->conn);
792 return ESYNTAX;
793 }
794 tmp = strtol(com->args[2], NULL, 10);
795 if((tmp < 0) || (tmp > 0xffff)) {
796 sendstr("Invalid port number."NEWLINE, com->conn);
797 return ESUCCESS;
798 }
799 rport = (u16_t)tmp;
800
801 /* Find the first unused connection in conns. */
802 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
803
804 if (i == NCONNS) {
805 sendstr("No more connections available, sorry."NEWLINE, com->conn);
806 return ESUCCESS;
807 }
808
809 sendstr("Setting up UDP connection without checksums from port ", com->conn);
810 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
811 sendstr(" to ", com->conn);
812 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
813 sendstr(":", com->conn);
814 netconn_write(com->conn, com->args[2], strlen(com->args[2]), NETCONN_COPY);
815 sendstr(NEWLINE, com->conn);
816
817 conns[i] = netconn_new(NETCONN_UDPNOCHKSUM);
818 if (conns[i] == NULL) {
819 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
820 return ESUCCESS;
821 }
822
823 err = netconn_connect(conns[i], &ipaddr, rport);
824 if (err != ERR_OK) {
825 netconn_delete(conns[i]);
826 conns[i] = NULL;
827 sendstr("Could not connect to remote host: ", com->conn);
828#ifdef LWIP_DEBUG
829 sendstr(lwip_strerr(err), com->conn);
830#else
831 sendstr("(debugging must be turned on for error message to appear)", com->conn);
832#endif /* LWIP_DEBUG */
833 sendstr(NEWLINE, com->conn);
834 return ESUCCESS;
835 }
836
837 err = netconn_bind(conns[i], IP_ADDR_ANY, lport);
838 if (err != ERR_OK) {
839 netconn_delete(conns[i]);
840 conns[i] = NULL;
841 sendstr("Could not bind: ", com->conn);
842#ifdef LWIP_DEBUG
843 sendstr(lwip_strerr(err), com->conn);
844#else
845 sendstr("(debugging must be turned on for error message to appear)", com->conn);
846#endif /* LWIP_DEBUG */
847 sendstr(NEWLINE, com->conn);
848 return ESUCCESS;
849 }
850
851 sendstr("Connection set up, connection identifier is ", com->conn);
852 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
853 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
854
855 return ESUCCESS;
856}
857/*-----------------------------------------------------------------------------------*/
858static s8_t
859com_udpb(struct command *com)
860{
861 ip_addr_t ipaddr;
862#if LWIP_IPV4
863 u16_t lport;
864#endif /* LWIP_IPV4 */
865 u16_t rport;
866 int i;
867 err_t err;
868 long tmp;
869
870 tmp = strtol(com->args[0], NULL, 10);
871 if((tmp < 0) || (tmp > 0xffff)) {
872 sendstr("Invalid port number."NEWLINE, com->conn);
873 return ESUCCESS;
874 }
875#if LWIP_IPV4
876 lport = (u16_t)tmp;
877#endif /* LWIP_IPV4 */
878 if (ipaddr_aton(com->args[1], &ipaddr) == -1) {
879 sendstr(strerror(errno), com->conn);
880 return ESYNTAX;
881 }
882 tmp = strtol(com->args[2], NULL, 10);
883 if((tmp < 0) || (tmp > 0xffff)) {
884 sendstr("Invalid port number."NEWLINE, com->conn);
885 return ESUCCESS;
886 }
887 rport = (u16_t)tmp;
888
889 /* Find the first unused connection in conns. */
890 for(i = 0; i < NCONNS && conns[i] != NULL; i++);
891
892 if (i == NCONNS) {
893 sendstr("No more connections available, sorry."NEWLINE, com->conn);
894 return ESUCCESS;
895 }
896
897 sendstr("Setting up UDP broadcast connection from port ", com->conn);
898 netconn_write(com->conn, com->args[0], strlen(com->args[0]), NETCONN_COPY);
899 sendstr(" to ", com->conn);
900 netconn_write(com->conn, com->args[1], strlen(com->args[1]), NETCONN_COPY);
901 sendstr(NEWLINE, com->conn);
902
903 conns[i] = netconn_new(NETCONN_UDP);
904 if (conns[i] == NULL) {
905 sendstr("Could not create connection identifier (out of memory)."NEWLINE, com->conn);
906 return ESUCCESS;
907 }
908
909 err = netconn_connect(conns[i], &ipaddr, rport);
910 if (err != ERR_OK) {
911 netconn_delete(conns[i]);
912 conns[i] = NULL;
913 sendstr("Could not connect to remote host: ", com->conn);
914#ifdef LWIP_DEBUG
915 sendstr(lwip_strerr(err), com->conn);
916#else
917 sendstr("(debugging must be turned on for error message to appear)", com->conn);
918#endif /* LWIP_DEBUG */
919 sendstr(NEWLINE, com->conn);
920 return ESUCCESS;
921 }
922
923#if LWIP_IPV4
924 if (IP_IS_V6_VAL(ipaddr)) {
925 err = netconn_bind(conns[i], &ip_addr_broadcast, lport);
926 if (err != ERR_OK) {
927 netconn_delete(conns[i]);
928 conns[i] = NULL;
929 sendstr("Could not bind: ", com->conn);
930#ifdef LWIP_DEBUG
931 sendstr(lwip_strerr(err), com->conn);
932#else
933 sendstr("(debugging must be turned on for error message to appear)", com->conn);
934#endif /* LWIP_DEBUG */
935 sendstr(NEWLINE, com->conn);
936 return ESUCCESS;
937 }
938 }
939#endif /* LWIP_IPV4 */
940
941 sendstr("Connection set up, connection identifier is ", com->conn);
942 snprintf((char *)buffer, sizeof(buffer), "%d"NEWLINE, i);
943 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
944
945 return ESUCCESS;
946}
947/*-----------------------------------------------------------------------------------*/
948static s8_t
949com_usnd(struct command *com)
950{
951 long i;
952 err_t err;
953 struct netbuf *buf;
954 char *mem;
955 u16_t len;
956 size_t tmp;
957
958 i = strtol(com->args[0], NULL, 10);
959
960 if (i > NCONNS) {
961 sendstr("Connection identifier too high."NEWLINE, com->conn);
962 return ESUCCESS;
963 }
964
965 if (conns[i] == NULL) {
966 sendstr("Connection identifier not in use."NEWLINE, com->conn);
967 return ESUCCESS;
968 }
969 tmp = strlen(com->args[1]) + 1;
970 if (tmp > 0xffff) {
971 sendstr("Invalid length."NEWLINE, com->conn);
972 return ESUCCESS;
973 }
974 len = (u16_t)tmp;
975
976 buf = netbuf_new();
977 mem = (char *)netbuf_alloc(buf, len);
978 if (mem == NULL) {
979 sendstr("Could not allocate memory for sending."NEWLINE, com->conn);
980 return ESUCCESS;
981 }
982 strncpy(mem, com->args[1], len);
983 err = netconn_send(conns[i], buf);
984 netbuf_delete(buf);
985 if (err != ERR_OK) {
986 sendstr("Could not send data: ", com->conn);
987#ifdef LWIP_DEBUG
988 sendstr(lwip_strerr(err), com->conn);
989#else
990 sendstr("(debugging must be turned on for error message to appear)", com->conn);
991#endif /* LWIP_DEBUG */
992 sendstr(NEWLINE, com->conn);
993 return ESUCCESS;
994 }
995
996 sendstr("Data sent."NEWLINE, com->conn);
997 return ESUCCESS;
998}
999/*-----------------------------------------------------------------------------------*/
1000#if LWIP_SOCKET
1001/*-----------------------------------------------------------------------------------*/
1002static s8_t
1003com_idxtoname(struct command *com)
1004{
1005 long i = strtol(com->args[0], NULL, 10);
1006
1007 if (lwip_if_indextoname((unsigned int)i, (char *)buffer)) {
1008 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
1009 sendstr(NEWLINE, com->conn);
1010 } else {
1011 snprintf((char *)buffer, sizeof(buffer), "if_indextoname() failed: %d"NEWLINE, errno);
1012 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
1013 }
1014 return ESUCCESS;
1015}
1016/*-----------------------------------------------------------------------------------*/
1017static s8_t
1018com_nametoidx(struct command *com)
1019{
1020 unsigned int idx = lwip_if_nametoindex(com->args[0]);
1021
1022 if (idx) {
1023 snprintf((char *)buffer, sizeof(buffer), "%u"NEWLINE, idx);
1024 netconn_write(com->conn, buffer, strlen((const char *)buffer), NETCONN_COPY);
1025 } else {
1026 sendstr("No interface found"NEWLINE, com->conn);
1027 }
1028 return ESUCCESS;
1029}
1030#endif /* LWIP_SOCKET */
1031/*-----------------------------------------------------------------------------------*/
1032#if LWIP_DNS
1033static s8_t
1034com_gethostbyname(struct command *com)
1035{
1036 ip_addr_t addr;
1037 err_t err = netconn_gethostbyname(com->args[0], &addr);
1038
1039 if (err == ERR_OK) {
1040 if (ipaddr_ntoa_r(&addr, (char *)buffer, sizeof(buffer))) {
1041 sendstr("Host found: ", com->conn);
1042 sendstr((char *)buffer, com->conn);
1043 sendstr(NEWLINE, com->conn);
1044 } else {
1045 sendstr("ipaddr_ntoa_r failed", com->conn);
1046 }
1047 } else {
1048 sendstr("No host found"NEWLINE, com->conn);
1049 }
1050 return ESUCCESS;
1051}
1052#endif /* LWIP_DNS */
1053/*-----------------------------------------------------------------------------------*/
1054static s8_t
1055com_help(struct command *com)
1056{
1057 sendstr(help_msg1, com->conn);
1058 sendstr(help_msg2, com->conn);
1059 sendstr(help_msg3, com->conn);
1060 return ESUCCESS;
1061}
1062/*-----------------------------------------------------------------------------------*/
1063static s8_t
1064parse_command(struct command *com, u32_t len)
1065{
1066 u16_t i;
1067 u16_t bufp;
1068
1069 if (strncmp((const char *)buffer, "open", 4) == 0) {
1070 com->exec = com_open;
1071 com->nargs = 2;
1072 } else if (strncmp((const char *)buffer, "lstn", 4) == 0) {
1073 com->exec = com_lstn;
1074 com->nargs = 1;
1075 } else if (strncmp((const char *)buffer, "acpt", 4) == 0) {
1076 com->exec = com_acpt;
1077 com->nargs = 1;
1078 } else if (strncmp((const char *)buffer, "clos", 4) == 0) {
1079 com->exec = com_clos;
1080 com->nargs = 1;
1081#if LWIP_STATS
1082 } else if (strncmp((const char *)buffer, "stat", 4) == 0) {
1083 com->exec = com_stat;
1084 com->nargs = 0;
1085#endif
1086 } else if (strncmp((const char *)buffer, "send", 4) == 0) {
1087 com->exec = com_send;
1088 com->nargs = 2;
1089 } else if (strncmp((const char *)buffer, "recv", 4) == 0) {
1090 com->exec = com_recv;
1091 com->nargs = 1;
1092 } else if (strncmp((const char *)buffer, "udpc", 4) == 0) {
1093 com->exec = com_udpc;
1094 com->nargs = 3;
1095 } else if (strncmp((const char *)buffer, "udpb", 4) == 0) {
1096 com->exec = com_udpb;
1097 com->nargs = 2;
1098 } else if (strncmp((const char *)buffer, "udpl", 4) == 0) {
1099 com->exec = com_udpl;
1100 com->nargs = 3;
1101 } else if (strncmp((const char *)buffer, "udpn", 4) == 0) {
1102 com->exec = com_udpn;
1103 com->nargs = 3;
1104 } else if (strncmp((const char *)buffer, "usnd", 4) == 0) {
1105 com->exec = com_usnd;
1106 com->nargs = 2;
1107#if LWIP_SOCKET
1108 } else if (strncmp((const char *)buffer, "idxtoname", 9) == 0) {
1109 com->exec = com_idxtoname;
1110 com->nargs = 1;
1111 } else if (strncmp((const char *)buffer, "nametoidx", 9) == 0) {
1112 com->exec = com_nametoidx;
1113 com->nargs = 1;
1114#endif /* LWIP_SOCKET */
1115#if LWIP_DNS
1116 } else if (strncmp((const char *)buffer, "gethostnm", 9) == 0) {
1117 com->exec = com_gethostbyname;
1118 com->nargs = 1;
1119#endif /* LWIP_DNS */
1120 } else if (strncmp((const char *)buffer, "help", 4) == 0) {
1121 com->exec = com_help;
1122 com->nargs = 0;
1123 } else if (strncmp((const char *)buffer, "quit", 4) == 0) {
1124 printf("quit"NEWLINE);
1125 return ECLOSED;
1126 } else {
1127 return ESYNTAX;
1128 }
1129
1130 if (com->nargs == 0) {
1131 return ESUCCESS;
1132 }
1133 bufp = 0;
1134 for(; bufp < len && buffer[bufp] != ' '; bufp++);
1135 for(i = 0; i < 10; i++) {
1136 for(; bufp < len && buffer[bufp] == ' '; bufp++);
1137 if (buffer[bufp] == '\r' ||
1138 buffer[bufp] == '\n') {
1139 buffer[bufp] = 0;
1140 if (i < com->nargs - 1) {
1141 return ETOOFEW;
1142 }
1143 if (i > com->nargs - 1) {
1144 return ETOOMANY;
1145 }
1146 break;
1147 }
1148 if (bufp > len) {
1149 return ETOOFEW;
1150 }
1151 com->args[i] = (char *)&buffer[bufp];
1152 for(; bufp < len && buffer[bufp] != ' ' && buffer[bufp] != '\r' &&
1153 buffer[bufp] != '\n'; bufp++) {
1154 if (buffer[bufp] == '\\') {
1155 buffer[bufp] = ' ';
1156 }
1157 }
1158 if (bufp > len) {
1159 return ESYNTAX;
1160 }
1161 buffer[bufp] = 0;
1162 bufp++;
1163 if (i == com->nargs - 1) {
1164 break;
1165 }
1166
1167 }
1168
1169 return ESUCCESS;
1170}
1171/*-----------------------------------------------------------------------------------*/
1172static void
1173shell_error(s8_t err, struct netconn *conn)
1174{
1175 switch (err) {
1176 case ESYNTAX:
1177 sendstr("## Syntax error"NEWLINE, conn);
1178 break;
1179 case ETOOFEW:
1180 sendstr("## Too few arguments to command given"NEWLINE, conn);
1181 break;
1182 case ETOOMANY:
1183 sendstr("## Too many arguments to command given"NEWLINE, conn);
1184 break;
1185 case ECLOSED:
1186 sendstr("## Connection closed"NEWLINE, conn);
1187 break;
1188 default:
1189 /* unknown error, don't assert here */
1190 break;
1191 }
1192}
1193/*-----------------------------------------------------------------------------------*/
1194static void
1195prompt(struct netconn *conn)
1196{
1197 sendstr("> ", conn);
1198}
1199/*-----------------------------------------------------------------------------------*/
1200static void
1201shell_main(struct netconn *conn)
1202{
1203 struct pbuf *p;
1204 u16_t len = 0, cur_len;
1205 struct command com;
1206 s8_t err;
1207 int i;
1208 err_t ret;
1209#if SHELL_ECHO
1210 void *echomem;
1211#endif /* SHELL_ECHO */
1212 uint8_t c, *pc, state = TELNET_STATE_DATA;
1213 int16_t clen;
1214
1215 do {
1216 ret = netconn_recv_tcp_pbuf(conn, &p);
1217 if (ret == ERR_OK) {
1218 pc = p->payload;
1219 clen = p->tot_len;
1220 cur_len = len;
1221 while(clen-- > 0) {
1222 c = *pc++;
1223
1224 switch(state){
1225 case TELNET_STATE_DATA:
1226 if(c == TELNET_IAC) {
1227 state = TELNET_STATE_IAC;
1228 break;
1229 }
1230 buffer[len++] = c;
1231
1232 if(c == '\r')
1233 state = TELNET_STATE_CR;
1234 break;
1235
1236 case TELNET_STATE_CR:
1237 /*
1238 * Convert CR+something as:
1239 * CR+NUL = CR only
1240 * CR+LF = CR+LF or CR only
1241 * CR+else = CR+LF+else or CR+else
1242 */
1243 if(c != 0x00){
1244 if(c != '\n')
1245 buffer[len++] = c;
1246 }
1247 state = TELNET_STATE_DATA;
1248 break;
1249
1250 case TELNET_STATE_IAC:
1251 switch(c){
1252 case TELNET_AYT:
1253 sendstr(NEWLINE"[yes]"NEWLINE, conn);
1254 state = TELNET_STATE_DATA;
1255 break;
1256 case TELNET_SB:
1257 state = TELNET_STATE_SB;
1258 break;
1259 case TELNET_WILL:
1260 state = TELNET_STATE_WILL;
1261 break;
1262 case TELNET_WONT:
1263 state = TELNET_STATE_WONT;
1264 break;
1265 case TELNET_DO:
1266 state = TELNET_STATE_DO;
1267 break;
1268 case TELNET_DONT:
1269 state = TELNET_STATE_DONT;
1270 break;
1271 case TELNET_IAC:
1272 buffer[len++] = c;
1273 state = TELNET_STATE_DATA;
1274 break;
1275 default:
1276 state = TELNET_STATE_DATA;
1277 break;
1278 }
1279 break;
1280
1281 case TELNET_STATE_SB:
1282 if(c == TELNET_IAC)
1283 state = TELNET_STATE_SE;
1284 break;
1285
1286 case TELNET_STATE_SE:
1287 if (c == TELNET_SE)
1288 state = TELNET_STATE_DATA;
1289 else
1290 state = TELNET_STATE_SB;
1291 break;
1292 default:
1293 state = TELNET_STATE_DATA;
1294 break;
1295 }
1296 }
1297#if SHELL_ECHO
1298 if(len > cur_len){
1299 echomem = mem_malloc(len-cur_len+1);
1300 if (echomem != NULL) {
1301 buffer[len] = '\n';
1302 MEMCPY(echomem, &buffer[cur_len], len-cur_len+1);
1303 if(buffer[len-1] == '\r')
1304 netconn_write(conn, echomem, len-cur_len+1, NETCONN_COPY);
1305 else
1306 netconn_write(conn, echomem, len-cur_len, NETCONN_COPY);
1307 mem_free(echomem);
1308 }
1309 }
1310#endif /* SHELL_ECHO */
1311 pbuf_free(p);
1312 if (((len > 0) && ((buffer[len-1] == '\r') || (buffer[len-1] == '\n'))) ||
1313 (len >= BUFSIZE)) {
1314 if (buffer[0] != 0xff &&
1315 buffer[1] != 0xfe && len > 1) {
1316 err = parse_command(&com, len);
1317 if (err == ESUCCESS) {
1318 com.conn = conn;
1319 err = com.exec(&com);
1320 }
1321 if (err == ECLOSED) {
1322 printf("Closed"NEWLINE);
1323 shell_error(err, conn);
1324 goto close;
1325 }
1326 if (err != ESUCCESS) {
1327 shell_error(err, conn);
1328 }
1329 } else {
1330 sendstr(NEWLINE NEWLINE
1331 "lwIP simple interactive shell."NEWLINE
1332 "(c) Copyright 2001, Swedish Institute of Computer Science."NEWLINE
1333 "Written by Adam Dunkels."NEWLINE
1334 "For help, try the \"help\" command."NEWLINE, conn);
1335 }
1336 if (ret == ERR_OK) {
1337 prompt(conn);
1338 }
1339 len = 0;
1340 }
1341 }
1342 } while (ret == ERR_OK);
1343 if(err == ERR_CLSD)
1344 printf("disconnect !"NEWLINE);
1345 else
1346 printf("err %s"NEWLINE, lwip_strerr(ret));
1347
1348close:
1349 netconn_close(conn);
1350
1351 for(i = 0; i < NCONNS; i++) {
1352 if (conns[i] != NULL) {
1353 netconn_delete(conns[i]);
1354 }
1355 conns[i] = NULL;
1356 }
1357}
1358/*-----------------------------------------------------------------------------------*/
1359static void
1360shell_thread(void *arg)
1361{
1362 struct netconn *conn, *newconn;
1363 err_t err;
1364 LWIP_UNUSED_ARG(arg);
1365
1366#if LWIP_IPV4 /* LWIP_IPV4 */
1367 conn = netconn_new(NETCONN_TCP);
1368 LWIP_ERROR("shell: invalid conn", (conn != NULL), return;);
1369 err = netconn_bind(conn, IP_ADDR_ANY, 23);
1370#elif LWIP_IPV6 /* LWIP_IPV6 */
1371 conn = netconn_new(NETCONN_TCP_IPV6);
1372 LWIP_ERROR("shell: invalid conn", (conn != NULL), return;);
1373 err = netconn_bind(conn, IP6_ADDR_ANY, 23);
1374#endif /* LWIP_IPV6 */
1375 LWIP_ERROR("shell: netconn_bind failed", (err == ERR_OK), netconn_delete(conn); return;);
1376 err = netconn_listen(conn);
1377 LWIP_ERROR("shell: netconn_listen failed", (err == ERR_OK), netconn_delete(conn); return;);
1378
1379 while (1) {
1380 err = netconn_accept(conn, &newconn);
1381 if (err == ERR_OK) {
1382 shell_main(newconn);
1383 netconn_delete(newconn);
1384 }
1385 }
1386}
1387/*-----------------------------------------------------------------------------------*/
1388void
1389shell_init(void)
1390{
1391 sys_thread_new("shell_thread", shell_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
1392}
1393
1394#endif /* LWIP_NETCONN && LWIP_TCP */
Note: See TracBrowser for help on using the repository browser.