home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpmhelp
/
xmodem11.hlp
< prev
next >
Wrap
Text File
|
1994-07-27
|
19KB
|
386 lines
XMODEM PROTOCOL
(How DOES it work?)
by
Dave Larsen
Update 1.1 ~ 22Jan87
Copyright (C) 1986, All rights reserved.
On more than one occasion, I've been asked to reveal the secrets of Xmodem
protocol. Xmodem is probably the most widely used communications protocol
in the personal computer world. Everyone knows what it is and yet no one
seems to know how it works. This text will help to relieve that problem.
Or just add to it...
Xmodem was originally described by Ward Christensen and has been known
variously as Christensen protocol, KMD and so on. In the years since its
first development, Xmodem has gone through many modifications. Xmodem with
CRC, 1k packet transfers and batch transfers are all improvements upon the
original Xmodem protocol which relies on the generation of checksum values
for error detection in file transfers. This is the flavor I will describe
here.
NOTE: This text is designed to help you write your own Xmodem protocol file
transfer routine regardless of the language you happen to be using
and thus is necessarily explained in generic terms. Programming
details are entirely your problem.
DEFINITIONS:
A. "Flag Byte" and "Status Byte" Arbitrary names I've given to bytes
transferred during an Xmodem protocol data transfer.
B. "Block Number" Xmodem sends its data in 128 Byte "Blocks." "Block
Number" refers to the number of the block being transferred.
C. "Local Block Number" The Block Number that you keep track of
internally when receiving a file.
D. "Remote Block Number" The Block Number that the sending computer sends
to you when you're receiving a file.
E. "Checksum #1" and "Checksum #2" One byte values that Xmodem uses in
order to detect errors in data transfer.
F. "Prompt the keyboard." By this I mean that you should send an
appropriate message to the monitor and wait for a reply.
G. "Check the keyboard." In this instance, you should check the keyboard
to see if a key has been pressed. Do not wait for a reply.
H. "Get the __________." When I say to "get" something, that means you
should check your status port and wait until it tells you there is
something in your data port. Then, get the data from the data port.
I. "Send the __________." When I say to "send" something, that means you
should send the indicated data out the data port. If you are receiving a
file, as a precautionary measure you should check the status port and
make sure that the line is clear.
OVERVIEW:
Xmodem could be described as "receiver driven." In other words, the
receiving computer is in control of the file transfer. It dictates to the
sending computer when it is ready to receive data, whether or not there is
an error, and so on.
Below is a simplified example of an Xmodem transfer session. Data sent by
the receiving computer is in parenthesis "()" and data sent by the sending
computer is in square brackets "[]".
1. (Flag Byte)
2. [Status Byte]
3. [Block Number]
4. [Checksum Byte #1]
5. [128 Byte "Block" of Data]
6. [Checksum Byte #2]...............go back to #1
First, the receiving computer sends a Flag Byte to the sending computer.
Depending on this value, the sending computer will resend the current
block, send the next block, or abort the transfer. Then, the sending
computer sends a Status Byte. This byte informs the receiving computer that
the transfer has been canceled, is complete, or that it is ready to
continue. Next, the sending computer sends the Block Number, then the first
Checksum Byte, then the 128 Byte Block of Data and finally, the second
Checksum Byte. The receiving computer evaluates the checksum data and sends
the appropriate Flag Byte and so on.
RECEIVING A FILE:
1. Prompt the keyboard for a file name and open it for input.
2. You should use this step to set aside whatever buffers, arrays, and/or
variables you may need.
3. Check the keyboard for a cancel command. This is done primarily to
allow you to gracefully escape from an unwanted transfer session. If
you've canceled the transfer, go to #4c below.
4. Send a Flag Byte to the sending computer. The Flag Byte will be one of
the following:
a. ACK (Acknowledge 06 HEX, crtl-F) - Indicates that there were no
errors in the last block sent. The sending computer will send the
next block.
b. NAK (Not Acknowledge 15 HEX, crtl-U) - Indicates that there was an
error in the last block sent. The sending computer will resend that
block. NOTE: WHEN A FILE TRANSFER IS STARTED UP, THE VERY FIRST FLAG
BYTE THAT YOU SEND OUT MUST BE A NAK. In this way, the sending
computer is prompted to send you the first block. Essentially,
you've tricked it in to thinking that there was an error in the first
block so it resends it. Tricky huh?
c. CAN (Cancel 18 HEX, crtl-X) - Indicates that the transfer has been
canceled by the receiving computer. Generally, you will have to send
more than one CAN. Five to ten CAN's in as many seconds should do
the trick. This is done in order to prevent aborting a file transfer
accidentally. It should be noted however that a CAN is generally,
but not universally, recognized by Xmodem protocols. You may have to
wait until the sending computer gets tired and abandons the send. In
any event, you should close the file that you opened in #1 and end.
5. Get the Status Byte. The Status Byte will be one of the following:
a. SOH (Start of Heading 01 HEX, ctrl-A) - Indicates that the sending
computer is ready to send a block.
b. EOT (End of Transmission 04 HEX, ctrl-D) - Indicates that the file
transfer is complete. To prevent accidentally ending the file
transfer session, it would be advisable to wait for five to ten
seconds to see if a byte other than EOT comes. If different data is
received, go back to #4b. If not, close the file that you opened in
#1, send out a final ACK, and end.
c. CAN (Cancel 18 HEX, crtl-X) - Indicates that the transfer has been
canceled by the sending computer. Again, to prevent accidentally
ending the file transfer session, it would be advisable to wait for
five to ten seconds to see if a byte other than CAN comes. If
different data is received, go back to #4b. If not, close the file
that you opened in #1, and end.
NOTE: If the Status Byte is not one of the above, or if no Status Byte is
received within 10 seconds, go back to #4b. If you do not receive an
appropriate Status Byte after 10 tries, you might as well forget it.
Close the file that you opened in #1, and end.
6. Get the Block Number. Put this value into a variable, you will need it
to calculate the checksum. If no Block Number is received within about
2 seconds, go back to #4b.
NOTE: This value is the nth block according to the sending computer.
Referred to hereafter as Remote Block Number. You should keep track
of the Block Number internally as well (Local Block Number).
Additionally, you should know that at the beginning of the file
transfer, the Block Number will be 1 and will go up to 255. After
the 255th block has been received, the Block Number will reset to 0.
7. Get Checksum Byte #1. Put this value into a variable, you will need it
later. Again, if no checksum is received within about 2 seconds, go
back to #4b.
8. Get a Block (128 Bytes) of Data. As this data comes in, store it in a
buffer or array of some sort. If you have to wait more than a second
for any single data byte chances are good that something is seriously
wrong. Go to #4b.
9. Get Checksum Byte #2. Put this value into a variable as well. Again,
if no checksum is received within about 2 seconds, go back to #4b.
****************************************************************************
* The sending computer is now waiting for you to send it a NAK or an ACK. *
* Before you can do that, you must decide if you've received everything *
* without error. The sending computer will wait for several seconds while *
* you do this, so don't panic. *
****************************************************************************
10. Compare the Local Block Number and the Remote Block Number. If they are
equal fine, go to #14.
11. If they are unequal, you'll want to keep track of how many times this
happens. Then go back to #4b. If the Block Numbers are unequal three
times in a row then that probably means that the sending computer is
either a block ahead of you or a block behind you.
12. If the sending computer is a block ahead of you there is nothing you can
do about it. Go to #4c.
13. If the sending computer is 1 block behind you all you have to do is tell
it to send the next block. Go to #4a. If the sending computer is more
than one block behind, you should give it up and try again. Go to #4c.
14. Evaluate the checksum data. Perform the following calculations:
(1) + (Remote Block Number) + (Checksum Byte #1) + (The ASCII value of each
character in the 128 Byte Block of Data). Let's call this value X. Plug X
into one of the following formulas:
In Hexadecimal form: Let Y = (X-(X/100h)*100h) (ie. If X = 213D, Y = 3D)
In Decimal form: Let Y = (X-INT(X/256)*256) (ie. X = 8509, Y=61)
Where INT returns the largest integer less than or equal to (X/256).
15. If Y = Checksum #2 then there are no errors. Save the 128 Byte Block to
disk or whatever. Increment the counter you are using for Local Block
Number and go to #3.
16. If Y is unequal to Checksum #2 then you've got an error. Go to #4b.
NOTE: Any time that you "go to" someplace, you will probably want to reset
some of the variables you are using. In particular, you will
probably want to clear out the buffer or array you are using to hold
the block of data. Again, exact program details are left up to you.
SENDING A FILE:
Since sending a file is pretty much the same as receiving a file, only in
reverse, this section is a little shorter. But not to fear, all will be
made clear.
1. Prompt the keyboard for a file name and open it for output.
2. You should use this step to set aside whatever buffers, arrays, and/or
variables you may need.
3. Check the keyboard for a cancel command. If you've canceled the
transfer, then go to #9c.
4. Get a Flag Byte.
a. If it's an ACK, send the next block.
b. If it's a NAK, resend the current block. Go to #9a.
c. If it's a CAN, close the file that you opened in #1, and end. Note,
you should check to make sure this is correct. (See RECEIVING A
FILE, #5c.)
NOTE: Many implementations of Xmodem protocol that I've seen will assume a
NAK and resend the block if an appropriate Flag Byte is not received
within 10 seconds. I do not recommend this. Rather, let the
protocol be completely receiver driven. In other words, simply wait
for an appropriate Flag Byte. If you do not receive it within 1
minute close the file that you opened in #1, and end.
****************************************************************************
* As you should know by now, the receiving computer is currently waiting *
* for you to send the Status Byte. In this time, you'll prepare the data *
* you need to send. *
****************************************************************************
5. Check to see if there are still 128 bytes left in the file. If yes, go
to #7.
6. Since Xmodem can only send data in 128 Byte Blocks, if there are fewer
than 128 bytes left in the file you will need to pad the end of the file
with control-Z's (1AH) so that you'll have a complete block. There are
no "short" blocks.
7. Calculate Checksum #1. Checksum #1 is calculated as FF (Hex) or 255
(Decimal) minus the Block Number.
8. Calculate Checksum #2. This is done the same as before. (See RECEIVING
A FILE, #14.)
9. Send a Status Byte.
a. Send a SOH if you're ready to send a block.
b. Send an EOT if you're finished with the transfer.
c. Send a CAN if you've canceled the transfer in #3 above. Close the
file that you opened in #1, and end. Note, you may have to send more
than one CAN. (See RECEIVING A FILE, #4c.)
10. Send the Block Number. Again, remember that the first Block Number will
be 1 and go to 255. After the 255th block, reset to zero.
11. Send Checksum Byte #1.
12. Send a Block (128 Bytes) of Data.
13. Send Checksum Byte #2.
14. Go to #3.
HEX DUMP:
I've included here a hex dump of an example file transfer session so you can
see exactly what happens. Only the data received is shown.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
-----------------------------------------------
A 01 01 FE 20 20 20 20 20 20 20 20 20 20 20 20 20 Receiving computer
B 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 sends out a NAK. The
C 20 20 20 20 20 20 20 20 0D 0A 20 20 43 4C 45 41 sending computer sends
D 52 49 4E 47 48 4F 55 53 45 20 4C 4F 43 41 4C 20 Status Byte: A01 (01H)
E 53 59 53 54 45 4D 53 20 44 49 52 45 43 54 4F 52 Block #: A02 (01H)
F 59 0D 0A 20 20 20 20 20 20 20 20 20 20 20 55 70 Checksum #1: A03 (FEH)
G 64 61 74 65 64 20 28 30 36 2F 31 36 2F 38 36 29 Data: A04-I03 [OK]
H 0D 0A 20 20 20 20 20 20 20 20 54 68 61 6E 6B 73 Checksum #2: I04 (43H)
I 20 74 6F 43 01 02 FD 20 42 72 69 61 63 20 48 65 Receiving computer
J 72 73 74 69 67 0D 0A 20 20 20 20 20 20 20 20 20 sends out an ACK. The
K 20 20 61 6E 64 20 4A 6F 65 20 57 68 69 70 70 6C sending computer sends
L 65 20 21 21 0D 0A 0D 0A 0D 0A 20 34 2D 42 20 43 Status Byte: I05 (01H)
M 4F 4D 57 68 79 20 64 69 64 20 79 6F 75 20 64 65 Block #: I06 (02H)
N 63 6F 64 65 20 74 68 69 73 3F 20 20 2D 38 39 36 Checksum #1: I07 (FDH)
O 36 0D 0A 0D 0A 20 37 54 48 20 46 4F 52 43 45 2E Data I08-Q07 [ERROR]
P 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E Checksum #2: Q08 (77H)
Q 2E 2E 2E 2E 38 38 35 77 01 02 FD 20 42 72 69 61 Receiving computer
R 6E 20 48 65 72 73 74 69 67 0D 0A 20 20 20 20 20 sends out a NAK. The
S 20 20 20 20 20 20 61 6E 64 20 4A 6F 65 20 57 68 sending computer sends
T 69 70 70 6C 65 20 21 21 0D 0A 0D 0A 0D 0A 20 34 Status Byte: Q09 (01H)
U 2D 42 20 43 4F 4D 50 55 54 45 52 20 53 54 4F 52 Block #: Q10 (02H)
V 45 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 38 39 30 Checksum #1: Q11 (FDH)
W 2D 38 39 36 36 0D 0A 0D 0A 20 37 54 48 20 46 4F Data Q12-Y11 [OK]
X 52 43 45 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E Checksum #2: Y12 (77H)
Y 2E 2E 2E 2E 2E 2E 2E 2E 38 38 35 77 01 03 FC 2D Receiving computer
Z 34 31 31 33 0D 0A 0D 0A 20 41 52 4D 41 44 41 2E sends out an ACK. The
AA 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E sending computer sends
BB 2E 2E 2E 2E 2E 2E 2E 38 35 35 2D 37 32 33 30 0D Status Byte: Y13 (01H)
CC 0A 0D 0A 20 41 52 4D 41 44 41 20 2F 2F 2E 2E 2E Block #: Y14 (03H)
DD 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E Checksum #1: Y15 (FCH)
EE 2E 2E 38 35 35 2D 32 37 30 36 0D 0A 0D 0A 20 41 Data: Y16-GG15 [OK]
FF 54 41 52 49 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E Checksum #2: GG16(50H)
GG 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 32 36 50 Receiving computer
HH 04 sends out an ACK. The
sending computer sends
Status Byte: HH01(04H)
Receiving computer
recognizes EOT, sends
ACK and quits. [DONE]
A FEW FINAL NOTES:
As far as I know, there is no set "standard" for Xmodem protocol. Ward
Christensen developed it, placed it in the public domain, and from then on
it was subject to change and modification by many people. The basic frame
work is the same but there are many different methods for achieving the same
end. I have presented but one of them.
Experienced programmers will probably notice that putting 128 Bytes of Data
into a buffer, then pulling the data out of the buffer to calculate the
ASCII value of each character is somewhat redundant. The justification for
this is simple. Since part of the idea behind this document is to describe
Xmodem protocol for implementation on many different computers and in many
different languages, I had to take into account the simple fact that some
computers and programming languages are faster than others. I had to
describe Xmodem so that it would work if you were programming in slow BASIC
or the fast Assembler. By calculating the ASCII value of each character
outside of the sending/receiving loop, no processing time is used which
could cause data loss in slower languages like BASIC. (Or at high baud
rates.) Once you understand the ins and outs of Xmodem and the limitations
of your hardware and software, streamlining your program should be no
trouble and is recommended.
I sincerely hope that this information has been of benefit to you. I know I
could have used something like this when I started out! Donations will be
gladly accepted (College students are always broke!) but are not expected.
In any case, please send suggestions, corrections, complaints, and the like
to:
Out To Lunch Software
c/o Dave Larsen
101 E. 14th ave. Suite S
Columbus, OH 43201-1855
Permission to reprint this text, in part or in whole, is freely given for
non-commercial uses only as long as proper credit is given to the author.
Any other uses of this text are strictly forbidden without the expressed
written consent of the author.
- eof -uthor.
Any other uses of this text are strictly forbidden without the expressed
written consent of