Adds file transfer capability to SimpleSerialProtocol
Dependents: SerialFileReceiver
SerialFileTransfer.cpp
- Committer:
- p3p
- Date:
- 2014-09-18
- Revision:
- 1:f8aaff9c57e3
- Parent:
- 0:31dff1f79b4f
File content as of revision 1:f8aaff9c57e3:
#include "SerialFileTransfer.h" extern Serial debug; LocalFileSystem local("local"); void SFTProtocol::update(SimpleSerialProtocol::Protocol* comms){ if(last_chunk_timer.read_ms() > 100 && transfer_in_progress){ last_chunk_timer.reset(); packet_retry_attempts++; if(packet_retry_attempts > 50){ ack(comms, 3); //debug.printf("Transfer Timeout\r\n"); packet_retry_attempts = 0; transfer_in_progress = false; chunks_last = 0; chunks_total = 0; fclose(fp); fp = 0; last_chunk_timer.stop(); last_chunk_timer.reset(); } else { //debug.printf("Request Packet Resend %d, %d\r\n", comms->droppedBytes(), comms->_corrupt_packets); ack(comms, 2); } } } void SFTProtocol::onFileStart(SimpleSerialProtocol::Protocol* comms, SimpleSerialProtocol::Packet* packet){ if(!packet)return; if (packet->_valid) { FileStartPacket::Interface* interface = packet->interpretData<FileStartPacket::Interface>(); if (interface) { //debug.printf("%s.%s has %d chunks\r\n", interface->name, interface->ext, interface->chunks); char buffer[25]; sprintf(buffer, "/local/%s.%s", interface->name, interface->ext); fp = fopen(buffer, "w"); if(fp){ transfer_in_progress = true; chunks_total = interface->chunks; ack(comms, 0); last_chunk_timer.start(); } } } return; } void SFTProtocol::onFileStream(SimpleSerialProtocol::Protocol* comms, SimpleSerialProtocol::Packet* packet){ if(!packet)return; if(transfer_in_progress){ if (packet->_valid) { FileStreamPacket::Interface* interface = packet->interpretData<FileStreamPacket::Interface>(); if (interface) { //debug.printf("%d,%d\r\n", interface->chunk, interface->length); //if(rand()%5 < 1){ //1in5 packet loss emulation if((interface->chunk <= chunks_last + 1) && fp ){ if(interface->chunk == chunks_last + 1){ chunks_last = interface->chunk; fwrite(interface->data, 1, interface->length, fp); } else { //debug.printf("Allready have chunk %d\r\n", interface->chunk); } if(chunks_last == chunks_total){ //debug.printf("Transfer Complete: Acked\r\n"); ack(comms, 1); fclose(fp); fp = 0; transfer_in_progress = false; chunks_last = 0; chunks_total = 0; last_chunk_timer.stop(); last_chunk_timer.reset(); }else{ ack(comms, 0); packet_retry_attempts = 0; last_chunk_timer.reset(); } } else { //debug.printf("Transfer Failed: chunk dropped or out of order\r\n"); transfer_in_progress = false; chunks_last = 0; chunks_total = 0; fclose(fp); fp = 0; ack(comms, 3); last_chunk_timer.stop(); last_chunk_timer.reset(); } } //} } } return; } void SFTProtocol::ack(SimpleSerialProtocol::Protocol* comms, uint8_t ack_type) { AckFileStartPacket message; message.interface.ack_type = ack_type; message.buildData<AckFileStartPacket::Interface>(&message.interface); comms->send(&message); }