From mboxrd@z Thu Jan 1 00:00:00 1970 From: Luca Ceresoli Date: Thu, 14 Apr 2011 17:52:56 +0200 Subject: [U-Boot] [PATCH 5/6] TFTP: net/tftp.c: add server mode receive In-Reply-To: <4DA5682A.8040203@comelit.it> References: <4DA5682A.8040203@comelit.it> Message-ID: <1302796377-3321-6-git-send-email-luca.ceresoli@comelit.it> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Signed-off-by: Luca Ceresoli Cc: Wolfgang Denk --- 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(-) 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 at denx.de + * Copyright 2011 Comelit Group SpA, + * Luca Ceresoli */ #include @@ -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 * (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