diff docs/protocol.txt @ 0:bef2801ac83e

Initial checkin with reference implementation of core protocol Initial checkin. Has the initial version of the protocol documentation along with a reference implementation of the core protocol.
author William Astle <lost@l-w.ca>
date Sun, 08 May 2016 12:56:39 -0600
parents
children 422f5e8fff85
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/protocol.txt	Sun May 08 12:56:39 2016 -0600
@@ -0,0 +1,423 @@
+DRAFT 2014-12-24
+
+Introduction
+============
+
+The LWWire protocol is based on the Drivewire protocol originally created by
+Boisy Pitre and later expanded by others including Aaron Wolfe.  The
+original Drivewire protocol was very simple.  It has since acquired quite a
+few bits and bobs that have unfortunate semantics.  Further, Over the years,
+Drivewire has accumulated quite a few features which it is not possible for
+the client to reliably detect support for.  In addition, the protocol seems
+to be ever expanding and accumulating features of limited utility.
+
+The goal of LWWire is to provide a stable core protocol that returns to the
+roots of Drivewire 3. The core protocol will support extension negotiation
+which allows the client to request specific additional features. This
+negotiation must occur before the features can be used.
+
+A secondary goal is for a basic Drivewire client to be able to perform block
+I/O on virtual drives even if it does not support the advanced negotiation.
+
+The Protocol
+============
+
+Throughout the protocol discussion, the term client will refer to the device
+being served, usually a Coco an emulator of some sort. The term server will
+refer to the software running on a PC or other similar device that answers
+requests from the client.
+
+The LWWire protocol is a master-slave protocol with the client serving the
+role of the master. This seems like a reversal but it is necessary because
+the client will usually be the device with limited resources which cannot
+reliably respond to a byte appearing on the communication channel. Thus, all
+transactions are initiated by the client.
+
+All values greater than a single octet are represented in network byte
+order, which is otherwise known as big endian. The protocol is octet based.
+
+The first octet of any request is an operation code. This operation code
+completely defines the request. Further data may follow the operation code,
+depending on the specifc operation. Some operations may require further
+round trips as well.
+
+There are two possible types of response from the server. The first is a
+standard fixed length response which is defined by the particular operation. 
+However, an operation may further define that it returns a variable length
+packet.  Such a packet is prefixed by a 16 bit length followed by the actual
+data.  Where such a packet is described, the header is not included in the
+description.  The variable length return values should be avoided except
+when there is a true benefit to using them.  Such a use might be passing
+along an IP packet, for instance.
+
+When a client comes online, it must send a "DWINIT" operation. The
+driver version/identifier value is not specified by the protocol and must
+not change the behaviour of the server. The server will then respond with
+its version number. If that number is anything other 0x80, the client must
+assume the server is NOT LWWire. If it receives no response, it may continue
+with the notion that it might be a Drivewire 3 server.
+
+If the client does receive an indicator that it is talking to LWWire, and it
+wishes to use anything other than requests in the Base protocol (anyting in
+the "Base Protocol" section below), it MUST initiate a feature negotiation
+request and it MUST NOT initiate any usage of the requested feature unless
+it receives an ACK response from the server.
+
+If the delay between subsequent bytes in a request is greater 10
+milliseconds, the server MUST assume the transaction has failed and treat
+it as an unknown transaction. The client MUST implement a similar timeout
+to prevent entering into an infinite loop waiting for octets that may never
+come. The timeout on the client must be no longer than 1000 milliseconds and
+should be no shorter than 10 milliseconds. These timeouts MUST be applied to
+ALL octets that are part of the communication stream.
+
+Notwithstanding the above, some operations may specify a longer timeout
+which must be respected by that operation.
+
+If the server receives an unknown request OR it detects a timeout receiving
+a request, it MUST abort any ongoing request. It MUST then remain silent for
+at least 1100 milliseconds to force a timeout on the client. The server MAY
+choose to change it's port speed parameters if it detects that the request
+may be valid but there is a transmission speed mismatch. This behaviour MUST
+NOT be relied upon by the client.
+
+
+Protocol Operations
+===================
+
+Each operation is formatted with a header indicating the operation code in
+hexadecimal following by it's name.  Below that is the specification of the
+actual request in a table organized by offset within the request. The table
+may be absent if the request consists of nothing but the operation code.
+Below that is prose describing the operation.
+
+
+Base Protocol
+-------------
+
+The base protocol is always active. It is basically the old Drivewire 3
+protocol with no support for wirebug, which turns out to be useful mostly on
+paper rather than in real circumstances. Operations are listed in numerical
+order.
+
+00 NOOP
+
+This request is a "no-op". The server MUST ignore it and not treat it as an
+error.
+
+
+23 TIME
+
+This request instructs the server to respond with its current date and time.
+The response looks as follows:
+
+Octet	Meaning
+-----	-------
+ 0	years since 1900
+ 1	month (1-12)
+ 2	day (1-31)
+ 3	hour (0-23)
+ 4	minute (0-59)
+ 5	second (0-60)
+ 6	day of week (0-6, 0 = Sunday)
+
+This packet roughly corresponds to the return structure for the localtime()
+function in C. Note that this request is part of the original Drivewire 3
+specification. However, Drivewire 3 specifies only 0-59 for the seconds
+value. LWWire allows the value 60 for the seconds value for the rare case
+where a leap second is in effect. This is unlikely to ever be a problem in
+real deployments since leap seconds can occur at most four times per year.
+
+
+46 PRINTFLUSH
+
+This operation tells the server to flush its print buffer to its defined
+printer or analogue. If it does not support a printer or analogue, or there
+is no data to flush, this operation does nothing.
+
+
+47 GETSTAT
+
+Octet	Meaning
+-----	-------
+ 0	operation code
+ 1	drive number
+ 2	GetStat or SetStat code
+
+This operations are specified for compatibility with Drivewire. There is no
+response defined. It SHOULD be treated the same as NOOP. The server MAY
+choose to log this request but is not required to.
+
+
+49 INIT
+
+This indicates the server MUST switch to Drivewire 3 mode (if it has one)
+or, if it doesn't, switch to Base Protocol mode by disabling all extensions.
+It must also clear any statistics counters and state set by any previous
+operations.
+
+
+50 PRINT
+
+Octet	Meaning
+-----	-------
+ 0	operation code
+ 1	print data octet
+
+This request tells the server to queue the specified print data octet for
+output to a printer or some analogue supported by the server. If the server
+does not support printing, it will simply ignore this request. The server
+MAY choose to flush the print buffer to its printer or analogue at any time,
+say because it has not received additional data for some time. The precise
+mechanism to do this is not specifically defined.
+
+
+52 READ
+
+NOTE: this operation should not be used unless a buffered I/O channel of
+some kind is in use.  Because the client must read the first response byte
+and then decide whether to read 258 further bytes, it is a good idea for the
+server to introduce a short delay after the result code, say the length of a
+single octet transmission. It is strongly recommended that the READEX
+operation be used instead. This operation is supported for compatibility
+with old Drivewire implementations.
+
+Octet	Meaning
+0	operation code
+1	drive number
+2-4	LSN requested
+
+This operation requests the server to read a sector from a specified drive. 
+In the event of an error, this operation will return a nonzero error code
+(see the "Error Codes" section below).  In the event of success, the
+response will look as follows:
+
+Octet	Meaning
+0	00
+1-2	16 bit checksum (simple sum)
+3-258	sector data
+
+If the checksum of the received data does not match, the client may choose
+to retry with the REREAD operation. The server may choose to treat REREAD as
+an alias of READ or it may treat a REREAD without a previous matching READ
+as an error.
+
+
+53 SETSTAT
+
+Octet	Meaning
+-----	-------
+ 0	operation code
+ 1	drive number
+ 2	GetStat or SetStat code
+
+This operation is specified for compatibility with Drivewire. There is no
+response defined. It SHOULD be treated the same as NOOP. The server MAY
+choose to log this request but is not required to.
+
+
+54 TERM
+
+This request indicates the client is finished with the protocol. It should
+be treated the same as INIT (49). It is only specified here for
+compatibility with the old Drivewire 3 protocol. New client implementations
+should not use this operation.
+
+
+57 WRITE
+
+Octet	Meaning
+-----	-------
+0	operation code
+1	drive number
+2-4	24 bit LSN
+5-260	sector data
+261-262	16 bit checksum
+
+This operation tells the server to write the specified sector data to the
+specified LSN on the specified drive.  Before doing the write, however, the
+server will verify the checksum (simple sum of sector octets) and if it
+fails, it will not write the sector and return the appropriate error code.
+Otherwise, it will attempt the write and return an error code if
+appropriate. The error codes are listed in the "Error Codes" section below.
+
+The response to this transaction is a single octet indicating success (00)
+or failure (error code). On a checksum error, the client may choose to retry
+with the REWRITE operation. On other errors, retrying does not make sense as
+the error condition is unlikely to go away.
+
+The server may choose to treat REWRITE as an alias of WRITE. It may also
+choose to treat a REWRITE in the absence of a matching WRITE immediately
+prior as an error. The client is not obligated to use the REWRITE operation
+ever.
+
+
+5A DWINIT
+
+Octet	Meaning
+-----	-------
+ 0	5A (opcode)
+ 1	driver version
+
+The driver version above may be a value assigned by the Drivewire
+maintainer. However, LWWire does not treat any values specially.
+
+Upon receiving this operation, the server must disable any extensions and
+enter into Base Protocol mode. It must also clear any statistics counters
+and state set by any previous operations.
+
+The server will respond with the following packet:
+
+Octet	Meaning
+-----	-------
+ 0	server identifier
+
+The server identifier received will be 0x80 if the server supports the
+LWWire protocol. If it is anything other than 0x80, the client MUST assume
+that the server is NOT LWWire and take whatever action it deems appropriate,
+which may include falling back to Drivewire mode.
+
+
+72 REREAD
+
+See 52 READ.
+
+
+77 REWRITE
+
+See 57 WRITE.
+
+
+D2 READEX
+
+Octet	Meaning
+-----	-------
+ 0	operation code
+ 1	drive number
+ 2-4	24 bit LSN
+
+The READEX  operation requests the server to read the logical sector
+specified by the LSN from the specified drive.  The server will respond with
+256 bytes of data.  In the event that an error occured, it will respond with
+256 NUL bytes.  Otherwise, it will respond with the actual sector data.
+
+The client will calculate a 16 bit checksum which is a simple sum of all
+bytes received.  It will then send that checksum to the server. The server
+must permit a longer timeout waiting for the checksum than is otherwise
+expected to give the remote side long enough to actually calculate the
+checksum. It is recommended that the timeout here be at least 50ms.
+
+Upon receipt of the checksum, the server will verify that it is correct. If
+there was an error reading the sector OR the checksum does not match, the
+server will return one of the error codes in the "Error Codes" section
+below. Otherwise it will return a NUL byte.
+
+In the event of a checksum error, the client may retry the read. Other
+errors are unlikely to go away on a retry so retrying in those cases is not
+recommended.
+
+The REREADEX request follows an identical flow. The server MAY choose to
+treat a REREADEX operation without an immediately preceding READEX operation
+as an error. It may choose to avoid re-reading the sector data from the
+backing store on the server if it has already read the same LSN for a
+previous READEX operation. However, it is also acceptable to simply treat
+this as an alias for READEX.
+
+
+F0 REQUESTEXTENSION
+
+Octet	Meaning
+0	operation code
+1	extension code (8 bits)
+
+This request is used to request a specific extension, as specified by the
+extension code. The server will respond with an ACK response (0x42) or a NAK
+response (0x55). Any other response must be considered an error and the
+client MUST re-initialize its driver and perform the DWINIT handshake again.
+That includes in the case of a timeout.
+
+A NAK means the server does not support the requested extension OR it is
+unwilling to make it available for whatever reason.
+
+An ACK means the server has enabled the requested extension for this
+particular client.
+
+See the section "Extension Codes" for a list of extension codes.
+
+
+F1 DISABLEEXTENSION
+
+Octet	Meaning
+0	operation code
+1	extension code
+
+This request is used to request that the server discontinue usage of a
+specific extension.  The server will respond with an ACK (0x42) if it is
+able to discontinue the extension. This is the normal response. Some
+extensions may not be disablable (which will be specified in the extension
+specification). In this case, the server will respond with a NAK (0x55). In
+the event of a NAK, the client may choose to continue with the extension
+enabled. It may also choose to treat that as an error condition and
+re-initiate the DWINIT handshake which will forcibly disable all extensions.
+
+Requesting to disable an extension that is not enabled is not considered
+an error since it doesn't require changing the state of anything. In that
+case, the ACK response is correct.
+
+See the section "Extension Codes" for a list of extension codes.
+
+
+F2 REREADEX
+
+See D2 READEX.
+
+
+F3 EXTENSIONOP
+
+This request indicates that the request is associated with a specific
+extension. The second octet is the extension number. Everything after that
+is defined entirely by the specified extension. If the specified extension
+is not enabled, this request MUST be treated as an unknown request. The
+server MUST NOT send a response to any request for any extension that is not
+currently active.
+
+This mechanism is provided so that extensions can provide their own
+operations without having to select operation codes from the global pool.
+Codes can only be assigned in the global pool by the LWWire maintainer.
+Codes used inside this request structure can be arbitrarily defined by the
+extension without any coordination.
+
+
+F8 RESET3
+FE RESET1
+FF RESET2
+
+Either one of these operations should be treated as though the client has
+gone away or restarted. These MUST be treated exactly like the INIT (49)
+operation.
+
+
+Error Codes
+===========
+
+Code	Meaning
+----	-------
+00	No error, checksum OK
+F3	checksum error
+F4	read error (out of bounds, underlying I/O error)
+F5	write error
+F6	not ready (invalid drive, etc)
+
+
+Extension Codes
+===============
+
+Any code not otherwise listed below is reserved. If you wish to have an
+official extension code assigned, contact the maintainer of LWWire to
+request one. If you are working on something that does not need general
+distribution, or which is only experimental, consider using the private
+range listed below.
+
+00	VPORT
+E0-EF	reserved for future extension code expansion
+F0-FF	reserved for private extensions and will never be assigned