Versão estável sem DMA e FFT. 128 amostras.

Dependencies:   EthernetInterface NTPClient mbed-rtos mbed

Committer:
rebonatto
Date:
Tue Jan 05 11:47:35 2016 +0000
Revision:
0:fac116e94d44
Vers?o est?vel sem DMA e FFT. 128 amostras.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rebonatto 0:fac116e94d44 1 #include "tftpsrv.h"
rebonatto 0:fac116e94d44 2 #include <ctype.h>
rebonatto 0:fac116e94d44 3
rebonatto 0:fac116e94d44 4 void tftpsrv::tftpsrv_Thread(void const* arg)
rebonatto 0:fac116e94d44 5 {
rebonatto 0:fac116e94d44 6 printf("\r\nTFTP start...\r\n");
rebonatto 0:fac116e94d44 7
rebonatto 0:fac116e94d44 8 tftpInicia();
rebonatto 0:fac116e94d44 9
rebonatto 0:fac116e94d44 10 int tam = 0;
rebonatto 0:fac116e94d44 11 char buffer[516];
rebonatto 0:fac116e94d44 12
rebonatto 0:fac116e94d44 13 int instancias = 10;
rebonatto 0:fac116e94d44 14 while (instancias > 0) {
rebonatto 0:fac116e94d44 15 // DEBUG ("\r\nEsperando pacote...\r\n");
rebonatto 0:fac116e94d44 16 tam = server.receiveFrom(client, buffer, sizeof(buffer));
rebonatto 0:fac116e94d44 17 while ( tam > 0 ) {
rebonatto 0:fac116e94d44 18 // DEBUG ("\r\nPacote recebido...\r\n");
rebonatto 0:fac116e94d44 19 switch (estado) {
rebonatto 0:fac116e94d44 20 case ESCUTANDO:
rebonatto 0:fac116e94d44 21 tftpEscutando(buffer);
rebonatto 0:fac116e94d44 22 break;
rebonatto 0:fac116e94d44 23 case LENDO:
rebonatto 0:fac116e94d44 24 tftpLendo(buffer);
rebonatto 0:fac116e94d44 25 break;
rebonatto 0:fac116e94d44 26 case ESCREVENDO:
rebonatto 0:fac116e94d44 27 tftpEscrevendo(tam, buffer);
rebonatto 0:fac116e94d44 28 break;
rebonatto 0:fac116e94d44 29 default:
rebonatto 0:fac116e94d44 30 tftpErr("Desconhecido ou nao implementado");
rebonatto 0:fac116e94d44 31 }
rebonatto 0:fac116e94d44 32 // DEBUG ("\r\nEsperando pacote...\r\n");
rebonatto 0:fac116e94d44 33 tam = server.receiveFrom(client, buffer, sizeof(buffer));
rebonatto 0:fac116e94d44 34 }
rebonatto 0:fac116e94d44 35 tftpReinicia();
rebonatto 0:fac116e94d44 36 instancias--;
rebonatto 0:fac116e94d44 37 printf("\r\nRestam %d instancias...\r\n", instancias);
rebonatto 0:fac116e94d44 38 //DEBUG ("\r\nRestam %d instancias...\r\n", instancias);
rebonatto 0:fac116e94d44 39 }
rebonatto 0:fac116e94d44 40 printf("Caiu fora TFTP\n");
rebonatto 0:fac116e94d44 41
rebonatto 0:fac116e94d44 42 // DEBUG ("\r\nTFTP end...\r\n");
rebonatto 0:fac116e94d44 43 }
rebonatto 0:fac116e94d44 44
rebonatto 0:fac116e94d44 45
rebonatto 0:fac116e94d44 46
rebonatto 0:fac116e94d44 47 void tftpsrv::tftpInicia()
rebonatto 0:fac116e94d44 48 {
rebonatto 0:fac116e94d44 49 // DEBUG ("\r\nIniciando TFTP...\r\n");
rebonatto 0:fac116e94d44 50 //server.init();
rebonatto 0:fac116e94d44 51 server.bind(69);
rebonatto 0:fac116e94d44 52 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 53 server.set_blocking(false, 20000);
rebonatto 0:fac116e94d44 54 }
rebonatto 0:fac116e94d44 55
rebonatto 0:fac116e94d44 56 void tftpsrv::tftpPara()
rebonatto 0:fac116e94d44 57 {
rebonatto 0:fac116e94d44 58 // DEBUG ("\r\nParando TFTP...\r\n");
rebonatto 0:fac116e94d44 59 server.close();
rebonatto 0:fac116e94d44 60 if (fp!=NULL) fclose(fp);
rebonatto 0:fac116e94d44 61 }
rebonatto 0:fac116e94d44 62
rebonatto 0:fac116e94d44 63 void tftpsrv::tftpReinicia()
rebonatto 0:fac116e94d44 64 {
rebonatto 0:fac116e94d44 65 tftpPara();
rebonatto 0:fac116e94d44 66 tftpInicia();
rebonatto 0:fac116e94d44 67 }
rebonatto 0:fac116e94d44 68
rebonatto 0:fac116e94d44 69 // send ACK to remote
rebonatto 0:fac116e94d44 70 void tftpsrv::tftpAck(int val)
rebonatto 0:fac116e94d44 71 {
rebonatto 0:fac116e94d44 72 char ack[4];
rebonatto 0:fac116e94d44 73 ack[0] = 0x00;
rebonatto 0:fac116e94d44 74 ack[1] = 0x04;
rebonatto 0:fac116e94d44 75 if ((val>603135) || (val<0)) val = 0;
rebonatto 0:fac116e94d44 76 ack[2] = val >> 8;
rebonatto 0:fac116e94d44 77 ack[3] = val & 255;
rebonatto 0:fac116e94d44 78
rebonatto 0:fac116e94d44 79 // DEBUG ("\r\nEnviando ACK...\r\n");
rebonatto 0:fac116e94d44 80 server.sendTo(client, ack, 4);
rebonatto 0:fac116e94d44 81 }
rebonatto 0:fac116e94d44 82
rebonatto 0:fac116e94d44 83 // send ERR message to named client
rebonatto 0:fac116e94d44 84 void tftpsrv::tftpErr(char* msg)
rebonatto 0:fac116e94d44 85 {
rebonatto 0:fac116e94d44 86 char message[32];
rebonatto 0:fac116e94d44 87 strncpy(message, msg, 32);
rebonatto 0:fac116e94d44 88 char err[37];
rebonatto 0:fac116e94d44 89 sprintf(err, "0000%s0", message);
rebonatto 0:fac116e94d44 90 err[0] = 0x00;
rebonatto 0:fac116e94d44 91 err[1] = 0x05;
rebonatto 0:fac116e94d44 92 err[2]=0x00;
rebonatto 0:fac116e94d44 93 err[3]=0x00;
rebonatto 0:fac116e94d44 94 int len = strlen(err);
rebonatto 0:fac116e94d44 95 err[len-1] = 0x00;
rebonatto 0:fac116e94d44 96 // DEBUG ("\r\nEnviando ERR ( %s )...\r\n", message);
rebonatto 0:fac116e94d44 97 server.sendTo(client, err, len);
rebonatto 0:fac116e94d44 98 }
rebonatto 0:fac116e94d44 99
rebonatto 0:fac116e94d44 100 int tftpsrv::tftpModo(char* buff)
rebonatto 0:fac116e94d44 101 {
rebonatto 0:fac116e94d44 102 int x = 2;
rebonatto 0:fac116e94d44 103 while (buff[x++] != 0); // get beginning of mode field
rebonatto 0:fac116e94d44 104 int y = x;
rebonatto 0:fac116e94d44 105 while (buff[y] != 0) {
rebonatto 0:fac116e94d44 106 buff[y] = tolower(buff[y]);
rebonatto 0:fac116e94d44 107 y++;
rebonatto 0:fac116e94d44 108 } // make mode field lowercase
rebonatto 0:fac116e94d44 109 return (strcmp(&buff[x++], "octet") == 0);
rebonatto 0:fac116e94d44 110 }
rebonatto 0:fac116e94d44 111
rebonatto 0:fac116e94d44 112 // get DATA block from file on disk into memory
rebonatto 0:fac116e94d44 113 void tftpsrv::tftpGetBlock()
rebonatto 0:fac116e94d44 114 {
rebonatto 0:fac116e94d44 115 // DEBUG ("\r\nLendo bloco... (em %d)\r\n", blockcnt);
rebonatto 0:fac116e94d44 116 blockcnt++;
rebonatto 0:fac116e94d44 117 char *p;
rebonatto 0:fac116e94d44 118 p = &sendbuff[4];
rebonatto 0:fac116e94d44 119 int len = fread(p, 1, 512, fp);
rebonatto 0:fac116e94d44 120 sendbuff[0] = 0x00;
rebonatto 0:fac116e94d44 121 sendbuff[1] = 0x03;
rebonatto 0:fac116e94d44 122 sendbuff[2] = blockcnt >> 8;
rebonatto 0:fac116e94d44 123 sendbuff[3] = blockcnt & 255;
rebonatto 0:fac116e94d44 124 blocksize = len+4;
rebonatto 0:fac116e94d44 125 }
rebonatto 0:fac116e94d44 126
rebonatto 0:fac116e94d44 127 // send DATA block to the client
rebonatto 0:fac116e94d44 128 void tftpsrv::tftpSendBlock()
rebonatto 0:fac116e94d44 129 {
rebonatto 0:fac116e94d44 130 // DEBUG ("\r\nEnviando bloco ( tam = %d )...\r\n", blocksize);
rebonatto 0:fac116e94d44 131 server.sendTo(client, sendbuff, blocksize);
rebonatto 0:fac116e94d44 132 }
rebonatto 0:fac116e94d44 133
rebonatto 0:fac116e94d44 134
rebonatto 0:fac116e94d44 135 void tftpsrv::tftpLer(char* buff)
rebonatto 0:fac116e94d44 136 {
rebonatto 0:fac116e94d44 137 tftpAck(0);
rebonatto 0:fac116e94d44 138
rebonatto 0:fac116e94d44 139 blockcnt = 0;
rebonatto 0:fac116e94d44 140 dupcnt = 0;
rebonatto 0:fac116e94d44 141
rebonatto 0:fac116e94d44 142 sprintf(filename, "/local/%s", &buff[2]);
rebonatto 0:fac116e94d44 143
rebonatto 0:fac116e94d44 144 fp = fopen(filename, "rb");
rebonatto 0:fac116e94d44 145 if (fp == NULL) {
rebonatto 0:fac116e94d44 146 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 147 tftpErr("Could not read file");
rebonatto 0:fac116e94d44 148 } else {
rebonatto 0:fac116e94d44 149 // file ready for reading
rebonatto 0:fac116e94d44 150 estado = LENDO;
rebonatto 0:fac116e94d44 151 // DEBUG ("\r\nRequisitado arquivo %s para %s\r\n", filename, client.get_address());
rebonatto 0:fac116e94d44 152 tftpGetBlock();
rebonatto 0:fac116e94d44 153 tftpSendBlock();
rebonatto 0:fac116e94d44 154 }
rebonatto 0:fac116e94d44 155 }
rebonatto 0:fac116e94d44 156
rebonatto 0:fac116e94d44 157 void tftpsrv::tftpEscrever(char* buff)
rebonatto 0:fac116e94d44 158 {
rebonatto 0:fac116e94d44 159 struct dirent *p;
rebonatto 0:fac116e94d44 160 DIR *dir = opendir("/local");
rebonatto 0:fac116e94d44 161 while ((p = readdir(dir)) != NULL) {
rebonatto 0:fac116e94d44 162 char *str = p->d_name;
rebonatto 0:fac116e94d44 163 if ((strstr(str, ".bin") != NULL) || (strstr(str, ".BIN") != NULL)) {
rebonatto 0:fac116e94d44 164 char buf[BUFSIZ];
rebonatto 0:fac116e94d44 165 snprintf(buf, sizeof(buf) - 1, "/local/%s", str);
rebonatto 0:fac116e94d44 166 remove(buf) == 0;
rebonatto 0:fac116e94d44 167 }
rebonatto 0:fac116e94d44 168 }
rebonatto 0:fac116e94d44 169 closedir(dir);
rebonatto 0:fac116e94d44 170
rebonatto 0:fac116e94d44 171 tftpAck(0);
rebonatto 0:fac116e94d44 172 blockcnt = 0;
rebonatto 0:fac116e94d44 173 dupcnt = 0;
rebonatto 0:fac116e94d44 174
rebonatto 0:fac116e94d44 175 sprintf(filename, "/local/%s", &buff[2]);
rebonatto 0:fac116e94d44 176
rebonatto 0:fac116e94d44 177 fp = fopen(filename, "ab");
rebonatto 0:fac116e94d44 178 if (fp == NULL) {
rebonatto 0:fac116e94d44 179 tftpErr("Could not open file to write");
rebonatto 0:fac116e94d44 180 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 181 } else {
rebonatto 0:fac116e94d44 182 // file ready for writing
rebonatto 0:fac116e94d44 183 fseek(fp, 0, SEEK_SET);
rebonatto 0:fac116e94d44 184 blockcnt = 0;
rebonatto 0:fac116e94d44 185 estado = ESCREVENDO;
rebonatto 0:fac116e94d44 186 // DEBUG ("\r\nRecebendo arquivo %s de %s\r\n", filename, client.get_address());
rebonatto 0:fac116e94d44 187 }
rebonatto 0:fac116e94d44 188 }
rebonatto 0:fac116e94d44 189
rebonatto 0:fac116e94d44 190 void tftpsrv::tftpEscutando(char* buff)
rebonatto 0:fac116e94d44 191 {
rebonatto 0:fac116e94d44 192 // DEBUG ("\r\nEscutando...\r\n");
rebonatto 0:fac116e94d44 193 switch (buff[1]) {
rebonatto 0:fac116e94d44 194 case 0x01: // RRQ
rebonatto 0:fac116e94d44 195 if (tftpModo(buff))
rebonatto 0:fac116e94d44 196 tftpLer(buff);
rebonatto 0:fac116e94d44 197 else
rebonatto 0:fac116e94d44 198 tftpErr("Not in octet mode");
rebonatto 0:fac116e94d44 199 break;
rebonatto 0:fac116e94d44 200 case 0x02: // WRQ
rebonatto 0:fac116e94d44 201 if (tftpModo(buff))
rebonatto 0:fac116e94d44 202 tftpEscrever(buff);
rebonatto 0:fac116e94d44 203 else
rebonatto 0:fac116e94d44 204 tftpErr("Not in octet mode");
rebonatto 0:fac116e94d44 205 break;
rebonatto 0:fac116e94d44 206 case 0x03: // DATA before connection established
rebonatto 0:fac116e94d44 207 tftpErr("No data expected");
rebonatto 0:fac116e94d44 208 break;
rebonatto 0:fac116e94d44 209 case 0x04: // ACK before connection established
rebonatto 0:fac116e94d44 210 tftpErr("No ack expected");
rebonatto 0:fac116e94d44 211 break;
rebonatto 0:fac116e94d44 212 case 0x05: // ERROR packet received
rebonatto 0:fac116e94d44 213 // DEBUG ("TFTP Eror received\n\r");
rebonatto 0:fac116e94d44 214 break;
rebonatto 0:fac116e94d44 215 default: // unknown TFTP packet type
rebonatto 0:fac116e94d44 216 tftpErr("Unknown TFTP packet type");
rebonatto 0:fac116e94d44 217 break;
rebonatto 0:fac116e94d44 218 } // switch buff[1]
rebonatto 0:fac116e94d44 219 }
rebonatto 0:fac116e94d44 220
rebonatto 0:fac116e94d44 221 void tftpsrv::tftpLendo(char *buff)
rebonatto 0:fac116e94d44 222 {
rebonatto 0:fac116e94d44 223 // DEBUG ("\r\nLendo...\r\n");
rebonatto 0:fac116e94d44 224 switch (buff[1]) {
rebonatto 0:fac116e94d44 225 case 0x01:
rebonatto 0:fac116e94d44 226 // to-do: verificar host e ip
rebonatto 0:fac116e94d44 227 break;
rebonatto 0:fac116e94d44 228 case 0x02:
rebonatto 0:fac116e94d44 229 // this should never happen, ignore
rebonatto 0:fac116e94d44 230 break; // case 0x02
rebonatto 0:fac116e94d44 231 case 0x03:
rebonatto 0:fac116e94d44 232 // we are the sending side, ignore
rebonatto 0:fac116e94d44 233 break;
rebonatto 0:fac116e94d44 234 case 0x04:
rebonatto 0:fac116e94d44 235 // last packet received, send next if there is one
rebonatto 0:fac116e94d44 236 dupcnt = 0;
rebonatto 0:fac116e94d44 237 if (blocksize == 516) {
rebonatto 0:fac116e94d44 238 tftpGetBlock();
rebonatto 0:fac116e94d44 239 tftpSendBlock();
rebonatto 0:fac116e94d44 240 } else { //EOF
rebonatto 0:fac116e94d44 241 // DEBUG ("\r\nFim de arquivo\r\n");
rebonatto 0:fac116e94d44 242 fclose(fp);
rebonatto 0:fac116e94d44 243 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 244 }
rebonatto 0:fac116e94d44 245 break;
rebonatto 0:fac116e94d44 246 default: // this includes 0x05 errors
rebonatto 0:fac116e94d44 247 fclose(fp);
rebonatto 0:fac116e94d44 248 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 249 break;
rebonatto 0:fac116e94d44 250 } // switch (buff[1])
rebonatto 0:fac116e94d44 251 }
rebonatto 0:fac116e94d44 252
rebonatto 0:fac116e94d44 253 void tftpsrv::tftpEscrevendo(int tam, char *buff)
rebonatto 0:fac116e94d44 254 {
rebonatto 0:fac116e94d44 255 // DEBUG ("\r\nEscrevendo...\r\n");
rebonatto 0:fac116e94d44 256
rebonatto 0:fac116e94d44 257 int block;
rebonatto 0:fac116e94d44 258 switch (buff[1]) {
rebonatto 0:fac116e94d44 259 case 0x02:
rebonatto 0:fac116e94d44 260 // a fazer: verificar host, ip e porta
rebonatto 0:fac116e94d44 261 break; // case 0x02
rebonatto 0:fac116e94d44 262 case 0x03:
rebonatto 0:fac116e94d44 263 block = (buff[2] << 8) + buff[3];
rebonatto 0:fac116e94d44 264 if ((blockcnt+1) == block) {
rebonatto 0:fac116e94d44 265 tftpAck(block);
rebonatto 0:fac116e94d44 266 // new packet
rebonatto 0:fac116e94d44 267 char *data = &buff[4];
rebonatto 0:fac116e94d44 268 fwrite(data, 1,tam-4, fp);
rebonatto 0:fac116e94d44 269 blockcnt++;
rebonatto 0:fac116e94d44 270 dupcnt = 0;
rebonatto 0:fac116e94d44 271 } else {
rebonatto 0:fac116e94d44 272 if ((blockcnt+1) < block) { // high block nr
rebonatto 0:fac116e94d44 273 // we missed a packet, error
rebonatto 0:fac116e94d44 274 // DEBUG ("\r\nMissed packet!\r\n");
rebonatto 0:fac116e94d44 275 fclose(fp);
rebonatto 0:fac116e94d44 276 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 277 } else { // duplicate packet, do nothing
rebonatto 0:fac116e94d44 278 // DEBUG ("\r\nPacote duplicado ( %d )\r\n", blockcnt);
rebonatto 0:fac116e94d44 279 if (dupcnt > 10) {
rebonatto 0:fac116e94d44 280 tftpErr("Too many dups");
rebonatto 0:fac116e94d44 281 fclose(fp);
rebonatto 0:fac116e94d44 282 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 283 } else {
rebonatto 0:fac116e94d44 284 tftpAck(blockcnt);
rebonatto 0:fac116e94d44 285 }
rebonatto 0:fac116e94d44 286 dupcnt++;
rebonatto 0:fac116e94d44 287 }
rebonatto 0:fac116e94d44 288 }
rebonatto 0:fac116e94d44 289 // DEBUG ("\r\nLendo pacote %d com blocksize = %d\n\r", blockcnt, tam);
rebonatto 0:fac116e94d44 290 if (tam<516) {
rebonatto 0:fac116e94d44 291 // DEBUG ("\r\nFim do arquivo -> %d\r\n", tam);
rebonatto 0:fac116e94d44 292 fflush(fp);
rebonatto 0:fac116e94d44 293 fclose(fp);
rebonatto 0:fac116e94d44 294 estado = ESCUTANDO;
rebonatto 0:fac116e94d44 295 }
rebonatto 0:fac116e94d44 296 break; // case 0x03
rebonatto 0:fac116e94d44 297 default:
rebonatto 0:fac116e94d44 298 tftpErr("No idea why you're sending me this!");
rebonatto 0:fac116e94d44 299 break; // default
rebonatto 0:fac116e94d44 300 } // switch (buff[1])
rebonatto 0:fac116e94d44 301 }