From 93718d46c6ade72e276eee3d24a75355804fb8cc Mon Sep 17 00:00:00 2001 From: Ricardo Casallas Date: Thu, 5 Dec 2024 13:39:45 -0500 Subject: [PATCH] Provision: Dynamic buffer allocation. --- .../provision/ProvisionStorageCustom.cpp | 2 +- .../provision/ProvisionStorageDefault.cpp | 31 +++++++++---------- .../silabs/provision/ProvisionEncoder.h | 26 +++++++++++++++- .../silabs/provision/ProvisionStorage.h | 11 ++++--- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/examples/platform/silabs/provision/ProvisionStorageCustom.cpp b/examples/platform/silabs/provision/ProvisionStorageCustom.cpp index 7efc990279..a03f5380bc 100644 --- a/examples/platform/silabs/provision/ProvisionStorageCustom.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageCustom.cpp @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "ProvisionStorage.h" +#include #include #include #include diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp index c607109448..744b3696aa 100644 --- a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -70,16 +70,26 @@ CHIP_ERROR ErasePage(uint32_t addr) return chip::DeviceLayer::Silabs::GetPlatform().FlashErasePage(addr); } -CHIP_ERROR WritePage(uint32_t addr, const uint8_t * data, size_t size) +size_t RoundNearest(size_t n, size_t multiple) { - return chip::DeviceLayer::Silabs::GetPlatform().FlashWritePage(addr, data, size); + return (n % multiple) > 0 ? n + (multiple - n % multiple) : n; } -size_t RoundNearest(size_t n, size_t multiple) +CHIP_ERROR WritePage(uint32_t addr, const uint8_t * data, size_t size, size_t max) { - return (n % multiple) > 0 ? n + (multiple - n % multiple) : n; + size_t size_32 = RoundNearest(size, 4); + if(size_32 != size) + { + uint8_t * p = (uint8_t *) data; + VerifyOrReturnError(size_32 <= max, CHIP_ERROR_BUFFER_TOO_SMALL); + memset(p + size, 0xff, size_32 - size); + size = size_32; + } + return chip::DeviceLayer::Silabs::GetPlatform().FlashWritePage(addr, data, size); } + + CHIP_ERROR WriteFile(Storage & store, SilabsConfig::Key offset_key, SilabsConfig::Key size_key, const ByteSpan & value) { uint32_t base_addr = 0; @@ -89,17 +99,7 @@ CHIP_ERROR WriteFile(Storage & store, SilabsConfig::Key offset_key, SilabsConfig ReturnErrorOnFailure(ErasePage(base_addr)); } - memcpy(Storage::aux_buffer, value.data(), value.size()); - if (value.size() < Storage::kArgumentSizeMax) - { - memset(Storage::aux_buffer + value.size(), 0xff, Storage::kArgumentSizeMax - value.size()); - } - - ChipLogProgress(DeviceLayer, "WriteFile, addr:0x%06x+%03u, size:%u", (unsigned) base_addr, (unsigned) sCredentialsOffset, - (unsigned) value.size()); - // ChipLogByteSpan(DeviceLayer, ByteSpan(value.data(), value.size() < kDebugLength ? value.size() : kDebugLength)); - - ReturnErrorOnFailure(WritePage(base_addr + sCredentialsOffset, Storage::aux_buffer, Storage::kArgumentSizeMax)); + ReturnErrorOnFailure(WritePage(base_addr + sCredentialsOffset, value.data(), value.size(), store.GetBufferSize())); // Store file offset ReturnErrorOnFailure(SilabsConfig::WriteConfigValue(offset_key, (uint32_t) sCredentialsOffset)); @@ -119,7 +119,6 @@ CHIP_ERROR ReadFileByOffset(Storage & store, const char * description, uint32_t ByteSpan span(address, size); ChipLogProgress(DeviceLayer, "%s, addr:0x%06x+%03u, size:%u", description, (unsigned) base_addr, (unsigned) offset, (unsigned) size); - // ChipLogByteSpan(DeviceLayer, ByteSpan(span.data(), span.size() < kDebugLength ? span.size() : kDebugLength)); return CopySpanToMutableSpan(span, value); } diff --git a/src/platform/silabs/provision/ProvisionEncoder.h b/src/platform/silabs/provision/ProvisionEncoder.h index 0c5a5e2bfe..c83313d955 100644 --- a/src/platform/silabs/provision/ProvisionEncoder.h +++ b/src/platform/silabs/provision/ProvisionEncoder.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace chip { namespace DeviceLayer { @@ -27,17 +28,39 @@ namespace Silabs { namespace Provision { namespace Encoding { +/* +begin out in end + |---------------v---------------v----------------| + |.....offset....|......left.....|.....spare......| + |..............size.............| + |......................limit.....................| +*/ + struct Buffer { Buffer(uint8_t * ptr, size_t size, bool at_end = false) { Init(ptr, size, at_end); } void Init(uint8_t * ptr, size_t size, bool at_end = false) { + Finish(); + if(nullptr == ptr) + { + ptr = static_cast(malloc(size)); + allocated = true; + } this->begin = ptr; this->end = ptr + size; this->in = at_end ? end : begin; this->out = ptr; } + void Finish() + { + if(this->begin && allocated) + { + free(this->begin); + } + this->begin = this->end = this->in = this->out = nullptr; + } void Clear() { this->in = this->out = this->begin; } size_t Limit() { return (this->end > this->begin) ? (this->end - this->begin) : 0; } @@ -62,6 +85,7 @@ struct Buffer uint8_t * end = nullptr; uint8_t * in = nullptr; uint8_t * out = nullptr; + bool allocated = false; }; //------------------------------------------------------------------------------ @@ -142,7 +166,7 @@ struct Argument : public Buffer State_Ready = 5, }; - Argument(uint8_t * ptr, size_t size) : Buffer(ptr, size) { Reset(); } + Argument(uint8_t * ptr = nullptr, size_t size = 0) : Buffer(ptr, size) { Reset(); } void Reset() { diff --git a/src/platform/silabs/provision/ProvisionStorage.h b/src/platform/silabs/provision/ProvisionStorage.h index 916d088fb6..c4a148ee59 100644 --- a/src/platform/silabs/provision/ProvisionStorage.h +++ b/src/platform/silabs/provision/ProvisionStorage.h @@ -60,7 +60,8 @@ enum ID : uint16_t kGeneratorFW = 0x0135, kProductionFW = 0x0136, kCertToolPath = 0x0137, - kPylinkLib = 0x0138, + kPylinkLib = 0x013a, + kBufferSize = 0x013b, // Instance Info, kSerialNumber = 0x0141, kVendorId = 0x0142, @@ -148,7 +149,6 @@ struct Storage : public GenericStorage, static constexpr size_t kSpake2pSaltB64LengthMax = BASE64_ENCODED_LEN(chip::Crypto::kSpake2p_Max_PBKDF_Salt_Length) + 1; static constexpr size_t kFirmwareInfoSizeMax = 32; static constexpr size_t kCertificationSizeMax = 350; - static constexpr size_t kCertificateSizeMax = kArgumentSizeMax; static constexpr size_t kDeviceAttestationKeySizeMax = 128; static constexpr size_t kSetupPayloadSizeMax = 32; static constexpr size_t kCsrLengthMax = 512; @@ -160,9 +160,7 @@ struct Storage : public GenericStorage, static constexpr size_t kTotalPayloadDataSize = kTotalPayloadDataSizeInBits / 8; public: - static uint8_t aux_buffer[Storage::kArgumentSizeMax]; - - friend class Manager; + friend class Manager; friend class Protocol1; friend class Command; friend class CsrCommand; @@ -238,6 +236,8 @@ struct Storage : public GenericStorage, CHIP_ERROR SetProvisionRequest(bool value); CHIP_ERROR GetProvisionRequest(bool & value); CHIP_ERROR GetTestEventTriggerKey(MutableByteSpan & keySpan); + void SetBufferSize(size_t size) { mBufferSize = size; } + size_t GetBufferSize() { return mBufferSize; } private: // Generic Interface @@ -291,6 +291,7 @@ struct Storage : public GenericStorage, uint32_t mRendezvousFlags = 0; uint32_t mPasscode = 0; uint32_t mKeyId = 0; + uint32_t mBufferSize = kArgumentSizeMax; char mCommonName[kCommonNameMax] = { 0 }; CustomStorage mCustom; };