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

Luca Ceresoli luca.ceresoli at comelit.it
Tue May 17 12:03:39 CEST 2011


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

---
Changes in v2: none.

Changes in v3:
 - rebased on top of the net/tftp.c cleanup;
 - removed all #ifdefs that used to remove negligible amounts of compiled code,
   at the cost of a much less readable source file; after measurements, it
   turned out this change does not increase code size.

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

diff --git a/net/tftp.c b/net/tftp.c
index 6386740..6d44298 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>
@@ -85,6 +87,7 @@ static short	TftpNumchars;
 #define STATE_TOO_LARGE	3
 #define STATE_BAD_MAGIC	4
 #define STATE_OACK	5
+#define STATE_RECV_WRQ	6
 
 /* default TFTP block size */
 #define TFTP_BLOCK_SIZE		512
@@ -257,6 +260,8 @@ TftpSend(void)
 							    (Mapsize*8), 0);
 		/*..falling..*/
 #endif
+
+	case STATE_RECV_WRQ:
 	case STATE_DATA:
 		xp = pkt;
 		s = (ushort *)pkt;
@@ -309,7 +314,8 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 #endif
 			return;
 	}
-	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort)
+	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
+	    TftpState != STATE_RECV_WRQ)
 		return;
 
 	if (len < 2)
@@ -322,12 +328,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,
@@ -402,7 +420,8 @@ 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 || TftpState == STATE_OACK ||
+		    TftpState == STATE_RECV_WRQ) {
 			/* first block received */
 			TftpState = STATE_DATA;
 			TftpRemotePort = src;
@@ -537,7 +556,8 @@ TftpTimeout(void)
 	} else {
 		puts("T ");
 		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
-		TftpSend();
+		if (TftpState != STATE_RECV_WRQ)
+			TftpSend();
 	}
 }
 
@@ -661,6 +681,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