Versão atual 13-12-2013.

Dependencies:   EthernetInterface mbed-rtos mbed

Committer:
rebonatto
Date:
Fri Dec 13 11:42:59 2013 +0000
Revision:
0:65c41a68b49a
Versao atual 13-12-2013.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rebonatto 0:65c41a68b49a 1 #include "TftpServer.h"
rebonatto 0:65c41a68b49a 2
rebonatto 0:65c41a68b49a 3 #include <stdio.h>
rebonatto 0:65c41a68b49a 4
rebonatto 0:65c41a68b49a 5 /*
rebonatto 0:65c41a68b49a 6 *
rebonatto 0:65c41a68b49a 7 * TFTP Formats
rebonatto 0:65c41a68b49a 8
rebonatto 0:65c41a68b49a 9
rebonatto 0:65c41a68b49a 10 Type Op # Format without header
rebonatto 0:65c41a68b49a 11 2 bytes string 1 byte string 1 byte
rebonatto 0:65c41a68b49a 12 -----------------------------------------------
rebonatto 0:65c41a68b49a 13 RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
rebonatto 0:65c41a68b49a 14 WRQ -----------------------------------------------
rebonatto 0:65c41a68b49a 15 2 bytes 2 bytes n bytes
rebonatto 0:65c41a68b49a 16 ---------------------------------
rebonatto 0:65c41a68b49a 17 DATA | 03 | Block # | Data |
rebonatto 0:65c41a68b49a 18 ---------------------------------
rebonatto 0:65c41a68b49a 19 2 bytes 2 bytes
rebonatto 0:65c41a68b49a 20 -------------------
rebonatto 0:65c41a68b49a 21 ACK | 04 | Block # |
rebonatto 0:65c41a68b49a 22 --------------------
rebonatto 0:65c41a68b49a 23 2 bytes 2 bytes string 1 byte
rebonatto 0:65c41a68b49a 24 ----------------------------------------
rebonatto 0:65c41a68b49a 25 ERROR | 05 | ErrorCode | ErrMsg | 0 |
rebonatto 0:65c41a68b49a 26 ----------------------------------------
rebonatto 0:65c41a68b49a 27
rebonatto 0:65c41a68b49a 28
rebonatto 0:65c41a68b49a 29 Listen to UDP port 69
rebonatto 0:65c41a68b49a 30
rebonatto 0:65c41a68b49a 31 On receive RRQ: Opens the file with semihosting
rebonatto 0:65c41a68b49a 32 Send the file
rebonatto 0:65c41a68b49a 33
rebonatto 0:65c41a68b49a 34 On receive WRQ: Open the file with semihosting
rebonatto 0:65c41a68b49a 35 Send Ack
rebonatto 0:65c41a68b49a 36 Receive Data Packet and write into the file
rebonatto 0:65c41a68b49a 37 Send Ack
rebonatto 0:65c41a68b49a 38 *
rebonatto 0:65c41a68b49a 39 */
rebonatto 0:65c41a68b49a 40
rebonatto 0:65c41a68b49a 41 //LocalFileSystem local("local");
rebonatto 0:65c41a68b49a 42
rebonatto 0:65c41a68b49a 43 /*
rebonatto 0:65c41a68b49a 44 static const char* file_not_found_msg = "\x00\x05\x00\x01\File not found.\x00"; //20
rebonatto 0:65c41a68b49a 45 static const char* file_too_big_msg = "\x00\x05\x00\x03\File is too big (>512kB).\x00"; //30
rebonatto 0:65c41a68b49a 46 static const char* file_already_exists_msg = "\x00\x05\x00\x06\File already exists.\x00"; //25
rebonatto 0:65c41a68b49a 47 static const char* file_unknown_error_msg = "\x00\x05\x00\x00Unable to open the file for write.\x00"; //40
rebonatto 0:65c41a68b49a 48 */
rebonatto 0:65c41a68b49a 49
rebonatto 0:65c41a68b49a 50 char* file_not_found_msg = "\x00\x05\x00\x01\File not found.\x00"; //20
rebonatto 0:65c41a68b49a 51 char* file_too_big_msg = "\x00\x05\x00\x03\File is too big (>512kB).\x00"; //30
rebonatto 0:65c41a68b49a 52 char* file_already_exists_msg = "\x00\x05\x00\x06\File already exists.\x00"; //25
rebonatto 0:65c41a68b49a 53 char* file_unknown_error_msg = "\x00\x05\x00\x00Unable to open the file for write.\x00"; //40
rebonatto 0:65c41a68b49a 54
rebonatto 0:65c41a68b49a 55
rebonatto 0:65c41a68b49a 56
rebonatto 0:65c41a68b49a 57 void TftpServer::TftpServerThread(void const *arg)
rebonatto 0:65c41a68b49a 58 {
rebonatto 0:65c41a68b49a 59 /*
rebonatto 0:65c41a68b49a 60 printf("TFTP Thread starting...\n");
rebonatto 0:65c41a68b49a 61
rebonatto 0:65c41a68b49a 62 UDPSocket server;
rebonatto 0:65c41a68b49a 63
rebonatto 0:65c41a68b49a 64 server.bind(69,NULL);
rebonatto 0:65c41a68b49a 65
rebonatto 0:65c41a68b49a 66 while(1)
rebonatto 0:65c41a68b49a 67 {
rebonatto 0:65c41a68b49a 68 char *buffer = NULL;
rebonatto 0:65c41a68b49a 69 int length = 0;
rebonatto 0:65c41a68b49a 70 Endpoint remote;
rebonatto 0:65c41a68b49a 71 if(server.receiveFrom(remote,&buffer,&length) == ERR_OK)
rebonatto 0:65c41a68b49a 72 {
rebonatto 0:65c41a68b49a 73 printf("Received %d bytes from %s:%d\n",length,remote.get_address(),remote.get_port());
rebonatto 0:65c41a68b49a 74 if(length > 2)
rebonatto 0:65c41a68b49a 75 {
rebonatto 0:65c41a68b49a 76 unsigned short int opcode = buffer[0]*0x100 + buffer[1];
rebonatto 0:65c41a68b49a 77 printf("Got opcode [%X]\n",opcode);
rebonatto 0:65c41a68b49a 78 if(opcode == 1)
rebonatto 0:65c41a68b49a 79 {
rebonatto 0:65c41a68b49a 80 TftpDoRead(remote,buffer,length);
rebonatto 0:65c41a68b49a 81 }
rebonatto 0:65c41a68b49a 82 else if(opcode == 2)
rebonatto 0:65c41a68b49a 83 {
rebonatto 0:65c41a68b49a 84 TftpDoWrite(remote,buffer,length);
rebonatto 0:65c41a68b49a 85 }
rebonatto 0:65c41a68b49a 86 delete buffer;
rebonatto 0:65c41a68b49a 87 }
rebonatto 0:65c41a68b49a 88 }
rebonatto 0:65c41a68b49a 89 }
rebonatto 0:65c41a68b49a 90 */
rebonatto 0:65c41a68b49a 91 }
rebonatto 0:65c41a68b49a 92
rebonatto 0:65c41a68b49a 93 void TftpServer::TftpDoRead(Endpoint remote,char *buffer,int length)
rebonatto 0:65c41a68b49a 94 {
rebonatto 0:65c41a68b49a 95 /*
rebonatto 0:65c41a68b49a 96 char *filename = buffer+2;
rebonatto 0:65c41a68b49a 97
rebonatto 0:65c41a68b49a 98 UDPSocket conn;
rebonatto 0:65c41a68b49a 99
rebonatto 0:65c41a68b49a 100 if(conn.connect(remote.get_address(),remote.get_port()) != ERR_OK)
rebonatto 0:65c41a68b49a 101 return;
rebonatto 0:65c41a68b49a 102
rebonatto 0:65c41a68b49a 103 char fullpath[256];
rebonatto 0:65c41a68b49a 104 strcpy(fullpath,"/local/");
rebonatto 0:65c41a68b49a 105 strcat(fullpath,filename);
rebonatto 0:65c41a68b49a 106 printf("File = %s\n",fullpath);
rebonatto 0:65c41a68b49a 107 FILE *f = fopen(fullpath,"rb");
rebonatto 0:65c41a68b49a 108
rebonatto 0:65c41a68b49a 109 char *ans=NULL;
rebonatto 0:65c41a68b49a 110 int len=0;
rebonatto 0:65c41a68b49a 111
rebonatto 0:65c41a68b49a 112 if(f == NULL)
rebonatto 0:65c41a68b49a 113 {
rebonatto 0:65c41a68b49a 114 conn.send((char*)file_not_found_msg,20);
rebonatto 0:65c41a68b49a 115 conn.receive(&ans,&len);
rebonatto 0:65c41a68b49a 116 delete ans;
rebonatto 0:65c41a68b49a 117 return;
rebonatto 0:65c41a68b49a 118 }
rebonatto 0:65c41a68b49a 119
rebonatto 0:65c41a68b49a 120 int idx = 1;
rebonatto 0:65c41a68b49a 121
rebonatto 0:65c41a68b49a 122 int readbytes;
rebonatto 0:65c41a68b49a 123 unsigned char *hdrptr = new unsigned char[516];
rebonatto 0:65c41a68b49a 124 unsigned char *dataptr = hdrptr+4;
rebonatto 0:65c41a68b49a 125
rebonatto 0:65c41a68b49a 126 do
rebonatto 0:65c41a68b49a 127 {
rebonatto 0:65c41a68b49a 128 //opcode
rebonatto 0:65c41a68b49a 129 hdrptr[0] = 0;
rebonatto 0:65c41a68b49a 130 hdrptr[1] = 3;
rebonatto 0:65c41a68b49a 131 //block #
rebonatto 0:65c41a68b49a 132 hdrptr[2] = idx/0x100;
rebonatto 0:65c41a68b49a 133 hdrptr[3] = idx%0x100;
rebonatto 0:65c41a68b49a 134
rebonatto 0:65c41a68b49a 135 readbytes = fread(dataptr,1,512,f);
rebonatto 0:65c41a68b49a 136 conn.send((char*)hdrptr,readbytes+4);
rebonatto 0:65c41a68b49a 137 conn.receive(&ans,&len);
rebonatto 0:65c41a68b49a 138 delete ans;
rebonatto 0:65c41a68b49a 139 idx++;
rebonatto 0:65c41a68b49a 140 }
rebonatto 0:65c41a68b49a 141 while(readbytes == 512);
rebonatto 0:65c41a68b49a 142
rebonatto 0:65c41a68b49a 143 fclose(f);
rebonatto 0:65c41a68b49a 144 delete hdrptr;
rebonatto 0:65c41a68b49a 145 */
rebonatto 0:65c41a68b49a 146 }
rebonatto 0:65c41a68b49a 147
rebonatto 0:65c41a68b49a 148 void TftpServer::TftpDoWrite(Endpoint remote,char *buffer,int length)
rebonatto 0:65c41a68b49a 149 {
rebonatto 0:65c41a68b49a 150 /*
rebonatto 0:65c41a68b49a 151 char *filename = buffer+2;
rebonatto 0:65c41a68b49a 152
rebonatto 0:65c41a68b49a 153 UDPSocket conn;
rebonatto 0:65c41a68b49a 154 err_t e;
rebonatto 0:65c41a68b49a 155 if((e=conn.connect(remote.get_address(),remote.get_port())) != ERR_OK)
rebonatto 0:65c41a68b49a 156 {
rebonatto 0:65c41a68b49a 157 printf("Connect error %d\n",e);
rebonatto 0:65c41a68b49a 158 return;
rebonatto 0:65c41a68b49a 159 }
rebonatto 0:65c41a68b49a 160
rebonatto 0:65c41a68b49a 161 char fullpath[256];
rebonatto 0:65c41a68b49a 162 strcpy(fullpath,"/local/");
rebonatto 0:65c41a68b49a 163 strcat(fullpath,filename);
rebonatto 0:65c41a68b49a 164 printf("File = %s\n",fullpath);
rebonatto 0:65c41a68b49a 165
rebonatto 0:65c41a68b49a 166 char *ans=NULL;
rebonatto 0:65c41a68b49a 167 int len=0;
rebonatto 0:65c41a68b49a 168
rebonatto 0:65c41a68b49a 169 FILE *f = fopen(fullpath,"rb");
rebonatto 0:65c41a68b49a 170 if(f != NULL)
rebonatto 0:65c41a68b49a 171 {
rebonatto 0:65c41a68b49a 172 conn.send((char*)file_already_exists_msg,25);
rebonatto 0:65c41a68b49a 173 //conn.receive(&ans,&len);
rebonatto 0:65c41a68b49a 174 fclose(f);
rebonatto 0:65c41a68b49a 175 delete ans;
rebonatto 0:65c41a68b49a 176 return;
rebonatto 0:65c41a68b49a 177 }
rebonatto 0:65c41a68b49a 178
rebonatto 0:65c41a68b49a 179 f = fopen(fullpath,"wb");
rebonatto 0:65c41a68b49a 180 if(f == NULL)
rebonatto 0:65c41a68b49a 181 {
rebonatto 0:65c41a68b49a 182 conn.send((char*)file_unknown_error_msg,40);
rebonatto 0:65c41a68b49a 183 //conn.receive(&ans,&len);
rebonatto 0:65c41a68b49a 184 delete ans;
rebonatto 0:65c41a68b49a 185 return;
rebonatto 0:65c41a68b49a 186 }
rebonatto 0:65c41a68b49a 187
rebonatto 0:65c41a68b49a 188 //int buflen;
rebonatto 0:65c41a68b49a 189 unsigned char ack[4];
rebonatto 0:65c41a68b49a 190 ack[0] = 0;
rebonatto 0:65c41a68b49a 191 ack[1] = 4;
rebonatto 0:65c41a68b49a 192 ack[2] = 0;
rebonatto 0:65c41a68b49a 193 ack[3] = 0;
rebonatto 0:65c41a68b49a 194
rebonatto 0:65c41a68b49a 195 conn.send((char*)ack,4);
rebonatto 0:65c41a68b49a 196 int error_tries = 5;
rebonatto 0:65c41a68b49a 197 char *buf = NULL;
rebonatto 0:65c41a68b49a 198
rebonatto 0:65c41a68b49a 199 do
rebonatto 0:65c41a68b49a 200 {
rebonatto 0:65c41a68b49a 201
rebonatto 0:65c41a68b49a 202 if(conn.receive(&buf,&len) != ERR_OK)
rebonatto 0:65c41a68b49a 203 {
rebonatto 0:65c41a68b49a 204 printf("Error\n");
rebonatto 0:65c41a68b49a 205 error_tries--;
rebonatto 0:65c41a68b49a 206 if(error_tries == 0)
rebonatto 0:65c41a68b49a 207 {
rebonatto 0:65c41a68b49a 208 return;
rebonatto 0:65c41a68b49a 209 }
rebonatto 0:65c41a68b49a 210 conn.send((char*)ack,4);
rebonatto 0:65c41a68b49a 211 continue;
rebonatto 0:65c41a68b49a 212 }
rebonatto 0:65c41a68b49a 213
rebonatto 0:65c41a68b49a 214 error_tries = 5;
rebonatto 0:65c41a68b49a 215 int idx = buf[2]*0x100 + buf[3];
rebonatto 0:65c41a68b49a 216
rebonatto 0:65c41a68b49a 217 printf("Len = %d, Idx = %d\n",len,idx);
rebonatto 0:65c41a68b49a 218
rebonatto 0:65c41a68b49a 219 fwrite(buf+4,1,len-4,f);
rebonatto 0:65c41a68b49a 220
rebonatto 0:65c41a68b49a 221 delete buf;
rebonatto 0:65c41a68b49a 222
rebonatto 0:65c41a68b49a 223 if(idx >= 1024)
rebonatto 0:65c41a68b49a 224 {
rebonatto 0:65c41a68b49a 225 conn.send((char*)file_too_big_msg,30);
rebonatto 0:65c41a68b49a 226 //conn.receive(&ans,&len);
rebonatto 0:65c41a68b49a 227 delete ans;
rebonatto 0:65c41a68b49a 228 return;
rebonatto 0:65c41a68b49a 229 }
rebonatto 0:65c41a68b49a 230
rebonatto 0:65c41a68b49a 231 ack[2] = idx/0x100;
rebonatto 0:65c41a68b49a 232 ack[3] = idx%0x100;
rebonatto 0:65c41a68b49a 233 conn.send((char*)ack,4);
rebonatto 0:65c41a68b49a 234 }
rebonatto 0:65c41a68b49a 235 while(len == 516);
rebonatto 0:65c41a68b49a 236
rebonatto 0:65c41a68b49a 237 fclose(f);
rebonatto 0:65c41a68b49a 238 */
rebonatto 0:65c41a68b49a 239 }