Mercurial > hg > index.cgi
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