Skip to content

Commit 82b1057

Browse files
authored
Handle migration from Provisioning 1.0 to Provisioning 2.0 (#6)
* add public key message * for zero-touch enabled boards read the storage before run zero-touch procedure * in read_storage state added a check if a peer is connected for configuration * update version 0.3.0
1 parent bd82bd6 commit 82b1057

14 files changed

+161
-20
lines changed

extras/test/src/test_provisioning_command_encode.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,66 @@
181181
}
182182
}
183183

184+
WHEN("Encode a message with provisioning public key")
185+
{
186+
ProvPublicKeyProvisioningMessage command;
187+
command.c.id = ProvisioningMessageId::ProvPublicKeyProvisioningMessageId;
188+
command.provPublicKey = "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7JxCtXl5SvIrHmiasqyN4pyoXRlm44d5WXNpqmvJ\nk0tH8UpmIeHG7YPAkKLaqid95v/wLVoWeX5EbjxmlCkFtw==\n-----END PUBLIC KEY-----\n";
189+
uint8_t buffer[512];
190+
size_t bytes_encoded = sizeof(buffer);
191+
192+
CBORMessageEncoder encoder;
193+
MessageEncoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
194+
195+
// Test the encoding is
196+
// DA 00012017 # tag(73751)
197+
// 81 # array(1)
198+
// 78 B4 # text(180)
199+
// 2D 2D 2D 2D 2D 4245 47 49 4E 20 50 55 42 4C 49 43204B45592D2D2D2D2D0A0A4D466B77457759484B6F5A497A6A3043415159494B6F5A497A6A3044415163445167414537
200+
// 4A784374586C3553764972486D69617371794E3470796F58526C6D3434643557584E70716D764A0A6B3074483855706D49654847375950416B4B4C617169643935762F774C566F5765583545626A786D6C436B4674773D3D0A0A2D2D2D2D2D454E44205055424C4943204B45592D2D2D2D2D0A
201+
202+
uint8_t expected_result[] = {
203+
0xDA, 0x00, 0x01, 0x20, 0x17, 0x81, 0x78, 0xB2,
204+
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49,
205+
0x43, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x46, 0x6B, 0x77,
206+
0x45, 0x77, 0x59, 0x48, 0x4B, 0x6F, 0x5A, 0x49,
207+
0x7A, 0x6A, 0x30, 0x43, 0x41, 0x51, 0x59, 0x49, 0x4B, 0x6F, 0x5A, 0x49,
208+
0x7A, 0x6A, 0x30, 0x44, 0x41, 0x51, 0x63, 0x44, 0x51, 0x67, 0x41, 0x45,
209+
0x37, 0x4A, 0x78, 0x43, 0x74, 0x58, 0x6C, 0x35, 0x53, 0x76, 0x49, 0x72,
210+
0x48, 0x6D, 0x69, 0x61, 0x73, 0x71, 0x79, 0x4E, 0x34, 0x70, 0x79, 0x6F,
211+
0x58, 0x52, 0x6C, 0x6D, 0x34, 0x34, 0x64, 0x35, 0x57, 0x58, 0x4E, 0x70,
212+
0x71, 0x6D, 0x76, 0x4A, 0x0A, 0x6B, 0x30, 0x74, 0x48, 0x38, 0x55, 0x70,
213+
0x6D, 0x49, 0x65, 0x48, 0x47, 0x37, 0x59, 0x50, 0x41, 0x6B, 0x4B, 0x4C,
214+
0x61, 0x71, 0x69, 0x64, 0x39, 0x35, 0x76, 0x2F, 0x77, 0x4C, 0x56, 0x6F,
215+
0x57, 0x65, 0x58, 0x35, 0x45, 0x62, 0x6A, 0x78, 0x6D, 0x6C, 0x43, 0x6B,
216+
0x46, 0x74, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
217+
0x45, 0x4E, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4C, 0x49, 0x43, 0x20, 0x4B,
218+
0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A
219+
};
220+
221+
THEN("The encoding is successful") {
222+
REQUIRE(err == MessageEncoder::Status::Complete);
223+
REQUIRE(bytes_encoded == sizeof(expected_result));
224+
REQUIRE(memcmp(buffer, expected_result, sizeof(expected_result)) == 0);
225+
}
226+
}
227+
228+
WHEN("Encode a message with provisioning public key")
229+
{
230+
ProvPublicKeyProvisioningMessage command;
231+
command.c.id = ProvisioningMessageId::ProvPublicKeyProvisioningMessageId;
232+
command.provPublicKey = "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7JxCtXl5SvIrHmiasqyN4pyoXRlm44d5WXNpqmvJ\nk0tH8UpmIeHG7YPAkKLaqid95v/wLVoWeX5EbjxmlCkFtw==\n-----END PUBLIC KEY-----\n";
233+
uint8_t buffer[50];
234+
size_t bytes_encoded = sizeof(buffer);
235+
236+
CBORMessageEncoder encoder;
237+
MessageEncoder::Status err = encoder.encode((Message*)&command, buffer, bytes_encoded);
238+
239+
THEN("The encoding is failing") {
240+
REQUIRE(err == MessageEncoder::Status::Error);
241+
}
242+
}
243+
184244
WHEN("Encode a message with provisioning ble mac Address ")
185245
{
186246
BLEMacAddressProvisioningMessage command;
@@ -256,7 +316,6 @@
256316
// 81 # array(1)
257317
// 65 # text(5)
258318
// 312E362E30 # "1.6.0"
259-
printf("res %d\n", (int)err);
260319
THEN("The encoding is successful") {
261320
REQUIRE(err == MessageEncoder::Status::Complete);
262321
REQUIRE(bytes_encoded == sizeof(expected_result));

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Arduino_NetworkConfigurator
2-
version=0.2.1
2+
version=0.3.0
33
author=Arduino
44
maintainer=Arduino <[email protected]>
55
sentence=This library allows to configure and update the network settings of a ConnectionHandler instance.

src/ANetworkConfigurator_Config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88
#pragma once
99

10-
#define ANetworkConfigurator_LIB_VERSION "0.2.1"
10+
#define ANetworkConfigurator_LIB_VERSION "0.3.0"
1111

1212
#if defined(ARDUINO_SAMD_MKRWIFI1010)
1313
#define NETWORK_CONFIGURATOR_COMPATIBLE 1

src/Arduino_NetworkConfigurator.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,9 @@ bool NetworkConfiguratorClass::begin() {
4949
if(_state != NetworkConfiguratorStates::END) {
5050
return true;
5151
}
52-
/*
53-
* If the board is zero touch capable, starts with zero touch configuration mode
54-
* In this state the board will try to connect to the network using a set of
55-
* default network settings ex. Ethernet with DHCP
56-
* This mode will fail if the provided ConnectionHandler is not GenericConnectionHandler type
57-
* falling back to read the network settings from the storage
58-
*/
5952

60-
#if ZERO_TOUCH_ENABLED
61-
_state = NetworkConfiguratorStates::ZERO_TOUCH_CONFIG;
62-
#else
6353
_state = NetworkConfiguratorStates::READ_STORED_CONFIG;
64-
#endif
54+
6555
_connectionHandler->enableCheckInternetAvailability(true);
6656

6757
memset(&_networkSetting, 0x00, sizeof(models::NetworkSetting));
@@ -98,10 +88,10 @@ NetworkConfiguratorStates NetworkConfiguratorClass::update() {
9888
_ledFeedback->update();
9989

10090
switch (_state) {
91+
case NetworkConfiguratorStates::READ_STORED_CONFIG: nextState = handleReadStorage (); break;
10192
#if ZERO_TOUCH_ENABLED
10293
case NetworkConfiguratorStates::ZERO_TOUCH_CONFIG: nextState = handleZeroTouchConfig(); break;
10394
#endif
104-
case NetworkConfiguratorStates::READ_STORED_CONFIG: nextState = handleReadStorage (); break;
10595
case NetworkConfiguratorStates::WAITING_FOR_CONFIG: nextState = handleWaitingForConf (); break;
10696
case NetworkConfiguratorStates::CONNECTING: nextState = handleConnecting (); break;
10797
case NetworkConfiguratorStates::CONFIGURED: nextState = handleConfigured (); break;
@@ -459,7 +449,7 @@ NetworkConfiguratorStates NetworkConfiguratorClass::handleZeroTouchConfig() {
459449
defaultEthernetSettings();
460450
#endif
461451
if (!_connectionHandler->updateSetting(_networkSetting)) {
462-
return NetworkConfiguratorStates::READ_STORED_CONFIG;
452+
return NetworkConfiguratorStates::WAITING_FOR_CONFIG;
463453
}
464454
_connectionHandlerIstantiated = true;
465455
_connectionTimeout.reload();
@@ -475,9 +465,10 @@ NetworkConfiguratorStates NetworkConfiguratorClass::handleZeroTouchConfig() {
475465
sendStatus(StatusMessage::ERROR);
476466
}
477467
_connectionHandlerIstantiated = false;
478-
return NetworkConfiguratorStates::READ_STORED_CONFIG;
468+
return NetworkConfiguratorStates::WAITING_FOR_CONFIG;
479469
}
480-
return NetworkConfiguratorStates::ZERO_TOUCH_CONFIG;
470+
471+
return handleWaitingForConf();
481472
}
482473
#endif
483474

@@ -512,13 +503,26 @@ NetworkConfiguratorStates NetworkConfiguratorClass::handleReadStorage() {
512503

513504
if(credFound && _connectionHandler->updateSetting(_networkSetting)) {
514505
_connectionHandlerIstantiated = true;
506+
_configInProgress = _agentsManager->isConfigInProgress();
507+
if (_configInProgress) {
508+
return NetworkConfiguratorStates::UPDATING_CONFIG;
509+
}
515510
return NetworkConfiguratorStates::CONFIGURED;
516511
}
517512

518513
if (_optionUpdateTimer.getWaitTime() == 0) {
519514
scanNetworkOptions();
520515
}
516+
/*
517+
* If the board is zero touch capable and without network configuration, it starts the zero touch configuration mode
518+
* In this state the board will try to connect to the network using a set of
519+
* default network settings ex. Ethernet with DHCP
520+
*/
521+
#if ZERO_TOUCH_ENABLED
522+
return NetworkConfiguratorStates::ZERO_TOUCH_CONFIG;
523+
#else
521524
return NetworkConfiguratorStates::WAITING_FOR_CONFIG;
525+
#endif
522526
}
523527

524528
NetworkConfiguratorStates NetworkConfiguratorClass::handleWaitingForConf() {
@@ -583,7 +587,8 @@ NetworkConfiguratorStates NetworkConfiguratorClass::handleConfigured() {
583587
}
584588

585589
NetworkConfiguratorStates NetworkConfiguratorClass::handleUpdatingConfig() {
586-
if (_agentsManager->isConfigInProgress() == false) {
590+
_configInProgress = _agentsManager->isConfigInProgress();
591+
if (_configInProgress == false) {
587592
//If peer disconnects without updating the network settings, go to connecting state for check the connection
588593
sendStatus(StatusMessage::CONNECTING);
589594
return NetworkConfiguratorStates::CONNECTING;

src/configuratorAgents/AgentsManager.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ void AgentsManagerClass::updateProgressRequest(MessageOutputType type) {
316316
case MessageOutputType::WIFI_FW_VERSION: key = RequestType::GET_WIFI_FW_VERSION ; break;
317317
case MessageOutputType::PROV_SKETCH_VERSION: key = RequestType::GET_PROVISIONING_SKETCH_VERSION; break;
318318
case MessageOutputType::NETCONFIG_LIB_VERSION: key = RequestType::GET_NETCONFIG_LIB_VERSION ; break;
319+
case MessageOutputType::PROV_PUBLIC_KEY: key = RequestType::GET_ID ; break;
319320
}
320321

321322
if (key == RequestType::NONE) {
@@ -324,7 +325,7 @@ void AgentsManagerClass::updateProgressRequest(MessageOutputType type) {
324325

325326
if( key == RequestType::GET_ID && _statusRequest.key == key && _statusRequest.pending){
326327
_statusRequest.completion++;
327-
if(_statusRequest.completion == 2){
328+
if(_statusRequest.completion == 3){
328329
_statusRequest.reset();
329330
}
330331
return;

src/configuratorAgents/MessagesDefinitions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ enum class MessageOutputType { STATUS,
6161
WIFI_FW_VERSION,
6262
PROV_SKETCH_VERSION,
6363
NETCONFIG_LIB_VERSION,
64+
PROV_PUBLIC_KEY
6465
};
6566

6667
/* Types of ingoing messages */
@@ -86,6 +87,7 @@ struct ProvisioningOutputMessage {
8687
const char *wifiFwVersion;
8788
const char *provSketchVersion;
8889
const char *netConfigLibVersion;
90+
const char *provPublicKey;
8991
} m;
9092
};
9193

src/configuratorAgents/agents/boardConfigurationProtocol/BoardConfigurationProtocol.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ bool BoardConfigurationProtocol::sendMsg(ProvisioningOutputMessage &msg) {
7575
case MessageOutputType::NETCONFIG_LIB_VERSION:
7676
res = sendVersion(msg.m.netConfigLibVersion, msg.type);
7777
break;
78+
case MessageOutputType::PROV_PUBLIC_KEY:
79+
res = sendProvPublicKey(msg.m.provPublicKey, strlen(msg.m.provPublicKey));
80+
break;
7881
default:
7982
break;
8083
}
@@ -294,6 +297,23 @@ bool BoardConfigurationProtocol::sendJwt(const char *jwt, size_t len) {
294297
return res;
295298
}
296299

300+
bool BoardConfigurationProtocol::sendProvPublicKey(const char *provPublicKey, size_t len) {
301+
302+
size_t cborDataLen = CBOR_MIN_PROV_PUBIC_KEY_LEN + len;
303+
uint8_t data[cborDataLen];
304+
305+
if (!CBORAdapter::provPublicKeyToCBOR(provPublicKey, data, &cborDataLen)) {
306+
return false;
307+
}
308+
309+
if (!sendData(PacketManager::MessageType::DATA, data, cborDataLen)) {
310+
DEBUG_WARNING("BoardConfigurationProtocol::%s failed to send JWT", __FUNCTION__);
311+
return false;
312+
}
313+
314+
return true;
315+
}
316+
297317
bool BoardConfigurationProtocol::sendBleMacAddress(const uint8_t *mac, size_t len) {
298318
bool res = false;
299319
if (len != BLE_MAC_ADDRESS_SIZE) {

src/configuratorAgents/agents/boardConfigurationProtocol/BoardConfigurationProtocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class BoardConfigurationProtocol {
9696
bool sendNetworkOptions(const NetworkOptions *netOptions);
9797
bool sendUhwid(const byte *uhwid);
9898
bool sendJwt(const char *jwt, size_t len);
99+
bool sendProvPublicKey(const char *provPublicKey, size_t len);
99100
bool sendBleMacAddress(const uint8_t *mac, size_t len);
100101
bool sendVersion(const char *version, MessageOutputType type);
101102
TransmissionResult transmitStream();

src/configuratorAgents/agents/boardConfigurationProtocol/CBORAdapter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,20 @@ bool CBORAdapter::BLEMacAddressToCBOR(const uint8_t *mac, uint8_t *data, size_t
6868
return status == MessageEncoder::Status::Complete ? true : false;
6969
}
7070

71+
bool CBORAdapter::provPublicKeyToCBOR(const char *provPublicKey, uint8_t *data, size_t *len) {
72+
CBORMessageEncoder encoder;
73+
if(*len < CBOR_MIN_PROV_PUBIC_KEY_LEN + strlen(provPublicKey)) {
74+
return false;
75+
}
76+
ProvPublicKeyProvisioningMessage provPublicKeyMsg;
77+
provPublicKeyMsg.c.id = ProvisioningMessageId::ProvPublicKeyProvisioningMessageId;
78+
provPublicKeyMsg.provPublicKey = provPublicKey;
79+
80+
MessageEncoder::Status status = encoder.encode((Message *)&provPublicKeyMsg, data, *len);
81+
82+
return status == MessageEncoder::Status::Complete ? true : false;
83+
}
84+
7185
bool CBORAdapter::statusToCBOR(StatusMessage msg, uint8_t *data, size_t *len) {
7286
bool result = false;
7387

src/configuratorAgents/agents/boardConfigurationProtocol/CBORAdapter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
#define CBOR_MIN_WIFI_FW_VERSION_LEN CBOR_DATA_HEADER_LEN + 1 // CBOR_DATA_HEADER_LEN + 1 byte for the length of the string
2222
#define CBOR_MIN_PROV_SKETCH_VERSION_LEN CBOR_DATA_HEADER_LEN + 1 // CBOR_DATA_HEADER_LEN + 1 byte for the length of the string
2323
#define CBOR_MIN_NETCONFIG_LIB_VERSION_LEN CBOR_DATA_HEADER_LEN + 1 // CBOR_DATA_HEADER_LEN + 1 byte for the length of the string
24+
#define CBOR_MIN_PROV_PUBIC_KEY_LEN CBOR_DATA_HEADER_LEN + 3 // CBOR_DATA_HEADER_LEN + 2 bytes for the length of the string + 1 byte for the type of the string
2425

2526
class CBORAdapter {
2627
public:
2728
static bool uhwidToCBOR(const byte *uhwid, uint8_t *data, size_t *len);
2829
static bool jwtToCBOR(const char *jwt, uint8_t *data, size_t *len);
30+
static bool provPublicKeyToCBOR(const char *provPublicKey, uint8_t *data, size_t *len);
2931
static bool BLEMacAddressToCBOR(const uint8_t *mac, uint8_t *data, size_t *len);
3032
static bool wifiFWVersionToCBOR(const char *wifiFWVersion, uint8_t *data, size_t *len);
3133
static bool provSketchVersionToCBOR(const char *provSketchVersion, uint8_t *data, size_t *len);

0 commit comments

Comments
 (0)