[U-Boot] [PATCH v2 5/6] TFTP: net/tftp.c: add server mode receive

Luca Ceresoli luca.ceresoli at comelit.it
Mon Apr 18 18:19:53 CEST 2011


Signed-off-by: Luca Ceresoli <luca.ceresoli at comelit.it>
Cc: Wolfgang Denk <wd at denx.de>
---
Changes in v2: none.

 net/tftp.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 net/tftp.h |    6 +++++
 2 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/net/tftp.c b/net/tftp.c
index e166a63..87eb0b8 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -2,6 +2,8 @@
  *	Copyright 1994, 1995, 2000 Neil Russell.
  *	(See License)
  *	Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd at denx.de
+ *	Copyright 2011 Comelit Group SpA,
+ *	               Luca Ceresoli <luca.ceresoli at comelit.it>
  */
 
 #include <common.h>
@@ -74,6 +76,7 @@ static short	TftpNumchars;	/* The number of hashes we printed      */
 #define STATE_TOO_LARGE	3
 #define STATE_BAD_MAGIC	4
 #define STATE_OACK	5
+#define STATE_RECV_WRQ	6
 
 #define TFTP_BLOCK_SIZE		512		    /* default TFTP block size	*/
 #define TFTP_SEQUENCE_SIZE	((ulong)(1<<16))    /* sequence number is 16 bit */
@@ -241,6 +244,10 @@ TftpSend (void)
 			TftpBlock=ext2_find_next_zero_bit(Bitmap,(Mapsize*8),0);
 		/*..falling..*/
 #endif
+
+#ifdef CONFIG_CMD_TFTPSRV
+	case STATE_RECV_WRQ:
+#endif
 	case STATE_DATA:
 		xp = pkt;
 		s = (ushort *)pkt;
@@ -293,7 +300,11 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 #endif
 		return;
 	}
-	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort)
+	if (TftpState != STATE_SEND_RRQ &&
+#ifdef CONFIG_CMD_TFTPSRV
+	    TftpState != STATE_RECV_WRQ &&
+#endif
+	    src != TftpRemotePort)
 		return;
 
 	if (len < 2) {
@@ -307,12 +318,24 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 	switch (ntohs(proto)) {
 
 	case TFTP_RRQ:
-	case TFTP_WRQ:
 	case TFTP_ACK:
 		break;
 	default:
 		break;
 
+#ifdef CONFIG_CMD_TFTPSRV
+	case TFTP_WRQ:
+		debug("Got WRQ\n");
+		TftpRemoteIP = sip;
+		TftpRemotePort = src;
+		TftpOurPort = 1024 + (get_timer(0) % 3072);
+		TftpLastBlock = 0;
+		TftpBlockWrap = 0;
+		TftpBlockWrapOffset = 0;
+		TftpSend(); /* Send ACK(0) */
+		break;
+#endif
+
 	case TFTP_OACK:
 		debug("Got OACK: %s %s\n",
 			pkt,
@@ -383,7 +406,11 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 		if (TftpState == STATE_SEND_RRQ)
 			debug("Server did not acknowledge timeout option!\n");
 
-		if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK) {
+		if (TftpState == STATE_SEND_RRQ ||
+#ifdef CONFIG_CMD_TFTPSRV
+		    TftpState == STATE_RECV_WRQ ||
+#endif
+		    TftpState == STATE_OACK) {
 			/* first block received */
 			TftpState = STATE_DATA;
 			TftpRemotePort = src;
@@ -518,7 +545,10 @@ TftpTimeout (void)
 	} else {
 		puts ("T ");
 		NetSetTimeout (TftpTimeoutMSecs, TftpTimeout);
-		TftpSend ();
+#ifdef CONFIG_CMD_TFTPSRV
+		if (TftpState != STATE_RECV_WRQ)
+#endif
+			TftpSend();
 	}
 }
 
@@ -639,6 +669,40 @@ TftpStart (void)
 	TftpSend ();
 }
 
+#ifdef CONFIG_CMD_TFTPSRV
+void
+TftpStartServer(void)
+{
+	tftp_filename[0] = 0;
+
+#if defined(CONFIG_NET_MULTI)
+	printf("Using %s device\n", eth_get_name());
+#endif
+	printf("Listening for TFTP transfer on %pI4\n", &NetOurIP);
+	printf("Load address: 0x%lx\n", load_addr);
+
+	puts("Loading: *\b");
+
+	TftpTimeoutCountMax = TIMEOUT_COUNT;
+	TftpTimeoutCount = 0;
+	TftpTimeoutMSecs = TIMEOUT;
+	NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
+
+	/* Revert TftpBlkSize to dflt */
+	TftpBlkSize = TFTP_BLOCK_SIZE;
+	TftpBlock = 0;
+	TftpOurPort = WELL_KNOWN_PORT;
+
+#ifdef CONFIG_TFTP_TSIZE
+	TftpTsize = 0;
+	TftpNumchars = 0;
+#endif
+
+	TftpState = STATE_RECV_WRQ;
+	NetSetHandler(TftpHandler);
+}
+#endif /* CONFIG_CMD_TFTPSRV */
+
 #ifdef CONFIG_MCAST_TFTP
 /* Credits: atftp project.
  */
diff --git a/net/tftp.h b/net/tftp.h
index e3dfb26..3abdf7b 100644
--- a/net/tftp.h
+++ b/net/tftp.h
@@ -2,6 +2,8 @@
  *	LiMon - BOOTP/TFTP.
  *
  *	Copyright 1994, 1995, 2000 Neil Russell.
+ *	Copyright 2011 Comelit Group SpA
+ *	               Luca Ceresoli <luca.ceresoli at comelit.it>
  *	(See License)
  */
 
@@ -16,6 +18,10 @@
 /* tftp.c */
 extern void	TftpStart (void);	/* Begin TFTP get */
 
+#ifdef CONFIG_CMD_TFTPSRV
+extern void	TftpStartServer(void);	/* Wait for incoming TFTP put */
+#endif
+
 /**********************************************************************/
 
 #endif /* __TFTP_H__ */
-- 
1.7.1



More information about the U-Boot mailing list