Skip to content

Commit

Permalink
Work on configuration block implementation
Browse files Browse the repository at this point in the history
- Add support for nanoframework/nf-debugger#173.
- Improve Monitor_UpdateConfiguration command to handle configuration blocks larger then the WP buffer size.
- Add new configuration block to store X509 certificates.
- Tested for STM32.
- **WIP for ESP32**

Signed-off-by: José Simões <jose.simoes@eclo.solutions>
  • Loading branch information
josesimoes committed Dec 11, 2018
1 parent f4782e5 commit c84edf0
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 17 deletions.
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pr:
branches:
include:
- master
- develop
- develop/*
- release/*
autoCancel: true

Expand Down
28 changes: 26 additions & 2 deletions src/CLR/Debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,9 +852,11 @@ bool CLR_DBG_Debugger::Monitor_QueryConfiguration( WP_Message* message)

Monitor_QueryConfiguration_Command *cmd = (Monitor_QueryConfiguration_Command*)message->m_payload;
int size = 0;
int sizeOfBlock = 0;

HAL_Configuration_NetworkInterface* configNetworkInterface;
HAL_Configuration_Wireless80211* configWireless80211NetworkInterface;
HAL_Configuration_X509Certificate* x509Certificate;

switch((DeviceConfigurationOption)cmd->Configuration)
{
Expand Down Expand Up @@ -885,7 +887,28 @@ bool CLR_DBG_Debugger::Monitor_QueryConfiguration( WP_Message* message)
platform_free(configWireless80211NetworkInterface);
}
break;


case DeviceConfigurationOption_X509Certificate:

if(g_TargetConfiguration.CertificateStore->Count > 0)
{
// because X509 certificate has a variable length need to compute the block size in two steps
sizeOfBlock = offsetof(HAL_Configuration_X509Certificate, Certificate);
sizeOfBlock += g_TargetConfiguration.CertificateStore->Certificates[cmd->BlockIndex]->CertificateSize;
}

x509Certificate = (HAL_Configuration_X509Certificate*)platform_malloc(sizeOfBlock);

if(ConfigurationManager_GetConfigurationBlock(x509Certificate, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex) == true)
{
size = sizeOfBlock;
success = true;

WP_ReplyToCommand( message, success, false, (uint8_t*)x509Certificate, size );
platform_free(x509Certificate);
}
break;

case DeviceConfigurationOption_WirelessNetworkAP:
// TODO missing implementation for now
break;
Expand Down Expand Up @@ -924,8 +947,9 @@ bool CLR_DBG_Debugger::Monitor_UpdateConfiguration(WP_Message* message)
{
case DeviceConfigurationOption_Network:
case DeviceConfigurationOption_Wireless80211Network:
case DeviceConfigurationOption_X509Certificate:
case DeviceConfigurationOption_All:
if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length) == true)
if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length, cmd->Offset) == true)
{
cmdReply.ErrorCode = 0;
success = true;
Expand Down
1 change: 1 addition & 0 deletions src/CLR/Include/WireProtocol_MonitorCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ typedef struct Monitor_UpdateConfiguration_Command
uint32_t Configuration;
uint32_t BlockIndex;
uint32_t Length;
uint32_t Offset;
uint8_t Data[1];

}Monitor_UpdateConfiguration_Command;
Expand Down
21 changes: 20 additions & 1 deletion src/HAL/Include/nanoHAL_ConfigurationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ typedef enum DeviceConfigurationOption
// Wireless Network as AP configuration block
DeviceConfigurationOption_WirelessNetworkAP = 3,

// X509 Certificate block
DeviceConfigurationOption_X509Certificate = 4,

// All configuration blocks
DeviceConfigurationOption_All = 255,

Expand Down Expand Up @@ -58,12 +61,25 @@ typedef struct HAL_CONFIGURATION_NETWORK_WIRELESS80211

} HAL_CONFIGURATION_NETWORK_WIRELESS80211;

// certificate store struct
// declared with a flexible array member to allow N config blocks totally independent of compilation
typedef struct HAL_CONFIGURATION_X509_CERTIFICATE
{
// count of the configs elements
uint8_t Count;

// pointer to the certificates
HAL_Configuration_X509Certificate* Certificates[];

} HAL_CONFIGURATION_X509_CERTIFICATE;

// target configuration storage struct
// the memory allocation for these will have to be done as required according to the number and type of blocks found in memory
typedef struct HAL_TARGET_CONFIGURATION
{
HAL_CONFIGURATION_NETWORK* NetworkInterfaceConfigs;
HAL_CONFIGURATION_NETWORK_WIRELESS80211* Wireless80211Configs;
HAL_CONFIGURATION_X509_CERTIFICATE* CertificateStore;

} HAL_TARGET_CONFIGURATION;

Expand All @@ -81,7 +97,7 @@ bool ConfigurationManager_GetConfigurationBlock(void* configurationBlock, Device

// StoreConfigurationBlock() is defined in targetHAL_ConfigurationManager.cpp at target level because the target
// needs to be free to implement the storage of the configuration block as they see fit
bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize);
bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize, uint32_t offset);

// UpdateConfigurationBlock() is defined in targetHAL_ConfigurationManager.cpp at target level because the target
// needs to be free to implement the storage of the configuration block as they see fit
Expand All @@ -103,6 +119,9 @@ void* ConfigurationManager_FindNetworkConfigurationBlocks(uint32_t startAddress,
// function that sweeps a memory region searching for wireless network configuration blocks
void* ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks(uint32_t startAddress, uint32_t endAddress);

// function that sweeps a memory region searching for X509 certificates configuration blocks
void* ConfigurationManager_FindX509CertificateConfigurationBlocks(uint32_t startAddress, uint32_t endAddress);

// gets the HAL_Configuration_Wireless80211 configuration block that has the specified Id, if that exists
// defined as weak needs to be free to implement the storage of the configuration block as they see fit
HAL_Configuration_Wireless80211* ConfigurationManager_GetWirelessConfigurationFromId(uint32_t configurationId);
Expand Down
17 changes: 17 additions & 0 deletions src/HAL/Include/nanoHAL_Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ static const unsigned char c_MARKER_CONFIGURATION_WIRELESS80211_V1[] = "WN1";
// Wireless AP configuration block start marker
static const unsigned char c_MARKER_CONFIGURATION_WIRELESS_AP_V1[] = "AP1";

// X509 certificate configuration block start marker
static const unsigned char c_MARKER_CONFIGURATION_X509CERTIFICATE_V1[] = "XC1";

////////////////////////////////////////////////////////////////////////////////////////////////////
// !!! KEEP IN SYNC WITH System.Net.NetworkInformation.NetworkInterfaceType (in managed code) !!! //
////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -206,6 +209,20 @@ typedef struct __nfpack HAL_Configuration_Wireless80211 {

} HAL_Configuration_Wireless80211;

typedef struct __nfpack HAL_Configuration_X509Certificate {

// this is the marker placeholder for this configuration block
uint8_t Marker[4];

// Size of the X509 certificate
uint32_t CertificateSize;

// Network password
uint8_t Certificate[1];

} HAL_Configuration_X509Certificate;


void nanoHAL_Network_Initialize();
void sys_signal_sock_event();

Expand Down
47 changes: 47 additions & 0 deletions src/HAL/nanoHAL_ConfigurationManager.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <string.h>
#include <nanoHAL_v2.h>
#include <nanoHAL_Network.h>

uint32_t FindNextBlock(uint32_t startAddress, uint32_t endAddress, const unsigned char* marker)
{
Expand Down Expand Up @@ -105,6 +106,52 @@ __nfweak void* ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks(
return networkWirelessConfigs;
}

__nfweak void* ConfigurationManager_FindX509CertificateConfigurationBlocks(uint32_t startAddress, uint32_t endAddress)
{
uint32_t nextBlock = startAddress;
uint32_t allocationSize = 0;

// first pass: find out how many blocks of this type we have
// because these blocks have an unknow size, need to call this without a fixed size
uint32_t blockCount = GetBlockCount(startAddress, endAddress, 1, c_MARKER_CONFIGURATION_X509CERTIFICATE_V1);

// start computing allocation size, first part is the struct initial fields
allocationSize = offsetof(HAL_CONFIGURATION_X509_CERTIFICATE, Certificates);

// second pass: find out the size of each X509 certificate (because they can have different sizes and we need this to allocate memory for the struct)
if(blockCount > 0)
{
for(uint32_t i = 0; i < blockCount; i++)
{
nextBlock = FindNextBlock(nextBlock, endAddress, c_MARKER_CONFIGURATION_X509CERTIFICATE_V1);

// header
allocationSize += offsetof(HAL_Configuration_X509Certificate, Certificate);

// certificate
allocationSize += ((HAL_Configuration_X509Certificate*)nextBlock)->CertificateSize;
}
}

// allocate config struct
HAL_CONFIGURATION_X509_CERTIFICATE *certificateStore = (HAL_CONFIGURATION_X509_CERTIFICATE *)platform_malloc(allocationSize);

// set collection count
certificateStore->Count = blockCount;

if(blockCount > 0)
{
// second pass: get address of each config block
for(uint32_t i = 0; i < blockCount; i++)
{
nextBlock = FindNextBlock(nextBlock, endAddress, c_MARKER_CONFIGURATION_X509CERTIFICATE_V1);
certificateStore->Certificates[i] = (HAL_Configuration_X509Certificate*)nextBlock;
}
}

return certificateStore;
}

__nfweak HAL_Configuration_Wireless80211* ConfigurationManager_GetWirelessConfigurationFromId(uint32_t configurationId)
{
for(int i = 0; i < g_TargetConfiguration.Wireless80211Configs->Count; i++)
Expand Down
8 changes: 8 additions & 0 deletions src/HAL/nanoHAL_ConfigurationManager_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ __nfweak void* ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks(
return NULL;
}

__nfweak void* ConfigurationManager_FindX509CertificateConfigurationBlocks(uint32_t startAddress, uint32_t endAddress)
{
(void)startAddress;
(void)endAddress;

return NULL;
}

__nfweak HAL_Configuration_Wireless80211* ConfigurationManager_GetWirelessConfigurationFromId(uint32_t configurationId)
{
(void)configurationId;
Expand Down
74 changes: 66 additions & 8 deletions targets/CMSIS-OS/ChibiOS/common/targetHAL_ConfigurationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,29 @@ __nfweak void ConfigurationManager_EnumerateConfigurationBlocks()
// find wireless 80211 network configuration blocks
HAL_CONFIGURATION_NETWORK_WIRELESS80211* networkWirelessConfigs = (HAL_CONFIGURATION_NETWORK_WIRELESS80211*)ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks((uint32_t)&__nanoConfig_start__, (uint32_t)&__nanoConfig_end__);

// find X509 certificate blocks
HAL_CONFIGURATION_X509_CERTIFICATE* certificateStore = (HAL_CONFIGURATION_X509_CERTIFICATE*)ConfigurationManager_FindX509CertificateConfigurationBlocks((uint32_t)&__nanoConfig_start__, (uint32_t)&__nanoConfig_end__);

// alloc memory for g_TargetConfiguration
// because this is a struct of structs that use flexible members the memory has to be allocated from the heap
// the malloc size for each struct is computed separately
uint32_t sizeOfNetworkInterfaceConfigs = offsetof(HAL_CONFIGURATION_NETWORK, Configs) + networkConfigs->Count * sizeof(networkConfigs->Configs[0]);
uint32_t sizeOfWireless80211Configs = offsetof(HAL_CONFIGURATION_NETWORK_WIRELESS80211, Configs) + networkWirelessConfigs->Count * sizeof(networkWirelessConfigs->Configs[0]);
uint32_t sizeOfX509CertificateStore = offsetof(HAL_CONFIGURATION_X509_CERTIFICATE, Certificates) + certificateStore->Count * sizeof(certificateStore->Certificates[0]);

g_TargetConfiguration.NetworkInterfaceConfigs = (HAL_CONFIGURATION_NETWORK*)platform_malloc(sizeOfNetworkInterfaceConfigs);
g_TargetConfiguration.Wireless80211Configs = (HAL_CONFIGURATION_NETWORK_WIRELESS80211*)platform_malloc(sizeOfWireless80211Configs);
g_TargetConfiguration.CertificateStore = (HAL_CONFIGURATION_X509_CERTIFICATE*)platform_malloc(sizeOfX509CertificateStore);

// copy structs to g_TargetConfiguration
memcpy((HAL_CONFIGURATION_NETWORK*)g_TargetConfiguration.NetworkInterfaceConfigs, networkConfigs, sizeOfNetworkInterfaceConfigs);
memcpy((HAL_CONFIGURATION_NETWORK_WIRELESS80211*)g_TargetConfiguration.Wireless80211Configs, networkWirelessConfigs, sizeOfWireless80211Configs);
memcpy((HAL_CONFIGURATION_X509_CERTIFICATE*)g_TargetConfiguration.CertificateStore, certificateStore, sizeOfX509CertificateStore);

// // now free the memory of the original structs
// now free the memory of the original structs
platform_free(networkConfigs);
platform_free(networkWirelessConfigs);
platform_free(certificateStore);
}
else
{
Expand Down Expand Up @@ -100,6 +107,22 @@ __nfweak bool ConfigurationManager_GetConfigurationBlock(void* configurationBloc
// get block address
blockAddress = (uint8_t*)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex];
}
else if(configuration == DeviceConfigurationOption_X509Certificate)
{
if(g_TargetConfiguration.CertificateStore->Count == 0 ||
(configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count)
{
return FALSE;
}

// get block address
blockAddress = (uint8_t*)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex];

// set block size
// because X509 certificate has a variable length need to compute the block size in two steps
sizeOfBlock = offsetof(HAL_Configuration_X509Certificate, Certificate);
sizeOfBlock += ((HAL_Configuration_X509Certificate*)blockAddress)->CertificateSize;
}

// copy the config block content to the pointer in the argument
memcpy(configurationBlock, blockAddress, sizeOfBlock);
Expand All @@ -111,7 +134,7 @@ __nfweak bool ConfigurationManager_GetConfigurationBlock(void* configurationBloc
// NOTE: because inserting or removing a configuration block it's very 'RAM expensive' we choose not to support those operations
// the host debugger will have to be used to manage these operations on the device configuration collection
// it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is used
__nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize)
__nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize, uint32_t offset)
{
ByteAddress storageAddress = 0;
bool requiresEnumeration = FALSE;
Expand All @@ -127,8 +150,8 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl
return FALSE;
}

// set storage address from block address
storageAddress = (ByteAddress)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex];
// set storage address from block address, plus the requested offset
storageAddress = (ByteAddress)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex] + offset;

// set block size, in case it's not already set
blockSize = sizeof(HAL_Configuration_NetworkInterface);
Expand All @@ -148,21 +171,42 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl
return FALSE;
}

// set storage address from block address
storageAddress = (ByteAddress)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex];
// set storage address from block address, plus the requested offset
storageAddress = (ByteAddress)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex] + offset;

// set block size, in case it's not already set
blockSize = sizeof(HAL_Configuration_Wireless80211);

// make sure the config block marker is set
memcpy(configurationBlock, c_MARKER_CONFIGURATION_WIRELESS80211_V1, sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1));
}
else if(configuration == DeviceConfigurationOption_X509Certificate)
{
if( g_TargetConfiguration.CertificateStore->Count == 0 ||
(configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count)
{
// there is no room for this block, or there are no blocks stored at all
// failing the operation
return FALSE;
}

// set storage address from block address, plus the requested offset
storageAddress = (ByteAddress)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex] + offset;

// set block size, in case it's not already set
// because X509 certificate has a variable length need to compute the block size in two steps
blockSize = offsetof(HAL_Configuration_X509Certificate, Certificate);
blockSize += ((HAL_Configuration_X509Certificate*)configurationBlock)->CertificateSize;

// make sure the config block marker is set
memcpy(configurationBlock, c_MARKER_CONFIGURATION_X509CERTIFICATE_V1, sizeof(c_MARKER_CONFIGURATION_X509CERTIFICATE_V1));
}
else if(configuration == DeviceConfigurationOption_All)
{
// particular situation where we are receiving the full configuration block

// set storage address as the start of the flash configuration sector
storageAddress = (ByteAddress)&__nanoConfig_start__;
// set storage address as the start of the flash configuration sector, plus the requested offset
storageAddress = (ByteAddress)&__nanoConfig_start__ + offset;

// always enumerate the blocks again after storing it
requiresEnumeration = TRUE;
Expand All @@ -182,6 +226,7 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl
// free the current allocation(s)
platform_free(g_TargetConfiguration.NetworkInterfaceConfigs);
platform_free(g_TargetConfiguration.Wireless80211Configs);
platform_free(g_TargetConfiguration.CertificateStore);

// perform enumeration of configuration blocks
ConfigurationManager_EnumerateConfigurationBlocks();
Expand Down Expand Up @@ -240,6 +285,19 @@ __nfweak bool ConfigurationManager_UpdateConfigurationBlock(void* configurationB
// make sure the config block marker is set
memcpy(configurationBlock, c_MARKER_CONFIGURATION_WIRELESS80211_V1, sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1));
}
else if(configuration == DeviceConfigurationOption_X509Certificate)
{
// storage address from block address
storageAddress = (ByteAddress)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex];

// set block size, in case it's not already set
// because X509 certificate has a variable length need to compute the block size in two steps
blockSize = offsetof(HAL_Configuration_X509Certificate, Certificate);
blockSize += ((HAL_Configuration_X509Certificate*)configurationBlock)->CertificateSize;

// make sure the config block marker is set
memcpy(configurationBlock, c_MARKER_CONFIGURATION_X509CERTIFICATE_V1, sizeof(c_MARKER_CONFIGURATION_X509CERTIFICATE_V1));
}
else
{
// this not a valid configuration option to update, quit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ int Monitor_UpdateConfiguration(WP_Message* message)
{
case DeviceConfigurationOption_Network:
case DeviceConfigurationOption_Wireless80211Network:
case DeviceConfigurationOption_X509Certificate:
case DeviceConfigurationOption_All:
if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length) == true)
if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length, cmd->Offset) == true)
{
cmdReply.ErrorCode = 0;
success = true;
Expand Down
Loading

0 comments on commit c84edf0

Please sign in to comment.