Commit e59e35620af0d57de75cddb9ec3f19449b998868
Committed by
Wolfgang Denk
1 parent
e3fb0abe2b
Exists in
master
and in
54 other branches
TFTP: net/tftp.c: add server mode receive
Signed-off-by: Luca Ceresoli <luca.ceresoli@comelit.it> Cc: Wolfgang Denk <wd@denx.de> Acked-by: Detlev Zundel <dzu@denx.de>
Showing 2 changed files with 64 additions and 4 deletions Side-by-side Diff
net/tftp.c
... | ... | @@ -2,6 +2,8 @@ |
2 | 2 | * Copyright 1994, 1995, 2000 Neil Russell. |
3 | 3 | * (See License) |
4 | 4 | * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de |
5 | + * Copyright 2011 Comelit Group SpA, | |
6 | + * Luca Ceresoli <luca.ceresoli@comelit.it> | |
5 | 7 | */ |
6 | 8 | |
7 | 9 | #include <common.h> |
... | ... | @@ -85,6 +87,7 @@ |
85 | 87 | #define STATE_TOO_LARGE 3 |
86 | 88 | #define STATE_BAD_MAGIC 4 |
87 | 89 | #define STATE_OACK 5 |
90 | +#define STATE_RECV_WRQ 6 | |
88 | 91 | |
89 | 92 | /* default TFTP block size */ |
90 | 93 | #define TFTP_BLOCK_SIZE 512 |
... | ... | @@ -257,6 +260,8 @@ |
257 | 260 | (Mapsize*8), 0); |
258 | 261 | /*..falling..*/ |
259 | 262 | #endif |
263 | + | |
264 | + case STATE_RECV_WRQ: | |
260 | 265 | case STATE_DATA: |
261 | 266 | xp = pkt; |
262 | 267 | s = (ushort *)pkt; |
... | ... | @@ -309,7 +314,8 @@ |
309 | 314 | #endif |
310 | 315 | return; |
311 | 316 | } |
312 | - if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort) | |
317 | + if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort && | |
318 | + TftpState != STATE_RECV_WRQ) | |
313 | 319 | return; |
314 | 320 | |
315 | 321 | if (len < 2) |
316 | 322 | |
... | ... | @@ -322,12 +328,24 @@ |
322 | 328 | switch (ntohs(proto)) { |
323 | 329 | |
324 | 330 | case TFTP_RRQ: |
325 | - case TFTP_WRQ: | |
326 | 331 | case TFTP_ACK: |
327 | 332 | break; |
328 | 333 | default: |
329 | 334 | break; |
330 | 335 | |
336 | +#ifdef CONFIG_CMD_TFTPSRV | |
337 | + case TFTP_WRQ: | |
338 | + debug("Got WRQ\n"); | |
339 | + TftpRemoteIP = sip; | |
340 | + TftpRemotePort = src; | |
341 | + TftpOurPort = 1024 + (get_timer(0) % 3072); | |
342 | + TftpLastBlock = 0; | |
343 | + TftpBlockWrap = 0; | |
344 | + TftpBlockWrapOffset = 0; | |
345 | + TftpSend(); /* Send ACK(0) */ | |
346 | + break; | |
347 | +#endif | |
348 | + | |
331 | 349 | case TFTP_OACK: |
332 | 350 | debug("Got OACK: %s %s\n", |
333 | 351 | pkt, |
... | ... | @@ -402,7 +420,8 @@ |
402 | 420 | if (TftpState == STATE_SEND_RRQ) |
403 | 421 | debug("Server did not acknowledge timeout option!\n"); |
404 | 422 | |
405 | - if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK) { | |
423 | + if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK || | |
424 | + TftpState == STATE_RECV_WRQ) { | |
406 | 425 | /* first block received */ |
407 | 426 | TftpState = STATE_DATA; |
408 | 427 | TftpRemotePort = src; |
... | ... | @@ -537,7 +556,8 @@ |
537 | 556 | } else { |
538 | 557 | puts("T "); |
539 | 558 | NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); |
540 | - TftpSend(); | |
559 | + if (TftpState != STATE_RECV_WRQ) | |
560 | + TftpSend(); | |
541 | 561 | } |
542 | 562 | } |
543 | 563 | |
... | ... | @@ -660,6 +680,40 @@ |
660 | 680 | |
661 | 681 | TftpSend(); |
662 | 682 | } |
683 | + | |
684 | +#ifdef CONFIG_CMD_TFTPSRV | |
685 | +void | |
686 | +TftpStartServer(void) | |
687 | +{ | |
688 | + tftp_filename[0] = 0; | |
689 | + | |
690 | +#if defined(CONFIG_NET_MULTI) | |
691 | + printf("Using %s device\n", eth_get_name()); | |
692 | +#endif | |
693 | + printf("Listening for TFTP transfer on %pI4\n", &NetOurIP); | |
694 | + printf("Load address: 0x%lx\n", load_addr); | |
695 | + | |
696 | + puts("Loading: *\b"); | |
697 | + | |
698 | + TftpTimeoutCountMax = TIMEOUT_COUNT; | |
699 | + TftpTimeoutCount = 0; | |
700 | + TftpTimeoutMSecs = TIMEOUT; | |
701 | + NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); | |
702 | + | |
703 | + /* Revert TftpBlkSize to dflt */ | |
704 | + TftpBlkSize = TFTP_BLOCK_SIZE; | |
705 | + TftpBlock = 0; | |
706 | + TftpOurPort = WELL_KNOWN_PORT; | |
707 | + | |
708 | +#ifdef CONFIG_TFTP_TSIZE | |
709 | + TftpTsize = 0; | |
710 | + TftpNumchars = 0; | |
711 | +#endif | |
712 | + | |
713 | + TftpState = STATE_RECV_WRQ; | |
714 | + NetSetHandler(TftpHandler); | |
715 | +} | |
716 | +#endif /* CONFIG_CMD_TFTPSRV */ | |
663 | 717 | |
664 | 718 | #ifdef CONFIG_MCAST_TFTP |
665 | 719 | /* Credits: atftp project. |
net/tftp.h
... | ... | @@ -2,6 +2,8 @@ |
2 | 2 | * LiMon - BOOTP/TFTP. |
3 | 3 | * |
4 | 4 | * Copyright 1994, 1995, 2000 Neil Russell. |
5 | + * Copyright 2011 Comelit Group SpA | |
6 | + * Luca Ceresoli <luca.ceresoli@comelit.it> | |
5 | 7 | * (See License) |
6 | 8 | */ |
7 | 9 | |
... | ... | @@ -15,6 +17,10 @@ |
15 | 17 | |
16 | 18 | /* tftp.c */ |
17 | 19 | extern void TftpStart (void); /* Begin TFTP get */ |
20 | + | |
21 | +#ifdef CONFIG_CMD_TFTPSRV | |
22 | +extern void TftpStartServer(void); /* Wait for incoming TFTP put */ | |
23 | +#endif | |
18 | 24 | |
19 | 25 | /**********************************************************************/ |
20 | 26 |