WSN-tools serial protocol update proposal

68 views
Skip to first unread message

David Hauweele

unread,
Dec 8, 2013, 7:28:20 PM12/8/13
to wsn-...@googlegroups.com
WSN-tools serial protocol update proposal
=========================================
B. Quoitin (bruno....@umons.ac.be)
based on discussions with D. Hauweele (da...@hauweele.net).

1. Motivation
-------------

The current serial protocol does not allow reliable synchronization between client (host PC) and device. Device firmware sends a special "ready" byte (0xFF) when it starts. Client software waits until this byte is received before starting its operations. The following two scenarios can happen. If device was started before client, client might miss the ready byte. If ready byte appears in another message sent by firmware, client could incorrectly believe that synchronization has been achieved.

In addition, the current protocol does not provide any protection against byte corruption or losses. Losses can typically occur on slow devices where the serial input buffer is tiny (a few bytes) and where no hardware serial flow control is available.


2. Overview of new protocol
---------------------------

In order to improve the ability of the client and firmware to synchronize, the serial protocol will rely on byte-stuffing to delimit serial frames. Byte stuffing works as follows. A special start-of-frame (SFX) byte marks the beginning of each frame. As a consequence, a frame cannot contain SFX bytes. Therefore, if a frame must carry an SFX byte it is escaped by a special (ESC) byte as follows : instead of sending SFX as part of the frame content, the sequence ESC (modified SFX) is sent ; instead of sending ESC as part of the frame content, the sequence ESC (modified ESC) is sent.

Using byte-stuffing, a receiver (either the client or the firmware) that has lost synchronization can ignore any received byte until a new frame (an SFX byte) is received.

To determine the end of a frame, two different approaches can be used. The first one consists in using another special byte to mark the end of a frame. The second approach consists in explicitly sending the frame length as part of the frame header. The later approach is assumed in this version of the protocol.

The serial protocol needs to carry messages in both directions. The following message types are required:
(A) Client -> firmware
(A.1) to set or get configuration parameters (e.g. set the RF channel).
(A.2) to request special actions from the firmware (e.g. send a frame).
(B) Firmware -> client
(B.1) answer related to received request (e.g. if client requested RF channel)
(B.2) acknowledgment of a received request (e.g. to acknowledge reception of a request to set RF channel)
(B.3) unsolicited messages, not related to a request (e.g. forward a received 802.15.4 frame)


3. Frame format
---------------

The protocol uses a single frame format.

Payload length : 8 bits (max. value = 255)
Type : 1 bit
Ack_unsolicited : 1 bit
Code : 6 bits
Payload : variable (max. length = 255)
Checksum : 8 bits

where:

* Payload length : number of bytes in payload. The frame length in bytes before byte-stuffing is equal to the value of this field + 3 (header and trailer).

* Type : 0 if the message is a request, 1 if the message is a response

* Ack_unsolicited : this field has different meanings if the message is a request or a response (see Type field). If the message is a request, this field controls if an acknowledgment is requested (field = 1). If the message is a response, this field indicates that it is un unsolicited response.

* Code : identifier of the message type (see section 4 below)

* Payload : content of message. Format depends on message type (see Code).

* Checksum : is the sum modulo 256 of all message bytes including the header. The checksum is computed before byte-stuffing is applied, thus excluding SFX and ESC bytes and any modified byte.





4. List of message types
------------------------

4.1. Requests / responses
-------------------------

Requests and responses have the same message Code. Requests have the Type field equal to 0. Responses have the Type field equal to 1. For requests, the Ack_unsolicited field can be equal to 0 or 1. For responses, the Ack_unsolicited field MUST be equal to 0.

SEND_FRAME
Code : 0
Description : request firmware to transmit a 802.15.frame
Payload : 802.15.4 frame
Response : none (see 4.2 TX_STATUS)

GET_VERSION
Type : 1
Description : request firmware to send its version
Payload : none
Response : major version (1 byte), minor version (1 byte)

GET_FIRMWARE_INFO
Type : 2
Description : request firmware information (informal version, authors, licence, ...)
Payload : none
Response : none (see 4.2 VERSION_INFO)

ENABLE_TRANSCEIVER
Type : 3
Description : request firmware to enable/power on RF transceiver
Payload : flags (1 byte)
bit 0 : 1 means ON, 0 means OFF
Response : none

ENABLE_PROMISCUOUS
Type : 3
Description : put transceiver into promiscuous mode
Payload : flags (1 byte)
bit 0 : 1 means promiscuous, 0 means not promiscuous
bit 1 : 1 means allow reception of frames with bad CRC
Response : none

SET_PARAMETER
Type : 4
Description : set value of firmware parameter
Payload : parameter code (1 byte), parameter length (1 byte), parameter value (variable)
Response : none

GET_PARAMETER
Type : 5
Description : get value of firmware parameter
Payload : parameter code (1 byte)
Response : parameter code (1 byte), parameter length (1 byte), parameter value (variable)


4.2 Unsolicited messages
------------------------

Unsolicited responses have the Type field equal to 1 and the Ack_unsolicited field equal to 1.

FRAME_RECEIVED
Type : 6
Description : frame received by firmware
Content : frame length (1 byte), flags (1 byte), 802.15.4 frame (up to 127 bytes), [RSSI (1 byte)], [LQI (1 byte)], [CRC 2 bytes]
flags.bit 0 : 1 RSSI available, 0 otherwise
flags.bit 1 : 1 LQI available, 0 otherwise
flags.bit 2 : 1 FCS available, 0 otherwise
Note : total payload length = frame_length + 1 + (flags.bit0?1:0)
+ (flags.bit1?1:0)
+ (flags.bit2?2:0)

VERSION_INFO
Type : 7
Description : response to GET_FIRMWARE_INFO
Content : length (1 byte), characters (variable)

TX_STATUS
Type : 8
Description : TX status related to previous SEND_FRAME request
Content : flags (1 byte), [number of retransmissions (1 byte)]
flags.bit 0 : 1 if CCA failed, 0 otherwise
flags.bit 1 : 1 if no ACK was received, 0 otherwise
flags.bit 4 : 1 if number of retransmissions available, 0 otherwise


5. List of parameters
---------------------

PARAM_RF_CHANNEL
Code : 0
Format : 1 byte

PARAM_SHORT_ADDRESS
Code : 1
Format : 2 bytes
byte 0 : LSB of address
byte 1 : MSB of address

PARAM_LONG_ADDRESS
Code : 2
Format : 8 bytes
byte 0 : LSB of address
...
byte 7 : MSB of address

PARAM_PAN_ID
Code : 3
Format : 2 bytes
byte 0 : LSB of PAN ID
byte 1 : MSB of PAN ID

PARAM_AUTO_ACK
Code : 4
Length : 1
Format : 1 byte
bit 0 : 1 auto-ACK ON, 0 auto-ACK disabled

PARAM_PA_GAIN
Code : 5
To be defined
(could be positive->gain or negative->attenuation
need to survey what is available in different transceivers ?)

PARAM_LNA_GAIN
Code : 6
To be defined
(see remark for PARAM_PA_GAIN)


6. Example session
------------------

A toy example session just to illustrate what I have in mind. The following message exchanges only show the message Code and payload bytes.


Firmware Client
| |
| --[ GET_VERSION ]--> |
| <--[ GET_VERSION,2,0 ]-- |
| --[ SET_PARAMETER,0,26 ]--> | /* set PARAM_RF_CHANNEL = 26 */
| <--[ SET_PARAMETER ]-- |
| --[ SET_PARAMETER,1,0xCD,0xAB ]--> | /* set PARAM_SHORT_ADDRESS
| <--[ SET_PARAMETER ]-- | = 0xABCD */
| |
... ... /* set other parameters
| | such as long address,
| | pan id, ... */
| |
| --[ ENABLE_TRANSCEIVER,1 ]--> |
| <--[ ENABLE_TRANSCEIVER ]-- |
| --[ SEND_FRAME,<frame>,ack=0 ]--> |
| |
... ...
| <--[ TX_STATUS ]-- |
... ...
| --[ ENABLE_PROMISCUOUS,1 ]--> |
| <--[ ENABLE_PROMISCUOUS ]-- |
| |
| <--[ FRAME_RECEIVED,<frame> ]-- |
| |
... ...
| |
| <--[ FRAME_RECEIVED,<frame> ]-- |
| |

...

7. Open questions
-----------------

* Shall we provide a means to relate a request to its response ? The most basic scheme would be to consider that a response corresponds to the previous request with same code. This is the approach considered in this document. Another more complex scheme would be to embed an ID into each request. A response would then carry the same ID as the request it is related to. This second scheme could be useful in case the response to a request is lost and the same request is issued again. It might be necessary to disambiguate to which request a response is related...

* It might be useful to merge the Type and Ack_unsolicited fields described in section 3 as follows. Use a single 2-bits Type field. The values of this field would then have the following meanings

00 : Request without ACK
10 : Request with ACK
01 : Response
11 : Unsolicited message

* Using a length field to determine the end of a frame has the following drawback. The length field cannot be protected by the checksum, as the length field is required to find the checksum. One possibility would be to store the message checksum in the header rather than the trailer. The checksum would then be at a fixed offset from the beginning of the frame. There is no reason to put the checksum in the trailer (this was just to copy some link-layer frame formats where the CRC is in the trailer to allow its computation during frame transmission).







Reply all
Reply to author
Forward
0 new messages