annotate packages/redboot/current/src/net/tftp_client.c @ 1223:dbcfe4e0dbd2

New platform - TAMS MOAB - and generic changes to support it
author gthomas
date Fri, 19 Sep 2003 17:11:18 +0000
parents c220ab07f5ed
children 43a89c18d005
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
1 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
2 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
3 // net/tftp_client.c
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
4 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
5 // Stand-alone TFTP support for RedBoot
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
6 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
7 //==========================================================================
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
8 //####ECOSGPLCOPYRIGHTBEGIN####
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
9 // -------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
10 // This file is part of eCos, the Embedded Configurable Operating System.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
1223
dbcfe4e0dbd2 New platform - TAMS MOAB - and generic changes to support it
gthomas
parents: 1064
diff changeset
12 // Copyright (C) 2002, 2003 Gary Thomas
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
13 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
14 // eCos is free software; you can redistribute it and/or modify it under
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
15 // the terms of the GNU General Public License as published by the Free
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
16 // Software Foundation; either version 2 or (at your option) any later version.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
17 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
21 // for more details.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
22 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
23 // You should have received a copy of the GNU General Public License along
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
26 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
27 // As a special exception, if other files instantiate templates or use macros
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
28 // or inline functions from this file, or you compile this file and link it
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
29 // with other works to produce a work based on this file, this file does not
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
30 // by itself cause the resulting work to be covered by the GNU General Public
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
31 // License. However the source code for this file must still be made available
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
32 // in accordance with section (3) of the GNU General Public License.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
33 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
34 // This exception does not invalidate any other reasons why a work based on
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
35 // this file might be covered by the GNU General Public License.
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
36 //
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
210
d2c90368aeef Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents: 208
diff changeset
38 // at http://sources.redhat.com/ecos/ecos-license/
208
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
39 // -------------------------------------------
e0c0827131d1 Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents: 197
diff changeset
40 //####ECOSGPLCOPYRIGHTEND####
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
41 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
42 //#####DESCRIPTIONBEGIN####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
43 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
44 // Author(s): gthomas
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
45 // Contributors: gthomas
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
46 // Date: 2000-07-14
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
47 // Purpose:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
48 // Description:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
49 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
50 // This code is part of RedBoot (tm).
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
51 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
52 //####DESCRIPTIONEND####
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
53 //
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
54 //==========================================================================
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
55
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
56 // TFTP client support
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
57
159
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 143
diff changeset
58 #include <redboot.h> // have_net
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
59 #include <net/net.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
60 #include <net/tftp.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
61 #include <net/tftp_support.h>
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
62
161
ac086aa3217e Merge from eCos master repository on 2001-06-08-21:11:51-BST
jlarmour
parents: 159
diff changeset
63 // So we remember which ports have been used
ac086aa3217e Merge from eCos master repository on 2001-06-08-21:11:51-BST
jlarmour
parents: 159
diff changeset
64 static int get_port = 7700;
ac086aa3217e Merge from eCos master repository on 2001-06-08-21:11:51-BST
jlarmour
parents: 159
diff changeset
65
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
66 static struct {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
67 bool open;
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
68 int total_timeouts, packets_received;
1064
c220ab07f5ed * src/net/tftp_client.c: Define tftp_stream.last_good_block to
jlarmour
parents: 952
diff changeset
69 unsigned long last_good_block;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
70 int avail, actual_len;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
71 struct sockaddr_in local_addr, from_addr;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
72 char data[SEGSIZE+sizeof(struct tftphdr)];
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
73 char *bufp;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
74 } tftp_stream;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
75
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
76 int
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
77 tftp_stream_open(connection_info_t *info,
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
78 int *err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
79 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
80 struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
81 char *cp, *fp;
143
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
82 char test_buf;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
83
159
511f4dc167f6 Merge from eCos master repository on 2001-05-18-01:30:05-BST
jlarmour
parents: 143
diff changeset
84 if (!have_net || tftp_stream.open) {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
85 *err = TFTP_INVALID; // Already open
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
86 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
87 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
88
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
89 // Create initial request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
90 hdr->th_opcode = htons(RRQ); // Read file
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
91 cp = (char *)&hdr->th_stuff;
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
92 fp = info->filename;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
93 while (*fp) *cp++ = *fp++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
94 *cp++ = '\0';
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
95 // Since this is used for downloading data, OCTET (binary) is the
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
96 // only mode that makes sense.
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
97 fp = "OCTET";
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
98 while (*fp) *cp++ = *fp++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
99 *cp++ = '\0';
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
100
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
101 memset((char *)&tftp_stream.local_addr, 0, sizeof(tftp_stream.local_addr));
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
102 tftp_stream.local_addr.sin_family = AF_INET;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
103 tftp_stream.local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
104 tftp_stream.local_addr.sin_port = htons(get_port++);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
105
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
106 if (info->server->sin_port == 0) {
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
107 info->server->sin_port = htons(TFTP_PORT);
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
108 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
109
162
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
110 // Send request - note: RFC 1350 (TFTP rev 2) indicates that this should be
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
111 // only as long as required to hold the request, with the nul terminator.
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
112 // Some servers silently go to lunch if the request is not the correct size.
2395031e7a66 Merge from eCos master repository on 2001-06-15-06:43:03-BST
jlarmour
parents: 161
diff changeset
113 if (__udp_sendto(tftp_stream.data, cp-(char *)hdr,
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
114 info->server, &tftp_stream.local_addr) < 0) {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
115 // Problem sending request
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
116 *err = TFTP_NETERR;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
117 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
118 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
119
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
120 tftp_stream.open = true;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
121 tftp_stream.avail = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
122 tftp_stream.actual_len = -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
123 tftp_stream.last_good_block = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
124 tftp_stream.total_timeouts = 0;
197
51b34619b677 Merge from eCos master repository on 2001-11-30-11:22:06-GMT
jlarmour
parents: 174
diff changeset
125 tftp_stream.from_addr.sin_port = 0;
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
126 tftp_stream.packets_received = 0;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
127
143
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
128 // Try and read the first byte [block] since no errors are
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
129 // reported until then.
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
130 if (tftp_stream_read(&test_buf, 1, err) == 1) {
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
131 // Back up [rewind] over this datum
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
132 tftp_stream.bufp--;
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
133 tftp_stream.avail++;
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
134 return 0; // Open and first read successful
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
135 } else {
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
136 tftp_stream.open = false;
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
137 return -1; // Couldn't read
6b5f480c6929 Merge from eCos master repository on 2000-12-08-02:09:36-GMT
jlarmour
parents: 115
diff changeset
138 }
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
139 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
140
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
141 static int
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
142 tftp_ack(int *err)
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
143 {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
144 struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
145 // ACK last packet so server can shut down
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
146 if (tftp_stream.packets_received > 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
147 hdr->th_opcode = htons(ACK);
1064
c220ab07f5ed * src/net/tftp_client.c: Define tftp_stream.last_good_block to
jlarmour
parents: 952
diff changeset
148 hdr->th_block = htons((cyg_uint16)tftp_stream.last_good_block & 0xFFFF);
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
149 if (__udp_sendto(tftp_stream.data, 4 /* FIXME */,
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
150 &tftp_stream.from_addr, &tftp_stream.local_addr) < 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
151 // Problem sending ACK
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
152 *err = TFTP_NETERR;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
153 return -1;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
154 }
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
155 }
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
156 return 0;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
157 }
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
158
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
159 void
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
160 tftp_stream_close(int *err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
161 {
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
162 tftp_ack(err);
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
163 tftp_stream.open = false;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
164 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
165
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
166 int
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
167 tftp_stream_read(char *buf,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
168 int len,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
169 int *err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
170 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
171 int total_bytes = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
172 int size, recv_len, data_len;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
173 struct timeval timeout;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
174 struct tftphdr *hdr = (struct tftphdr *)tftp_stream.data;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
175
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
176 while (total_bytes < len) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
177 // Move any bytes which we've already read/buffered
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
178 if (tftp_stream.avail > 0) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
179 size = tftp_stream.avail;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
180 if (size > (len - total_bytes)) size = len - total_bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
181 memcpy(buf, tftp_stream.bufp, size);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
182 buf += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
183 tftp_stream.bufp += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
184 tftp_stream.avail -= size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
185 total_bytes += size;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
186 } else {
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
187 if (tftp_ack(err) < 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
188 return -1;
174
38892b97b685 Merge from eCos master repository on 2001-07-28-00:17:32-BST
jlarmour
parents: 162
diff changeset
189 }
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
190 if ((tftp_stream.actual_len >= 0) && (tftp_stream.actual_len < SEGSIZE)) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
191 // Out of data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
192 break;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
193 }
1223
dbcfe4e0dbd2 New platform - TAMS MOAB - and generic changes to support it
gthomas
parents: 1064
diff changeset
194 timeout.tv_sec = (tftp_stream.last_good_block == 0) ? 10*TFTP_TIMEOUT_PERIOD : TFTP_TIMEOUT_PERIOD;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
195 timeout.tv_usec = 0;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
196 recv_len = sizeof(tftp_stream.data);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
197 if ((data_len = __udp_recvfrom(&tftp_stream.data[0], recv_len, &tftp_stream.from_addr,
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
198 &tftp_stream.local_addr, &timeout)) < 0) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
199 // No data, try again
1223
dbcfe4e0dbd2 New platform - TAMS MOAB - and generic changes to support it
gthomas
parents: 1064
diff changeset
200 diag_printf("TFTP timed out %d/%d\n", tftp_stream.total_timeouts+1, TFTP_TIMEOUT_MAX);
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
201 if ((++tftp_stream.total_timeouts > TFTP_TIMEOUT_MAX) ||
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
202 (tftp_stream.last_good_block == 0)) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
203 // Timeout - no data received
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
204 *err = TFTP_TIMEOUT;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
205 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
206 }
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
207 // Send out the ACK for the last block - maybe server will retry
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
208 if (tftp_ack(err) < 0) {
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
209 return -1;
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
210 }
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
211 } else {
952
ff91ad81d086 ACK last packet on close.
gthomas
parents: 270
diff changeset
212 tftp_stream.packets_received++;
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
213 if (ntohs(hdr->th_opcode) == DATA) {
1064
c220ab07f5ed * src/net/tftp_client.c: Define tftp_stream.last_good_block to
jlarmour
parents: 952
diff changeset
214 if (ntohs(hdr->th_block) == (cyg_uint16)((tftp_stream.last_good_block+1) & 0xFFFF)) {
115
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
215 // Consume this data
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
216 data_len -= 4; /* Sizeof TFTP header */
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
217 tftp_stream.avail = tftp_stream.actual_len = data_len;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
218 tftp_stream.bufp = hdr->th_data;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
219 tftp_stream.last_good_block++;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
220 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
221 } else {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
222 if (ntohs(hdr->th_opcode) == ERROR) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
223 *err = ntohs(hdr->th_code);
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
224 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
225 } else {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
226 // What kind of packet is this?
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
227 *err = TFTP_PROTOCOL;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
228 return -1;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
229 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
230 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
231 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
232 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
233 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
234 return total_bytes;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
235 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
236
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
237 char *
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
238 tftp_error(int err)
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
239 {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
240 char *errmsg = "Unknown error";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
241
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
242 switch (err) {
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
243 case TFTP_ENOTFOUND:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
244 return "file not found";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
245 case TFTP_EACCESS:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
246 return "access violation";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
247 case TFTP_ENOSPACE:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
248 return "disk full or allocation exceeded";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
249 case TFTP_EBADOP:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
250 return "illegal TFTP operation";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
251 case TFTP_EBADID:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
252 return "unknown transfer ID";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
253 case TFTP_EEXISTS:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
254 return "file already exists";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
255 case TFTP_ENOUSER:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
256 return "no such user";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
257 case TFTP_TIMEOUT:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
258 return "operation timed out";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
259 case TFTP_NETERR:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
260 return "some sort of network error";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
261 case TFTP_INVALID:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
262 return "invalid parameter";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
263 case TFTP_PROTOCOL:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
264 return "protocol violation";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
265 case TFTP_TOOLARGE:
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
266 return "file is larger than buffer";
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
267 }
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
268 return errmsg;
6ed91473a1cd Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
diff changeset
269 }
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
270
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
271 //
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
272 // RedBoot interface
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
273 //
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
274 GETC_IO_FUNCS(tftp_io, tftp_stream_open, tftp_stream_close,
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
275 0, tftp_stream_read, tftp_error);
245
a6660704f7a6 Fix problem with x/y-modem load.
gthomas
parents: 228
diff changeset
276 RedBoot_load(tftp, tftp_io, true, true, 0);
228
e1b642d73533 Improve load command - make I/O methods table driven.
gthomas
parents: 210
diff changeset
277