This is the firmware for the LaOS - Laser Open Source project. You can use it to drive a laser cutter. For hardware and more information, look at our wiki: http://wiki.laoslaser.org

Dependencies:   EthernetNetIf mbed

Committer:
fablabtruck
Date:
Fri Jun 08 09:26:40 2012 +0000
Revision:
0:3852426a5068
svn revision 379

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fablabtruck 0:3852426a5068 1 /*
fablabtruck 0:3852426a5068 2 * TFTPServer.cpp
fablabtruck 0:3852426a5068 3 * Simple TFTP server
fablabtruck 0:3852426a5068 4 *
fablabtruck 0:3852426a5068 5 * Copyright (c) 2011 Jaap Vermaas
fablabtruck 0:3852426a5068 6 *
fablabtruck 0:3852426a5068 7 * This file is part of the LaOS project (see: http://wiki.laoslaser.org)
fablabtruck 0:3852426a5068 8 *
fablabtruck 0:3852426a5068 9 * LaOS is free software: you can redistribute it and/or modify
fablabtruck 0:3852426a5068 10 * it under the terms of the GNU General Public License as published by
fablabtruck 0:3852426a5068 11 * the Free Software Foundation, either version 3 of the License, or
fablabtruck 0:3852426a5068 12 * (at your option) any later version.
fablabtruck 0:3852426a5068 13 *
fablabtruck 0:3852426a5068 14 * LaOS is distributed in the hope that it will be useful,
fablabtruck 0:3852426a5068 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
fablabtruck 0:3852426a5068 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fablabtruck 0:3852426a5068 17 * GNU General Public License for more details.
fablabtruck 0:3852426a5068 18 *
fablabtruck 0:3852426a5068 19 * You should have received a copy of the GNU General Public License
fablabtruck 0:3852426a5068 20 * along with LaOS. If not, see <http://www.gnu.org/licenses/>.
fablabtruck 0:3852426a5068 21 *
fablabtruck 0:3852426a5068 22 */
fablabtruck 0:3852426a5068 23 #include "TFTPServer.h"
fablabtruck 0:3852426a5068 24
fablabtruck 0:3852426a5068 25 // create a new tftp server, with file directory dir and
fablabtruck 0:3852426a5068 26 // listening on port
fablabtruck 0:3852426a5068 27
fablabtruck 0:3852426a5068 28
fablabtruck 0:3852426a5068 29
fablabtruck 0:3852426a5068 30 TFTPServer::TFTPServer(char* dir, int myport) {
fablabtruck 0:3852426a5068 31 port = myport;
fablabtruck 0:3852426a5068 32 printf("TFTPServer(): port=%d\n", myport);
fablabtruck 0:3852426a5068 33 ListenSock = new UDPSocket();
fablabtruck 0:3852426a5068 34 ListenSock->setOnEvent(this, &TFTPServer::onListenUDPSocketEvent);
fablabtruck 0:3852426a5068 35 state = listen;
fablabtruck 0:3852426a5068 36 if (ListenSock->bind(Host(IpAddr(), port)))
fablabtruck 0:3852426a5068 37 state = error;
fablabtruck 0:3852426a5068 38 //TFTPServerTimer.attach(this, &TFTPServer::cleanUp, 5000);
fablabtruck 0:3852426a5068 39 sprintf(workdir, "%s", dir);
fablabtruck 0:3852426a5068 40 filecnt = 0;
fablabtruck 0:3852426a5068 41 }
fablabtruck 0:3852426a5068 42
fablabtruck 0:3852426a5068 43 // destroy this instance of the tftp server
fablabtruck 0:3852426a5068 44 TFTPServer::~TFTPServer() {
fablabtruck 0:3852426a5068 45 ListenSock->resetOnEvent();
fablabtruck 0:3852426a5068 46 delete(ListenSock);
fablabtruck 0:3852426a5068 47 delete(remote);
fablabtruck 0:3852426a5068 48 state = deleted;
fablabtruck 0:3852426a5068 49 }
fablabtruck 0:3852426a5068 50
fablabtruck 0:3852426a5068 51 void TFTPServer::reset() {
fablabtruck 0:3852426a5068 52 ListenSock->resetOnEvent();
fablabtruck 0:3852426a5068 53 delete(ListenSock);
fablabtruck 0:3852426a5068 54 delete(remote);
fablabtruck 0:3852426a5068 55 //TFTPServerTimer.detach();
fablabtruck 0:3852426a5068 56 ListenSock = new UDPSocket();
fablabtruck 0:3852426a5068 57 ListenSock->setOnEvent(this, &TFTPServer::onListenUDPSocketEvent);
fablabtruck 0:3852426a5068 58 state = listen;
fablabtruck 0:3852426a5068 59 if (ListenSock->bind(Host(IpAddr(), port)))
fablabtruck 0:3852426a5068 60 state = error;
fablabtruck 0:3852426a5068 61 //TFTPServerTimer.attach(this, &TFTPServer::cleanUp, 5000);
fablabtruck 0:3852426a5068 62 sprintf(filename, "");
fablabtruck 0:3852426a5068 63 filecnt = 0;
fablabtruck 0:3852426a5068 64 }
fablabtruck 0:3852426a5068 65
fablabtruck 0:3852426a5068 66 // get current tftp status
fablabtruck 0:3852426a5068 67 TFTPServerState TFTPServer::State() {
fablabtruck 0:3852426a5068 68 return state;
fablabtruck 0:3852426a5068 69 }
fablabtruck 0:3852426a5068 70
fablabtruck 0:3852426a5068 71 // Temporarily disable incoming TFTP connections
fablabtruck 0:3852426a5068 72 void TFTPServer::suspend() {
fablabtruck 0:3852426a5068 73 state = suspended;
fablabtruck 0:3852426a5068 74 }
fablabtruck 0:3852426a5068 75
fablabtruck 0:3852426a5068 76 // Resume after suspension
fablabtruck 0:3852426a5068 77 void TFTPServer::resume() {
fablabtruck 0:3852426a5068 78 if (state == suspended)
fablabtruck 0:3852426a5068 79 state = listen;
fablabtruck 0:3852426a5068 80 }
fablabtruck 0:3852426a5068 81
fablabtruck 0:3852426a5068 82 // During read and write, this gives you the filename
fablabtruck 0:3852426a5068 83 void TFTPServer::getFilename(char* name) {
fablabtruck 0:3852426a5068 84 sprintf(name, "%s", filename);
fablabtruck 0:3852426a5068 85 }
fablabtruck 0:3852426a5068 86
fablabtruck 0:3852426a5068 87 // return number of received files
fablabtruck 0:3852426a5068 88 int TFTPServer::fileCnt() {
fablabtruck 0:3852426a5068 89 return filecnt;
fablabtruck 0:3852426a5068 90 }
fablabtruck 0:3852426a5068 91
fablabtruck 0:3852426a5068 92 // create a new connection reading a file from server
fablabtruck 0:3852426a5068 93 void TFTPServer::ConnectRead(char* buff, Host* client) {
fablabtruck 0:3852426a5068 94 extern LaosFileSystem sd;
fablabtruck 0:3852426a5068 95 IpAddr clientIp = client->getIp();
fablabtruck 0:3852426a5068 96 int clientPort = client->getPort();
fablabtruck 0:3852426a5068 97 remote = new Host(clientIp, clientPort);
fablabtruck 0:3852426a5068 98 Ack(0);
fablabtruck 0:3852426a5068 99 blockcnt = 0;
fablabtruck 0:3852426a5068 100 dupcnt = 0;
fablabtruck 0:3852426a5068 101
fablabtruck 0:3852426a5068 102 sprintf(filename, "%s", &buff[2]);
fablabtruck 0:3852426a5068 103
fablabtruck 0:3852426a5068 104 fp = sd.openfile(filename, "rb");
fablabtruck 0:3852426a5068 105 if (fp == NULL) {
fablabtruck 0:3852426a5068 106 state = listen;
fablabtruck 0:3852426a5068 107 delete(remote);
fablabtruck 0:3852426a5068 108 Err("Could not read file", client);
fablabtruck 0:3852426a5068 109 } else {
fablabtruck 0:3852426a5068 110 // file ready for reading
fablabtruck 0:3852426a5068 111 blockcnt = 0;
fablabtruck 0:3852426a5068 112 state = reading;
fablabtruck 0:3852426a5068 113 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 114 char debugmsg[256];
fablabtruck 0:3852426a5068 115 sprintf(debugmsg, "Listen: Requested file %s from TFTP connection %d.%d.%d.%d port %d",
fablabtruck 0:3852426a5068 116 filename, clientIp[0], clientIp[1], clientIp[2], clientIp[3], clientPort);
fablabtruck 0:3852426a5068 117 TFTP_DEBUG(debugmsg);
fablabtruck 0:3852426a5068 118 #endif
fablabtruck 0:3852426a5068 119 getBlock();
fablabtruck 0:3852426a5068 120 sendBlock();
fablabtruck 0:3852426a5068 121 }
fablabtruck 0:3852426a5068 122 }
fablabtruck 0:3852426a5068 123
fablabtruck 0:3852426a5068 124 // create a new connection writing a file to the server
fablabtruck 0:3852426a5068 125 void TFTPServer::ConnectWrite(char* buff, Host* client) {
fablabtruck 0:3852426a5068 126 extern LaosFileSystem sd;
fablabtruck 0:3852426a5068 127 IpAddr clientIp = client->getIp();
fablabtruck 0:3852426a5068 128 int clientPort = client->getPort();
fablabtruck 0:3852426a5068 129 remote = new Host(clientIp, clientPort);
fablabtruck 0:3852426a5068 130 Ack(0);
fablabtruck 0:3852426a5068 131 blockcnt = 0;
fablabtruck 0:3852426a5068 132 dupcnt = 0;
fablabtruck 0:3852426a5068 133
fablabtruck 0:3852426a5068 134 sprintf(filename, "%s", &buff[2]);
fablabtruck 0:3852426a5068 135 sd.shorten(filename, MAXFILESIZE);
fablabtruck 0:3852426a5068 136 fp = sd.openfile(filename, "wb");
fablabtruck 0:3852426a5068 137 if (fp == NULL) {
fablabtruck 0:3852426a5068 138 Err("Could not open file to write", client);
fablabtruck 0:3852426a5068 139 state = listen;
fablabtruck 0:3852426a5068 140 delete(remote);
fablabtruck 0:3852426a5068 141 } else {
fablabtruck 0:3852426a5068 142 // file ready for writing
fablabtruck 0:3852426a5068 143 blockcnt = 0;
fablabtruck 0:3852426a5068 144 state = writing;
fablabtruck 0:3852426a5068 145 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 146 char debugmsg[256];
fablabtruck 0:3852426a5068 147 sprintf(debugmsg, "Listen: Incoming file %s on TFTP connection from %d.%d.%d.%d clientPort %d",
fablabtruck 0:3852426a5068 148 filename, clientIp[0], clientIp[1], clientIp[2], clientIp[3], clientPort);
fablabtruck 0:3852426a5068 149 TFTP_DEBUG(debugmsg);
fablabtruck 0:3852426a5068 150 #endif
fablabtruck 0:3852426a5068 151 }
fablabtruck 0:3852426a5068 152 }
fablabtruck 0:3852426a5068 153
fablabtruck 0:3852426a5068 154 // get DATA block from file on disk into memory
fablabtruck 0:3852426a5068 155 void TFTPServer::getBlock() {
fablabtruck 0:3852426a5068 156 blockcnt++;
fablabtruck 0:3852426a5068 157 char *p;
fablabtruck 0:3852426a5068 158 p = &sendbuff[4];
fablabtruck 0:3852426a5068 159 int len = fread(p, 1, 512, fp);
fablabtruck 0:3852426a5068 160 sendbuff[0] = 0x00;
fablabtruck 0:3852426a5068 161 sendbuff[1] = 0x03;
fablabtruck 0:3852426a5068 162 sendbuff[2] = blockcnt >> 8;
fablabtruck 0:3852426a5068 163 sendbuff[3] = blockcnt & 255;
fablabtruck 0:3852426a5068 164 blocksize = len+4;
fablabtruck 0:3852426a5068 165 }
fablabtruck 0:3852426a5068 166
fablabtruck 0:3852426a5068 167 // send DATA block to the client
fablabtruck 0:3852426a5068 168 void TFTPServer::sendBlock() {
fablabtruck 0:3852426a5068 169 ListenSock->sendto(sendbuff, blocksize, remote);
fablabtruck 0:3852426a5068 170 }
fablabtruck 0:3852426a5068 171
fablabtruck 0:3852426a5068 172
fablabtruck 0:3852426a5068 173 // compare host IP and Port with connected remote machine
fablabtruck 0:3852426a5068 174 int TFTPServer::cmpHost(Host* client) {
fablabtruck 0:3852426a5068 175 IpAddr clientIp = client->getIp();
fablabtruck 0:3852426a5068 176 IpAddr remoteIp = remote->getIp();
fablabtruck 0:3852426a5068 177 int clientPort = client->getPort();
fablabtruck 0:3852426a5068 178 int remotePort = remote->getPort();
fablabtruck 0:3852426a5068 179 return ((clientIp == remoteIp) && (clientPort == remotePort));
fablabtruck 0:3852426a5068 180 }
fablabtruck 0:3852426a5068 181
fablabtruck 0:3852426a5068 182 // send ACK to remote
fablabtruck 0:3852426a5068 183 void TFTPServer::Ack(int val) {
fablabtruck 0:3852426a5068 184 char ack[4];
fablabtruck 0:3852426a5068 185 ack[0] = 0x00;
fablabtruck 0:3852426a5068 186 ack[1] = 0x04;
fablabtruck 0:3852426a5068 187 if ((val>603135) || (val<0)) val = 0;
fablabtruck 0:3852426a5068 188 ack[2] = val >> 8;
fablabtruck 0:3852426a5068 189 ack[3] = val & 255;
fablabtruck 0:3852426a5068 190 ListenSock->sendto(ack, 4, remote);
fablabtruck 0:3852426a5068 191 }
fablabtruck 0:3852426a5068 192
fablabtruck 0:3852426a5068 193 // send ERR message to named client
fablabtruck 0:3852426a5068 194 void TFTPServer::Err(char* msg, Host* client) {
fablabtruck 0:3852426a5068 195 char message[32];
fablabtruck 0:3852426a5068 196 strncpy(message, msg, 32);
fablabtruck 0:3852426a5068 197 char err[37];
fablabtruck 0:3852426a5068 198 sprintf(err, "0000%s0", message);
fablabtruck 0:3852426a5068 199 err[0] = 0x00;
fablabtruck 0:3852426a5068 200 err[1] = 0x05;
fablabtruck 0:3852426a5068 201 err[2]=0x00;
fablabtruck 0:3852426a5068 202 err[3]=0x00;
fablabtruck 0:3852426a5068 203 int len = strlen(err);
fablabtruck 0:3852426a5068 204 err[len-1] = 0x00;
fablabtruck 0:3852426a5068 205 ListenSock->sendto(err, len, client);
fablabtruck 0:3852426a5068 206 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 207 char debugmsg[256];
fablabtruck 0:3852426a5068 208 sprintf(debugmsg, "Error: %s", message);
fablabtruck 0:3852426a5068 209 TFTP_DEBUG(debugmsg);
fablabtruck 0:3852426a5068 210 #endif
fablabtruck 0:3852426a5068 211 }
fablabtruck 0:3852426a5068 212
fablabtruck 0:3852426a5068 213 // check if connection mode of client is octet/binary
fablabtruck 0:3852426a5068 214 int TFTPServer::modeOctet(char* buff) {
fablabtruck 0:3852426a5068 215 int x = 2;
fablabtruck 0:3852426a5068 216 while (buff[x++] != 0); // get beginning of mode field
fablabtruck 0:3852426a5068 217 int y = x;
fablabtruck 0:3852426a5068 218 while (buff[y] != 0) {
fablabtruck 0:3852426a5068 219 buff[y] = tolower(buff[y]);
fablabtruck 0:3852426a5068 220 y++;
fablabtruck 0:3852426a5068 221 } // make mode field lowercase
fablabtruck 0:3852426a5068 222 return (strcmp(&buff[x++], "octet") == 0);
fablabtruck 0:3852426a5068 223 }
fablabtruck 0:3852426a5068 224
fablabtruck 0:3852426a5068 225 // timed routine to avoid hanging after interrupted transfers
fablabtruck 0:3852426a5068 226 void TFTPServer::cleanUp() {
fablabtruck 0:3852426a5068 227 extern Timer systime;
fablabtruck 0:3852426a5068 228 static int lastblock;
fablabtruck 0:3852426a5068 229 int now = systime.read();
fablabtruck 0:3852426a5068 230 switch (state) {
fablabtruck 0:3852426a5068 231 case reading:
fablabtruck 0:3852426a5068 232 if (lastblock+5 < now) {
fablabtruck 0:3852426a5068 233 fclose(fp);
fablabtruck 0:3852426a5068 234 state=listen;
fablabtruck 0:3852426a5068 235 delete(remote);
fablabtruck 0:3852426a5068 236 }
fablabtruck 0:3852426a5068 237 lastblock = now;
fablabtruck 0:3852426a5068 238 break;
fablabtruck 0:3852426a5068 239 case writing:
fablabtruck 0:3852426a5068 240 if (lastblock+5 < now) {
fablabtruck 0:3852426a5068 241 fclose(fp);
fablabtruck 0:3852426a5068 242 state = listen;
fablabtruck 0:3852426a5068 243 remove(filename);
fablabtruck 0:3852426a5068 244 delete(remote);
fablabtruck 0:3852426a5068 245 }
fablabtruck 0:3852426a5068 246 lastblock = now;
fablabtruck 0:3852426a5068 247 break;
fablabtruck 0:3852426a5068 248 } // state
fablabtruck 0:3852426a5068 249 lastblock = now;
fablabtruck 0:3852426a5068 250 }
fablabtruck 0:3852426a5068 251
fablabtruck 0:3852426a5068 252 // event driven routines to handle incoming packets
fablabtruck 0:3852426a5068 253 void TFTPServer::onListenUDPSocketEvent(UDPSocketEvent e) {
fablabtruck 0:3852426a5068 254 cleanUp();
fablabtruck 0:3852426a5068 255 extern LaosFileSystem sd;
fablabtruck 0:3852426a5068 256 Host* client = new Host();
fablabtruck 0:3852426a5068 257 char buff[516];
fablabtruck 0:3852426a5068 258 if (e == UDPSOCKET_READABLE) {
fablabtruck 0:3852426a5068 259 switch (state) {
fablabtruck 0:3852426a5068 260 case listen:
fablabtruck 0:3852426a5068 261 if (int len = ListenSock->recvfrom(buff, 516, client)) {
fablabtruck 0:3852426a5068 262 switch (buff[1]) {
fablabtruck 0:3852426a5068 263 case 0x01: // RRQ
fablabtruck 0:3852426a5068 264 if (modeOctet(buff))
fablabtruck 0:3852426a5068 265 ConnectRead(buff, client);
fablabtruck 0:3852426a5068 266 else
fablabtruck 0:3852426a5068 267 Err("Not in octet mode", client);
fablabtruck 0:3852426a5068 268 break;
fablabtruck 0:3852426a5068 269 case 0x02: // WRQ
fablabtruck 0:3852426a5068 270 if (modeOctet(buff))
fablabtruck 0:3852426a5068 271 ConnectWrite(buff, client);
fablabtruck 0:3852426a5068 272 else
fablabtruck 0:3852426a5068 273 Err("Not in octet mode", client);
fablabtruck 0:3852426a5068 274 break;
fablabtruck 0:3852426a5068 275 case 0x03: // DATA before connection established
fablabtruck 0:3852426a5068 276 Err("No data expected", client);
fablabtruck 0:3852426a5068 277 break;
fablabtruck 0:3852426a5068 278 case 0x04: // ACK before connection established
fablabtruck 0:3852426a5068 279 Err("No ack expected", client);
fablabtruck 0:3852426a5068 280 break;
fablabtruck 0:3852426a5068 281 case 0x05: // ERROR packet received
fablabtruck 0:3852426a5068 282 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 283 TFTP_DEBUG("TFTP Eror received\n\r");
fablabtruck 0:3852426a5068 284 #endif
fablabtruck 0:3852426a5068 285 break;
fablabtruck 0:3852426a5068 286 default: // unknown TFTP packet type
fablabtruck 0:3852426a5068 287 Err("Unknown TFTP packet type", client);
fablabtruck 0:3852426a5068 288 break;
fablabtruck 0:3852426a5068 289 } // switch buff[1]
fablabtruck 0:3852426a5068 290 } // recvfrom
fablabtruck 0:3852426a5068 291 break; // case listen
fablabtruck 0:3852426a5068 292 case reading:
fablabtruck 0:3852426a5068 293 while (int len = ListenSock->recvfrom(buff, 516, client) ) {
fablabtruck 0:3852426a5068 294 switch (buff[1]) {
fablabtruck 0:3852426a5068 295 case 0x01:
fablabtruck 0:3852426a5068 296 // if this is the receiving host, send first packet again
fablabtruck 0:3852426a5068 297 if ((cmpHost(client) && blockcnt==1)) {
fablabtruck 0:3852426a5068 298 sendBlock();
fablabtruck 0:3852426a5068 299 dupcnt++;
fablabtruck 0:3852426a5068 300 }
fablabtruck 0:3852426a5068 301 if (dupcnt>10) { // too many dups, stop sending
fablabtruck 0:3852426a5068 302 fclose(fp);
fablabtruck 0:3852426a5068 303 state=listen;
fablabtruck 0:3852426a5068 304 delete(remote);
fablabtruck 0:3852426a5068 305 }
fablabtruck 0:3852426a5068 306 break;
fablabtruck 0:3852426a5068 307 case 0x02:
fablabtruck 0:3852426a5068 308 // this should never happen, ignore
fablabtruck 0:3852426a5068 309 break; // case 0x02
fablabtruck 0:3852426a5068 310 case 0x03:
fablabtruck 0:3852426a5068 311 // we are the sending side, ignore
fablabtruck 0:3852426a5068 312 break;
fablabtruck 0:3852426a5068 313 case 0x04:
fablabtruck 0:3852426a5068 314 // last packet received, send next if there is one
fablabtruck 0:3852426a5068 315 dupcnt = 0;
fablabtruck 0:3852426a5068 316 if (blocksize == 516) {
fablabtruck 0:3852426a5068 317 getBlock();
fablabtruck 0:3852426a5068 318 sendBlock();
fablabtruck 0:3852426a5068 319 } else { //EOF
fablabtruck 0:3852426a5068 320 fclose(fp);
fablabtruck 0:3852426a5068 321 state = listen;
fablabtruck 0:3852426a5068 322 delete(remote);
fablabtruck 0:3852426a5068 323 }
fablabtruck 0:3852426a5068 324 break;
fablabtruck 0:3852426a5068 325 default: // this includes 0x05 errors
fablabtruck 0:3852426a5068 326 fclose(fp);
fablabtruck 0:3852426a5068 327 state = listen;
fablabtruck 0:3852426a5068 328 delete(remote);
fablabtruck 0:3852426a5068 329 break;
fablabtruck 0:3852426a5068 330 } // switch (buff[1])
fablabtruck 0:3852426a5068 331 } // while
fablabtruck 0:3852426a5068 332 break; // reading
fablabtruck 0:3852426a5068 333 case writing:
fablabtruck 0:3852426a5068 334 while (int len = ListenSock->recvfrom(buff, 516, client) ) {
fablabtruck 0:3852426a5068 335 switch (buff[1]) {
fablabtruck 0:3852426a5068 336 case 0x02:
fablabtruck 0:3852426a5068 337 // if this is a returning host, send ack again
fablabtruck 0:3852426a5068 338 if (cmpHost(client)) {
fablabtruck 0:3852426a5068 339 Ack(0);
fablabtruck 0:3852426a5068 340 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 341 TFTP_DEBUG("Resending Ack on WRQ");
fablabtruck 0:3852426a5068 342 #endif
fablabtruck 0:3852426a5068 343 }
fablabtruck 0:3852426a5068 344 break; // case 0x02
fablabtruck 0:3852426a5068 345 case 0x03:
fablabtruck 0:3852426a5068 346 if (cmpHost(client)) { // check if this is our partner
fablabtruck 0:3852426a5068 347 int block = (buff[2] << 8) + buff[3];
fablabtruck 0:3852426a5068 348 if ((blockcnt+1) == block) {
fablabtruck 0:3852426a5068 349 Ack(block);
fablabtruck 0:3852426a5068 350 // new packet
fablabtruck 0:3852426a5068 351 char *data = &buff[4];
fablabtruck 0:3852426a5068 352 fwrite(data, 1,len-4, fp);
fablabtruck 0:3852426a5068 353 blockcnt++;
fablabtruck 0:3852426a5068 354 dupcnt = 0;
fablabtruck 0:3852426a5068 355 } else {
fablabtruck 0:3852426a5068 356 if ((blockcnt+1) < block) { // high block nr
fablabtruck 0:3852426a5068 357 // we missed a packet, error
fablabtruck 0:3852426a5068 358 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 359 TFTP_DEBUG("Missed packet!");
fablabtruck 0:3852426a5068 360 #endif
fablabtruck 0:3852426a5068 361 fclose(fp);
fablabtruck 0:3852426a5068 362 state = listen;
fablabtruck 0:3852426a5068 363 remove(filename);
fablabtruck 0:3852426a5068 364 delete(remote);
fablabtruck 0:3852426a5068 365 } else { // duplicate packet, do nothing
fablabtruck 0:3852426a5068 366 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 367 char debugmsg[256];
fablabtruck 0:3852426a5068 368 sprintf(debugmsg, "Dupblicate packet %d", blockcnt);
fablabtruck 0:3852426a5068 369 TFTP_DEBUG(debugmsg);
fablabtruck 0:3852426a5068 370 #endif
fablabtruck 0:3852426a5068 371 if (dupcnt > 10) {
fablabtruck 0:3852426a5068 372 Err("Too many dups", client);
fablabtruck 0:3852426a5068 373 fclose(fp);
fablabtruck 0:3852426a5068 374 remove(filename);
fablabtruck 0:3852426a5068 375 state = listen;
fablabtruck 0:3852426a5068 376 } else {
fablabtruck 0:3852426a5068 377 Ack(blockcnt);
fablabtruck 0:3852426a5068 378 }
fablabtruck 0:3852426a5068 379 dupcnt++;
fablabtruck 0:3852426a5068 380 }
fablabtruck 0:3852426a5068 381 }
fablabtruck 0:3852426a5068 382 //printf ("Read packet %d with blocksize = %d\n\r", blockcnt, len);
fablabtruck 0:3852426a5068 383 if (len<516) {
fablabtruck 0:3852426a5068 384 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 385 char debugmsg[256];
fablabtruck 0:3852426a5068 386 sprintf(debugmsg, "Read last block %d", len);
fablabtruck 0:3852426a5068 387 TFTP_DEBUG(debugmsg);
fablabtruck 0:3852426a5068 388 #endif
fablabtruck 0:3852426a5068 389 fclose(fp);
fablabtruck 0:3852426a5068 390 state = listen;
fablabtruck 0:3852426a5068 391 delete(remote);
fablabtruck 0:3852426a5068 392 filecnt++;
fablabtruck 0:3852426a5068 393 }
fablabtruck 0:3852426a5068 394 break; // case 0x03
fablabtruck 0:3852426a5068 395 } else // if cmpHost
fablabtruck 0:3852426a5068 396 Err("Wrong IP/Port: Not your connection!", client);
fablabtruck 0:3852426a5068 397 break; // case 0x03
fablabtruck 0:3852426a5068 398 default:
fablabtruck 0:3852426a5068 399 Err("No idea why you're sending me this!", client);
fablabtruck 0:3852426a5068 400 break; // default
fablabtruck 0:3852426a5068 401 } // switch (buff[1])
fablabtruck 0:3852426a5068 402 } // while
fablabtruck 0:3852426a5068 403 break; // writing
fablabtruck 0:3852426a5068 404 case suspended:
fablabtruck 0:3852426a5068 405 if (int len = ListenSock->recvfrom(buff, 516, client))
fablabtruck 0:3852426a5068 406 Err("Packet received on suspended socket, discarded", client);
fablabtruck 0:3852426a5068 407 break;
fablabtruck 0:3852426a5068 408 } // state
fablabtruck 0:3852426a5068 409 } else {
fablabtruck 0:3852426a5068 410 #ifdef TFTP_DEBUG
fablabtruck 0:3852426a5068 411 TFTP_DEBUG("TFTP unknown UDP status");
fablabtruck 0:3852426a5068 412 #endif
fablabtruck 0:3852426a5068 413 }
fablabtruck 0:3852426a5068 414 delete(client);
fablabtruck 0:3852426a5068 415 }