/* -------------------------------------------------------------------------
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. |