Enrollment Module (ID 5)
Purpose
The EnrollmentModule has ModuleId 5. New nodes are normally flashed without a networkId
assigned (set to 0). This means they will not connect to a mesh as long as they are not enrolled. The term enrolled is used in synonym with provisioned or commisioned.
In order to assign a node to a mesh, the user has to give a networkId
, the networkKey
and a unique nodeId
for this mesh. This can be done by a MeshGateway or a dedicated enrollment app. The enrollment packet should be sent to the broadcast address 0 and must contain to serial number of the node to be enrolled.
For enrolling devices using a smartphone app it is very common to use QR codes. Please see our specification on QR codes on how to generate QR codes that are compatible with the rest of the BlueRange Mesh / BlueRange ecosystem.
Functionality
Enrolling Over The Mesh
The EnrollmentModule supports enrollments over the mesh. A normal enrollment message is sent as a broadcast through the mesh together with the nodeKey
of the node that should be enrolled. All receiving nodes of this message try - at a certain random percentage - to scan for this node. They temporarily store the enrollment data and connect to the node once it is found and enroll it. Also, at a certain random percentage, the node sends an enrollment proposal through the mesh that contains some nearby serial numbers that the MeshGateway might like to enroll.
If the message is sent to a specific nodeId
, this node will try to scan for the other node with a 100 percent probability. This is useful if the nodes position is already known, e.g. by parsing an enrollment proposal.
Pre-Enrollment
The EnrollmentModule supports PreEnrollments. A module can register itself using SetPreEnrollmentHandler. The EnrollmentModule then calls this handler when an unenrollment or enrollment is received. The module then has a fixed time to perform an enrollment of other components, e.g. an external controller. Once it is done, it must call SaveEnrollment so that the node enrollment is processed. If this is not called within a defined time, the enrollment will fail with the result code PreEnrollmentFailed
.
Unencrypted Enrollment
If allowUnenrolledUnsecureConnections
is set in the feature set and the node is in an unenrolled state, nodes accept connections with FM_KEY_ID_ZERO
for enrollment. This allows an easier enrollment process.
Such nodes should never be used in an environment where unauthorized people have access because these people also have easy access by design. |
Preferred Network Enrollment
Preferred network enrollment is used for assets because we would like to set their network id in order for assets to send their measurement to nodes in a particular network. In case of preferred network enrollment, the asset won’t restart. In PreferredNetwork only networkId and nodekey is given.
Nearby Enrollment
It is possible to activate nearby enrollment by enabling allowUnenrolledUnsecureConnections
through the featureset. A node can then be enrolled using a MeshAccessConnection with the known ZeroKey. This can only be done if a node is unenrolled. This is useful if no QR code or other method is available to distribute the device key. The featureset has to provide some means of resetting the node to an unenrolled state, e.g. by pressing a button, resetting the power, etc,… This is necessary because the user might lose access to the Network Key and might be unable to remove the enrollment afterwards.
Unenrollment on button press
For most nodes and asset tags that have a user accessible button which is not directly wired to do a power cycle, it is possible to perform an unenrollment by pressing the button for a duration between 10 to 14 seconds. Afterwards, the leds will start flashing frantically for about 7 seconds to signal that the unenrollment is performed.
Most devices can also be powered off by pressing the button for a short time. Read more about this topic here.
Factory Reset on Enrollment
A node performs a factory reset on enrollment. This means that first the whole settings flash is erased, then the new enrollment is written, and then the node reboots to also erase the RAM. To make sure that the factory reset is as secure as possible, a special lock down mode was introduced to the flash storage. Once any module starts the factory reset, the flash storage switches to lock down, and thus no other module is allowed to send any command to the flash storage anymore until the node has rebooted. The node that performed the lock down however is still able to write to the flash. This way the enrollment module can still write the new enrollment data to the flash before executing the reboot.
Different Enrollment Scenarios
Unenrolled Node
If the defaultNetworkId
(flashed into UICR) is set to 0 and no enrollment configuration is present, the node is unenrolled and the node module is inactive. Enrollment is possible by connecting using a MeshAccessConnection with the node key and sending the enrollment data.
Node Enrolled Into A Different Network
If the node was previously enrolled into a different network, the user might not have access to this network. The node module is active and searches for other nodes in the same network. It is still possible to connect by using a MeshAccessConnection and send a different enrollment to the node.
Default Enrollment
The data stored in the UICR defines the default enrollment of a node. If a node is assigned to networkId
0 by default, it doesn’t participate in the mesh until it is enrolled. If a node is assigned another networkId
and networkKey
as a default, it tries to connect to the mesh after it is flashed. Resetting the node reverts the node back to its defaults.
Terminal Commands
Enrolling A Node
//Enroll a node
action [nodeId] enroll basic [serialNumber] [newNodeId] [newNetworkId] {newNetworkKey} {newUserBaseKey} {newOrganizationKey} {nodeKey} {timeoutSec} {enrollOnlyIfUnenrolled} {requestHandle}
//Enroll BBBBB into network 7 that already has nodes 1 and 2
//Node must be connected to terminal or connected to the node with the terminal (e.g. by using a MeshAccessConnection)
action 0 enroll basic BBBBB 3 7 78:56:34:12:78:56:34:12:78:56:34:12:78:56:34:12
//Enroll node BBBBB into network 5 over the mesh with new node id 2
//networkKey will be 11:..., userBaseKey 22:..., orgaKey: 33:...
//nodeKey is given so that enrollment over mesh can connect securely to the node
action 0 enroll basic BBBBB 2 5 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 22:22:22:22:22:22:22:22:22:22:22:22:22:22:22:22
33:33:33:33:33:33:33:33:33:33:33:33:33:33:33:33
73:63:92:12:63:94:30:44:63:67:23:11:90:11:42:52 10 0
Removing An Enrollment
Removing an enrollment from a node will reset all settings to default (factory reset). The node will return to its default network.
//Remove an enrollment
action [nodeId] enroll remove [serialNumber] {requestHandle}
//E.g. removing the enrollment of the node with serial number BCBCF
action 0 enroll remove BCBCF
Setting only the Network
If the node is an asset, it allows rapid network id changes by using this command. A connection must have been established before executing this command, no mesh access connection is automatically created.
//Set a preferred network
action [nodeId] enroll set_network [newNetworkId] {requestHandler}
//E.g. set preferred network of the node with serial number BBBBN
action 0 enroll set_network 12
Requesting specific proposals
In some situations (e.g. when the nodes are placed in a line) it can be helpful to specifically query which node sees which serial numbers before sending the enrollment. Therefore, it is possible to send the request_proposals message with several serial numbers that are then temporarily stored on the target node. The target node will respond with a proposal message as soon as it receives a broadcast message of one of the nodes to be enrolled.
//Query which node sees which serial numbers
action [nodeId] enroll request_proposals [up to 11 serial numbers]
//E.g. ask all connected nodes which of them sees any of the given serial numbers
action 0 enroll request_proposals BBBBD BBBBF BBBBG BBBBH BBBBJ BBBBK BBBBL BBBBM BBBBN BBBBP BBBBQ
//E.g. only ask for three serial numbers
action 0 enroll request_proposals BBZ3F ZZZZZ ZFGBB
The nodes then scan for one minute if they see any of the specified serial numbers. Upon arrival, the message is answered with the following JSON (1 JSON per serial number):
{
//NodeID 1 was able to scan serialNumber BBBBG
"nodeId":1,
"type":"request_proposals_response",
"serialNumber":BBBBG,
"module":5,
"requestHandle":0
}
Messages
Message Types
enum EnrollmentModuleTriggerActionMessages{
SET_ENROLLMENT_BY_SERIAL=0,
REMOVE_ENROLLMENT=1
};
enum EnrollmentModuleActionResponseMessages{
ENROLLMENT_RESPONSE=0,
REMOVE_ENROLLMENT_RESPONSE=1,
ENROLLMENT_PROPOSAL=2
};
Enroll A Beacon
Request
actionType: SET_ENROLLMENT
Bytes |
Type |
Description |
8 |
||
4 |
serialNumberIndex |
Index of the serial number to be enrolled |
2 |
newNodeId |
The new node id that should be assigned to this node (Set to 0 to leave unchanged) |
2 |
newNetworkId |
The new network id to be assigned (Set to 0 to leave unchanged) |
16 |
newNetworkKey |
The network encryption key to be used (Set to 000….000 to leave unchanged) |
16 |
newUserBaseKey |
The new user base key to derrive all user keys from (Set to 000….000 to leave unchanged) |
16 |
newOrganizationKey |
A key used for an organization, e.g. used by assets because these must work organization wide. |
16 |
nodeKey (optional) |
If the enrollment should be done over the mesh, the nodeKey must be given so that another node can connect securely to the to-be-enrolled node |
7 bit |
timeoutSec (optional) |
Enrollment over the mesh uses a timeout how long a node will try to look for the to-be-enrolled node. A good default value is 10 seconds which will result in a maximum of 14 seconds time for an enrollment. (Sending 0 will use the default value) |
1 bit |
enrollOnlyIfUnenrolled (optional) |
If set to 0, the enrollment will be done even if the other node is already enrolled. If set to 1, the node will generate an error response for the enrollment (ENROLL_RESPONSE with error code . |
Response
This acknowledges a received enrollment.
0x00 = ENROLL_RESPONSE_OK
0x01 = ENROLL_RESPONSE_FLASH_BUSY //(please retry)
0x02 = ENROLL_RESPONSE_WRONG_DATA_ALIGNMENT //(fatal error)
0x03 = ENROLL_RESPONSE_NO_SPACE //(fatal error)
0x10 = ENROLL_RESPONSE_ALREADY_ENROLLED_WITH_DIFFERENT_DATA //(can use enrollOnlyIfUnenrolled = 0 to force the enrollment)
0x11 = ENROLL_RESPONSE_PREENROLLMENT_FAILED //Another module that needs to enroll itself first, failed to enroll in the required time
actionType: ENROLLMENT_RESPONSE
Bytes |
Type |
Description |
8 |
||
4 |
serialNumberIndex |
Index of the serial number that was enrolled |
1 |
result |
See above for possible result codes |
Response
Randomly and if available, a node might respond with an enrollment proposal that contains a number of nearby serialNumberIndexes. If the MeshGateway wants to enroll one of these nodes, it can send a directed message to this node to enroll the other nearby node. If a serialNumberIndex is 0, there were not enough nodes around or not yet scanned.
actionType: ENROLLMENT_PROPOSAL
Bytes |
Type |
Description |
8 |
||
4 |
serialNumberIndex[0] |
nearby node serial number index |
4 |
serialNumberIndex[1] |
nearby node serial number index |
4 |
serialNumberIndex[2] |
nearby node serial number index |
Remove an Enrollment
Request
actionType: REMOVE_ENROLLMENT
Bytes |
Type |
Description |
8 |
||
4 |
serialNumberIndex |
Index of the serial number to be enrolled |
Response
The result of removing an enrollment:
0x00 = ENROLL_RESPONSE_OK
0x01 = ENROLL_RESPONSE_FLASH_BUSY //(please retry)
0x02 = ENROLL_RESPONSE_WRONG_DATA_ALIGNMENT //(fatal error)
0x03 = ENROLL_RESPONSE_NO_SPACE //(fatal error)
actionType: REMOVE_ENROLLMENT_RESPONSE
Bytes |
Type |
Description |
8 |
||
4 |
serialNumberIndex |
Index of the serial number that was enrolled |
1 |
result |
See above for possible result codes |
Requesting Proposals
Request
actionType: REQUEST_PROPOSALS (4)
Bytes |
Type |
Description |
8 |
||
4 - 44 |
serialNumberIndices |
Up to 11 serial indices. |
Response
actionType: REQUEST_PROPOSALS_RESPONSE (4)
Bytes |
Type |
Description |
8 |
||
4 |
serialNumberIndex |
The serial index that was possible to scan. |