You are here

RF protocol version 1

General

Since NRF24 protocol does not resolve packet collision, we won’t implement that ourselves, but will implement a pulling mechanism of transmission. Thus, we do not have a requirement that all the devices have to hear each other. We do not use NRF ACK mechanism.

We use nrf24l01 buffers only. Send packages instantly on receive via uart. Received packages are being stored in the internal buffer (up to 8) and shall be read by a command.

Every client device has to have a unique MAC address. MAC address is being assigned to a device during installation sequence.

Internal structure

Every device consists of a number of units. Every unit represents one isolated functional, like one sensor, one actuator, etc. Units always number from 0 consecutively without any gaps. Units contain readable-writable nodes and functions to read or write data.

Unit 0 always corresponds to the controller itself and contains slave info and rf control functions.

Obtaining MAC address at installation process

Device enters installation mode on button press. At this point it constantly sends (every 500ms) device info packet to its address (from eeprom) — todo: determine single address. In this state it still replies to all the commands. After that, the concentrator decides which address should be given to it and sends the package “change MAC address”, “change RF channel” and finally “change mode to normal slave”.

Constants

  • Modem address: 00:00:00:00:01 A5:42:42:42:XX

  • Broadcast address for endpoint devices: 00:00:00:00:00

 

RF package structure

Every unit should have predefined by a protocol nodes enlisted in a table below. Node numbers 0 .. 0x0F and function numbers 0x80 .. 0x8F are standard and required.

Custom device nodes to control the hardware should start from 0x10. Custom device functions to control the hardware should start from 0x90.

Data abstractions

Every data abstraction has 1-byte id from a common mapping namespace (unique per unit). If MSB of id is 0, then it is node, if it is 1, then it is a method.

  1. Method — the most primitive data abstraction. Input and output data types may be different.
    1. Input data type
    2. Output data type
  2. Node — it is basically two methods in one entity, one for read, one for write. Read method should not have any side effects and can not be the trigger for any action. Write might be the trigger for an action.
    In the package, if there is no payload to the function given, it means it is node read, node write otherwise. Therefore node can not have no data type (0xF)
    1. Data type
    2. Access permissions

Package format

Request

1{transaction id}{unit id}{function id}{data}

  • 1 is protocol version

  • Transaction id, 1 byte, for synchronization between messages of server and client. Slave does not keep track of it.

  • Unit id, 1 byte, id of unit behind that transceiver, basically enhansion of the address

  • Function id, 1 byte, data abstraction id, see the table below

  • Data, up to 28 bytes payload, arguments to a function. Functions with variable length of the data will specify the format of that length.

A slave unit shall send a response to a master for every request. If a request can not be parsed, the slave shall send an error response to the master. List of error responses is below.

Response

2{transaction id}{code}{response data}

  • 2 is response protocol version (only to distinguish from the request)
  • Transaction id should be equal to transaction id of the request regardless of whether it is valid or not.

  • Response code, see table Slave error responses below

  • Response data is for code 0 (up to 29 bytes)

For the advertisement packet it is a response to a function GetProperties of unit 0 with transaction id 0xAA.

Function table

Code

Description
_______________

Access

Data format _________________________________

Error codes
_____________

Comment
_____________________

Unit 0 custom functions

0x10

Session key

W

Request:

{cipher type}{key}

Length is total length of the data

Cipher type is 1 byte (TODO)

Key is 16 bytes long array (AES-128) or 24 bytes long (AES-192)

 

Should be encrypted by current session key unless it is “setup” mode, which is being activated only once during install process

0x12

MAC address

W

Request:

{address}

Address is 5 bytes long array

0x00 ok

0x01 bad address length

 

0x16

RF channel

W

Request:

{RF channel} 0 --- 127

0x00 ok

0x80 bad channel

Applied only after the response

0x13

Device statistics

R

Response:

All fields are uint16_t, LSB first (little-endian)

{requests}{responses}{errors} {transaction errors}{ack t/o}{validation errors}

Requests --- total requests received

Responses --- all responses with return code less that 0x80

Errors --- total responses with return code > 0x80

Transaction errors --- separate counter of transaction errors

Ack t/o --- count of responses with timeouted ack from master

Validation errors --- any other packet validation errors

 

Master should regularly check on statistics of all slave units to be aware of any troubles with sending packets. There are: lost response packets (without ack), sent packets (with ack), received packets, other error counters

0x90

NOP

   

0x00

Returns code OK, nothing else

0x91

Reset transaction ID

       

0x17

Slave mode

W

Request:

1 --- advertisement mode

2 --- normal slave mode

Response:

none

 

In advertisement mode slave constantly sends adv packet (every 500ms), but still replies to all the commands

Standard unit-related functions, for all units

0

Get number of units and serial number (for unit 0)

Get list of unit functions (for other units)

R

Request:

(only for units 1+)

0 --- get unit mapping id and unit functions list pages count

other --- get unit functions list page+1

Response:

Unit 0:
{number of units} uint8_t
{fw version (date)}

Unit 1+, page 0:
{pages count} uint8_t
{unit mapping id} z-string up to 28 bytes

Unit 1+, pages 1+, per function:
{function number} uint8_t

for node:
RW00DDDD
RW is access permissions (two bits)
D is data type (four bits)
0 is reserved (two bits)

for method:
{input data type} uint8_t high tetrade
{output data type} uint8_t low tetrade

0x00 ok

0xA0 bad unit id

0xE2 wrong page number

No limit for functions number per unit

Unit mapping id is unique for every mapping. Units with identical mapping id should have identical functions list.

2

Text description

RW

Response:

{utf8 text}

0x00 ok

0x08 bad unit id

 User description of the unit.

Slave error responses

There are two kinds of status codes: critical error, when the message was not passed to a given function, and when the function was run. First group error codes have MSB set. Second group errors depend on the function called.

Name

Code (hex)

Description

Response data

None

0

No error, normal response

 

BadVersion

0x90

Incorrect package version field

 

BadUnitId

0xA0

No such unit

 

NotConsecutiveTransactionId

0xB0

Probably, some packets from master was not received

Current transaction id, next valid should be one above

SameTransactionId

31

Probably ACK to master was lost

 

BadFunctionId

0xC0

There is no such a function in a given unit

 

ResponseTooBig

0xD0

Requested data can not fit into packet

 

BadRequestData

0xE0

General request data parsing error

For example if packet length is too short

NodePermissionViolation

0xE1

Reading unreadable or writing unwritable

 

BadArguments

0xE2

Argument validation failed, i.e. incorrect argument length

 

Function not implemented

0x7F

Requested function id is legal, but not implemented

 
 Internal error 0xFF Some bug happened  

Data types of function input/output

 

Data type

Code

Length

none

0

0

bool

1

1

byte

2

1

int32

3

4

string

4

 

byte array

5

 

unspecified

0xF

 

 

RF model

Has 3 modes, idle by default:

  1. rmIdle — do nothing, just put received packets (data and ack) into a buffer, also ack timeout is possible as it is a hardware feature.

  2. rmSlave — always in a listen mode, process received packets using RF protocol module and responses back.

  3. rmMaster — utilizes timeout feature. For every sent packet it listens to the same address and expects the response in a specified period of time, otherwise it puts eptResponseTimeout packet into a buffer. It should stop listening to the timeouted address.

 

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <b> <i> <s> <u> <em> <strong> <sub> <sup> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
3 - 3 =
Solve this simple math problem and enter the result. "-" means plus. E.g. for 1-3, enter 4.