Skip to content

Commit 830bf53

Browse files
[Telink] Add OTA resume support (#37978)
* [Telink] Add OTA resume support * Restyled by whitespace * Restyled by clang-format --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 168ad35 commit 830bf53

File tree

2 files changed

+76
-12
lines changed

2 files changed

+76
-12
lines changed

src/platform/telink/OTAImageProcessorImpl.cpp

+69-12
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <app/clusters/ota-requestor/OTADownloader.h>
2121
#include <app/clusters/ota-requestor/OTARequestorInterface.h>
2222
#include <platform/CHIPDeviceLayer.h>
23+
#include <platform/KeyValueStoreManager.h>
2324

2425
#include <zephyr/dfu/mcuboot.h>
2526
#include <zephyr/storage/flash_map.h>
@@ -28,6 +29,8 @@
2829

2930
static struct stream_flash_ctx stream;
3031

32+
using namespace ::chip::DeviceLayer::PersistedStorage;
33+
3134
namespace chip {
3235
namespace {
3336

@@ -53,33 +56,39 @@ CHIP_ERROR OTAImageProcessorImpl::PrepareDownload()
5356

5457
return DeviceLayer::SystemLayer().ScheduleLambda([this] { mDownloader->OnPreparedForDownload(PrepareDownloadImpl()); });
5558
}
59+
const struct device * flash_dev;
5660

57-
CHIP_ERROR OTAImageProcessorImpl::PrepareDownloadImpl()
61+
CHIP_ERROR OTAImageProcessorImpl::InitFlashStream(size_t offset)
5862
{
59-
mHeaderParser.Init();
60-
mParams = {};
61-
62-
const struct device * flash_dev;
63-
6463
flash_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller));
6564
if (flash_dev == NULL)
6665
{
6766
ChipLogError(SoftwareUpdate, "Failed to get flash device");
6867
return System::MapErrorZephyr(-EFAULT);
6968
}
7069

71-
int err = stream_flash_init(&stream, flash_dev, mBuffer, sizeof(mBuffer), FIXED_PARTITION_OFFSET(slot1_partition),
72-
FIXED_PARTITION_SIZE(slot1_partition), NULL);
70+
int err = stream_flash_init(&stream, flash_dev, mBuffer, sizeof(mBuffer), FIXED_PARTITION_OFFSET(slot1_partition) + offset,
71+
FIXED_PARTITION_SIZE(slot1_partition) - offset, NULL);
7372

7473
if (err)
7574
{
7675
ChipLogError(SoftwareUpdate, "stream_flash_init failed (err %d)", err);
7776
}
7877

79-
PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadInProgress);
8078
return System::MapErrorZephyr(err);
8179
}
8280

81+
CHIP_ERROR OTAImageProcessorImpl::PrepareDownloadImpl()
82+
{
83+
mHeaderParser.Init();
84+
mParams = {};
85+
86+
CHIP_ERROR error = InitFlashStream(0);
87+
88+
PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadInProgress);
89+
return error;
90+
}
91+
8392
CHIP_ERROR OTAImageProcessorImpl::Finalize()
8493
{
8594
int err = stream_flash_buffered_write(&stream, NULL, 0, true);
@@ -136,8 +145,16 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock)
136145

137146
if (error == CHIP_NO_ERROR)
138147
{
139-
error = System::MapErrorZephyr(stream_flash_buffered_write(&stream, aBlock.data(), aBlock.size(), false));
140-
mParams.downloadedBytes += aBlock.size();
148+
if (downloadedBytesRestored)
149+
{
150+
mParams.downloadedBytes = downloadedBytesRestored;
151+
}
152+
else
153+
{
154+
error = System::MapErrorZephyr(stream_flash_buffered_write(&stream, aBlock.data(), aBlock.size(), false));
155+
mParams.downloadedBytes += aBlock.size();
156+
}
157+
ReturnErrorOnFailure(KeyValueStoreMgr().Put(kDownloadedBytes, &mParams.downloadedBytes, sizeof(mParams.downloadedBytes)));
141158
}
142159

143160
// Report the result back to the downloader asynchronously.
@@ -146,7 +163,15 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock)
146163
{
147164
ChipLogDetail(SoftwareUpdate, "Downloaded %u/%u bytes", static_cast<unsigned>(mParams.downloadedBytes),
148165
static_cast<unsigned>(mParams.totalFileBytes));
149-
mDownloader->FetchNextData();
166+
if (downloadedBytesRestored)
167+
{
168+
mDownloader->SkipData(downloadedBytesRestored - aBlock.size());
169+
downloadedBytesRestored = 0;
170+
}
171+
else
172+
{
173+
mDownloader->FetchNextData();
174+
}
150175
}
151176
else
152177
{
@@ -174,6 +199,34 @@ CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage()
174199
return System::MapErrorZephyr(boot_write_img_confirmed());
175200
}
176201

202+
CHIP_ERROR OTAImageProcessorImpl::RestoreBytes(ByteSpan & aBlock)
203+
{
204+
uint8_t * ImageDigestBuffer = new uint8_t[aBlock.size()];
205+
MutableByteSpan mImageDigest(ImageDigestBuffer, aBlock.size());
206+
207+
if (KeyValueStoreMgr().Get(kImageDigest, mImageDigest.data(), mImageDigest.size()) == CHIP_NO_ERROR &&
208+
KeyValueStoreMgr().Get(kDownloadedBytes, &downloadedBytesRestored, sizeof(downloadedBytesRestored)) == CHIP_NO_ERROR &&
209+
mImageDigest.data_equal(aBlock) && downloadedBytesRestored < mParams.totalFileBytes)
210+
{
211+
// Align to the nearest lower multiple of sector size (4 KB) for Flash erase/write
212+
downloadedBytesRestored = ROUND_DOWN(downloadedBytesRestored, 0x1000);
213+
ChipLogDetail(SoftwareUpdate, "Restored %u/%u bytes", static_cast<unsigned>(downloadedBytesRestored),
214+
static_cast<unsigned>(mParams.totalFileBytes))
215+
216+
// Reinit Flash Stream with offset
217+
ReturnErrorOnFailure(System::MapErrorZephyr(stream_flash_buffered_write(&stream, NULL, 0, true)));
218+
ReturnErrorOnFailure(InitFlashStream(downloadedBytesRestored));
219+
}
220+
else
221+
{
222+
downloadedBytesRestored = 0;
223+
ReturnErrorOnFailure(KeyValueStoreMgr().Put(kImageDigest, aBlock.data(), aBlock.size()));
224+
}
225+
delete[] ImageDigestBuffer;
226+
227+
return CHIP_NO_ERROR;
228+
}
229+
177230
CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & aBlock)
178231
{
179232
if (mHeaderParser.IsInitialized())
@@ -186,6 +239,10 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & aBlock)
186239
ReturnErrorOnFailure(error);
187240

188241
mParams.totalFileBytes = header.mPayloadSize;
242+
243+
// Restore interrupted OTA process
244+
RestoreBytes(header.mImageDigest);
245+
189246
mHeaderParser.Clear();
190247
}
191248

src/platform/telink/OTAImageProcessorImpl.h

100755100644
+7
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,17 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
4444
private:
4545
CHIP_ERROR PrepareDownloadImpl();
4646
CHIP_ERROR ProcessHeader(ByteSpan & aBlock);
47+
CHIP_ERROR InitFlashStream(size_t offset);
48+
CHIP_ERROR RestoreBytes(ByteSpan & aBlock);
4749

4850
OTADownloader * mDownloader = nullptr;
4951
OTAImageHeaderParser mHeaderParser;
5052
uint8_t mBuffer[kBufferSize];
53+
54+
// Define non-volatile storage keys for DownloadedBytes and ImageDigest.
55+
static constexpr char kDownloadedBytes[] = "DownloadedBytes";
56+
static constexpr char kImageDigest[] = "ImageDigest";
57+
uint64_t downloadedBytesRestored = 0;
5158
};
5259

5360
} // namespace DeviceLayer

0 commit comments

Comments
 (0)