mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
Integrating TFTP put
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@888 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -142,6 +142,9 @@ int tftp_sockinit(struct sockaddr_in *server, in_addr_t addr)
|
|||||||
* N bytes: mode
|
* N bytes: mode
|
||||||
* 1 byte: 0
|
* 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)
|
int tftp_mkreqpacket(ubyte *buffer, int opcode, const char *path, boolean binary)
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ int tftp_mkdatapacket(int fd, off_t offset, ubyte *packet, uint16 blockno)
|
|||||||
* packet - buffer to use for the tranfers
|
* packet - buffer to use for the tranfers
|
||||||
* server - The address of the server
|
* server - The address of the server
|
||||||
* port - The port number of the server (0 if not yet known)
|
* 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:
|
* Returned Value:
|
||||||
* OK:success and blockno valid, ERROR:failure.
|
* 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 */
|
/* Receive the next UDP packet from the server */
|
||||||
|
|
||||||
nbytes = tftp_recvfrom(sd, packet, TFTP_IOBUFSIZE, &from);
|
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 */
|
/* Get the port being used by the server if that has not yet been established */
|
||||||
|
|
||||||
@@ -298,7 +311,7 @@ static int tftp_rcvack(int sd, ubyte *packet, struct sockaddr_in *server,
|
|||||||
|
|
||||||
/* We have tried TFTP_RETRIES times */
|
/* 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 */
|
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 packetlen; /* The length of the data packet */
|
||||||
int sd; /* Socket descriptor for socket I/O */
|
int sd; /* Socket descriptor for socket I/O */
|
||||||
int fd; /* File descriptor for file I/O */
|
int fd; /* File descriptor for file I/O */
|
||||||
|
int retry; /* Retry counter */
|
||||||
int result = ERROR; /* Assume failure */
|
int result = ERROR; /* Assume failure */
|
||||||
int ret; /* Generic return status */
|
int ret; /* Generic return status */
|
||||||
|
|
||||||
@@ -370,8 +384,14 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
|
|||||||
goto errout_with_fd;
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (retry = 0; retry < TFTP_RETRIES; retry++)
|
||||||
|
{
|
||||||
packetlen = tftp_mkreqpacket(packet, TFTP_WRQ, remote, binary);
|
packetlen = tftp_mkreqpacket(packet, TFTP_WRQ, remote, binary);
|
||||||
ret = tftp_sendto(sd, packet, packetlen, &server);
|
ret = tftp_sendto(sd, packet, packetlen, &server);
|
||||||
if (ret != packetlen)
|
if (ret != packetlen)
|
||||||
@@ -381,7 +401,13 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
|
|||||||
|
|
||||||
/* 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 */
|
/* 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
|
#else
|
||||||
offset = 0;
|
offset = 0;
|
||||||
next = 0;
|
next = 0;
|
||||||
|
retry = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -544,8 +571,25 @@ int tftpput(const char *local, const char *remote, in_addr_t addr, boolean binar
|
|||||||
|
|
||||||
blockno++;
|
blockno++;
|
||||||
offset = next;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user