git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@893 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2008-09-07 20:18:36 +00:00
parent 2c0d7733b9
commit cd1ddef34a
7 changed files with 252 additions and 202 deletions
+25 -16
View File
@@ -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;
+10
View File
@@ -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 */
+54
View File
@@ -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 */