#include #include #include #include "external/TinyFeather/DSP/autopilot/util/minimal_io.h" #include "external/TinyFeather/DSP/autopilot/util/minimal_io.cpp" #include "external/TinyFeather/DSP/autopilot/util/ymodem.h" #include "external/TinyFeather/DSP/autopilot/util/ymodem.cpp" #include "util/comstream.h" using namespace std; int debug(0); struct MinimalIOStream : public MinimalIO { iostream &io; unsigned int receive(char *buf, const unsigned int buf_size){ io.read(buf, buf_size); if(debug > 0){ cerr << "RX:" << buf_size << endl; } return io.gcount(); } unsigned int transmit(const char *buf, const unsigned int buf_size){ io.write(buf, buf_size); io.flush(); if(debug > 0){ cerr << "TX:" << buf_size << endl; } return buf_size; } MinimalIOStream(iostream &std_io) : MinimalIO(), io(std_io){} ~MinimalIOStream(){} }; int file_count; YModem::FileInfo info; char *file_content(NULL); struct FileFetcher { int read_done; void operator()(YModem::DataBlock &blk, int blk_index){ if(blk_index == 0){read_done = 0;} if(debug > 1){ cerr << "--read-- : block " << blk_index; cerr << hex; for(int i(0); i < blk.data_size; i++){ if(i % 16 == 0){ cerr << endl << setfill('0') << setw(8) << (i + read_done) << ": "; } cerr << setfill('0') << setw(2) << (unsigned int)(blk.data[i]) << ' '; } cerr << endl << "CRC_orig: " << setfill('0') << setw(4) << blk.crc << "; CRC_cal: " << setfill('0') << setw(4) << num_2_be_num(CRC16::crc16(blk.data, blk.data_size, 0)); cerr << dec; cerr << endl; } if(blk_index == 0){ blk.decode_block0(info); cerr << info.file_name << ", " << info.file_size << endl; int buf_size(2 << (int)(log((double)info.file_size) / log(2.0))); delete [] file_content; file_content = new char [buf_size]; file_count++; }else{ int copy_size(info.file_size - read_done); if(blk.data_size < copy_size){ copy_size = blk.data_size; } memcpy(file_content + read_done, blk.data, copy_size); read_done += copy_size; } } }; struct FileFeeder { int write_done; void operator()(YModem::DataBlock &blk, int blk_index){ int write_done_advance(0); if(blk_index == 0){ blk.header = YModem::CTRL_SOH; blk.data_size = 128; write_done = 0; if(file_count > 0){ // change file name int last_char(0); while(info.file_name[last_char] != '\0'){last_char++;} int last_dot(last_char); while((last_dot > 0) && (info.file_name[--last_dot] != '.')); if(last_dot > 0){ memmove( &(info.file_name[last_dot + 2]), &(info.file_name[last_dot]), last_char - last_dot); }else{ last_dot = last_char; } info.file_name[last_dot++] = '.'; info.file_name[last_dot++] = '2'; info.file_name[last_char + 2] = '\0'; cerr << info.file_name << ", " << info.file_size << endl; info.encode_block0(blk); file_count--; }else{ memset(blk.data, YModem::DATA_NUL, blk.data_size); } }else{ int copy_size(info.file_size - write_done); if(copy_size == 0){ blk.header = YModem::CTRL_EOT; blk.data_size = 0; }else if(128 >= copy_size){ blk.header = YModem::CTRL_SOH; blk.data_size = 128; }else if(1024 >= copy_size){ blk.header = YModem::CTRL_STX; blk.data_size = 1024; }else{ blk.header = YModem::CTRL_STX; blk.data_size = 1024; copy_size = blk.data_size; } memcpy(blk.data, file_content + write_done, copy_size); memset(blk.data + copy_size, YModem::DATA_EOF, blk.data_size - copy_size); write_done_advance = copy_size; } blk.num = blk_index & 0xFF; blk.num_inv = ~blk.num; blk.update_crc(); if(debug > 1){ cerr << "--write-- : block " << blk_index; cerr << hex; for(int i(0); i < blk.data_size; i++){ if(i % 16 == 0){ cerr << endl << setfill('0') << setw(8) << (i + write_done) << ": "; } cerr << setfill('0') << setw(2) << (unsigned int)(blk.data[i]) << ' '; } cerr << dec; cerr << endl; } write_done += write_done_advance; } }; bool check_spec(char *spec){ using std::cerr; using std::endl; #define CHECK_OPTION(name, operation, disp) \ if(std::strstr(spec, "--" #name "=") == spec){ \ char *value(spec + strlen("--" #name "=")); \ {operation;} \ std::cerr << #name << ": " << disp << std::endl; \ return true; \ } CHECK_OPTION(debug, debug = atoi(value), debug); #undef CHECK_OPTION return false; } int main(int argc, char *argv[]) { int argv_index(0); while((++argv_index) < argc){ if(!check_spec(argv[argv_index])){break;} } if(argv_index >= argc){ cerr << "Usage: " << argv[0] << " (options) COMn" << endl; exit(-1); } try{ ComportStream com_io(argv[argv_index]); MinimalIOStream mio(com_io); YModem ymodem(mio); char buf[32]; cin.getline(buf, sizeof(buf)); cerr << "RX Ready..." << endl; FileFetcher fetcher; file_count = 0; ymodem.receive_files(fetcher); cerr << "RX Done." << endl; cin.getline(buf, sizeof(buf)); cerr << "TX Ready..." << endl; FileFeeder feeder; file_count = 1; ymodem.transmit_files(feeder); cerr << "TX Done." << endl; }catch(exception &e){ cerr << e.what() << endl; } delete [] file_content; return 0; }