Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| ref:xmodem [2010/03/04 17:16] – created digitalman | ref:xmodem [2011/07/13 23:49] (current) – digitalman | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== XMODEM ====== | + | ====== XMODEM, CRC XMODEM, WXMODEM File Transfer Protocols |
| - | FIXME - import ymodem.doc | + | |
| + | < | ||
| + | Please circulate this document anyway that you see | ||
| + | fit without alteration except on the page at the | ||
| + | end titled: "Notes and Comments" | ||
| + | that anyone using these protocols within a commer- | ||
| + | cial product not charge for them as an option or | ||
| + | surcharge, but include XMODEM and its derivations | ||
| + | as part of the basic product. | ||
| + | |||
| + | |||
| + | Peter Boswell | ||
| + | June 20, 1986 | ||
| + | | ||
| + | </ | ||
| + | |||
| + | This document was converted to Wiki syntax by [[person: | ||
| + | |||
| + | ===== Preface ===== | ||
| + | |||
| + | In the years that have past since Xmodem was first developed as a file | ||
| + | transfer protocol, many thousands of people have been involved in | ||
| + | finding reasonable ways to move data via asynchronous telephone communications. | ||
| + | learn from many of these people. | ||
| + | that did not actually come from someone else. Indeed, whether it is | ||
| + | WXMODEM, X.PC, Synchronous dial-up X.25, SNA, ZMODEM, Blast, Kermit or | ||
| + | any other protocol that becomes the dominant dial-up file transfer | ||
| + | protocol for personal and home computers is just not important. | ||
| + | is important is that the public domain have a high speed file transfer | ||
| + | protocol that is reasonably popular and commonly available for many | ||
| + | types of personal computers, for bulletin boards and for services such | ||
| + | as People/ | ||
| + | |||
| + | Here are a few people that all of us should thank and I would especially like to recognize: | ||
| + | |||
| + | * Ward Christensen | ||
| + | Ward, a true pioneer in the microcomputer | ||
| + | communications area, is the author of the original Checksum | ||
| + | Xmodem protocol. | ||
| + | stupid" | ||
| + | ---- | ||
| + | * Chuck Forsberg | ||
| + | Chuck has edited perhaps the best work on | ||
| + | Xmodem and has provided both YMODEM (1K Xmodem) and ZMODEM | ||
| + | (Windowed YMODEM) to the public domain. | ||
| + | me a protocol which would deal with the X-On/X-Off problem | ||
| + | and reminding me that there is such a thing as a DLE character. | ||
| + | ---- | ||
| + | * Richard (Scott) McGinnis | ||
| + | Scott is the architect, the moving | ||
| + | force, for the People/Link software system. | ||
| + | comments and encouragement have been wonderful. | ||
| + | you see his visual conference program for the IBM PC! | ||
| + | Thanks for showing me how to use a DLE. | ||
| + | ---- | ||
| + | * Gene Plantz | ||
| + | Gene operates a major IBM PC bulletin board in | ||
| + | the Chicago area and has been active in the National SYSOP | ||
| + | Association. | ||
| + | performance. | ||
| + | |||
| + | ---- | ||
| + | |||
| + | In a historical perspective, | ||
| + | computer systems development that can shed some light on where we stand | ||
| + | and how we got here. The pattern is function first, then integrity and | ||
| + | finally performance. | ||
| + | |||
| + | Any kind of software must first do something worthwhile. | ||
| + | point in being error free, or inexpensive to operate if we do not want | ||
| + | the function. | ||
| + | between microcomputers. | ||
| + | function Xmodem provided met a real need to many microcomputer users. | ||
| + | |||
| + | Once we have a new function and we accept it, there is a normal desire | ||
| + | for the function to be correct. | ||
| + | software users have pointed out ... "that new function is super, but | ||
| + | the results are wrong" | ||
| + | to providing integrity. | ||
| + | response to the integrity phase of a service as it reduced undetected | ||
| + | transmission errors by many orders of magnitude. | ||
| + | |||
| + | After the integrity has been accepted, people begin to look toward cost | ||
| + | and performance. | ||
| + | Forsberg' | ||
| + | block sizes, batch mode and more. His ZMODEM is a major step toward | ||
| + | making XMODEM derivative protocols work effectively with Public Data | ||
| + | Networks and most importantly, | ||
| + | at the point of failure. | ||
| + | solution to ZMODEM which is, hopefully, an easier solution to the most | ||
| + | important performance problems. | ||
| + | |||
| + | No one really knows where XMODEM and the file transfer function will go | ||
| + | in the coming years. | ||
| + | Synchronous X.25 will slowly push XMODEM, et. al, into history. | ||
| + | think this will happen, but not for maybe 5 to 10 years. | ||
| + | 50% of the households outgrow the Commodore 64, or when modem manufac- | ||
| + | turers can provide a $50 synchronous modem we will see the beginning of | ||
| + | the end for XMODEM, but not today. | ||
| + | |||
| + | |||
| + | ===== Introduction ===== | ||
| + | |||
| + | XMODEM and its derivatives have become the primary method for file | ||
| + | transfer for personal computers. | ||
| + | people to understand these protocols and to implement them on their | ||
| + | own. In particular, this document presents an additional XMODEM | ||
| + | derivation to the public domain: WXMODEM. | ||
| + | |||
| + | === Why develop another file transfer protocol? === | ||
| + | After working with bulletin boards, Public Data Networks such as Tymnet | ||
| + | and Telenet, and commercial host systems such as People/ | ||
| + | CompuServe and others, a number of people came to believe that hobbyist, home and business users would benefit significantly from a new, | ||
| + | conceptually simple file transfer protocol which would provide improved | ||
| + | performance and fully support the public data networks such as Tymnet, | ||
| + | Telenet and Datapac. | ||
| + | |||
| + | But before WXMODEM can be presented, XMODEM and CRC XMODEM must be | ||
| + | described in detail. | ||
| + | |||
| + | |||
| + | ===== Terminology ===== | ||
| + | |||
| + | I've elected to use two special terms: transmitter and receiver. | ||
| + | transmitter is the computer/ | ||
| + | and receiving acknowledgement characters. | ||
| + | |||
| + | Here is a table of special ASCII characters that are used throughout | ||
| + | this paper: | ||
| + | < | ||
| + | Name Decimal | ||
| + | |||
| + | SOH 01 | ||
| + | EOT 04 | ||
| + | ACK 06 | ||
| + | DLE 16 | ||
| + | X-On (DC1) | ||
| + | X-Off(DC3) | ||
| + | NAK 21 | ||
| + | SYN 22 | ||
| + | CAN 24 | ||
| + | </ | ||
| + | |||
| + | ===== XMODEM ===== | ||
| + | |||
| + | Xmodem is a popular error recovery type protocol for transferring files | ||
| + | between computers via serial, asynchronous communications. | ||
| + | learning more about Xmodem, it is important to hear what its author has | ||
| + | to say: | ||
| + | |||
| + | "It was a quick hack I threw together, very unplanned (like | ||
| + | everything I do), to satisfy a personal need to communicate | ||
| + | with some other people. | ||
| + | 8/77, and that I put it in the public domain immediately, | ||
| + | made it become the standard that it is" | ||
| + | suggest I make SIGNIFICANT changes to the protocol, such as | ||
| + | 'full duplex', | ||
| + | destinations', | ||
| + | simplicity of the protocol is one of the reasons it survived | ||
| + | to this day in as many machines and programs as it may be | ||
| + | found in!" | ||
| + | |||
| + | |||
| + | ==== Xmodem Hardware Level Protocol ==== | ||
| + | The protocol is Asynchronous, | ||
| + | bit. Modems which are commonly used are AT&T 103 (300 baud), AT&T | ||
| + | 212A (1200 baud) and CCITT V.22 (2400 baud). | ||
| + | |||
| + | Typically, the data in a file is transmitted without change (if a | ||
| + | 7 bit machine, the left most, high order, bit is always zero) | ||
| + | except that CP/M and MS/DOS operating systems want a ^Z (decimal | ||
| + | 26) to represent end-of-file. | ||
| + | |||
| + | ==== Xmodem Initiation ==== | ||
| + | |||
| + | |||
| + | Prior to entering the protocol, both the transmitting and receiving computer must know where to get the data (what file is to be | ||
| + | transmitted) and where to put the data (file to store the data or | ||
| + | buffer area). | ||
| + | always in charge (local computer), asking the other side (remote | ||
| + | computer) to either transmit a file or to accept a file. Through | ||
| + | a dialog outside of Xmodem the local computer (your PC) first | ||
| + | sends commands to the remote computer to select a file name | ||
| + | to prepare to transmit or receive a file via XMODEM. | ||
| + | completed the remote computer enters the XMODEM protocol. | ||
| + | local computer must be told what file to transmit or receive and | ||
| + | it enters the XMODEM protocol, and hopefully data starts moving. | ||
| + | |||
| + | |||
| + | Upon entering the Xmodem protocol, the transmitting computer waits | ||
| + | between 10 seconds and a minute to receive an NAK character from | ||
| + | the receiving computer. | ||
| + | the protocol. | ||
| + | any character other than a NAK or CAN is read by the transmitter, | ||
| + | it is ignored. | ||
| + | Xmodem file transfer and that the transmitter should leave the | ||
| + | Xmodem protocol. | ||
| + | 10 seconds for data to begin to arrive. | ||
| + | seconds, the receiver will send another NAK and continue to repeat | ||
| + | 10 times at which point the receiver will leave the Xmodem | ||
| + | protocol (typically with a super cryptic error message such as | ||
| + | " | ||
| + | |||
| + | < | ||
| + | Transmitter | ||
| + | |||
| + | [wait for one minute] | ||
| + | |||
| + | [begin block transmission] | ||
| + | </ | ||
| + | |||
| + | ==== Xmodem Data Transmission ==== | ||
| + | |||
| + | |||
| + | The transmitter takes the data, divides it into 128, 8 bit byte | ||
| + | pieces and places it in an Xmodem Packet. | ||
| + | |||
| + | The Xmodem Packet looks like this: | ||
| + | < | ||
| + | [SOH] [seq] [cmpl [seq] [128 data bytes] [csum] | ||
| + | |||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | wraps around to zero. | ||
| + | |||
| + | cmpl seq one byte 1's complement of seq. This can be | ||
| + | | ||
| + | xor as cmpl = (255 and seq) xor 255. | ||
| + | |||
| + | | ||
| + | CP/M and MS/DOS files a ^Z (decimal 26) must be | ||
| + | added to then end of the file. If the last block | ||
| + | of data is less than 128 bytes, the Xmodem packet | ||
| + | must be padded with characters, usually ^Z' | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | Once Xmodem Initiation has completed, the transmitter sends the | ||
| + | first Xmodem packet and then waits. | ||
| + | full packet, it will compare its own checksum calculation with the | ||
| + | checksum that was sent by the transmitter. | ||
| + | match, the receiver will send an ACK. If the checksums are | ||
| + | different, the receiver will send a NAK. | ||
| + | |||
| + | After receiving an ACK the transmitter will send the next Xmodem | ||
| + | packet. | ||
| + | same XMODEM packet again. | ||
| + | |||
| + | Once the transmitter has sent the last Xmodem packet and has | ||
| + | received an ACK, the transmitter will send an EOT and then wait | ||
| + | for a final ACK from the receiver before leaving the Xmodem | ||
| + | protocol. | ||
| + | first character the next packet), the receiver transmits an ACK | ||
| + | character, closes its files and leaves the Xmodem protocol. | ||
| + | |||
| + | Let's look at a three block file transfer: | ||
| + | < | ||
| + | | ||
| + | |||
| + | <<<<< | ||
| + | | ||
| + | <<<<< | ||
| + | | ||
| + | <<<<< | ||
| + | | ||
| + | <<<<< | ||
| + | | ||
| + | <<<<< | ||
| + | </ | ||
| + | Seems easy, right? | ||
| + | |||
| + | ==== Xmodem Cancellation ==== | ||
| + | |||
| + | It has become a defacto standard that the receiver may cancel the | ||
| + | file transfer by sending a CAN character and then leaving the | ||
| + | protocol. | ||
| + | expecting either a NAK or ACK, the transmitter is to terminate and leave the protocol. | ||
| + | when expecting an SOH (start of packet) it should terminate the | ||
| + | file transfer. | ||
| + | |||
| + | ==== Xmodem Error Recovery and Timing ==== | ||
| + | |||
| + | Error detection and recovery are the primary purposes of the | ||
| + | Xmodem protocol. | ||
| + | retry until 10 errors in a row have occurred. | ||
| + | error conditions are listed below: | ||
| + | |||
| + | === Complement Error === | ||
| + | |||
| + | If the sequence number does not match the complement | ||
| + | sequence number, the packet must be discarded and a NAK | ||
| + | sent to the transmitter. | ||
| + | |||
| + | === Duplicate packet condition === | ||
| + | |||
| + | If the sequence number is the same as the sequence | ||
| + | number of the last packet received, the packet should be | ||
| + | discarded and an ACK sent to the transmitter. | ||
| + | |||
| + | === Out of sequence error === | ||
| + | |||
| + | If the sequence number matches the complement sequence | ||
| + | number and it is neither the expected sequence number | ||
| + | nor the last sequence number, the receiver should send | ||
| + | two CAN characters and leave the Xmodem protocol | ||
| + | (e. g. abort the file transfer). | ||
| + | |||
| + | === Receive timeout errors === | ||
| + | |||
| + | |||
| + | When expecting data, if 10 seconds ever pass without | ||
| + | receipt of a character, the receiver should send another | ||
| + | NAK. This should be repeated 10 times. | ||
| + | first character of a packet, SOH, and then reduce the | ||
| + | timeout for characters in a packet. | ||
| + | not go below 5 seconds if the protocol is to be used | ||
| + | with public data networks. | ||
| + | |||
| + | === Transmit timeout errors === | ||
| + | |||
| + | |||
| + | In the original protocol, the transmitter would wait 10 | ||
| + | seconds for an ACK, NAK or CAN and then retransmit the | ||
| + | last Xmodem packet as if a NAK had been received. | ||
| + | implementations either have the transmitter wait for a | ||
| + | very long time (30 seconds to a minute) and then | ||
| + | terminate the file transfer if an ACK, NAK or CAN has | ||
| + | not been receive or wait about 30 seconds and retransmit | ||
| + | the last packet. | ||
| + | |||
| + | === Packet synchronization errors === | ||
| + | |||
| + | |||
| + | Since extraneous characters are frequently generated | ||
| + | when using asynchronous communications, | ||
| + | should not count on receiving exactly 132 characters for | ||
| + | each Xmodem packet. | ||
| + | |||
| + | * Assume that the checksum algorithm will cause re-transmission of Xmodem packets which contain extraneous | ||
| + | |||
| + | * If the character received when expecting the start of a | ||
| + | |||
| + | * Once a SOH is found, assume that the next two characters | ||
| + | |||
| + | * Send a NAK if a timeout occurs while attempting to re-synchronize (e.g. continue to process timeouts as described above). | ||
| + | * If no re-synchronization occurs within 135 characters | ||
| + | |||
| + | === False EOT condition === | ||
| + | |||
| + | |||
| + | When the receiver sees an EOT (which was not sent by the | ||
| + | transmitter, | ||
| + | instead of a SOH character, the receiver assumes incorrectly | ||
| + | that the complete file has been transmitted. | ||
| + | typically an unrecoverable error and it does occur especially | ||
| + | when the transmitting and receiving UARTs are clocked | ||
| + | slightly differently. | ||
| + | return a NAK for the first EOT received and only assume true | ||
| + | end of transmission after receiving two EOT' | ||
| + | < | ||
| + | Transmitter | ||
| + | |||
| + | [last block .. ] >>>>> | ||
| + | <<<<< | ||
| + | [EOT] >>>>> | ||
| + | <<<<< | ||
| + | [EOT] >>>>> | ||
| + | <<<<< | ||
| + | </ | ||
| + | Just in case the transmitter was not prepared to resend the | ||
| + | EOT, it might be wise to set the timeout to about 3 seconds | ||
| + | and retransmit the NAK up to 3 times and then issue a warning | ||
| + | message but assume end of transmission. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | === False CAN condition === | ||
| + | |||
| + | |||
| + | Some Xmodem implementations will terminate on a single CAN | ||
| + | character. | ||
| + | a communications error and if this occurs and is seen by the | ||
| + | receiver between packets or is ever seen by the transmitter, | ||
| + | the file transfer will be incorrectly canceled. | ||
| + | implementations now require two CAN characters in a row | ||
| + | before assuming that the file transfer is to be aborted. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ===== CRC XMODEM ===== | ||
| + | |||
| + | |||
| + | CRC Xmodem is very similar to Checksum Xmodem. | ||
| + | has changed and the 8 bit checksum has been replaced by a 16 bit CRC. | ||
| + | Only theses changes are presented. | ||
| + | |||
| + | One of the earliest and most persistent problems with Xmodem were | ||
| + | transmission errors which were not caught by the checksum algorithm. | ||
| + | Assuming that there is no bias in asynchronous communications errors, | ||
| + | we would expect that 1 out of every 256 erroneous complete or oversized | ||
| + | Xmodem packets to have a valid checksum. | ||
| + | the checksum were 16 bits, we would expect 1 out of every 65,536 | ||
| + | erroneous complete or oversized packets would have a valid checksum. | ||
| + | |||
| + | ==== CRC Calculation Rules ==== | ||
| + | |||
| + | |||
| + | Considerable theoretical research has shown that a 16 bit cyclical | ||
| + | redundancy check character (CRC/16) will detect a much higher | ||
| + | percent of errors such that it would only allow 1 undetected | ||
| + | bit in error for every 10^14 bits transmitted. | ||
| + | something around 10^9 to 10^10 is more realistic. | ||
| + | improvement over the checksum algorithm? | ||
| + | unique properties that prime numbers have when being divided into | ||
| + | integers. | ||
| + | number, the remainder is unique. | ||
| + | 1024 data bits in an Xmodem packet as an integer, multiples that | ||
| + | integer by 2^16 and then divides that 1040 bit number by a 17 bit | ||
| + | prime number. | ||
| + | 16 bit CRC. | ||
| + | |||
| + | The 17 bit prime number in CRC Xmodem is 2^16 + 2^12 + 2^5 + 1 or | ||
| + | 65536 + 4096 + 32 + 1 = 69665. | ||
| + | just multiply the 128 byte data number by 65536, divide by 69665 | ||
| + | and the low order 16 bits of the remainder are the CRC. The only | ||
| + | problem is, I've never seen a computer which has instructions to | ||
| + | support 130 byte integer arithmetic! | ||
| + | Satchell, Satchell Evaluations, | ||
| + | efficient algorithm to calculate the CRC without either 130 byte | ||
| + | arithmetic or bit manipulation. | ||
| + | code, in IBM/PC BASIC, for the calculation of a CRC. | ||
| + | |||
| + | Other methods of calculating CRC's for Xmodem involve bit level logic.((Chuck Forsber, " | ||
| + | |||
| + | |||
| + | ==== CRC Xmodem Initiation ==== | ||
| + | |||
| + | |||
| + | The initiation of CRC Xmodem was designed to provide for automatic | ||
| + | fall back to Checksum Xmodem if the transmitter does not support | ||
| + | the CRC version. | ||
| + | |||
| + | The receiver requests CRC Xmodem by sending the letter C (decimal | ||
| + | 67) instead of a NAK. If the transmitter supports CRC Xmodem, it | ||
| + | will begin transmission of the first Xmodem packet upon receipt of | ||
| + | the C. If the transmitter does not support CRC Xmodem, it will | ||
| + | ignore the C. The receiver should timeout after 3 seconds and | ||
| + | repeat sending the C. After 3 timeouts, the receiver should fall | ||
| + | back to the checksum Xmodem protocol and send a NAK. | ||
| + | |||
| + | |||
| + | |||
| + | ===== Windowed XMODEM (WXMODEM) ===== | ||
| + | |||
| + | This section assumes that the reader is already familiar with Xmodem and CRC Xmodem presented above. | ||
| + | |||
| + | First, Xmodem provided the basic file transfer function, then CRC | ||
| + | Xmodem improved the data integrity, now we come to WXmodem which | ||
| + | provides better cost/ | ||
| + | |||
| + | ==== WXmodem Design Criteria ==== | ||
| + | |||
| + | |||
| + | A few people began discussing improvements to Xmodem with me in | ||
| + | late 1985, over time we developed the following criteria: | ||
| + | - The protocol must be as similar as possible to the XMODEM originally developed by Ward Christensen. The popularity of XMODEM, I believe, is based on its conceptual simplicity. | ||
| + | - The protocol must overcome the propagation delay that is characteristic of the public data networks. | ||
| + | - The protocol must overcome the flow control problems which are characteristic in many public data network situations. | ||
| + | - The protocol should improve error recovery by simplifying the manner in which a programmer can determine the beginning of an XMODEM block. | ||
| + | |||
| + | ==== Transparency and Flow Control Rules (Byte Level Rules) ==== | ||
| + | |||
| + | |||
| + | This protocol provides special public data network support for | ||
| + | non-X.25 hosts and PC-Pursuit access to bulletin boards. | ||
| + | to accomplish this, the transmitter is not permitted to transmit | ||
| + | the X-On and X-Off characters in the Xmodem packets. | ||
| + | for this restriction is simple: | ||
| + | |||
| + | * By the very nature of X.25 public data networks, without flow control, buffer overruns and lost data are inevitable from time to time at any baud rate. | ||
| + | |||
| + | * To avoid data loss public data networks must always assume that any X-Off and X-On character is a flow control character when supporting PC-Pursuit for bulletin boards and when supporting non-X.25 host systems. | ||
| + | |||
| + | Since many non-X.25 hosts, bulletin boards and communications | ||
| + | programs use X-On and X-Off as flow control characters, public | ||
| + | data networks must support those X-Off and X-On requests at the | ||
| + | point of connection where the X-Off is received by the public data | ||
| + | network. | ||
| + | up in the network would be transmitted by the public data network | ||
| + | before the X-Off used for flow control reached the transmitter. | ||
| + | The public data network has no way to know whether an X-On/ | ||
| + | protocol or Xmodem is operational at any point in time. Therefore | ||
| + | a Xmodem packet which contains an X-Off character and no succeeding X-On character will cause the public data network to stop | ||
| + | forwarding the ACK or NAK. | ||
| + | |||
| + | In addition, error recovery requires sophisticated programming for | ||
| + | the receiver to determine the start of an XMODEM packet. | ||
| + | protocol simplifies this task by dedicating a special character as | ||
| + | an indicator that an XMODEM packet is about to begin. | ||
| + | SYN (synch, decimal 22) character is used for this purpose. | ||
| + | The presence of one or more SYN characters in a data stream always | ||
| + | indicates that the next non SYN character is the beginning of an | ||
| + | XMODEM packet (e.g. SOH). | ||
| + | |||
| + | The method used here to handle these situations is through the | ||
| + | insertion of the DLE character (H010, decimal 16, data link escape | ||
| + | character) as an indicator that the character following the DLE is | ||
| + | in fact a modified DLE, SYN, X-On, or X-Off character. | ||
| + | |||
| + | === Rules === | ||
| + | |||
| + | - Whenever an X-On, X-Off, SYN or DLE character is about to be transmitted as any part of an actual | ||
| + | - The inserted DLE characters are not counted in the 128 byte data length of the data portion of the XMODEM packet. | ||
| + | - Neither the DLE nor the adjusted characters are used in the CRC calculation, | ||
| + | - When the receiver sees a DLE character, it does not count it in the XMODEM block length calculation, | ||
| + | - Prior to transmission of a XMODEM packet, the | ||
| + | - Except for the character received after a DLE, the | ||
| + | - The transmitter must support flow control characters (X-On, and X-Off) during transmission of | ||
| + | |||
| + | ==== Initial Handshake Rules ==== | ||
| + | |||
| + | |||
| + | An initial handshake is provided to permit the receiver to | ||
| + | indicate to the transmitter whether it can support checksum | ||
| + | Xmodem, CRC Xmodem, or Windowed Xmodem: | ||
| + | |||
| + | - WXMODEM - The receiver will send a character W | ||
| + | - CRC XMODEM - The receiver will send a character C | ||
| + | - Checksum XMODEM - The receivers will send a NAK and wait up to 3 seconds for the beginning of a Xmodem packet. | ||
| + | |||
| + | ==== Window Packet Transmission Rules ==== | ||
| + | |||
| + | |||
| + | In order to overcome the propagation delays inherent with public | ||
| + | data networks such as Tymnet, Telenet, Datapac, IPSS, Transpac and | ||
| + | dozens more, the protocol must permit the transmitter to send more | ||
| + | than one packet before receiving an acknowledgement from the | ||
| + | receiver. | ||
| + | before stopping transmission if an acknowledgement has not been | ||
| + | received is called the " | ||
| + | packets for several reasons. | ||
| + | set of timing rules which would deal reasonably well with a wide | ||
| + | range of baud rates (that implied keeping the window fairly | ||
| + | small). | ||
| + | to the Xmodem packet sequence number which, hopefully, will | ||
| + | simplify implementation of windowing. | ||
| + | |||
| + | |||
| + | |||
| + | === Rules === | ||
| + | |||
| + | 1. The window is always 4 Xmodem packets. | ||
| + | |||
| + | 2. The receiver will transmit acknowledgements in the form: | ||
| + | |||
| + | | ||
| + | |||
| + | The [sequence] field is an 8 bit number where the | ||
| + | high order or most significant 6 bits are always | ||
| + | zero and the low order or least significant 2 bits | ||
| + | are always the same as the low order 2 bits of the | ||
| + | XMODEM block sequence number of the XMODEM packet | ||
| + | being acknowledged (value in decimal may range | ||
| + | from 0 to 3). | ||
| + | |||
| + | 3. The receiver does not have to acknowledge every | ||
| + | packet, but must acknowledge at minimum every | ||
| + | fourth packet. | ||
| + | ACK[sequence] for multiple XMODEM packets. | ||
| + | example, after an unknown number of packets: | ||
| + | < | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | Since some transmitters must close the window and | ||
| + | cease all communications before doing disk I/O to | ||
| + | read more data, it is suggested that acknowledgements be sent for every packet (except when the | ||
| + | receiver can easily determine that another packet | ||
| + | is already being received at the point in time that | ||
| + | the ACK[sequence] is about to be sent).3 | ||
| + | |||
| + | |||
| + | |||
| + | 4. The receiver will reject a packet (request retransmission) by sending: | ||
| + | |||
| + | NAK[sequence] | ||
| + | |||
| + | Where [sequence] is then next window sequence | ||
| + | number (between H000 and H003) after the [sequence] | ||
| + | of the last good block. | ||
| + | up to 3 Xmodem packets received after the NAK is | ||
| + | transmitted until it receives the packet with the | ||
| + | sequence number that had previously been nak'ed by | ||
| + | the receiver. | ||
| + | NAK until another packet with the same sequence | ||
| + | number is received which is also invalid or a | ||
| + | timeout has occurred. | ||
| + | |||
| + | 5. When the transmitter receives a NAK[sequence], | ||
| + | will complete transmission of any XMODEM block | ||
| + | currently being transmitted and then begin re- | ||
| + | transmission starting with the block which was | ||
| + | nak' | ||
| + | |||
| + | 6. The receiver will discard duplicate packets but | ||
| + | count them in the window for purposes of deter- | ||
| + | mining the maximum receive window without an ACK in | ||
| + | response. | ||
| + | sequence number 127 four times in a row, it must | ||
| + | send an ACK H003 even if the receiver has previously acked that block. | ||
| + | |||
| + | 7. The timeout intervals at various points in processing are: | ||
| + | |||
| + | * Waiting for a character on receive, start of packet | ||
| + | * Waiting for a character on receive, start of packet has been recognized: | ||
| + | * Waiting for an Ack or Nak on transmit side after the window has closed: | ||
| + | * Waiting for an X-On after receipt of an X-Off by the transmitter: | ||
| + | |||
| + | 8. When the transmitter times out waiting for an ACK or NAK when the window is closed (e.g. four blocks | ||
| + | |||
| + | 9. Where possible, it is recommended that the receiver | ||
| + | |||
| + | If the receiver cannot overlap disk I/O and communications | ||
| + | I/O, the receiver can temporarily stop transmission by either: | ||
| + | |||
| + | - " | ||
| + | - Transmitting an X-Off followed by an X-On when the receiver | ||
| + | - Each approach has its advantages, but the X-Off approach will | ||
| + | |||
| + | |||
| + | ==== Notes for X.25 Hosts ==== | ||
| + | |||
| + | |||
| + | Host computer systems which utilize the X.25 protocol | ||
| + | (examples: People/ | ||
| + | interface with the various public data networks may send special | ||
| + | control packets which change the manner in which the network will | ||
| + | communicate with the remote personal computer, bulletin board or | ||
| + | terminal. | ||
| + | X.25 host can already support CRC and/or Checksum Xmodem and | ||
| + | present only the changes for WXMODEM. | ||
| + | |||
| + | - When an X.25 Host is the transmitter, | ||
| + | - When an X.25 Host is the receiver and in WXMODEM | ||
| + | |||
| + | |||
| + | |||
| + | ===== Appendix A - CRC Calculation Rules ===== | ||
| + | |||
| + | |||
| + | The purpose of this appendix is to give non-technical and non mathematical software writers a cook book approach to calculating the CRC-16 | ||
| + | used in Xmodem. | ||
| + | in the examples below has been tested on an IBM PC and found to work | ||
| + | effectively even at 9600 with compiled Basic. | ||
| + | not offer an XOR function and others do not have MKI$ and CVI functions | ||
| + | which simplified the movement of data between data types. | ||
| + | hope to provide a Commodore C-64/C-128 implementation which simulates | ||
| + | XOR, but not today! | ||
| + | |||
| + | My thanks go to Chuck Forsberg, Joe Noonan, John Byrns and Stephen | ||
| + | Satchell. | ||
| + | have never been possible. | ||
| + | |||
| + | ==== IBM PC - 8088/8086 Data Structure ==== | ||
| + | |||
| + | |||
| + | The Intel 8080 and upward has a feature, convenient only to some | ||
| + | electrical engineer somewhere, which places 2 byte (16) bit | ||
| + | integers in BYTE REVERSE order in memory. | ||
| + | significant byte is placed in memory before the most significant | ||
| + | byte for integer operations. | ||
| + | number 52 and it is assigned to I% using the ASC function, the | ||
| + | binary value (52) ends up in the first byte of I% and the second | ||
| + | byte is zero. | ||
| + | < | ||
| + | Result | ||
| + | |||
| + | I%=0 [x' | ||
| + | I%=1 [x' | ||
| + | A$=" | ||
| + | I%=ASC(A$) | ||
| + | B$=MKI$(I%) | ||
| + | I%=CVI(CHR$(0)+A$) | ||
| + | A$=CHR$(65) | ||
| + | </ | ||
| + | Once this is understood, many problems with these algorithms goes away. | ||
| + | |||
| + | ==== BASIC Implementation of Bit Shift Method ==== | ||
| + | |||
| + | |||
| + | The bit shift method here was converted from the " | ||
| + | presented in Chuck Forsberg' | ||
| + | and from an old IBM two page reference guide that Joe Noonan | ||
| + | carries with him in his appointment calendar! | ||
| + | |||
| + | === Chucks' | ||
| + | < | ||
| + | |||
| + | /* | ||
| + | * This function calculates the CRC used by the XMODEM/CRC Protocol | ||
| + | * The first argument is a pointer to the message block. | ||
| + | * The second argument is the number of bytes in the message block. | ||
| + | * The function returns an integer which contains the CRC. | ||
| + | * The low order 16 bits are the coefficients of the CRC. | ||
| + | */ | ||
| + | int calcrc(ptr, count) | ||
| + | char *ptr; | ||
| + | int count; | ||
| + | { | ||
| + | int crc, i; | ||
| + | |||
| + | crc = 0; | ||
| + | while (--count >= 0) { | ||
| + | crc = crc ^ (int)*ptr++ << 8; | ||
| + | for (i = 0; i < 8; ++i) | ||
| + | if (crc & 0x8000) | ||
| + | crc = crc << 1 ^ 0x1021; | ||
| + | else | ||
| + | crc = crc << 1; | ||
| + | } | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | But in IBM PC BASIC, our implementation looks like: | ||
| + | < | ||
| + | 100 DEFINT A-Z ' | ||
| + | 2000 REM * V$ CONTAINS 133 CHARACTER COMPLETE XMODEM PACKET | ||
| + | 2010 REM * CRC$ IS TWO BYTE CRC WITH MOST SIGNIFICANT BYTE FIRST | ||
| + | 2020 CRC$=CHR$(0)+CHR$(0) | ||
| + | 2030 FOR I2=4 TO 131 | ||
| + | | ||
| + | | ||
| + | 2060 NEXT I2 | ||
| + | 2070 REM * CRC$ CONTAINS CALCULATED CRC! | ||
| + | |||
| + | 3000 IF CRC$=MID$(V$, | ||
| + | |||
| + | 4000 REM * CRC BITWISE CALCULATION (WHAT A JOKE!) | ||
| + | 4010 CRCH1=ASC(LEFT$(CRC$, | ||
| + | 4020 CRCL1=ASC(RIGHT$(CRC$, | ||
| + | 4030 FOR I3 = 0 TO 7 | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | 4110 NEXT I3 | ||
| + | 4130 CRC$=CHR$(CRCH1)+CHR$(CRCL1) | ||
| + | 4140 RETURN ' | ||
| + | </ | ||
| + | |||
| + | That routine will execute 128 * 7 + 128 * 9 * 8 BASIC statements | ||
| + | for each Xmodem packet or 10112 statements per Xmodem packet! | ||
| + | will work for low baud rates in compiled BASIC, but just is too | ||
| + | much for interpretive BASIC. | ||
| + | |||
| + | ==== BASIC Implementation of the Table Method ==== | ||
| + | |||
| + | |||
| + | This method is based on routine M4 in Steven Satchell' | ||
| + | "Test of CRC Routines for CRC-CCITT", | ||
| + | cant differences. | ||
| + | with the bit shift method is used to avoid performing the bit | ||
| + | shift during communications. | ||
| + | each byte value from 0 to 255 when the original CRC is zero. The | ||
| + | result of this calculation is included in the DATA statements in | ||
| + | the code. | ||
| + | |||
| + | The comments are intended to show what is logically happening | ||
| + | rather than physically. | ||
| + | integers in the 8088, a logical shift of 8 bits to the left is a | ||
| + | physical shift of eight bits to the right! | ||
| + | < | ||
| + | 200 DEFINT A-Z 'ALL INTEGERS | ||
| + | 210 DIM CRCTB(256) | ||
| + | |||
| + | 300 GOSUB 9000 ' | ||
| + | |||
| + | 6200 REM * CRC CALCULATION USING TABLE METHOD, V$=XMODEM PACKET | ||
| + | 6210 CRC$=CHR$(0)+CHR$(0) | ||
| + | 6220 FOR Q=4 TO 131 | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | 6270 NEXT Q | ||
| + | 6280 IF CRC$ <> MID$(V$, | ||
| + | 6290 REM * END OF CRC CALC | ||
| + | |||
| + | 9000 FOR I%=0 TO 255 ' INITIALIZE CRC TABLE | ||
| + | | ||
| + | 9020 NEXT I% | ||
| + | 9025 RETURN | ||
| + | 9030 DATA 0, 4129, 8258, 12387, 16516, 20645, 24774, 28903 | ||
| + | 9040 DATA -32504, | ||
| + | 9050 DATA 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302 | ||
| + | 9060 DATA -27847, | ||
| + | 9070 DATA 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637 | ||
| + | 9080 DATA -23190, | ||
| + | 9090 DATA 13907, 9842, 5649, 1584, 30423, 26358, 22165, 18100 | ||
| + | 9100 DATA -18597, | ||
| + | 9110 DATA 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371 | ||
| + | 9120 DATA -13876, | ||
| + | 9130 DATA 23285, 19156, 31415, 27286, 6769, 2640, 14899, 10770 | ||
| + | 9140 DATA -9219, | ||
| + | 9150 DATA 27814, 31879, 19684, 23749, 11298, 15363, 3168, 7233 | ||
| + | 9160 DATA -4690, | ||
| + | 9170 DATA 32407, 28342, 24277, 20212, 15891, 11826, 7761, 3696 | ||
| + | 9180 DATA -97, | ||
| + | 9190 DATA -28280, | ||
| + | 9200 DATA 4224, 161, 12482, 8419, 20484, 16421, 28742, 24679 | ||
| + | 9210 DATA -31815, | ||
| + | 9300 DATA 689, 4752, 8947, 13010, 16949, 21012, 25207, 29270 | ||
| + | 9310 DATA -18966, | ||
| + | 9320 DATA 13538, 9411, 5280, 1153, 29798, 25671, 21540, 17413 | ||
| + | 9330 DATA -22565, | ||
| + | 9340 DATA 9939, 14066, 1681, 5808, 26199, 30326, 17941, 22068 | ||
| + | 9350 DATA -9908, | ||
| + | 9360 DATA 22596, 18533, 30726, 26663, 6336, 2273, 14466, 10403 | ||
| + | 9370 DATA -13443, | ||
| + | 9380 DATA 19061, 23124, 27191, 31254, 2801, 6864, 10931, 14994 | ||
| + | 9390 DATA -722, | ||
| + | 9400 DATA 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265 | ||
| + | 9410 DATA -4321, | ||
| + | 9420 DATA 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920 | ||
| + | </ | ||
| + | This method uses 128 * 6 BASIC statements per Xmodem packet or a | ||
| + | miserly 768 BASIC statements per packet. | ||
| + | code can be tightened still more. Unfortunately, | ||
| + | tightening that we could see would eliminate most of the already | ||
| + | limited readability of the code. | ||
| + | |||
| + | ===== Notes and Comments ===== | ||
| + | |||
| + | Please add your notes and comments here or send them to me and I'll get | ||
| + | them added to the current copy on People/ | ||
| + | |||
| + | - This was originally set up to ADD 32 to the character on transmit | ||
| + | - The use of the SYN character was added at the request of several | ||
| + | - The suggestion that ACK[sequence] be sent for every block received | ||
| + | - The original value for the ACK/NAK timeout was 10 seconds. | ||
| + | |||
| + | XMODEM and its derivatives have become the primary method for file | ||
| + | transfer for personal computers and is a popular error recovery type | ||
| + | protocol. Before learning more about Xmodem, it is important to hear | ||
| + | what its author has to say: | ||
| + | |||
| + | "It was a quick hack I threw together, very unplanned (like | ||
| + | everything I do), to satisfy a personal need to communicate | ||
| + | with some other people. | ||
| + | 8/77, and that I put it in the public domain immediately, | ||
| + | made it become the standard that it is" | ||
| + | suggest I make SIGNIFICANT changes to the protocol, such as | ||
| + | 'full duplex', | ||
| + | destinations', | ||
| + | simplicity of the protocol is one of the reasons it survived | ||
| + | to this day in as many machines and programs as it may be | ||
| + | found in!" | ||
| + | |||
| + | Ward Christensen, | ||
| + | in 1985. Edited by Chuck Forsberg, " | ||
| + | Reference", | ||
| + | |||
| + | The protocol is Asynchronous, | ||
| ===== See Also ===== | ===== See Also ===== | ||
| Line 6: | Line 890: | ||
| {{tag> | {{tag> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||