2017-03-23 10:05:31 +11:00
|
|
|
The IoT Protocol
|
|
|
|
- 20kdc, 2017
|
|
|
|
|
|
|
|
One of the core uses of Copper is network-connected small devices.
|
|
|
|
These have a set list of requirements:
|
|
|
|
1. The device itself can't be forced to do much in the way of work,
|
|
|
|
at least for simple cases.
|
|
|
|
2. The protocol needs to be relatively flexible.
|
|
|
|
|
2017-03-24 03:38:38 +11:00
|
|
|
The protocol is written here as 3 parts.
|
|
|
|
|
|
|
|
"The device" refers to the server / controllable object.
|
|
|
|
"The client" refers to the client.
|
|
|
|
|
|
|
|
Another thing to note is that due to the "cannot do much work" requirement,
|
|
|
|
only one device per hostname is supported via this protocol.
|
2017-03-23 10:05:31 +11:00
|
|
|
|
|
|
|
Part 1. General Mainport Packet Description
|
|
|
|
|
|
|
|
The "Main port" is port 4.
|
|
|
|
This port is the port via which most data exchange happens.
|
|
|
|
|
|
|
|
First things first - in case of error, do nothing at all.
|
|
|
|
If it's possible to just ignore a protocol violation, do so.
|
|
|
|
For example, a get request with data should be treated as a get request without it.
|
|
|
|
|
2017-03-24 03:38:38 +11:00
|
|
|
Secondly, it is allowed for the device to present different 'faces' depending on which client is accessing it.
|
|
|
|
However, all 'faces' must have the same descriptor (variable 0).
|
|
|
|
This is useful for devices which have some state, like a concurrent storage server
|
|
|
|
(allowing the download of different 1499-byte 'parts'),
|
|
|
|
but still keeping enough consistency for the device to be uniquely identifiable.
|
|
|
|
|
2017-03-23 10:05:31 +11:00
|
|
|
In all packets on the main port,
|
|
|
|
the first byte's upper 2 bits indicate what kind of packet this is -
|
|
|
|
the lower 6 bits is the 'variable number'.
|
|
|
|
The remainder of the packet is the parameter data.
|
|
|
|
|
2017-03-24 03:38:38 +11:00
|
|
|
00: Request: Get. This has no further data.
|
|
|
|
This must only be sent by the client to the device.
|
|
|
|
If valid, the device responds with the standard reliability-layer acknowledgement,
|
|
|
|
and a Response: Get packet to the client.
|
|
|
|
If invalid, the device only responds with acknowledgement.
|
|
|
|
|
|
|
|
01: Request: Set. The data is the new variable contents.
|
|
|
|
This must only be sent by the client to the device.
|
|
|
|
The device only responds with the standard reliability-layer acknowledgement.
|
|
|
|
Success is determined by checking acknowledgement, then performing a Get.
|
|
|
|
|
|
|
|
10: Perform Action. The data is the parameter.
|
|
|
|
This must only be sent by the client to the device.
|
|
|
|
The device only responds with the standard reliability-layer acknowledgement.
|
|
|
|
|
|
|
|
11: Response: Get. The data is the variable contents.
|
|
|
|
This must only be sent by the device to the client.
|
|
|
|
The client only responds with the standard reliability-layer acknowledgement.
|
2017-03-23 10:05:31 +11:00
|
|
|
|
|
|
|
Part 2. Variable Types
|
|
|
|
|
|
|
|
Variable types indicate to the program what values are expected in variables.
|
|
|
|
Firstly, the upper bit being set indicates an Action - only the lower bits actually give the variable type-code.
|
|
|
|
Secondly, if it's not an Action, the second-to-upper bit indicates if it can be set.
|
|
|
|
|
|
|
|
They are, as follows:
|
|
|
|
|
|
|
|
0: Void (Only useful for Actions. Think 'ignore anything out of here'.
|
|
|
|
1: Human-Readable String (Generic string that a user could feasibly type. No special characters.)
|
2017-03-25 21:58:44 +11:00
|
|
|
2: Boolean ("false" means false, "true" means true, anything else is disallowed.)
|
2017-03-23 10:05:31 +11:00
|
|
|
3: Float (See Human-Readable String, but translated to a number by the device.)
|
|
|
|
4: Descriptor (See Part 3.)
|
|
|
|
|
|
|
|
Part 3. Discovery & Description
|
|
|
|
|
2017-03-23 12:10:09 +11:00
|
|
|
Upon the receipt of any packet on port 1 that is addressed to "*" or the IoT device name,
|
2017-03-23 10:05:31 +11:00
|
|
|
it should send a packet back on port 4 formatted as a Get response packet for variable 0.
|
|
|
|
|
|
|
|
Variable 0 is always the Descriptor, which describes the variables and actions available.
|
|
|
|
|
|
|
|
The Descriptor is simply a list of variable types and 7-byte variable names,
|
|
|
|
starting from variable index 1 (as 0 is always the descriptor)
|
|
|
|
It's recommended the variable names are in camel-case.
|
|
|
|
|
|
|
|
Example descriptor for a networked lightbulb:
|
|
|
|
|
|
|
|
"\x42lActive"
|
|
|
|
|
|
|
|
Example descriptor for a networked turtle (Lua-escaped):
|
|
|
|
|
|
|
|
"\x80turnLft\x80turnRgt\x80forward\x80backwrd\x02fwd!air"
|