From ef29861465d4a61371c96a3bd9bf2398fc3c6240 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 6 Sep 2008 15:44:41 +0000 Subject: [PATCH] TFTP Get integration git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@885 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/Documentation/NuttShell.html | 6 ++- nuttx/configs/ntosd-dm320/nsh/defconfig | 2 +- nuttx/configs/ntosd-dm320/src/up_network.c | 10 ++-- nuttx/examples/nsh/README.txt | 6 ++- nuttx/examples/nsh/nsh_netcmds.c | 8 +++- nuttx/net/socket.c | 12 +++-- nuttx/netutils/tftpc/tftpc_get.c | 44 +++++++++-------- nuttx/netutils/tftpc/tftpc_internal.h | 9 ---- nuttx/netutils/tftpc/tftpc_packets.c | 56 +++++++++------------- nuttx/netutils/tftpc/tftpc_put.c | 14 +++--- 10 files changed, 83 insertions(+), 84 deletions(-) diff --git a/nuttx/Documentation/NuttShell.html b/nuttx/Documentation/NuttShell.html index fa8003a17..2719e549b 100644 --- a/nuttx/Documentation/NuttShell.html +++ b/nuttx/Documentation/NuttShell.html @@ -1473,7 +1473,7 @@ usleep <usec> get CONFIG_NET && CONFIG_NET_UDP && - CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 558 + CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 5581 help @@ -1528,7 +1528,7 @@ usleep <usec> put CONFIG_NET && CONFIG_NET_UDP && - CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 558 + CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 5581 pwd @@ -1572,6 +1572,8 @@ usleep <usec> +

1Because of hardware padding, the actual required packet size may be larger

+
diff --git a/nuttx/configs/ntosd-dm320/nsh/defconfig b/nuttx/configs/ntosd-dm320/nsh/defconfig index 1115d7ee0..f8e1d831d 100644 --- a/nuttx/configs/ntosd-dm320/nsh/defconfig +++ b/nuttx/configs/ntosd-dm320/nsh/defconfig @@ -283,7 +283,7 @@ CONFIG_NET=y CONFIG_NET_IPv6=n CONFIG_NSOCKET_DESCRIPTORS=8 CONFIG_NET_SOCKOPTS=y -CONFIG_NET_BUFSIZE=558 +CONFIG_NET_BUFSIZE=562 CONFIG_NET_TCP=y CONFIG_NET_TCP_CONNS=8 CONFIG_NET_MAX_LISTENPORTS=8 diff --git a/nuttx/configs/ntosd-dm320/src/up_network.c b/nuttx/configs/ntosd-dm320/src/up_network.c index 19d56ab3b..69bbba713 100644 --- a/nuttx/configs/ntosd-dm320/src/up_network.c +++ b/nuttx/configs/ntosd-dm320/src/up_network.c @@ -80,8 +80,8 @@ void up_netinitialize(void) * width is 16-bits. */ - lldbg("CS4CTRL1=%04x CS4CTRL2=%04x\n", - getreg16(DM320_EMIF_CS4CTRL1), getreg16(DM320_EMIF_CS4CTRL2)); + nlldbg("CS4CTRL1=%04x CS4CTRL2=%04x\n", + getreg16(DM320_EMIF_CS4CTRL1), getreg16(DM320_EMIF_CS4CTRL2)); /* It is assumed that bootloader has already configured CS4. Here, * we will only make certain that the GIO is properly configured @@ -92,9 +92,9 @@ void up_netinitialize(void) GIO_INTERRUPT(GIO_DM9000A_INT); GIO_RISINGEDGE(GIO_DM9000A_INT); - lldbg("GIO DIR0=%04x INV0=%04x IRQPORT=%04x IRQEDGE=%04x\n", - getreg16(DM320_GIO_DIR0), getreg16(DM320_GIO_INV0), - getreg16(DM320_GIO_IRQPORT), getreg16(DM320_GIO_IRQEDGE)); + nlldbg("GIO DIR0=%04x INV0=%04x IRQPORT=%04x IRQEDGE=%04x\n", + getreg16(DM320_GIO_DIR0), getreg16(DM320_GIO_INV0), + getreg16(DM320_GIO_IRQPORT), getreg16(DM320_GIO_IRQEDGE)); /* Then initialize the driver */ diff --git a/nuttx/examples/nsh/README.txt b/nuttx/examples/nsh/README.txt index 0c0bc2eba..74f23692f 100644 --- a/nuttx/examples/nsh/README.txt +++ b/nuttx/examples/nsh/README.txt @@ -574,7 +574,7 @@ Command Dependencies on Configuration Settings echo -- exec -- exit -- - get CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 558 + get CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 558* help -- ifconfig CONFIG_NET ls CONFIG_NFILE_DESCRIPTORS > 0 @@ -587,7 +587,7 @@ Command Dependencies on Configuration Settings mount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_FAT ping CONFIG_NET && CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING && !CONFIG_DISABLE_CLOCK && !CONFIG_DISABLE_SIGNALS ps -- - put CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 558 + put CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NET_BUFSIZE >= 558* pwd !CONFIG_DISABLE_ENVIRON && CONFIG_NFILE_DESCRIPTORS > 0 rm !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 rmdir !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 @@ -599,6 +599,8 @@ Command Dependencies on Configuration Settings unset !CONFIG_DISABLE_ENVIRON usleep !CONFIG_DISABLE_SIGNALS +* NOTE: Because of hardware padding, the actual required size may be larger. + NSH-Specific Configuration Settings ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/nuttx/examples/nsh/nsh_netcmds.c b/nuttx/examples/nsh/nsh_netcmds.c index 33eeb9966..3bc0d1e7e 100644 --- a/nuttx/examples/nsh/nsh_netcmds.c +++ b/nuttx/examples/nsh/nsh_netcmds.c @@ -389,6 +389,7 @@ errout: int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { struct tftpc_args_s args; + char *fullpath; /* Parse the input parameter list */ @@ -397,9 +398,13 @@ int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) return ERROR; } + /* Get the full path to the local file */ + + fullpath = nsh_getfullpath(vtbl, args.srcpath); + /* Then perform the TFTP get operation */ - if (tftpget(args.srcpath, args.destpath, args.ipaddr, args.binary) != OK) + if (tftpget(args.srcpath, fullpath, args.ipaddr, args.binary) != OK) { nsh_output(vtbl, g_fmtcmdfailed, argv[0], "tftpget", NSH_ERRNO); } @@ -410,6 +415,7 @@ int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { free(args.destpath); } + free(fullpath); return OK; } #endif diff --git a/nuttx/net/socket.c b/nuttx/net/socket.c index 644f5a8c2..d9d4e440b 100644 --- a/nuttx/net/socket.c +++ b/nuttx/net/socket.c @@ -107,12 +107,16 @@ int socket(int domain, int type, int protocol) /* Only SOCK_STREAM and possible SOCK_DRAM are supported */ -#if defined(CONFIG_NET_UDP) && defined(CONFIG_NET_TCP) - if (protocol != 0 || (type != SOCK_STREAM && type != SOCK_DGRAM)) +#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_UDP) + if ((type == SOCK_STREAM && protocol != 0 && protocol != IPPROTO_TCP) || + (type == SOCK_DGRAM && protocol != 0 && protocol != IPPROTO_UDP) || + (type != SOCK_STREAM && type != SOCK_DGRAM)) #elif defined(CONFIG_NET_TCP) - if (protocol != 0 || type != SOCK_STREAM) + if ((type == SOCK_STREAM && protocol != 0 && protocol != IPPROTO_TCP) || + (type != SOCK_STREAM)) #elif defined(CONFIG_NET_UDP) - if (protocol != 0 || type != SOCK_DGRAM) + if ((type == SOCK_DGRAM && protocol != 0 && protocol != IPPROTO_UDP) || + (type != SOCK_DGRAM)) #endif { err = EPROTONOSUPPORT; diff --git a/nuttx/netutils/tftpc/tftpc_get.c b/nuttx/netutils/tftpc/tftpc_get.c index 584664599..9b63405d5 100644 --- a/nuttx/netutils/tftpc/tftpc_get.c +++ b/nuttx/netutils/tftpc/tftpc_get.c @@ -95,7 +95,7 @@ static inline ssize_t tftp_write(int fd, const ubyte *buf, size_t len) if (nbyteswritten < 0) { - ndbg(g_tftpcallfailed, "write", errno); + ndbg("write failed: %d\n", errno); return ERROR; } @@ -152,7 +152,6 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar struct sockaddr_in from; /* The address the last UDP message recv'd from */ ubyte *packet; /* Allocated memory to hold one packet */ uint16 blockno = 0; /* The current transfer block number */ - uint16 port = 0; /* This is the port number for the transfer */ uint16 opcode; /* Received opcode */ uint16 rblockno; /* Received block number */ int len; /* Generic length */ @@ -174,7 +173,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar packet = (ubyte*)zalloc(TFTP_IOBUFSIZE); if (!packet) { - ndbg(g_tftpnomemory, "packet"); + ndbg("packet memory allocation failure\n"); errno = ENOMEM; goto errout; } @@ -184,7 +183,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar fd = open(local, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (fd < 0) { - ndbg(g_tftpcallfailed, "open", errno); + ndbg("open failed: %d\n", errno); goto errout_with_packet; } @@ -196,7 +195,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar goto errout_with_fd; } - /* Send the read request */ + /* Send the read request using the well-known port number */ len = tftp_mkreqpacket(packet, TFTP_RRQ, remote, binary); ret = tftp_sendto(sd, packet, len, &server); @@ -205,6 +204,12 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar goto errout_with_sd; } + /* Subsequent recvfrom will use any port number until the correct + * port for the data transfer is established. + */ + + server.sin_port = 0; + /* Then enter the transfer loop. Loop until the entire file has * been received or until an error occurs. */ @@ -233,28 +238,20 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar if (nbytesrecvd >= 0) { - /* Replace the server port to the one in the response */ - - if (!port) - { - port = from.sin_port; - server.sin_port = port; - } - /* Verify the sender address and port number */ if (server.sin_addr.s_addr != from.sin_addr.s_addr) { - nvdbg(g_tftpaddress, "recvfrom"); + nvdbg("Invalid address in DATA\n"); retry--; continue; } - if (port != from.sin_port) + if (server.sin_port && server.sin_port != from.sin_port) { - nvdbg(g_tftpport, "recvfrom"); + nvdbg("Invalid port in DATA\n"); len = tftp_mkerrpacket(packet, TFTP_ERR_UNKID, TFTP_ERRST_UNKID); - ret = tftp_sendto(sd, packet, len, &server); + ret = tftp_sendto(sd, packet, len, &from); retry--; continue; } @@ -269,12 +266,19 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar if (opcode > TFTP_MAXRFC1350) { len = tftp_mkerrpacket(packet, TFTP_ERR_ILLEGALOP, TFTP_ERRST_ILLEGALOP); - ret = tftp_sendto(sd, packet, len, &server); + ret = tftp_sendto(sd, packet, len, &from); } continue; } - /* Break out of the loop when we receive a good data packet */ + /* Replace the server port to the one in the good data response */ + + if (!server.sin_port) + { + server.sin_port = from.sin_port; + } + + /* Then break out of the loop */ break; } @@ -284,7 +288,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar if (retry == TFTP_RETRIES) { - nvdbg(g_tftptoomanyretries); + nvdbg("Retry limit exceeded\n"); goto errout_with_sd; } diff --git a/nuttx/netutils/tftpc/tftpc_internal.h b/nuttx/netutils/tftpc/tftpc_internal.h index 801165204..3a6bf8ecb 100644 --- a/nuttx/netutils/tftpc/tftpc_internal.h +++ b/nuttx/netutils/tftpc/tftpc_internal.h @@ -142,15 +142,6 @@ * Public Data ****************************************************************************/ -#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) -extern const char g_tftpcallfailed[]; -extern const char g_tftpcalltimedout[]; -extern const char g_tftpnomemory[]; -extern const char g_tftptoomanyretries[]; -extern const char g_tftpaddress[]; -extern const char g_tftpport[]; -#endif - /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/nuttx/netutils/tftpc/tftpc_packets.c b/nuttx/netutils/tftpc/tftpc_packets.c index d3da57544..e48b61481 100644 --- a/nuttx/netutils/tftpc/tftpc_packets.c +++ b/nuttx/netutils/tftpc/tftpc_packets.c @@ -60,7 +60,7 @@ #include "tftpc_internal.h" -#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP) +#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0 /**************************************************************************** * Definitions @@ -70,15 +70,6 @@ * Public Data ****************************************************************************/ -#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_NET) -const char g_tftpcallfailed[] = "%s failed: %d\n"; -const char g_tftpcalltimedout[] = "%s timed out\n"; -const char g_tftpnomemory[] = "%s memory allocation failure\n"; -const char g_tftptoomanyretries[] = "Retry limit exceeded\n"; -const char g_tftpaddress[] = "%s invalid address\n"; -const char g_tftpport[] = "%s invalid port\n"; -#endif - /**************************************************************************** * Private Functions ****************************************************************************/ @@ -114,29 +105,28 @@ int tftp_sockinit(struct sockaddr_in *server, in_addr_t addr) /* Create the UDP socket */ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sd >= 0) + if (sd < 0) { - ndbg(g_tftpcallfailed, "socket", errno); + ndbg("socket failed: %d\n", errno); + return ERROR; } - else + + /* Set the recvfrom timeout */ + + timeo.tv_sec = CONFIG_NETUTILS_TFTP_TIMEOUT / 10; + timeo.tv_usec = (CONFIG_NETUTILS_TFTP_TIMEOUT % 10) * 100000; + ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(struct timeval)); + if (ret < 0) { - /* Set the recvfrom timeout */ - - timeo.tv_sec = CONFIG_NETUTILS_TFTP_TIMEOUT / 10; - timeo.tv_usec = (CONFIG_NETUTILS_TFTP_TIMEOUT % 10) * 100000; - ret = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(struct timeval)); - if (ret < 0) - { - ndbg(g_tftpcallfailed, "setsockopt", errno); - } - - /* Initialize the server address structure */ - - memset(server, 0, sizeof(struct sockaddr_in)); - server->sin_family = AF_INET; - server->sin_addr.s_addr = addr; - server->sin_port = HTONS(CONFIG_NETUTILS_TFTP_PORT); + ndbg("setsockopt failed: %d\n", errno); } + + /* Initialize the server address structure */ + + memset(server, 0, sizeof(struct sockaddr_in)); + server->sin_family = AF_INET; + server->sin_addr.s_addr = addr; + server->sin_port = HTONS(CONFIG_NETUTILS_TFTP_PORT); return sd; } @@ -265,7 +255,7 @@ ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from) if (errno == EAGAIN) { - ndbg(g_tftpcalltimedout, "recvfrom"); + ndbg("recvfrom timed out\n"); return ERROR; } @@ -273,7 +263,7 @@ ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from) else if (errno != EINTR) { - ndbg(g_tftpcallfailed, "recvfrom", errno); + ndbg("recvfrom failed: %d\n", errno); return ERROR; } } @@ -317,7 +307,7 @@ ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to) if (errno != EINTR) { - ndbg(g_tftpcallfailed, "sendto", errno); + ndbg("sendto failed: %d\n", errno); return ERROR; } } @@ -331,4 +321,4 @@ ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to) } } -#endif /* CONFIG_NET && CONFIG_NET_UDP */ +#endif /* CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS */ diff --git a/nuttx/netutils/tftpc/tftpc_put.c b/nuttx/netutils/tftpc/tftpc_put.c index ca158a783..b003af3c9 100644 --- a/nuttx/netutils/tftpc/tftpc_put.c +++ b/nuttx/netutils/tftpc/tftpc_put.c @@ -114,7 +114,7 @@ static inline ssize_t tftp_read(int fd, ubyte *buf, size_t buflen) if (nbytesread < 0) { - ndbg(g_tftpcallfailed, "read", errno); + ndbg("read failed: %d\n", errno); return ERROR; } @@ -175,7 +175,7 @@ int tftp_mkdatapacket(int fd, off_t offset, ubyte *packet, uint16 blockno) tmp = lseek(fd, offset, SEEK_SET); if (tmp == (off_t)-1) { - ndbg(g_tftpcallfailed, "lseek", errno); + ndbg("lseek failed: %d\n", errno); return ERROR; } @@ -245,13 +245,13 @@ static int tftp_rcvack(int sd, ubyte *packet, struct sockaddr_in *server, if (server->sin_addr.s_addr != from.sin_addr.s_addr) { - nvdbg(g_tftpaddress, "recvfrom"); + nvdbg("Invalid address in DATA\n"); continue; } if (*port != server->sin_port) { - nvdbg(g_tftpport, "recvfrom"); + nvdbg("Invalid port in DATA\n"); packetlen = tftp_mkerrpacket(packet, TFTP_ERR_UNKID, TFTP_ERRST_UNKID); (void)tftp_sendto(sd, packet, packetlen, server); continue; @@ -348,7 +348,7 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar packet = (ubyte*)zalloc(TFTP_IOBUFSIZE); if (!packet) { - ndbg(g_tftpnomemory, "packet"); + ndbg("packet memory allocation failure\n"); errno = ENOMEM; goto errout; } @@ -358,7 +358,7 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar fd = open(local, O_RDONLY); if (fd < 0) { - ndbg(g_tftpcallfailed, "open", errno); + ndbg("open failed: %d\n", errno); goto errout_with_packet; } @@ -370,7 +370,7 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar goto errout_with_fd; } - /* Send the write request */ + /* Send the write request using the well known port */ packetlen = tftp_mkreqpacket(packet, TFTP_WRQ, remote, binary); ret = tftp_sendto(sd, packet, packetlen, &server);