diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-12-02 18:18:59 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-12-02 18:18:59 +0000 |
commit | 3fd3ce2c6946e6162a2895f7e031231f64ebf6f3 (patch) | |
tree | bef21208f8dd5756a663dc937dde70fd43280be4 /nuttx/examples/nsh | |
parent | eb4d3300acdff3332ca4ad06ff1a5ae3bbc1449d (diff) | |
download | px4-nuttx-3fd3ce2c6946e6162a2895f7e031231f64ebf6f3.tar.gz px4-nuttx-3fd3ce2c6946e6162a2895f7e031231f64ebf6f3.tar.bz2 px4-nuttx-3fd3ce2c6946e6162a2895f7e031231f64ebf6f3.zip |
Add TELNET front end to NSH
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@421 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/examples/nsh')
-rw-r--r-- | nuttx/examples/nsh/Makefile | 15 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh.h | 61 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_envcmds.c | 16 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_fscmds.c | 96 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_main.c | 146 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_proccmds.c | 36 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_serial.c | 129 | ||||
-rw-r--r-- | nuttx/examples/nsh/nsh_telnetd.c | 565 |
8 files changed, 896 insertions, 168 deletions
diff --git a/nuttx/examples/nsh/Makefile b/nuttx/examples/nsh/Makefile index faeb30246..ef812a00d 100644 --- a/nuttx/examples/nsh/Makefile +++ b/nuttx/examples/nsh/Makefile @@ -1,5 +1,5 @@ -############################################################ -# Makefile +############################################################################ +# examples/nsh/Makefile # # Copyright (C) 2007 Gregory Nutt. All rights reserved. # Author: Gregory Nutt <spudmonkey@racsa.co.cr> @@ -31,7 +31,7 @@ # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # -############################################################ +############################################################################ -include $(TOPDIR)/.config -include $(TOPDIR)/Make.defs @@ -39,8 +39,15 @@ MKDEP = $(TOPDIR)/tools/mkdeps.sh ASRCS = -AOBJS = $(ASRCS:.S=$(OBJEXT)) CSRCS = nsh_main.c nsh_fscmds.c nsh_proccmds.c nsh_envcmds.c + +ifeq ($(CONFIG_EXAMPLES_NSH_TELNET),y) +CSRCS += nsh_telnetd.c +else +CSRCS += nsh_serial.c +endif + +AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) diff --git a/nuttx/examples/nsh/nsh.h b/nuttx/examples/nsh/nsh.h index fc9f807d2..7d0179b8e 100644 --- a/nuttx/examples/nsh/nsh.h +++ b/nuttx/examples/nsh/nsh.h @@ -41,23 +41,30 @@ ****************************************************************************/ #include <nuttx/config.h> +#ifdef CONFIG_EXAMPLES_NSH_TELNET +#else +# include <stdio.h> +#endif /**************************************************************************** * Definitions ****************************************************************************/ +#define NSH_MAX_ARGUMENTS 6 + #define errno (*get_errno_ptr()) /**************************************************************************** * Public Types ****************************************************************************/ -typedef void (*cmd_t)(int argc, char **argv); +typedef void (*cmd_t)(FAR void *handle, int argc, char **argv); /**************************************************************************** * Public Data ****************************************************************************/ +extern const char g_nshprompt[]; extern const char g_fmtargrequired[]; extern const char g_fmtarginvalid[]; extern const char g_fmtcmdnotfound[]; @@ -71,30 +78,56 @@ extern const char g_fmtcmdoutofmemory[]; * Public Function Prototypes ****************************************************************************/ +/* Message handler */ + +extern int nsh_parse(FAR void *handle, char *cmdline); + +/* I/O interfaces */ + +#ifdef CONFIG_EXAMPLES_NSH_TELNET + +extern int nsh_telnetmain(void); +extern int nsh_telnetout(FAR void *handle, const char *fmt, ...); + +# define nsh_main() nsh_telnetmain() +# define nsh_output(handle, ...) nsh_telnetout(handle, __VA_ARGS__) + +#else + +extern int nsh_serialmain(void); + +# define nsh_main() nsh_serialmain() +# define nsh_output(handle, ...) printf(__VA_ARGS__) + +#endif + +/* Shell command handlers */ + #if CONFIG_NFILE_DESCRIPTORS > 0 -extern void cmd_cat(int argc, char **argv); -extern void cmd_cp(int argc, char **argv); +extern void cmd_cat(FAR void *handle, int argc, char **argv); +extern void cmd_cp(FAR void *handle, int argc, char **argv); #endif -extern void cmd_echo(int argc, char **argv); -extern void cmd_exec(int argc, char **argv); +extern void cmd_echo(FAR void *handle, int argc, char **argv); +extern void cmd_exec(FAR void *handle, int argc, char **argv); +extern void cmd_exit(FAR void *handle, int argc, char **argv); #if CONFIG_NFILE_DESCRIPTORS > 0 -extern void cmd_ls(int argc, char **argv); +extern void cmd_ls(FAR void *handle, int argc, char **argv); #endif #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -extern void cmd_mkdir(int argc, char **argv); -extern void cmd_mount(int argc, char **argv); +extern void cmd_mkdir(FAR void *handle, int argc, char **argv); +extern void cmd_mount(FAR void *handle, int argc, char **argv); #endif -extern void cmd_ps(int argc, char **argv); +extern void cmd_ps(FAR void *handle, int argc, char **argv); #ifndef CONFIG_DISABLE_ENVIRON -extern void cmd_set(int argc, char **argv); +extern void cmd_set(FAR void *handle, int argc, char **argv); #endif #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -extern void cmd_rm(int argc, char **argv); -extern void cmd_rmdir(int argc, char **argv); -extern void cmd_umount(int argc, char **argv); +extern void cmd_rm(FAR void *handle, int argc, char **argv); +extern void cmd_rmdir(FAR void *handle, int argc, char **argv); +extern void cmd_umount(FAR void *handle, int argc, char **argv); #endif #ifndef CONFIG_DISABLE_ENVIRON -extern void cmd_unset(int argc, char **argv); +extern void cmd_unset(FAR void *handle, int argc, char **argv); #endif #endif /* __NSH_H */ diff --git a/nuttx/examples/nsh/nsh_envcmds.c b/nuttx/examples/nsh/nsh_envcmds.c index c6ff9a0f2..4af3d026d 100644 --- a/nuttx/examples/nsh/nsh_envcmds.c +++ b/nuttx/examples/nsh/nsh_envcmds.c @@ -79,7 +79,7 @@ * Name: cmd_echo ****************************************************************************/ -void cmd_echo(int argc, char **argv) +void cmd_echo(FAR void *handle, int argc, char **argv) { int i; @@ -97,16 +97,16 @@ void cmd_echo(int argc, char **argv) char *value = getenv(argv[i]+1); if (value) { - printf("%s ", value); + nsh_output(handle, "%s ", value); } } else #endif { - printf("%s ", argv[i]); + nsh_output(handle, "%s ", argv[i]); } } - putchar('\n'); + nsh_output(handle, "\n"); } /**************************************************************************** @@ -114,11 +114,11 @@ void cmd_echo(int argc, char **argv) ****************************************************************************/ #ifndef CONFIG_DISABLE_ENVIRON -void cmd_set(int argc, char **argv) +void cmd_set(FAR void *handle, int argc, char **argv) { if (setenv(argv[1], argv[2], TRUE) < 0) { - printf(g_fmtcmdfailed, argv[0], "setenv", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "setenv", strerror(errno)); } } #endif @@ -128,11 +128,11 @@ void cmd_set(int argc, char **argv) ****************************************************************************/ #ifndef CONFIG_DISABLE_ENVIRON -void cmd_unset(int argc, char **argv) +void cmd_unset(FAR void *handle, int argc, char **argv) { if (unsetenv(argv[1]) < 0) { - printf(g_fmtcmdfailed, argv[0], "unsetenv", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "unsetenv", strerror(errno)); } } #endif diff --git a/nuttx/examples/nsh/nsh_fscmds.c b/nuttx/examples/nsh/nsh_fscmds.c index a40120d8f..6f7a38a50 100644 --- a/nuttx/examples/nsh/nsh_fscmds.c +++ b/nuttx/examples/nsh/nsh_fscmds.c @@ -90,7 +90,7 @@ * Private Types ****************************************************************************/ -typedef int (*direntry_handler_t)(const char *, struct dirent *, void *); +typedef int (*direntry_handler_t)(FAR void *, const char *, struct dirent *, void *); /**************************************************************************** * Private Function Prototypes @@ -151,7 +151,8 @@ static char *getdirpath(const char *path, const char *file) * Name: foreach_direntry ****************************************************************************/ -static int foreach_direntry(const char *cmd, const char *dirpath, +#if CONFIG_NFILE_DESCRIPTORS > 0 +static int foreach_direntry(FAR void *handle, const char *cmd, const char *dirpath, direntry_handler_t handler, void *pvarg) { DIR *dirp; @@ -171,7 +172,7 @@ static int foreach_direntry(const char *cmd, const char *dirpath, { /* Failed to open the directory */ - printf(g_fmtnosuch, cmd, "directory", dirpath); + nsh_output(handle, g_fmtnosuch, cmd, "directory", dirpath); return ERROR; } @@ -189,7 +190,7 @@ static int foreach_direntry(const char *cmd, const char *dirpath, /* Call the handler with this directory entry */ - if (handler(dirpath, entryp, pvarg) < 0) + if (handler(handle, dirpath, entryp, pvarg) < 0) { /* The handler reported a problem */ @@ -201,13 +202,14 @@ static int foreach_direntry(const char *cmd, const char *dirpath, closedir(dirp); return ret; } +#endif /**************************************************************************** * Name: ls_handler ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg) +static int ls_handler(FAR void *handle, const char *dirpath, struct dirent *entryp, void *pvarg) { unsigned int lsflags = (unsigned int)pvarg; int ret; @@ -225,7 +227,7 @@ static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg) free(fullpath); if (ret != 0) { - printf(g_fmtcmdfailed, "ls", "stat", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, "ls", "stat", strerror(errno)); return OK; } @@ -290,30 +292,30 @@ static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg) details[9]='x'; } - printf(" %s", details); + nsh_output(handle, " %s", details); } if ((lsflags & LSFLAGS_SIZE) != 0) { - printf("%8d", buf.st_size); + nsh_output(handle, "%8d", buf.st_size); } } /* then provide the filename that is common to normal and verbose output */ #ifdef CONFIG_FULL_PATH - printf(" %s/%s", arg, entryp->d_name); + nsh_output(handle, " %s/%s", arg, entryp->d_name); #else - printf(" %s", entryp->d_name); + nsh_output(handle, " %s", entryp->d_name); #endif if (DIRENT_ISDIRECTORY(entryp->d_type)) { - printf("/\n"); + nsh_output(handle, "/\n"); } else { - putchar('\n'); + nsh_output(handle, "\n"); } return OK; } @@ -324,7 +326,7 @@ static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg) ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -static int ls_recursive(const char *dirpath, struct dirent *entryp, void *pvarg) +static int ls_recursive(FAR void *handle, const char *dirpath, struct dirent *entryp, void *pvarg) { /* Is this entry a directory? */ @@ -337,12 +339,12 @@ static int ls_recursive(const char *dirpath, struct dirent *entryp, void *pvarg) /* List the directory contents */ - printf("%s:\n", newpath); - foreach_direntry("ls", newpath, ls_handler, pvarg); + nsh_output(handle, "%s:\n", newpath); + foreach_direntry(handle, "ls", newpath, ls_handler, pvarg); /* Then recurse to list each directory within the directory */ - foreach_direntry("ls", newpath, ls_recursive, pvarg); + foreach_direntry(handle, "ls", newpath, ls_recursive, pvarg); free(newpath); } return OK; @@ -358,7 +360,7 @@ static int ls_recursive(const char *dirpath, struct dirent *entryp, void *pvarg) ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_cat(int argc, char **argv) +void cmd_cat(FAR void *handle, int argc, char **argv) { char buffer[1024]; @@ -367,7 +369,7 @@ void cmd_cat(int argc, char **argv) int fd = open(argv[1], O_RDONLY); if (fd < 0) { - printf(g_fmtcmdfailed, argv[0], "open", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "open", strerror(errno)); return; } @@ -385,7 +387,7 @@ void cmd_cat(int argc, char **argv) if (errno != EINTR) { - printf(g_fmtcmdfailed, argv[0], "read", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "read", strerror(errno)); break; } } @@ -405,7 +407,7 @@ void cmd_cat(int argc, char **argv) if (errno != EINTR) { - printf(g_fmtcmdfailed, argv[0], "write", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "write", strerror(errno)); break; } } @@ -433,7 +435,7 @@ void cmd_cat(int argc, char **argv) ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_cp(int argc, char **argv) +void cmd_cp(FAR void *handle, int argc, char **argv) { struct stat buf; char *fullpath = NULL; @@ -448,7 +450,7 @@ void cmd_cp(int argc, char **argv) rdfd = open(argv[1], O_RDONLY); if (rdfd < 0) { - printf(g_fmtcmdfailed, argv[0], "open", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "open", strerror(errno)); return; } @@ -470,7 +472,7 @@ void cmd_cp(int argc, char **argv) fullpath = getdirpath(argv[2], basename(argv[1]) ); if (!fullpath) { - printf(g_fmtcmdoutofmemory, argv[0]); + nsh_output(handle, g_fmtcmdoutofmemory, argv[0]); goto out_with_rdfd; } @@ -490,7 +492,7 @@ void cmd_cp(int argc, char **argv) wrfd = open(wrpath, oflags, 0666); if (wrfd < 0) { - printf(g_fmtcmdfailed, argv[0], "open", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "open", strerror(errno)); goto out_with_fullpath; } @@ -514,7 +516,7 @@ void cmd_cp(int argc, char **argv) { /* Read error */ - printf(g_fmtcmdfailed, argv[0], "read", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "read", strerror(errno)); goto out_with_wrfd; } } @@ -531,7 +533,7 @@ void cmd_cp(int argc, char **argv) { /* Read error */ - printf(g_fmtcmdfailed, argv[0], "write", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "write", strerror(errno)); goto out_with_wrfd; } } @@ -557,7 +559,7 @@ out_with_rdfd: ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_ls(int argc, char **argv) +void cmd_ls(FAR void *handle, int argc, char **argv) { unsigned int lsflags = 0; int ret; @@ -583,7 +585,7 @@ void cmd_ls(int argc, char **argv) case '?': default: - printf(g_fmtarginvalid, argv[0]); + nsh_output(handle, g_fmtarginvalid, argv[0]); return; } } @@ -592,24 +594,24 @@ void cmd_ls(int argc, char **argv) if (optind + 1 < argc) { - printf(g_fmttoomanyargs, argv[0]); + nsh_output(handle, g_fmttoomanyargs, argv[0]); return; } else if (optind + 1 > argc) { - printf(g_fmtargrequired, argv[0]); + nsh_output(handle, g_fmtargrequired, argv[0]); return; } /* List the directory contents */ - printf("%s:\n", argv[optind]); - ret = foreach_direntry("ls", argv[optind], ls_handler, (void*)lsflags); + nsh_output(handle, "%s:\n", argv[optind]); + ret = foreach_direntry(handle, "ls", argv[optind], ls_handler, (void*)lsflags); if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0) { /* Then recurse to list each directory within the directory */ - ret = foreach_direntry("ls", argv[optind], ls_recursive, (void*)lsflags); + ret = foreach_direntry(handle, "ls", argv[optind], ls_recursive, (void*)lsflags); } } #endif @@ -619,12 +621,12 @@ void cmd_ls(int argc, char **argv) ****************************************************************************/ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_mkdir(int argc, char **argv) +void cmd_mkdir(FAR void *handle, int argc, char **argv) { int result = mkdir(argv[1], 0777); if ( result < 0) { - printf(g_fmtcmdfailed, argv[0], "mkdir", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "mkdir", strerror(errno)); } } #endif @@ -634,7 +636,7 @@ void cmd_mkdir(int argc, char **argv) ****************************************************************************/ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_mount(int argc, char **argv) +void cmd_mount(FAR void *handle, int argc, char **argv) { char *filesystem = 0; int result; @@ -651,12 +653,12 @@ void cmd_mount(int argc, char **argv) break; case ':': - printf(g_fmtargrequired, argv[0]); + nsh_output(handle, g_fmtargrequired, argv[0]); return; case '?': default: - printf(g_fmtarginvalid, argv[0]); + nsh_output(handle, g_fmtarginvalid, argv[0]); return; } } @@ -665,12 +667,12 @@ void cmd_mount(int argc, char **argv) if (optind + 2 < argc) { - printf(g_fmttoomanyargs, argv[0]); + nsh_output(handle, g_fmttoomanyargs, argv[0]); return; } else if (optind + 2 > argc) { - printf(g_fmtargrequired, argv[0]); + nsh_output(handle, g_fmtargrequired, argv[0]); return; } @@ -678,7 +680,7 @@ void cmd_mount(int argc, char **argv) result = mount(argv[optind], argv[optind+1], filesystem, 0, NULL); if ( result < 0) { - printf(g_fmtcmdfailed, argv[0], "mount", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "mount", strerror(errno)); } } #endif @@ -688,11 +690,11 @@ void cmd_mount(int argc, char **argv) ****************************************************************************/ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_rm(int argc, char **argv) +void cmd_rm(FAR void *handle, int argc, char **argv) { if (unlink(argv[1]) < 0) { - printf(g_fmtcmdfailed, argv[0], "unlink", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "unlink", strerror(errno)); } } #endif @@ -702,11 +704,11 @@ void cmd_rm(int argc, char **argv) ****************************************************************************/ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_rmdir(int argc, char **argv) +void cmd_rmdir(FAR void *handle, int argc, char **argv) { if (rmdir(argv[1]) < 0) { - printf(g_fmtcmdfailed, argv[0], "rmdir", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "rmdir", strerror(errno)); } } #endif @@ -716,13 +718,13 @@ void cmd_rmdir(int argc, char **argv) ****************************************************************************/ #if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 -void cmd_umount(int argc, char **argv) +void cmd_umount(FAR void *handle, int argc, char **argv) { /* Perform the umount */ int result = umount(argv[1]); if ( result < 0) { - printf(g_fmtcmdfailed, argv[0], "umount", strerror(errno)); + nsh_output(handle, g_fmtcmdfailed, argv[0], "umount", strerror(errno)); } } #endif diff --git a/nuttx/examples/nsh/nsh_main.c b/nuttx/examples/nsh/nsh_main.c index a52d2d0b8..cb65833d1 100644 --- a/nuttx/examples/nsh/nsh_main.c +++ b/nuttx/examples/nsh/nsh_main.c @@ -51,7 +51,6 @@ #define CONFIG_NSH_LINE_SIZE 80 #undef CONFIG_FULL_PATH -#define NSH_MAX_ARGUMENTS 6 /**************************************************************************** * Private Types @@ -70,14 +69,13 @@ struct cmdmap_s * Private Function Prototypes ****************************************************************************/ -static void cmd_help(int argc, char **argv); -static void cmd_unrecognized(int argc, char **argv); +static void cmd_help(FAR void *handle, int argc, char **argv); +static void cmd_unrecognized(FAR void *handle, int argc, char **argv); /**************************************************************************** * Private Data ****************************************************************************/ -static char line[CONFIG_NSH_LINE_SIZE]; static const char delim[] = " \t\n"; static const struct cmdmap_s g_cmdmap[] = @@ -92,6 +90,7 @@ static const struct cmdmap_s g_cmdmap[] = { "echo", cmd_echo, 0, NSH_MAX_ARGUMENTS, "[<string> [<string>...]]" }, #endif { "exec", cmd_exec, 2, 3, "<hex-address>" }, + { "exit", cmd_exit, 1, 1, NULL }, { "help", cmd_help, 1, 1, NULL }, #if CONFIG_NFILE_DESCRIPTORS > 0 { "ls", cmd_ls, 2, 5, "[-lRs] <dir-path>" }, @@ -119,6 +118,7 @@ static const struct cmdmap_s g_cmdmap[] = * Public Data ****************************************************************************/ +const char g_nshprompt[] = "nsh> "; const char g_fmtargrequired[] = "nsh: %s: missing required argument(s)\n"; const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n"; const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n"; @@ -136,20 +136,20 @@ const char g_fmtcmdoutofmemory[] = "nsh: %s: out of memory\n"; * Name: cmd_help ****************************************************************************/ -static void cmd_help(int argc, char **argv) +static void cmd_help(FAR void *handle, int argc, char **argv) { const struct cmdmap_s *ptr; - printf("NSH commands:\n"); + nsh_output(handle, "NSH commands:\n"); for (ptr = g_cmdmap; ptr->cmd; ptr++) { if (ptr->usage) { - printf(" %s %s\n", ptr->cmd, ptr->usage); + nsh_output(handle, " %s %s\n", ptr->cmd, ptr->usage); } else { - printf(" %s\n", ptr->cmd); + nsh_output(handle, " %s\n", ptr->cmd); } } } @@ -158,9 +158,9 @@ static void cmd_help(int argc, char **argv) * Name: cmd_unrecognized ****************************************************************************/ -static void cmd_unrecognized(int argc, char **argv) +static void cmd_unrecognized(FAR void *handle, int argc, char **argv) { - printf(g_fmtcmdnotfound, argv[0]); + nsh_output(handle, g_fmtcmdnotfound, argv[0]); } /**************************************************************************** @@ -182,94 +182,86 @@ void user_initialize(void) int user_start(int argc, char *argv[]) { - printf("NuttShell (NSH)\n"); - fflush(stdout); - - for (;;) - { - const struct cmdmap_s *cmdmap; - char *saveptr; - char *cmd; + return nsh_main(); +} - /* Get the next line of input */ +/**************************************************************************** + * Name: nsh_parse + ****************************************************************************/ - fgets(line, CONFIG_NSH_LINE_SIZE, stdin); +int nsh_parse(FAR void *handle, char *cmdline) +{ + const struct cmdmap_s *cmdmap; + char *argv[NSH_MAX_ARGUMENTS+1]; + char *saveptr; + char *cmd; + int argc; - /* Parse out the command at the beginning of the line */ + /* Parse out the command at the beginning of the line */ - cmd = strtok_r(line, " \t\n", &saveptr); - if (cmd) - { - cmd_t handler = cmd_unrecognized; + cmd = strtok_r(cmdline, " \t\n", &saveptr); + if (cmd) + { + cmd_t handler = cmd_unrecognized; - /* Parse all of the arguments following the command name */ + /* Parse all of the arguments following the command name */ - char *cmd_argv[NSH_MAX_ARGUMENTS+1]; - int cmd_argc; - cmd_argv[0] = cmd; - for (cmd_argc = 1; cmd_argc < NSH_MAX_ARGUMENTS+1; cmd_argc++) + argv[0] = cmd; + for (argc = 1; argc < NSH_MAX_ARGUMENTS+1; argc++) + { + argv[argc] = strtok_r( NULL, " \t\n", &saveptr); + if (!argv[argc]) { - cmd_argv[cmd_argc] = strtok_r( NULL, " \t\n", &saveptr); - if ( !cmd_argv[cmd_argc] ) - { - break; - } + break; } + } - if (cmd_argc > NSH_MAX_ARGUMENTS) - { - printf(g_fmttoomanyargs, cmd); - } + if (argc > NSH_MAX_ARGUMENTS) + { + nsh_output(handle, g_fmttoomanyargs, cmd); + } - /* See if the command is one that we understand */ + /* See if the command is one that we understand */ - for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++) + { + if (strcmp(cmdmap->cmd, cmd) == 0) { - if (strcmp(cmdmap->cmd, cmd) == 0) - { - /* Check if a valid number of arguments was provided. We + /* Check if a valid number of arguments was provided. We * do this simple, imperfect checking here so that it does * not have to be performed in each command. */ - if (cmd_argc < cmdmap->minargs) - { - /* Fewer than the minimum number were provided */ - - printf(g_fmtargrequired, cmd); - handler = NULL; - break; - } - else if (cmd_argc > cmdmap->maxargs) - { - /* More than the maximum number were provided */ - - printf(g_fmttoomanyargs, cmd); - handler = NULL; - break; - } - else - { - /* A valid number of arguments were provided (this does - * not mean they are right. - */ - - handler = cmdmap->handler; - break; - } + if (argc < cmdmap->minargs) + { + /* Fewer than the minimum number were provided */ + + nsh_output(handle, g_fmtargrequired, cmd); + return ERROR; } - } + else if (argc > cmdmap->maxargs) + { + /* More than the maximum number were provided */ - /* If a error was detected above, handler will be nullified to - * prevent reporting multiple errors. - */ + nsh_output(handle, g_fmttoomanyargs, cmd); + return ERROR; + } + else + { + /* A valid number of arguments were provided (this does + * not mean they are right). + */ - if (handler) - { - handler(cmd_argc, cmd_argv); + handler = cmdmap->handler; + break; + } } } - fflush(stdout); + + handler(handle, argc, argv); + return OK; } + + return ERROR; } diff --git a/nuttx/examples/nsh/nsh_proccmds.c b/nuttx/examples/nsh/nsh_proccmds.c index 285db5586..70a5add0c 100644 --- a/nuttx/examples/nsh/nsh_proccmds.c +++ b/nuttx/examples/nsh/nsh_proccmds.c @@ -97,27 +97,27 @@ static void ps_task(FAR _TCB *tcb, FAR void *arg) { boolean needcomma = FALSE; int i; - printf("%5d %3d %4s %7s%c%c %8s ", - tcb->pid, tcb->sched_priority, - tcb->flags & TCB_FLAG_ROUND_ROBIN ? "RR " : "FIFO", - tcb->flags & TCB_FLAG_PTHREAD ? "PTHREAD" : "TASK ", - tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : ' ', - tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : ' ', - g_statenames[tcb->task_state]); - - printf("%s(", tcb->argv[0]); + nsh_output(arg, "%5d %3d %4s %7s%c%c %8s ", + tcb->pid, tcb->sched_priority, + tcb->flags & TCB_FLAG_ROUND_ROBIN ? "RR " : "FIFO", + tcb->flags & TCB_FLAG_PTHREAD ? "PTHREAD" : "TASK ", + tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : ' ', + tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : ' ', + g_statenames[tcb->task_state]); + + nsh_output(arg, "%s(", tcb->argv[0]); for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && tcb->argv[i]; i++) { if (needcomma) { - printf(", %p", tcb->argv[i]); + nsh_output(arg, ", %p", tcb->argv[i]); } else { - printf("%p", tcb->argv[i]); + nsh_output(arg, "%p", tcb->argv[i]); } } - printf(")\n"); + nsh_output(arg, ")\n"); } /**************************************************************************** @@ -128,7 +128,7 @@ static void ps_task(FAR _TCB *tcb, FAR void *arg) * Name: cmd_exec ****************************************************************************/ -void cmd_exec(int argc, char **argv) +void cmd_exec(FAR void *handle, int argc, char **argv) { char *endptr; long addr; @@ -136,11 +136,11 @@ void cmd_exec(int argc, char **argv) addr = strtol(argv[1], &endptr, 0); if (!addr || endptr == argv[1] || *endptr != '\0') { - printf(g_fmtarginvalid, argv[0]); + nsh_output(handle, g_fmtarginvalid, argv[0]); return; } - printf("Calling %p\n", (exec_t)addr); + nsh_output(handle, "Calling %p\n", (exec_t)addr); ((exec_t)addr)(); } @@ -148,8 +148,8 @@ void cmd_exec(int argc, char **argv) * Name: cmd_ps ****************************************************************************/ -void cmd_ps(int argc, char **argv) +void cmd_ps(FAR void *handle, int argc, char **argv) { - printf("PID PRI SCHD TYPE NP STATE NAME\n"); - sched_foreach(ps_task, NULL); + nsh_output(handle, "PID PRI SCHD TYPE NP STATE NAME\n"); + sched_foreach(ps_task, handle); } diff --git a/nuttx/examples/nsh/nsh_serial.c b/nuttx/examples/nsh/nsh_serial.c new file mode 100644 index 000000000..7716521ab --- /dev/null +++ b/nuttx/examples/nsh/nsh_serial.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * examples/nsh/nsh_serial.h + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <sys/types.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "nsh.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define CONFIG_NSH_LINE_SIZE 80 +#undef CONFIG_FULL_PATH + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct cmdmap_s +{ + const char *cmd; /* Name of the command */ + cmd_t handler; /* Function that handles the command */ + ubyte minargs; /* Minimum number of arguments (including command) */ + ubyte maxargs; /* Maximum number of arguments (including command) */ + const char *usage; /* Usage instructions for 'help' command */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static char line[CONFIG_NSH_LINE_SIZE]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_main + ****************************************************************************/ + +int nsh_serialmain(void) +{ + printf("NuttShell (NSH)\n"); + fflush(stdout); + + for (;;) + { + /* Display the prompt string */ + + fputs(g_nshprompt, stdout); + fflush(stdout); + + /* Get the next line of input */ + + fgets(line, CONFIG_NSH_LINE_SIZE, stdin); + + /* Parse process the command */ + + (void)nsh_parse(NULL, line); + fflush(stdout); + } +} + +/**************************************************************************** + * Name: cmd_exit + * + * Description: + * Exit the shell task + * + ****************************************************************************/ + +void cmd_exit(void *handle, int argc, char **argv) +{ + exit(0); +} diff --git a/nuttx/examples/nsh/nsh_telnetd.c b/nuttx/examples/nsh/nsh_telnetd.c new file mode 100644 index 000000000..f90f535ba --- /dev/null +++ b/nuttx/examples/nsh/nsh_telnetd.c @@ -0,0 +1,565 @@ +/**************************************************************************** + * examples/nsh/nsh_telnetd.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * This is a leverage of similar logic from uIP: + * + * Author: Adam Dunkels <adam@sics.se> + * Copyright (c) 2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <sys/socket.h> + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <pthread.h> +#include <debug.h> + +#include <net/uip/uip-lib.h> + +#include "nsh.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define ISO_nl 0x0a +#define ISO_cr 0x0d + +#define STATE_NORMAL 0 +#define STATE_IAC 1 +#define STATE_WILL 2 +#define STATE_WONT 3 +#define STATE_DO 4 +#define STATE_DONT 5 +#define STATE_CLOSE 6 + +#define TELNET_IAC 255 +#define TELNET_WILL 251 +#define TELNET_WONT 252 +#define TELNET_DO 253 +#define TELNET_DONT 254 + +/* Configurable settings */ + +#ifndef CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE +# define CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE 512 +#endif + +#ifndef CONFIG_EXAMPLES_NSH_CMD_SIZE +# define CONFIG_EXAMPLES_NSH_CMD_SIZE 40 +#endif + +/* As threads are created to handle each request, a stack must be allocated + * for the thread. Use a default if the user provided no stacksize. + */ + +#ifndef CONFIG_EXAMPLES_NSH_STACKSIZE +# define CONFIG_EXAMPLES_NSH_STACKSIZE 4096 +#endif + +/* Enabled dumping of all input/output buffers */ + +#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct telnetd_s +{ + int tn_sockfd; + char tn_iobuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE]; + char tn_cmd[CONFIG_EXAMPLES_NSH_CMD_SIZE]; + uint8 tn_bufndx; + uint8 tn_state; +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_dumpbuffer + * + * Description: + * Dump a buffer of data (debug only) + * + ****************************************************************************/ + +#ifdef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER +static void nsh_dumpbuffer(const char *msg, const char *buffer, ssize_t nbytes) +{ +#ifdef CONFIG_DEBUG + char line[128]; + int ch; + int i; + int j; + + dbg("%s:\n", msg); + for (i = 0; i < nbytes; i += 16) + { + sprintf(line, "%04x: ", i); + + for ( j = 0; j < 16; j++) + { + if (i + j < nbytes) + { + sprintf(&line[strlen(line)], "%02x ", buffer[i+j] ); + } + else + { + strcpy(&line[strlen(line)], " "); + } + } + + for ( j = 0; j < 16; j++) + { + if (i + j < nbytes) + { + ch = buffer[i+j]; + sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.'); + } + } + dbg("%s\n", line); + } +#endif +} +#else +# define nsh_dumpbuffer(msg,buffer,nbytes) +#endif + +/**************************************************************************** + * Name: nsh_putchar + * + * Description: + * Add another parsed character to the TELNET command string + * + ****************************************************************************/ + +static void nsh_putchar(struct telnetd_s *pstate, uint8 ch) +{ + /* Ignore carriage returns */ + + if (ch == ISO_cr) + { + return; + } + + /* Add all other characters to the cmd buffer */ + + pstate->tn_cmd[pstate->tn_bufndx] = ch; + + /* If a newline was added or if the buffer is full, then process it now */ + + if (ch == ISO_nl || pstate->tn_bufndx == (CONFIG_EXAMPLES_NSH_CMD_SIZE - 1)) + { + if (pstate->tn_bufndx > 0) + { + pstate->tn_cmd[pstate->tn_bufndx] = '\0'; + } + + nsh_dumpbuffer("TELNET CMD", pstate->tn_cmd, strlen(pstate->tn_cmd)); + nsh_parse((void*)pstate, pstate->tn_cmd); + pstate->tn_bufndx = 0; + } + else + { + pstate->tn_bufndx++; + vdbg("Add '%c', bufndx=%d\n", ch, pstate->tn_bufndx); + } +} + +/**************************************************************************** + * Name: nsh_sendopt + * + * Description: + * + ****************************************************************************/ + +static void nsh_sendopt(struct telnetd_s *pstate, uint8 option, uint8 value) +{ + uint8 optbuf[4]; + optbuf[0] = TELNET_IAC; + optbuf[1] = option; + optbuf[2] = value; + optbuf[3] = 0; + + nsh_dumpbuffer("Send optbuf", optbuf, 4); + if (send(pstate->tn_sockfd, optbuf, 4, 0) < 0) + { + dbg("[%d] Failed to send TELNET_IAC\n", pstate->tn_sockfd); + } +} + +/**************************************************************************** + * Name: nsh_receive + * + * Description: + * Process a received TELENET buffer + * + ****************************************************************************/ + +static int nsh_receive(struct telnetd_s *pstate, size_t len) +{ + char *ptr = pstate->tn_iobuffer; + uint8 ch; + + while (len > 0) + { + ch = *ptr++; + len--; + + vdbg("ch=%02x state=%d\n", ch, pstate->tn_state); + switch (pstate->tn_state) + { + case STATE_IAC: + if (ch == TELNET_IAC) + { + nsh_putchar(pstate, ch); + pstate->tn_state = STATE_NORMAL; + } + else + { + switch (ch) + { + case TELNET_WILL: + pstate->tn_state = STATE_WILL; + break; + + case TELNET_WONT: + pstate->tn_state = STATE_WONT; + break; + + case TELNET_DO: + pstate->tn_state = STATE_DO; + break; + + case TELNET_DONT: + pstate->tn_state = STATE_DONT; + break; + + default: + pstate->tn_state = STATE_NORMAL; + break; + } + } + break; + + case STATE_WILL: + /* Reply with a DONT */ + + nsh_sendopt(pstate, TELNET_DONT, ch); + pstate->tn_state = STATE_NORMAL; + break; + + case STATE_WONT: + /* Reply with a DONT */ + + nsh_sendopt(pstate, TELNET_DONT, ch); + pstate->tn_state = STATE_NORMAL; + break; + + case STATE_DO: + /* Reply with a WONT */ + + nsh_sendopt(pstate, TELNET_WONT, ch); + pstate->tn_state = STATE_NORMAL; + break; + + case STATE_DONT: + /* Reply with a WONT */ + + nsh_sendopt(pstate, TELNET_WONT, ch); + pstate->tn_state = STATE_NORMAL; + break; + + case STATE_NORMAL: + if (ch == TELNET_IAC) + { + pstate->tn_state = STATE_IAC; + } + else + { + nsh_putchar(pstate, ch); + } + break; + } + } + return OK; +} + +/**************************************************************************** + * Name: nsh_prompt + * + * Description: + * Print a prompt to the shell window. + * + * This function can be used by the shell back-end to print out a prompt + * to the shell window. + * + ****************************************************************************/ + +static void nsh_prompt(struct telnetd_s *pstate, const char *str) +{ + int len = strlen(str); + + strncpy(pstate->tn_iobuffer, str, len); + nsh_dumpbuffer("Shell prompt", pstate->tn_iobuffer, len); + if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len, 0) < 0) + { + dbg("[%d] Failed to send prompt\n", pstate->tn_sockfd); + } +} + +/**************************************************************************** + * Name: nsh_connection + * + * Description: + * Each time a new connection to port 23 is made, a new thread is created + * that begins at this entry point. There should be exactly one argument + * and it should be the socket descriptor (+1). + * + ****************************************************************************/ + +static void *nsh_connection(void *arg) +{ + struct telnetd_s *pstate = (struct telnetd_s *)malloc(sizeof(struct telnetd_s)); + int sockfd = (int)arg; + int ret = ERROR; + + dbg("[%d] Started\n", sockfd); + + /* Verify that the state structure was successfully allocated */ + + if (pstate) + { + /* Initialize the thread state structure */ + + memset(pstate, 0, sizeof(struct telnetd_s)); + pstate->tn_sockfd = sockfd; + pstate->tn_state = STATE_NORMAL; + + /* Loop processing each TELNET command */ + + do + { + /* Display the prompt string */ + + nsh_prompt(pstate, g_nshprompt); + + /* Read a buffer of data from the TELNET client */ + + ret = recv(pstate->tn_sockfd, pstate->tn_iobuffer, CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, 0); + if (ret > 0) + { + + /* Process the received TELNET data */ + + nsh_dumpbuffer("Received buffer", pstate->tn_iobuffer, ret); + ret = nsh_receive(pstate, ret); + } + } + while (ret >= 0 && pstate->tn_state != STATE_CLOSE); + dbg("[%d] ret=%d tn_state=%d\n", sockfd, ret, pstate->tn_state); + + /* End of command processing -- Clean up and exit */ + + free(pstate); + } + + /* Exit the task */ + + dbg("[%d] Exitting\n", sockfd); + close(sockfd); + pthread_exit(NULL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_telnetmain + * + * Description: + * This is the main processing thread for telnetd. It never returns + * unless an error occurs + * + ****************************************************************************/ + +int nsh_telnetmain(void) +{ + struct in_addr addr; +#if defined(CONFIG_EXAMPLES_NSH_DHCPC) || defined(CONFIG_EXAMPLES_NSH_NOMAC) + uint8 mac[IFHWADDRLEN]; +#endif + +/* Many embedded network interfaces must have a software assigned MAC */ + +#ifdef CONFIG_EXAMPLES_NSH_NOMAC + mac[0] = 0x00; + mac[1] = 0xe0; + mac[2] = 0xb0; + mac[3] = 0x0b; + mac[4] = 0xba; + mac[5] = 0xbe; + uip_setmacaddr("eth0", mac); +#endif + + /* Set up our host address */ + +#if !defined(CONFIG_EXAMPLES_NSH_DHCPC) + addr.s_addr = HTONL(CONFIG_EXAMPLES_NSH_IPADDR); +#else + addr.s_addr = 0; +#endif + uip_sethostaddr("eth0", &addr); + + /* Set up the default router address */ + + addr.s_addr = HTONL(CONFIG_EXAMPLES_NSH_DRIPADDR); + uip_setdraddr("eth0", &addr); + + /* Setup the subnet mask */ + + addr.s_addr = HTONL(CONFIG_EXAMPLES_NSH_NETMASK); + uip_setnetmask("eth0", &addr); + +#if defined(CONFIG_EXAMPLES_NSH_DHCPC) + /* Set up the resolver */ + + resolv_init(); +#endif + +#if defined(CONFIG_EXAMPLES_NSH_DHCPC) + /* Get the MAC address of the NIC */ + + uip_getmacaddr("eth0", mac); + + /* Set up the DHCPC modules */ + + handle = dhcpc_open(&mac, IFHWADDRLEN); + + /* Get an IP address */ + + if (handle) + { + struct dhcpc_state ds; + (void)dhcpc_request(handle, &ds); + uip_sethostaddr("eth1", &ds.ipaddr); + if (ds.netmask.s_addr != 0) + { + uip_setnetmask("eth0", &ds.netmask); + } + if (ds.default_router.s_addr != 0) + { + uip_setdraddr("eth0", &ds.default_router); + } + if (ds.dnsaddr.s_addr != 0) + { + resolv_conf(&ds.dnsaddr); + } + dhcpc_close(handle); + } +#endif + + /* Execute nsh_connection on each connection to port 23 */ + + uip_server(HTONS(23), nsh_connection, CONFIG_EXAMPLES_NSH_STACKSIZE); + return OK; +} + +/**************************************************************************** + * Name: nsh_telnetout + * + * Description: + * Print a string to the remote shell window. + * + * This function is implemented by the shell GUI / telnet server and + * can be called by the shell back-end to output a string in the + * shell window. The string is automatically appended with a linebreak. + * + ****************************************************************************/ + +int nsh_telnetout(FAR void *handle, const char *fmt, ...) +{ + struct telnetd_s *pstate = (struct telnetd_s *)handle; + unsigned len; + va_list ap; + + va_start(ap, fmt); + vsnprintf(pstate->tn_iobuffer, CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, fmt, ap); + va_end(ap); + + len = strlen(pstate->tn_iobuffer); + if (len < (CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - 1) && pstate->tn_iobuffer[len-1] == '\n') + { + pstate->tn_iobuffer[len-1] = ISO_cr; + pstate->tn_iobuffer[len] = ISO_nl; + pstate->tn_iobuffer[len+1] = '\0'; + len++; + } + + nsh_dumpbuffer("Shell output", pstate->tn_iobuffer, len); + if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len, 0) < 0) + { + dbg("[%d] Failed to send response\n", pstate->tn_sockfd); + return ERROR; + } + + return len; +} + +/**************************************************************************** + * Name: cmd_exit + * + * Description: + * Quit the shell instance + * + ****************************************************************************/ + +void cmd_exit(void *handle, int argc, char **argv) +{ + struct telnetd_s *pstate = (struct telnetd_s *)handle; + pstate->tn_state = STATE_CLOSE; +} + |