Like, how will the project look like? Which features will be implemented? How should the packet look like?
A lot of packet processing is done by nRF24L01+ (like address processing, CRC, ACK….) But some things still should be done. So:
nRFF project
The idea of this project is to combine some ideas and create a lightweight secure mesh (or, dynamic-tree) network, with an MQTT-like interface.
Targets:
- Security (with modern SDR, packets without any protection can be easily decoded)
- nonce to prevent replay attack
- XXTEA block coding – lightweight and secure for short packets
- Message-based (like MQTT)
- eliminated the need of knowing the exact module address & co
- network can be easily extended with new modules
- 12 bit message id (+4 bit for message counter)
- Mesh network (more preicesily: dynamic-tree)
- dynamically configurable network
- one server, for managing network and message distributions
- static addresses for fixed devices for manual network configuration
- dynamic addresses for flexible network configurations, which can be stored for faster connection
- dynamic addresses for moving devices, which are never stored
- dynamically configurable network
Limitations
- 24 bytes pro message. Can be solved by multi-packet transmision
- 12 bit message ID
Packet structure
typedef struct {
uint8_t version; // protocol version
uint8_t dir_size; // DONW | SERVICE | MULTIPACKET | DATA_SIZE[5]
uint16_t msg_cnt_id; // COUNTER[4] | MESSAGE_ID[12]
uint32_t nonce; // 32 bits
uint8_t data[24]; // 24 bytes max in one packet (total packet size 32 bytes)
} NRFF_PACKET;
And this packet will be coded with XXTEA algorithm. Don’t know what to do with the length, but I want to use the dynamic length feature. (just to save some radio-on time, and instead of 8 words send only 3, if needed).
So, my plan is to test and try:
- dynamic payload feature
- XXTEA coding
- Message-based packets
- Automatic mesh network configuration
Network config
Each device should have its own ID (=MAC), 1 byte should be enough. (e.g. 1-255). If it has no static address, it searches next available host. After this, it receives an address.
Addressing
The root device address is 0. Devices connected to root become addresses 1~6. Next in the chain, e.g. connected to 1 will become 0o11, 0o21… and so on. Because of max. device count for one module is 5 (one connection goes to the host), it is practical to use the octal system.
Let see one example:
0: (0)
├── 1: 1
│ ├── 11: 4
│ │ ├── 111: 8
│ │ └── 211: 9
│ │ └── 1211: 10
│ │ └── 11211: 11 # here is 11211 is address, 11 is ID
│ ├── 21: 5
│ ├── 31: 6
│ └── 41: 7
├── 2: 2
├── 3: 3
└── 5: 33
Yeah, I’ve made python script to convert to the tree view (above) something like this (pairs address:ID):
{0o1:1, 0o2:2, 0o3:3, 0o11:4, 0o21:5, 0o31:6, 0o41:7, 0o111:8, 0o211:9, 0o1211:10, 0o11211:11, 0o5:33}
I think this is really nice visualization, which should help me with testing and designing the network.