diff --git a/source/USB Test App WPF/MainWindow.xaml.cs b/source/USB Test App WPF/MainWindow.xaml.cs
index 1e3d9ac4..ed8b973a 100644
--- a/source/USB Test App WPF/MainWindow.xaml.cs
+++ b/source/USB Test App WPF/MainWindow.xaml.cs
@@ -27,6 +27,72 @@ namespace Serial_Test_App_WPF
///
public partial class MainWindow : Window
{
+ // Baltimore CyberTrust Root
+ // from https://cacert.omniroot.com/bc2025.crt
+
+ // X509 RSA key PEM format 2048 bytes
+ private const string baltimoreCACertificate =
+@"-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
+RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
+VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
+DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
+ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
+VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
+mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
+IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
+mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
+XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
+dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
+jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
+BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
+DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
+9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
+jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
+Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
+ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
+R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----";
+
+ // Let’s Encrypt Authority X3 (IdenTrust cross-signed)
+ // from https://letsencrypt.org/certificates/
+
+ // X509 RSA key PEM format 2048 bytes
+ private const string letsEncryptCACertificate =
+@"-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1
+WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
+RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX
+NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf
+89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl
+Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc
+Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz
+uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB
+AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU
+BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB
+FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo
+SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js
+LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF
+BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG
+AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD
+VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB
+ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx
+A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM
+UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2
+DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1
+eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu
+OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw
+p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY
+2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0
+ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR
+PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b
+rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt
+-----END CERTIFICATE-----";
+
+
public MainWindow()
{
InitializeComponent();
@@ -757,10 +823,6 @@ private async void SetDeviceConfigButton_Click(object sender, RoutedEventArgs e)
// get device info
var deviceConfig = device.DebugEngine.GetDeviceConfiguration(cts.Token);
- // change device configuration using the global configuration class
- //deviceConfig.NetworkConfiguraton.MacAddress = new byte[] { 0, 0x80, 0xe1, 0x01, 0x35, 0x56 };
- //deviceConfig.NetworkConfiguraton.StartupAddressMode = DeviceConfiguration.AddressMode.DHCP;
-
// update new network configuration
DeviceConfiguration.NetworkConfigurationProperties newDeviceNetworkConfiguration = new DeviceConfiguration.NetworkConfigurationProperties
{
@@ -774,16 +836,35 @@ private async void SetDeviceConfigButton_Click(object sender, RoutedEventArgs e)
// write device configuration to device
var returnValue = device.DebugEngine.UpdateDeviceConfiguration(newDeviceNetworkConfiguration, 0);
- // add new wireless 802.11 configuration
- DeviceConfiguration.Wireless80211ConfigurationProperties newWireless80211Configuration = new DeviceConfiguration.Wireless80211ConfigurationProperties()
- {
- Id = 44,
- Ssid = "Nice_Ssid",
- Password = "1234",
- };
+ //// add new wireless 802.11 configuration
+ //DeviceConfiguration.Wireless80211ConfigurationProperties newWireless80211Configuration = new DeviceConfiguration.Wireless80211ConfigurationProperties()
+ //{
+ // Id = 44,
+ // Ssid = "Nice_Ssid",
+ // Password = "1234",
+ //};
+
+ //// write wireless configuration to device
+ //returnValue = device.DebugEngine.UpdateDeviceConfiguration(newWireless80211Configuration, 0);
+
+ // build a CA certificate bundle
+ DeviceConfiguration.X509CaRootBundleProperties newX509CertificateBundle = new DeviceConfiguration.X509CaRootBundleProperties();
+
+ // add CA root certificates
+
+ /////////////////////////////////////////////////////////
+ // BECAUSE WE ARE PARSING FROM A BASE64 encoded format //
+ // NEED TO ADD A TERMINATOR TO THE STRING //
+ /////////////////////////////////////////////////////////
+
+ string caRootBundle = baltimoreCACertificate + letsEncryptCACertificate + "\0";
+
+ byte[] certificateRaw = Encoding.UTF8.GetBytes(caRootBundle);
+
+ newX509CertificateBundle.Certificate = certificateRaw;
- // write wireless configuration to device
- returnValue = device.DebugEngine.UpdateDeviceConfiguration(newWireless80211Configuration, 0);
+ // write CA certificate to device
+ returnValue = device.DebugEngine.UpdateDeviceConfiguration(newX509CertificateBundle, 0);
Debug.WriteLine("");
Debug.WriteLine("");
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfiguration.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfiguration.cs
index 290e96a1..380862ff 100644
--- a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfiguration.cs
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfiguration.cs
@@ -35,6 +35,11 @@ public partial class DeviceConfiguration
///
public static string MarkerConfigurationWireless80211AP_v1 = "AP1\0";
+ ///
+ /// X509 CA Root bundle configuration marker
+ ///
+ public static string MarkerConfigurationX509CaRootBundle_v1 = "XB1\0";
+
/////////////////////////////////////////////////////////////
///
@@ -47,19 +52,27 @@ public partial class DeviceConfiguration
///
public List Wireless80211Configurations { get; set; }
+ ///
+ /// Collection of blocks in a target device.
+ ///
+ public List X509Certificates { get; set; }
+
public DeviceConfiguration()
: this(new List(),
- new List())
+ new List(),
+ new List())
{
}
public DeviceConfiguration(
List networkConfiguratons,
- List networkWirelessConfiguratons
+ List networkWirelessConfiguratons,
+ List x509Certificates
)
{
NetworkConfigurations = networkConfiguratons;
Wireless80211Configurations = networkWirelessConfiguratons;
+ X509Certificates = x509Certificates;
}
// operator to allow cast_ing a DeviceConfiguration object to DeviceConfigurationBase
@@ -68,7 +81,8 @@ public static explicit operator DeviceConfigurationBase(DeviceConfiguration valu
return new DeviceConfigurationBase()
{
NetworkConfigurations = value.NetworkConfigurations.Select(i => (NetworkConfigurationBase)i).ToArray(),
- Wireless80211Configurations = value.Wireless80211Configurations.Select(i => (Wireless80211ConfigurationBase)i).ToArray()
+ Wireless80211Configurations = value.Wireless80211Configurations.Select(i => (Wireless80211ConfigurationBase)i).ToArray(),
+ X509CaRootBundle = value.X509Certificates.Select(i => (X509CaRootBundleBase)i).ToArray()
};
}
@@ -245,6 +259,41 @@ public static explicit operator Wireless80211ConfigurationBase(Wireless80211Conf
}
+
+ [AddINotifyPropertyChangedInterface]
+ public class X509CaRootBundleProperties : X509CaRootBundlePropertiesBase
+ {
+ public bool IsUnknown { get; set; } = true;
+
+ public X509CaRootBundleProperties()
+ {
+
+ }
+
+ public X509CaRootBundleProperties(X509CaRootBundleBase certificate)
+ {
+ CertificateSize = (uint)certificate.Certificate.Length;
+ Certificate = certificate.Certificate;
+
+ // reset unknown flag
+ IsUnknown = false;
+ }
+
+ // operator to allow cast_ing a X509CaRootBundleBaseProperties object to X509CaRootBundleBase
+ public static explicit operator X509CaRootBundleBase(X509CaRootBundleProperties value)
+ {
+ var x509Certificate = new X509CaRootBundleBase()
+ {
+ Marker = Encoding.UTF8.GetBytes(MarkerConfigurationX509CaRootBundle_v1),
+
+ CertificateSize = (uint)value.Certificate.Length,
+ Certificate = value.Certificate,
+ };
+
+ return x509Certificate;
+ }
+ }
+
/////////////////////////////////////////////////////////////
}
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationBase.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationBase.cs
index 966d9522..7d5ae079 100644
--- a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationBase.cs
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationBase.cs
@@ -11,5 +11,7 @@ public class DeviceConfigurationBase
public NetworkConfigurationBase[] NetworkConfigurations;
public Wireless80211ConfigurationBase[] Wireless80211Configurations { get; internal set; }
+
+ public X509CaRootBundleBase[] X509CaRootBundle { get; internal set; }
}
}
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationOption.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationOption.cs
index d4613ac2..d5c00c9b 100644
--- a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationOption.cs
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/DeviceConfigurationOption.cs
@@ -31,6 +31,11 @@ public enum DeviceConfigurationOption : byte
///
WirelessNetworkAP = 3,
+ ///
+ /// X509 Certificate block
+ ///
+ X509Certificate = 4,
+
///
/// All configuration blocks
///
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/X509CaRootBundleBase.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/X509CaRootBundleBase.cs
new file mode 100644
index 00000000..d9ec0e7f
--- /dev/null
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/X509CaRootBundleBase.cs
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2018 The nanoFramework project contributors
+// See LICENSE file in the project root for full license information.
+//
+
+namespace nanoFramework.Tools.Debugger
+{
+ public class X509CaRootBundleBase
+ {
+ ///
+ /// This is the marker placeholder for this configuration block
+ /// 4 bytes length.
+ ///
+ public byte[] Marker;
+
+ ///
+ /// Size of the certificate.
+ ///
+ public uint CertificateSize;
+
+ ///
+ /// Certificate
+ ///
+ public byte[] Certificate;
+
+ public X509CaRootBundleBase()
+ {
+ // need to init these here to match the expected size on the struct to be sent to the device
+ Marker = new byte[4];
+ Certificate = new byte[64];
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/X509CaRootBundlePropertiesBase.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/X509CaRootBundlePropertiesBase.cs
new file mode 100644
index 00000000..f84d3345
--- /dev/null
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/DeviceConfiguration/X509CaRootBundlePropertiesBase.cs
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2018 The nanoFramework project contributors
+// See LICENSE file in the project root for full license information.
+//
+
+using PropertyChanged;
+
+namespace nanoFramework.Tools.Debugger
+{
+ [AddINotifyPropertyChangedInterface]
+ public class X509CaRootBundlePropertiesBase
+ {
+ private byte[] _certificate;
+
+ public uint CertificateSize { get; set; }
+
+ public byte[] Certificate
+ {
+ get => _certificate;
+ set
+ {
+ _certificate = value;
+ CertificateSize = (uint)value.Length;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Commands.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Commands.cs
index 5c56d182..fe9beec3 100644
--- a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Commands.cs
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Commands.cs
@@ -335,6 +335,23 @@ public void PrepareForDeserialize(int size, byte[] data, Converter converter)
Password = new byte[64];
}
}
+
+ public class X509CaRootBundleConfig : X509CaRootBundleBase, IConverter
+ {
+ public X509CaRootBundleConfig()
+ {
+ Marker = new byte[4];
+ CertificateSize = 0xFFFF;
+ Certificate = new byte[64];
+ }
+
+ public void PrepareForDeserialize(int size, byte[] data, Converter converter)
+ {
+ Marker = new byte[4];
+ CertificateSize = 0xFFFF;
+ Certificate = new byte[size - 4 - 4];
+ }
+ }
}
public class Monitor_UpdateConfiguration
@@ -342,6 +359,7 @@ public class Monitor_UpdateConfiguration
public uint Configuration;
public uint BlockIndex;
public uint Length = 0;
+ public uint Offset = 0;
public byte[] Data = null;
public class Reply
@@ -349,12 +367,14 @@ public class Reply
public uint ErrorCode;
};
- public void PrepareForSend(byte[] data, int length)
+ public void PrepareForSend(byte[] data, int length, int offset = 0)
{
Length = (uint)length;
Data = new byte[length];
- Array.Copy(data, 0, Data, 0, length);
+ Offset = (uint)offset;
+
+ Array.Copy(data, offset, Data, 0, length);
}
}
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs
index 2c8df383..5fce8d63 100644
--- a/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/WireProtocol/Engine.cs
@@ -3219,7 +3219,17 @@ public DeviceConfiguration GetDeviceConfiguration(CancellationToken cancellation
return null;
}
- return new DeviceConfiguration(networkConfigs, networkWirelessConfigs);
+ // get all wireless network configuration blocks
+ var x509Certificates = GetAllX509Certificates();
+ // check for cancellation request
+ if (cancellationToken.IsCancellationRequested)
+ {
+ // cancellation requested
+ Debug.WriteLine("cancellation requested");
+ return null;
+ }
+
+ return new DeviceConfiguration(networkConfigs, networkWirelessConfigs, x509Certificates);
}
public List GetAllNetworkConfigurations()
@@ -3268,6 +3278,29 @@ public DeviceConfiguration GetDeviceConfiguration(CancellationToken cancellation
return wireless80211Configurations;
}
+ public List GetAllX509Certificates()
+ {
+ List x509Certificates = new List();
+
+ DeviceConfiguration.X509CaRootBundleProperties x509CertificatesProperties = null;
+ uint index = 0;
+
+ do
+ {
+ // get next X509 certificate configuration block, if available
+ x509CertificatesProperties = GetX509CertificatesProperties(index++);
+
+ // add to list, if valid
+ if(!x509CertificatesProperties.IsUnknown)
+ {
+ x509Certificates.Add(x509CertificatesProperties);
+ }
+ }
+ while (!x509CertificatesProperties.IsUnknown);
+
+ return x509Certificates;
+ }
+
public DeviceConfiguration.NetworkConfigurationProperties GetNetworkConfiguratonProperties(uint configurationBlockIndex)
{
Debug.WriteLine("NetworkConfiguratonProperties");
@@ -3321,6 +3354,29 @@ public DeviceConfiguration.Wireless80211ConfigurationProperties GetWireless80211
return wirelessConfigProperties;
}
+ public DeviceConfiguration.X509CaRootBundleProperties GetX509CertificatesProperties(uint configurationBlockIndex)
+ {
+ Debug.WriteLine("X509CertificateProperties");
+
+ IncomingMessage reply = GetDeviceConfiguration((uint)DeviceConfiguration.DeviceConfigurationOption.X509Certificate, configurationBlockIndex);
+
+ Commands.Monitor_QueryConfiguration.X509CaRootBundleConfig x509Certificate = new Commands.Monitor_QueryConfiguration.X509CaRootBundleConfig();
+
+ DeviceConfiguration.X509CaRootBundleProperties x509CertificateProperties = new DeviceConfiguration.X509CaRootBundleProperties();
+
+ if (reply != null)
+ {
+ if (reply.Payload is Commands.Monitor_QueryConfiguration.Reply cmdReply && cmdReply.Data != null)
+ {
+ new Converter().Deserialize(x509Certificate, cmdReply.Data);
+
+ x509CertificateProperties = new DeviceConfiguration.X509CaRootBundleProperties(x509Certificate);
+ }
+ }
+
+ return x509CertificateProperties;
+ }
+
private IncomingMessage GetDeviceConfiguration(uint configuration, uint configurationBlockIndex)
{
Commands.Monitor_QueryConfiguration cmd = new Commands.Monitor_QueryConfiguration
@@ -3341,6 +3397,7 @@ private IncomingMessage GetDeviceConfiguration(uint configuration, uint configur
public bool UpdateDeviceConfiguration(DeviceConfiguration configuration)
{
bool okToUploadConfig = false;
+ Commands.Monitor_FlashSectorMap.FlashSectorData configSector = new Commands.Monitor_FlashSectorMap.FlashSectorData();
// the requirement to erase flash before storing is dependent on CLR capabilities which is only available if the device is running nanoCLR
// when running nanoBooter those are not available
@@ -3362,7 +3419,7 @@ public bool UpdateDeviceConfiguration(DeviceConfiguration configuration)
}
// get configuration sector details
- var configSector = FlashSectorMap.FirstOrDefault(item => (item.m_flags & Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) == Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG);
+ configSector = FlashSectorMap.FirstOrDefault(item => (item.m_flags & Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_MASK) == Commands.Monitor_FlashSectorMap.c_MEMORY_USAGE_CONFIG);
// check if the device has a config sector
if (configSector.m_NumBlocks > 0)
@@ -3396,27 +3453,58 @@ public bool UpdateDeviceConfiguration(DeviceConfiguration configuration)
// serialize the configuration block
var configurationSerialized = CreateConverter().Serialize(((DeviceConfigurationBase)configuration));
- // prepare command to upload new configuration
- Commands.Monitor_UpdateConfiguration cmd = new Commands.Monitor_UpdateConfiguration
- {
- Configuration = (uint)DeviceConfiguration.DeviceConfigurationOption.All
- };
- cmd.PrepareForSend(configurationSerialized, configurationSerialized.Length);
+ // counters to manage the chunked update process
+ int count = configurationSerialized.Length;
+ int position = 0;
- IncomingMessage reply = PerformSyncRequest(Commands.c_Monitor_UpdateConfiguration, 0, cmd);
+ // flag to signal the update operation success/failure
+ bool updateFailed = true;
- if (reply != null)
+ while (count > 0)
{
- Commands.Monitor_UpdateConfiguration.Reply cmdReply = reply.Payload as Commands.Monitor_UpdateConfiguration.Reply;
+ Commands.Monitor_UpdateConfiguration cmd = new Commands.Monitor_UpdateConfiguration
+ {
+ Configuration = (uint)DeviceConfiguration.DeviceConfigurationOption.All
+ };
+
+ // get packet length, either the maximum allowed size or whatever is still available to TX
+ int packetLength = Math.Min((int)WireProtocolPacketSize, count);
+
+ cmd.PrepareForSend(configurationSerialized, packetLength, position);
+
+ IncomingMessage reply = PerformSyncRequest(Commands.c_Monitor_UpdateConfiguration, 0, cmd);
- if (reply.IsPositiveAcknowledge() && cmdReply.ErrorCode == 0)
+ if (reply != null)
{
- return true;
+ Commands.Monitor_UpdateConfiguration.Reply cmdReply = reply.Payload as Commands.Monitor_UpdateConfiguration.Reply;
+
+ if (!reply.IsPositiveAcknowledge() || cmdReply.ErrorCode != 0)
+ {
+ break;
+ }
+
+ count -= packetLength;
+ position += packetLength;
+
+ if(count == 0)
+ {
+ // update was OK, switch flag
+ updateFailed = false;
+ }
}
}
- // write failed, try to replace back the old config?
- // FIXME
+ if(updateFailed)
+ {
+ // failed to upload new configuration
+ // revert back old one
+
+ // TODO
+ }
+ else
+ {
+ return true;
+ }
}
// default to false
@@ -3469,15 +3557,27 @@ public bool UpdateDeviceConfiguration(T configuration, uint blockIndex)
currentConfiguration.Wireless80211Configurations[(int)blockIndex] = configuration as DeviceConfiguration.Wireless80211ConfigurationProperties;
}
}
+ else if (configuration.GetType().Equals(typeof(DeviceConfiguration.X509CaRootBundleProperties)))
+ {
+ // if list is empty and request index is 0
+ if (currentConfiguration.X509Certificates.Count == 0 && blockIndex == 0)
+ {
+ currentConfiguration.X509Certificates.Add(configuration as DeviceConfiguration.X509CaRootBundleProperties);
+ }
+ else
+ {
+ currentConfiguration.X509Certificates[(int)blockIndex] = configuration as DeviceConfiguration.X509CaRootBundleProperties;
+ }
+ }
- if(UpdateDeviceConfiguration(currentConfiguration))
+ if (UpdateDeviceConfiguration(currentConfiguration))
{
// done here
return true;
}
else
{
- // write failed, the old configuration is supposed to have been reverted by
+ // write failed, the old configuration it's supposed to have been reverted by now
}
}
diff --git a/source/nanoFramework.Tools.DebugLibrary.Shared/nanoFramework.Tools.DebugLibrary.Net.projitems b/source/nanoFramework.Tools.DebugLibrary.Shared/nanoFramework.Tools.DebugLibrary.Net.projitems
index 6b95b6c5..5b1fcb6e 100644
--- a/source/nanoFramework.Tools.DebugLibrary.Shared/nanoFramework.Tools.DebugLibrary.Net.projitems
+++ b/source/nanoFramework.Tools.DebugLibrary.Shared/nanoFramework.Tools.DebugLibrary.Net.projitems
@@ -17,6 +17,8 @@
+
+