Source: include/xmodem.H


Annotated List
Files
Globals
Hierarchy
Index
/* -------------------------------------------------------------------------
   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.