Having listed our requirements in the precedent post, designing our protocol has been just an issue of applying logics and dimensioning frame fields. At this stage, we should still decide some of the technical aspects around the protocol such as data rates, maximum hop count allowed and data encryptions. However, the rest is quite clear so far.
First of all, our SWAP frames had to fit into the original CC11XX packet structure in order to take advantage of the full list of features provided by the TI IC's. The following picture shows the SWAP frame format compared with the original CC11XX frame:
Figure 1: SWAP packet structure
The above packet structure will be constant, regardless of the type of message (function), optimizing the frame parser significantly. In fact, the retained frame structure has been specially designed to simplify the protocol stack and reduce the amount of lines of code. Device addresses are 1-byte fields, taking advantage of the automatic address filter provided by the CC1101 chip. Thus, the microcontroller has not to worry about checking and discarding messages addressed to other devices. 0 is the broadcast address, as marked by the CC1101 data sheet.
Regarding the sub-addressing, that is the way device resources are addressed, SWAP is endpoint oriented, each endpoint being identified by a unique ID within the wireless node. Every parameter in a node may become an endpoint, including configuration parameters so that they may be addressed and controlled in the same way other regular endpoints (ADC inputs, binary outputs, etc) are treated. Again, this policy provides an extra degree of simplicity to the protocol since no special configuration function has to be created. Besides, this makes the protocol extremely flexible and powerful as new features may be added in the future without having to change the frame format or the protocol itself.
Every SWAP frame will contain the following fields:
- Preamble (preamble, 4 bytes): It's a typical 10101010... preamble sent to mark the beginning of the wireless frame.
- Network Identifier (network id, 2+2 bytes): Each wireless network is identified by its own 2-byte id. Since this identifier sits on the CC1101 synchronization field, the network id is duplicated in order to provide better consistency to the packet.
- Data Length (len, 1 byte): Length of the CC1101 data field. This length is later used to calculate the actual length of the endpoint value.
- Destination Address (dest addr, 1 byte): address of the targeted device. Broadcast address = 0.
- Source Address (src addr, 1 byte): Address of the transmitter.
- Repeater hop (hop, 4 bits): Amount of times that each message is repeated. Original value = 0.
- Security option (secu, 4 bits): Encryption method used. Default value = 0 (no encryption).
- Cyclic nonce (nonce, 1 byte): Value incremented on each device each time an information message is sent. This mechanism acts as a protection against playback attacks. Default value = 0.
- Function code (function, 1 byte):
Function = 1: Query packet. IT requests information (endpoint value) on the destination device. Once received by the destination node, it has to broadcast an information packet about the endpoint being queried. Query packets are the only exception to the above frame format, not transporting any data field
Function = 2: Command packet. Commands are sent to change endpoint values on the receiver. In order to minimize transmission explosions and avoid packet collisions, we should broadcast commands and queries only in case of punctual necessity.
- Endpoint Address (ep addr, 1 byte): Address of the device containing the endpoint being queried or controlled. This address has not necessarily to be the same than the destination address since SWAP allows querying a device (data recorder or central controller) about and endpoint contained in a third wireless node. This feature should be specially useful to get values from any battery-operated device, typically sleeping during long periods of time.
- Endpoint Identifier (ep id, 1 byte): Each endpoint is identified by its own 1-byte ID. This ID will be later used to index the endpoint in a global table by the protocol stack.
- Endpoint value (endpoint value, n bytes): This is a variable length field. Each endpoint will have a its own length, depending on the nature of its value. This length may be calculated following a basic formula:
SWAP is contents-agnostic. This means that SWAP frames do not contain any information about the type of endpoint value being transported. As result, the receiver has to know how to decode the received value by its own means. This philosophy has its own pros and cons but, in general, abstract protocols are easier to maintain and provide extra flexibility. The reduced plug&playability is maybe the main drawback of such protocols.
- Cyclic Redundancy Check (crc, 2 bytes): 16-bit CRC automatically added by the CC1101 chip.
In summary, this protocol should give us a good result in terms of compactness, flexibility and speed. In a future post I'll try to document my first impressions regarding the size of the protocol stack, performance and integration with real applications.