summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-06 23:31:50 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-09-06 23:31:50 +0000
commit4d69dacca30e9955a11cfe67a48bf54176fb23d4 (patch)
tree3d43f205f11ab768a9daff221bc12990d2ab839b /nuttx
parent2c8d0bbb4ac987bd1800b18c2cfedb131464953f (diff)
downloadpx4-nuttx-4d69dacca30e9955a11cfe67a48bf54176fb23d4.tar.gz
px4-nuttx-4d69dacca30e9955a11cfe67a48bf54176fb23d4.tar.bz2
px4-nuttx-4d69dacca30e9955a11cfe67a48bf54176fb23d4.zip
Integrating TFTP put
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@888 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/netutils/tftpc/tftpc_packets.c3
-rw-r--r--nuttx/netutils/tftpc/tftpc_put.c70
2 files changed, 60 insertions, 13 deletions
diff --git a/nuttx/netutils/tftpc/tftpc_packets.c b/nuttx/netutils/tftpc/tftpc_packets.c
index e48b61481..af10493db 100644
--- a/nuttx/netutils/tftpc/tftpc_packets.c
+++ b/nuttx/netutils/tftpc/tftpc_packets.c
@@ -142,6 +142,9 @@ int tftp_sockinit(struct sockaddr_in *server, in_addr_t addr)
* N bytes: mode
* 1 byte: 0
*
+ * Return
+ * Then number of bytes in the request packet (never fails)
+ *
****************************************************************************/
int tftp_mkreqpacket(ubyte *buffer, int opcode, const char *path, boolean binary)
diff --git a/nuttx/netutils/tftpc/tftpc_put.c b/nuttx/netutils/tftpc/tftpc_put.c
index b003af3c9..187897ccd 100644
--- a/nuttx/netutils/tftpc/tftpc_put.c
+++ b/nuttx/netutils/tftpc/tftpc_put.c
@@ -203,7 +203,7 @@ int tftp_mkdatapacket(int fd, off_t offset, ubyte *packet, uint16 blockno)
* packet - buffer to use for the tranfers
* server - The address of the server
* port - The port number of the server (0 if not yet known)
- * blockno - The block number of the ACK
+ * blockno - Location to return block number in the received ACK
*
* Returned Value:
* OK:success and blockno valid, ERROR:failure.
@@ -231,7 +231,20 @@ static int tftp_rcvack(int sd, ubyte *packet, struct sockaddr_in *server,
/* Receive the next UDP packet from the server */
nbytes = tftp_recvfrom(sd, packet, TFTP_IOBUFSIZE, &from);
- if (nbytes >= TFTP_ACKHEADERSIZE)
+ if (nbytes < TFTP_ACKHEADERSIZE)
+ {
+ /* Failed to receive a good packet */
+
+ if (nbytes >= 0)
+ {
+ ndbg("tftp_recvfrom short packet: %d bytes\n", nbytes);
+ }
+
+ /* Break out to bump up the retry count */
+
+ break;
+ }
+ else
{
/* Get the port being used by the server if that has not yet been established */
@@ -259,8 +272,8 @@ static int tftp_rcvack(int sd, ubyte *packet, struct sockaddr_in *server,
/* Parse the error message */
- opcode = (uint16)packet[0] << 8 | (uint16)packet[1];
- rblockno = (uint16)packet[2] << 8 | (uint16)packet[3];
+ opcode = (uint16)packet[0] << 8 | (uint16)packet[1];
+ rblockno = (uint16)packet[2] << 8 | (uint16)packet[3];
/* Verify that the message that we received is an ACK for the
* expected block number.
@@ -298,7 +311,7 @@ static int tftp_rcvack(int sd, ubyte *packet, struct sockaddr_in *server,
/* We have tried TFTP_RETRIES times */
- ndbg("Timeout, No ACK for block %d\n", blockno);
+ ndbg("Timeout, Waiting for ACK\n");
return ERROR; /* Will never get here */
}
@@ -329,6 +342,7 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
int packetlen; /* The length of the data packet */
int sd; /* Socket descriptor for socket I/O */
int fd; /* File descriptor for file I/O */
+ int retry; /* Retry counter */
int result = ERROR; /* Assume failure */
int ret; /* Generic return status */
@@ -370,18 +384,30 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
goto errout_with_fd;
}
- /* Send the write request using the well known port */
+ /* Send the write request using the well known port. This may need
+ * to be done several times because (1) UDP is inherenly unreliable
+ * and packets may be lost normally, and (2) uIP has a nasty habit
+ * of droppying packets if there is nothing hit in the ARP table.
+ */
- packetlen = tftp_mkreqpacket(packet, TFTP_WRQ, remote, binary);
- ret = tftp_sendto(sd, packet, packetlen, &server);
- if (ret != packetlen)
+ for (retry = 0; retry < TFTP_RETRIES; retry++)
{
- goto errout_with_sd;
- }
+ packetlen = tftp_mkreqpacket(packet, TFTP_WRQ, remote, binary);
+ ret = tftp_sendto(sd, packet, packetlen, &server);
+ if (ret != packetlen)
+ {
+ goto errout_with_sd;
+ }
- /* Receive the ACK for the write request */
+ /* Receive the ACK for the write request */
- (void)tftp_rcvack(sd, packet, &server, &port, NULL);
+ if (tftp_rcvack(sd, packet, &server, &port, NULL) == 0)
+ {
+ break;
+ }
+
+ ndbg("Re-sending request\n");
+ }
/* Then loop sending the entire file to the server in chunks */
@@ -393,6 +419,7 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
#else
offset = 0;
next = 0;
+ retry = 0;
#endif
for (;;)
@@ -544,8 +571,25 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
blockno++;
offset = next;
+ retry = 0;
+
+ /* Skip the retry test */
+
+ continue;
}
}
+
+ /* We are going to loop and (probably) re-send the data packet and
+ * certainly try to receive the ACK packet. Check the retry count
+ * so that we do not loop forever.
+ */
+
+ if (++retry > TFTP_RETRIES)
+ {
+ ndbg("Retry count exceeded\n");
+ errno = ETIMEDOUT;
+ goto errout_with_sd;
+ }
#endif
}