Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

CRC


September 1990/XMODEM, XMODEM-1K, And XMODEM/CRC/Listing 1

Listing 1

/*--------------------------------------------
XMODEM.H

Author    Date       Description
-------------------------------------
Jon Ward  22 Apr 90  Initial Revision.
--------------------------------------------*/

#ifndef XMODEM_H
#define XMODEM_H

/*--------------------------------------------
        Xmodem Transfer Errors
--------------------------------------------*/
enum xmodem_errors   
  {
  XERR_OK,  /* No errors */
  
  XERR_XMIT_FUNC,  /* NULL Transmit function pointer */
  XERR_RCVR_FUNC,  /* NULL Receive function pointer */
  
  XERR_RCVR_CANCEL,  /* Receiver cancelled the transfer */
  XERR_SEND_CANCEL,  /* Sender cancelled the transfer */
  XERR_USER CANCEL,  /* User cancelled the transfer */
  
  XERR_FILE_READ,   /* Error reading the file */
  XERR_FILE_WRITE,  /* Error writing the file */
  
  XERR_ACK_TIMEOUT,    /* Timed out waiting for data pack ACK */
  XERR_NAK_TIMEOUT,    /* Timed out waiting for initial NAK */
  XERR_SOH_TIMEOUT,    /* Timed out waiting for SOH */
  XERR_DATA_TIMEOUT,   /* Timed out waiting for data */
  XERR_LAST_ACK_TIMEOUT,/* Timed out waiting for final ACK */
  
  XERR_INVALID_SOH,    /* Invalid char waiting for SOH */
  XERR_INVALID_BLOCK_NUM,/* Block mismatch in packet header */
  XERR_INVALID_CRC,    /* CRC is incorrect */
  XERR_INVALID_CHECKSUM,/* Checksum is incorrect */
  XERR_BLOCK_SEQUENCE, /* Block out of sequence */
  
  XERR_CHAR_ERROR, /* Received character error */
  XERR_OFFLINE,        /* Modem not online */
  
  XERR_BLOCK_NAK,  /* NAK received */
  };
  
#ifdef XMODEM_LIB
/*------------------------------------------------
Number of attempts and timeout for each attempt
to transferr using CRC.
------------------------------------------------*/
#define CRC_RETRY_COUNT        4
#define CRC_TIMEOUT        (3L * MS_PER_SEC)

/*------------------------------------------------
Number of attempts and timeout for each attempt
to Negative Acknowledge a bad packet. This also
includes the initial NAK to get the thing started.
------------------------------------------------*/
#define NAK_RETRY_COUNT        10
#define NAK_TIMEOUT        (10L * MS_PER_SEC)

/*------------------------------------------------
Number of attempts and timeout for each attempt
to Acknowledge a good packet.
------------------------------------------------*/
#define ACK_RETRY_COUNT        10
#define ACK_TIMEOUT        (10L * MS_PER_SEC)

/*------------------------------------------------
Number of consecutive CANs and the timeout between
them.
------------------------------------------------*/
#define CAN_COUNT_ABORT        2

#define CAN_TIMEOUT        (2L * MS_PER_SEC)

/*------------------------------------------------
Timeout between packet data bytes.
------------------------------------------------*/
#define DATA_TIMEOUT       (1L * MS_PER_SEC)

/*------------------------------------------------
Number of false start characters that the sender
can receive before aborting the transmission.
------------------------------------------------*/
#define START_XMIT_RETRY_COUNT 10
#define START_XMIT_TIMEOUT (60L * MS_PER_SEC)

/*------------------------------------------------
Maximum number of attempts to send a single block.
------------------------------------------------*/
#define BLOCK_RETRY_COUNT      10

/*------------------------------------------------
Timeout for block responses.
------------------------------------------------*/
#define BLOCK_RESP_TIMEOUT (10L * MS_PER_SEC)

/*------------------------------------------------
Macro to purge all characters from the receive
buffer. This waits until there are no characters
received for a 1 second period.
------------------------------------------------*/
#define PURGE_RECEIVER(c) \
while ((*(c)) (MS_PER_SEC, NULL) != RECV_TIMEOUT)

#endif /* XMODEM_LIB */

/*------------------------------------------------
Number of milliseconds in a second. I know this
is silly, but it makes the meaning a little more
obvious.
------------------------------------------------*/
#define MS_PER_SEC     1000L

/*------------------------------------------------
Block sizes for normal and for 1K XMODEM
transfers.
------------------------------------------------*/
#define XMODEM_BLOCK_SIZE 128
#define XMODEM_1K_BLOCK_SIZE   1024

/*------------------------------------------------
Values returned by the receive character serial
interface function.
------------------------------------------------*/
#define RECV_TIMEOUT -1 /* receiver timed-out */

/*------------------------------------------------
Error bits stored in the receiv character error
flag.
------------------------------------------------*/
#define RE_OVERRUN_  0x01   /* receiver overrun error */
#define RE_PARITY_  0x02    /* receiver parity error */
#define RE_FRAMING_  0x04  /* receiver framing error */

/*------------------------------------------------
Values returned by the transmit character serial
interface function.
------------------------------------------------*/
#define XMIT_OK        0   /* character enqued for transmission */
#define XMIT_OFFLINE   -1  /* modem offline */

/*-----------------------------------------------
     ASCII values used by XMODEM
-----------------------------------------------*/
#define SOH        1
#define STX        2
#define EOT        4
#define ACK        6
#define BACKSPACE  8
#define NAK        21
#define CAN        24

#define CPMEOF     26

/*-----------------------------------------------
XMODEM block description structure. This is only
used internally by the send and receive routines
and should not be visible outside of these.
-----------------------------------------------*/
#ifdef XMODEM_LIB
struct xmodem_block_st
  {
  long total_block_count;  /* total blocks transferred */
  long total_byte_count;   /* total bytes transferred */
  
  unsigned char start_char;  /* block starting character */
  unsigned char block_num; /* transmission block number */
  unsigned char not_block_num; /* one's complement block number */
  char buffer [XMODEM_1K_BLOCK_SIZE + 1];  /* data buffer */
  int buflen;          /* buffer length (128 or 1024) */
  unsigned char checksum;  /* data checksum */
  unsigned int crc;        /* data CRC-16 */
  
  unsigned int crc_used: 1;    /* 0=Checksum 1=CRC-16 */
  };

typedef struct xmodem_block_st xblock;
#endif /* XMODEM_LIB */

/*-----------------------------------------------
XMODEM function pointer structure.
-----------------------------------------------*/
#ifdef XMODEM_LIB
struct xmodem_func_st
  {
  int (*transmit) (    /* xmit function */
    char);
  
  int (*receive) (  /* recv function */
    long,
    unsigned int *);
  
  void (*dispstat) (   /* display function */
    long,
    long,
    const char *);
  
  int (*check_abort) (void);  /* manual abort function */
  };

typedef struct xmodem_func_st xfunc;
#endif /* XMODEM_LIB */


/*-----------------------------------------------
         XMODEMR.C
-----------------------------------------------*/
int xmodem_recv (
  FILE *f,                 /* file to write to */
  int (*transmit) (char),          /* xmit function */
  int (*receive) (long, unsigned int *),   /* recv function */
  void (*dispstat) (long, long, const char *), /* display function */
  int (*check_abort) (void));          /* manual abort function */

#ifdef XMODEM_LIB
int xm_perror (
  int error,               /* error number */
  xfunc *xmf);             /* xmodem external functions */

void xm_no_disp_func (
  long a,
  long b,
  const char *buf);

int xm_no_abort_func (void);
#endif /* XMODEM_LIB */




/*-----------------------------------------------
         XMODEMS.C
-----------------------------------------------*/
int xmodem_send (
  int block_size,              /* maximum block size */
  FILE *f,                 /* file to write to */
  int (*transmit) (char),         /* xmit function */
  int (*receive) (long, unsigned int *),  /* recv function */
  void (*dispstat) (long, long, const char *), /* display function */
  int (*check_abort) (void));           /* manual abort function */

#ifdef XMODEM_LIB
unsigned int xm_update_CRC (
  unsigned int crc,       /* current CRC */
  unsigned int c);    /* character to add to CRC */

void xm_send_cancel (
  int (*transmit) (char)); /* transmit function */
#endif /* XMODEM_LIB */

#endif     /* XMODEM_H */

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.