Adds file transfer capability to SimpleSerialProtocol

Dependents:   SerialFileReceiver

Committer:
p3p
Date:
Thu Sep 18 17:48:59 2014 +0000
Revision:
1:f8aaff9c57e3
Parent:
0:31dff1f79b4f
Updated to reflect changes in SimpleSErialProtocol

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p3p 0:31dff1f79b4f 1 #include "SerialFileTransfer.h"
p3p 0:31dff1f79b4f 2
p3p 0:31dff1f79b4f 3 extern Serial debug;
p3p 0:31dff1f79b4f 4
p3p 0:31dff1f79b4f 5 LocalFileSystem local("local");
p3p 0:31dff1f79b4f 6
p3p 0:31dff1f79b4f 7 void SFTProtocol::update(SimpleSerialProtocol::Protocol* comms){
p3p 0:31dff1f79b4f 8 if(last_chunk_timer.read_ms() > 100 && transfer_in_progress){
p3p 0:31dff1f79b4f 9 last_chunk_timer.reset();
p3p 0:31dff1f79b4f 10 packet_retry_attempts++;
p3p 0:31dff1f79b4f 11 if(packet_retry_attempts > 50){
p3p 0:31dff1f79b4f 12 ack(comms, 3);
p3p 0:31dff1f79b4f 13 //debug.printf("Transfer Timeout\r\n");
p3p 0:31dff1f79b4f 14 packet_retry_attempts = 0;
p3p 0:31dff1f79b4f 15 transfer_in_progress = false;
p3p 0:31dff1f79b4f 16 chunks_last = 0;
p3p 0:31dff1f79b4f 17 chunks_total = 0;
p3p 0:31dff1f79b4f 18 fclose(fp);
p3p 0:31dff1f79b4f 19 fp = 0;
p3p 0:31dff1f79b4f 20 last_chunk_timer.stop();
p3p 0:31dff1f79b4f 21 last_chunk_timer.reset();
p3p 0:31dff1f79b4f 22 } else {
p3p 0:31dff1f79b4f 23 //debug.printf("Request Packet Resend %d, %d\r\n", comms->droppedBytes(), comms->_corrupt_packets);
p3p 0:31dff1f79b4f 24 ack(comms, 2);
p3p 0:31dff1f79b4f 25 }
p3p 0:31dff1f79b4f 26 }
p3p 0:31dff1f79b4f 27 }
p3p 0:31dff1f79b4f 28
p3p 0:31dff1f79b4f 29 void SFTProtocol::onFileStart(SimpleSerialProtocol::Protocol* comms, SimpleSerialProtocol::Packet* packet){
p3p 0:31dff1f79b4f 30 if(!packet)return;
p3p 0:31dff1f79b4f 31 if (packet->_valid) {
p3p 0:31dff1f79b4f 32 FileStartPacket::Interface* interface = packet->interpretData<FileStartPacket::Interface>();
p3p 0:31dff1f79b4f 33 if (interface) {
p3p 0:31dff1f79b4f 34 //debug.printf("%s.%s has %d chunks\r\n", interface->name, interface->ext, interface->chunks);
p3p 0:31dff1f79b4f 35
p3p 0:31dff1f79b4f 36 char buffer[25];
p3p 0:31dff1f79b4f 37 sprintf(buffer, "/local/%s.%s", interface->name, interface->ext);
p3p 0:31dff1f79b4f 38 fp = fopen(buffer, "w");
p3p 0:31dff1f79b4f 39 if(fp){
p3p 0:31dff1f79b4f 40 transfer_in_progress = true;
p3p 0:31dff1f79b4f 41 chunks_total = interface->chunks;
p3p 0:31dff1f79b4f 42 ack(comms, 0);
p3p 0:31dff1f79b4f 43 last_chunk_timer.start();
p3p 0:31dff1f79b4f 44 }
p3p 0:31dff1f79b4f 45 }
p3p 0:31dff1f79b4f 46 }
p3p 0:31dff1f79b4f 47 return;
p3p 0:31dff1f79b4f 48 }
p3p 0:31dff1f79b4f 49
p3p 0:31dff1f79b4f 50 void SFTProtocol::onFileStream(SimpleSerialProtocol::Protocol* comms, SimpleSerialProtocol::Packet* packet){
p3p 0:31dff1f79b4f 51 if(!packet)return;
p3p 0:31dff1f79b4f 52 if(transfer_in_progress){
p3p 0:31dff1f79b4f 53 if (packet->_valid) {
p3p 0:31dff1f79b4f 54 FileStreamPacket::Interface* interface = packet->interpretData<FileStreamPacket::Interface>();
p3p 0:31dff1f79b4f 55 if (interface) {
p3p 0:31dff1f79b4f 56 //debug.printf("%d,%d\r\n", interface->chunk, interface->length);
p3p 0:31dff1f79b4f 57 //if(rand()%5 < 1){ //1in5 packet loss emulation
p3p 0:31dff1f79b4f 58 if((interface->chunk <= chunks_last + 1) && fp ){
p3p 0:31dff1f79b4f 59
p3p 0:31dff1f79b4f 60 if(interface->chunk == chunks_last + 1){
p3p 0:31dff1f79b4f 61 chunks_last = interface->chunk;
p3p 0:31dff1f79b4f 62 fwrite(interface->data, 1, interface->length, fp);
p3p 0:31dff1f79b4f 63 } else {
p3p 0:31dff1f79b4f 64 //debug.printf("Allready have chunk %d\r\n", interface->chunk);
p3p 0:31dff1f79b4f 65 }
p3p 0:31dff1f79b4f 66
p3p 0:31dff1f79b4f 67 if(chunks_last == chunks_total){
p3p 0:31dff1f79b4f 68 //debug.printf("Transfer Complete: Acked\r\n");
p3p 0:31dff1f79b4f 69 ack(comms, 1);
p3p 0:31dff1f79b4f 70 fclose(fp);
p3p 0:31dff1f79b4f 71 fp = 0;
p3p 0:31dff1f79b4f 72 transfer_in_progress = false;
p3p 0:31dff1f79b4f 73 chunks_last = 0;
p3p 0:31dff1f79b4f 74 chunks_total = 0;
p3p 0:31dff1f79b4f 75 last_chunk_timer.stop();
p3p 0:31dff1f79b4f 76 last_chunk_timer.reset();
p3p 0:31dff1f79b4f 77 }else{
p3p 0:31dff1f79b4f 78 ack(comms, 0);
p3p 0:31dff1f79b4f 79 packet_retry_attempts = 0;
p3p 0:31dff1f79b4f 80 last_chunk_timer.reset();
p3p 0:31dff1f79b4f 81 }
p3p 0:31dff1f79b4f 82
p3p 0:31dff1f79b4f 83 } else {
p3p 0:31dff1f79b4f 84 //debug.printf("Transfer Failed: chunk dropped or out of order\r\n");
p3p 0:31dff1f79b4f 85 transfer_in_progress = false;
p3p 0:31dff1f79b4f 86 chunks_last = 0;
p3p 0:31dff1f79b4f 87 chunks_total = 0;
p3p 0:31dff1f79b4f 88 fclose(fp);
p3p 0:31dff1f79b4f 89 fp = 0;
p3p 0:31dff1f79b4f 90 ack(comms, 3);
p3p 0:31dff1f79b4f 91 last_chunk_timer.stop();
p3p 0:31dff1f79b4f 92 last_chunk_timer.reset();
p3p 0:31dff1f79b4f 93 }
p3p 0:31dff1f79b4f 94 }
p3p 0:31dff1f79b4f 95 //}
p3p 0:31dff1f79b4f 96 }
p3p 0:31dff1f79b4f 97 }
p3p 0:31dff1f79b4f 98 return;
p3p 0:31dff1f79b4f 99 }
p3p 0:31dff1f79b4f 100
p3p 0:31dff1f79b4f 101 void SFTProtocol::ack(SimpleSerialProtocol::Protocol* comms, uint8_t ack_type) {
p3p 0:31dff1f79b4f 102 AckFileStartPacket message;
p3p 0:31dff1f79b4f 103 message.interface.ack_type = ack_type;
p3p 0:31dff1f79b4f 104 message.buildData<AckFileStartPacket::Interface>(&message.interface);
p3p 1:f8aaff9c57e3 105 comms->send(&message);
p3p 0:31dff1f79b4f 106 }