diff options
Diffstat (limited to 'nuttx/netutils')
-rw-r--r-- | nuttx/netutils/tftpc/tftpc_get.c | 41 | ||||
-rw-r--r-- | nuttx/netutils/tftpc/tftpc_internal.h | 10 | ||||
-rw-r--r-- | nuttx/netutils/tftpc/tftpc_packets.c | 54 |
3 files changed, 89 insertions, 16 deletions
diff --git a/nuttx/netutils/tftpc/tftpc_get.c b/nuttx/netutils/tftpc/tftpc_get.c index 1471fb0a0..abd34db21 100644 --- a/nuttx/netutils/tftpc/tftpc_get.c +++ b/nuttx/netutils/tftpc/tftpc_get.c @@ -97,6 +97,7 @@ static inline ssize_t tftp_write(int fd, const ubyte *buf, size_t len) /* Handle partial writes */ + nvdbg("Wrote %d bytes to file\n", nbyteswritten); left -= nbyteswritten; buf += nbyteswritten; } @@ -186,22 +187,6 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar goto errout_with_fd; } - /* 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); - if (ret != len) - { - goto errout_with_sd; - } - - /* Subsequent sendto will use the port number selected by the TFTP - * server. Setting the server port to zero indicates that we have - * not yet received the server port number. - */ - - server.sin_port = 0; - /* Then enter the transfer loop. Loop until the entire file has * been received or until an error occurs. */ @@ -219,6 +204,29 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar for (retry = 0; retry < TFTP_RETRIES; retry++) { + /* Send the read request using the well-known port number before + * receiving the first block. Each retry of the first block will + * re-send the request. + */ + + if (blockno == 1) + { + len = tftp_mkreqpacket(packet, TFTP_RRQ, remote, binary); + server.sin_port = HTONS(CONFIG_NETUTILS_TFTP_PORT); + ret = tftp_sendto(sd, packet, len, &server); + if (ret != len) + { + goto errout_with_sd; + } + + /* Subsequent sendto will use the port number selected by the TFTP + * server in the DATA packet. Setting the server port to zero + * here indicates that we have not yet received the server port number. + */ + + server.sin_port = 0; + } + /* Get the next packet from the server */ nbytesrecvd = tftp_recvfrom(sd, packet, TFTP_IOBUFSIZE, &from); @@ -284,6 +292,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, boolean binar /* Write the received data chunk to the file */ ndatabytes = nbytesrecvd - TFTP_DATAHEADERSIZE; + tftp_dumpbuffer("Recvd DATA", packet + TFTP_DATAHEADERSIZE, ndatabytes); if (tftp_write(fd, packet + TFTP_DATAHEADERSIZE, ndatabytes) < 0) { goto errout_with_sd; diff --git a/nuttx/netutils/tftpc/tftpc_internal.h b/nuttx/netutils/tftpc/tftpc_internal.h index c7716f903..57a081022 100644 --- a/nuttx/netutils/tftpc/tftpc_internal.h +++ b/nuttx/netutils/tftpc/tftpc_internal.h @@ -69,6 +69,10 @@ # define CONFIG_NETUTILS_TFTP_TIMEOUT 10 /* One second */ #endif +/* Dump received buffers */ + +#undef CONFIG_NETUTILS_TFTP_DUMPBUFFERS + /* Sizes of TFTP messsage headers */ #define TFTP_ACKHEADERSIZE 4 @@ -153,4 +157,10 @@ extern int tftp_parseerrpacket(const ubyte *packet); extern ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from); extern ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to); +#ifdef CONFIG_NETUTILS_TFTP_DUMPBUFFERS +extern void tftp_dumpbuffer(const char *msg, ubyte *buffer, int nbytes); +#else +# define tftp_dumpbuffer(msg, buffer, nbytes) +#endif + #endif /* __NETUTILS_TFTP_TFTPC_INTERNAL_H */ diff --git a/nuttx/netutils/tftpc/tftpc_packets.c b/nuttx/netutils/tftpc/tftpc_packets.c index 0e606da69..73e4bd110 100644 --- a/nuttx/netutils/tftpc/tftpc_packets.c +++ b/nuttx/netutils/tftpc/tftpc_packets.c @@ -241,6 +241,12 @@ ssize_t tftp_recvfrom(int sd, void *buf, size_t len, struct sockaddr_in *from) for (;;) { + /* For debugging, it is helpful to start with a clean buffer */ + +#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_NET) + memset(buf, 0, len); +#endif + /* Receive the packet */ addrlen = sizeof(struct sockaddr_in); @@ -320,4 +326,52 @@ ssize_t tftp_sendto(int sd, const void *buf, size_t len, struct sockaddr_in *to) } } +/**************************************************************************** + * Name: tftp_sendto + * + * Description: + * Dump a buffer of data + * + ****************************************************************************/ + +#ifdef CONFIG_NETUTILS_TFTP_DUMPBUFFERS +void tftp_dumpbuffer(const char *msg, ubyte *buffer, int 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 +} +#endif + #endif /* CONFIG_NET && CONFIG_NET_UDP && CONFIG_NFILE_DESCRIPTORS */ |