|
|
/* ------------------------------------------------------------------------- xmodem.H - Protocol Class for Xmodem ------------------------------------------------------------------------- Copyright (C) 2000-2001 Eric R. Schendel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ------------------------------------------------------------------------- */ #ifndef XMODEM_H #define XMODEM_H #include <fstream> #include <string> #include "status.H" #include "transfer.H" namespace TransferProtocols { using namespace StatusMsgs; const int ACKWAIT = 2000; const int BYTEWAIT = 4000; const int CONTROLWAIT = 500; const int NAKWAIT = 1000; const int WRITECANWAIT = 100; const short BADMAX = 20; const short CANMAX = 5; const short EOTMAX = 10; const short NAKMAX = 10; const short STXMAX = 5; const unsigned char SOH = 0x01; const unsigned char STX = 0x02; const unsigned char EOT = 0x04; const unsigned char ACK = 0x06; const unsigned char NAK = 0x15; const unsigned char CAN = 0x18; const unsigned char CTRLZ = 0x1A; class Xmodem: public DirectTransfer { public: Xmodem(const string serial, const int speed, LogLevel lvl = NONE); virtual void terminateConnection(); virtual bool send(const string fname); virtual bool receive(const string fname); protected: /* * Xmodem's General Methods (protected) */ string getPacketData() { return packet.getData(); } void setPacketCheck(const string chk) { packet.setCheck(chk); } StatusMsgs::Error checkTerminateRequest(); void closeFile(const string name); /* * Xmodem's Send Methods (protected) */ StatusMsgs::Error initializeSend(const string name); StatusMsgs::Error negotiateSend(); unsigned long processSendData(bool& isDone); void processSendCheck(); StatusMsgs::Error sendPacket(bool& bad); void retryPacket(unsigned long offset); StatusMsgs::Error endSend(); /* * Xmodem's Receive Methods (protected) */ StatusMsgs::Error initializeReceive(const string name); StatusMsgs::Error negotiateReceive(); StatusMsgs::Error processReceiveData(const unsigned char ch, bool& haveReadPacket, bool& badPacket, bool& nextPacket, bool& isDone); bool processReceiveCheck(bool& ack); StatusMsgs::Error savePacket(); StatusMsgs::Error handleReceiveStatus(const bool bad, const bool ack); private: Log log; unsigned int packetnum; unsigned short badcnt; unsigned long filesize; fstream fs; /* * Xmodem's General Methods (private) */ void initialize(); unsigned char calculate_packet_chksum(); unsigned long get_file_size(const string& name); /* * Xmodem's Send Methods (private) */ void read_file_to_packet(const int sz); /* * Xmodem's Receive Methods (private) */ bool read_connection_to_packet(const int bufsz, bool& ack); StatusMsgs::Error end_receive(bool& done); class packet_class { public: packet_class() { reset(); } void reset() { pkt.assign(3, (char)0); dsz = 0; csz = 0; } inline void setData(const string data); void setCheck(const string chk) { pkt.resize(pkt.size() - csz); pkt += chk; csz = chk.size(); } void setType(unsigned char type) { pkt[0] = type; } void setNum(unsigned char ch) { pkt[1] = ch; pkt[2] = ~ch; } unsigned char getType() const { return pkt[0]; } unsigned char getNum() const { return pkt[1]; } unsigned char getNumCheck() const { return pkt[2]; } string getData() const { return pkt.substr(3, dsz); } operator string() const { return pkt; } private: string pkt; unsigned long dsz; unsigned short csz; } packet; }; } #endif
Generated on Fri Mar 9 02:04:42 2001, using kdoc 2.0a43. |