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

login
register
mail settings
Submitter Luca Ceresoli
Date April 14, 2011, 3:52 p.m.
Message ID <1302796377-3321-6-git-send-email-luca.ceresoli@comelit.it>
Download mbox | patch
Permalink /patch/91260/
State Superseded
Headers show

Comments

Luca Ceresoli - April 14, 2011, 3:52 p.m.
Signed-off-by: Luca Ceresoli <luca.ceresoli@comelit.it>
Cc: Wolfgang Denk <wd@denx.de>
---

A note on the style of this patch.
There are many hunks like this:

> -	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort)
> +	if (TftpState != STATE_SEND_RRQ &&
> +#ifdef CONFIG_CMD_TFTPSRV
> +	    TftpState != STATE_RECV_WRQ &&
> +#endif
> +	    src != TftpRemotePort)

where I put a comparison between TftpState and STATE_RECV_WRQ in #ifdefs.

The #ifdef is not necessary, as both TftpState and STATE_RECV_WRQ are defined
even when CONFIG_CMD_TFTPSRV is off. Simply, TftpState can never be equal to
STATE_RECV_WRQ.

I've put the #ifdefs with the intention of optimizing the code as much as
possible, avoiding a comparison that would be always true (or always false).
I understand that this makes the code a lot more difficult to read.

Should I instead remote the #ifdefs and make the code more readable (but less
optimized)?

Thanks,
Luca


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

Patch

diff --git a/net/tftp.c b/net/tftp.c
index 2c96358..c586a9f 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@denx.de
+ *	Copyright 2011 Comelit Group SpA,
+ *	               Luca Ceresoli <luca.ceresoli@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@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__ */