49 res.which_kind = pb_UpdateResponse_ack_tag;
50 res.kind.ack.chunk_size = CHUNK_SIZE;
54static void make_success(pb_UpdateResponse &res) { res.which_kind = pb_UpdateResponse_success_tag; }
57static void make_failure(pb_UpdateResponse &res,
const char *reason) {
58 res.which_kind = pb_UpdateResponse_failure_tag;
59 strncpy(res.kind.failure.reason, reason,
sizeof(res.kind.failure.reason) - 1);
60 res.kind.failure.reason[
sizeof(res.kind.failure.reason) - 1] =
'\0';
66void Updater::reset_state() {
69 memset(m_expected_hash.data(), 0,
sizeof(m_expected_hash));
76static inline
void flush(
void *addr, uint32_t
size)
78 uint32_t
location = (uint32_t)addr & 0xFFFFFFE0;
80 asm volatile(
"": : :
"memory");
93 while (offset <
size) {
94 const uint32_t remaining =
size - offset;
95 auto *cur = base + offset;
96 const uintptr_t addr =
reinterpret_cast<uintptr_t
>(cur);
98 if (remaining >= BLOCK_64K && (addr % BLOCK_64K == 0)) {
101 }
else if (remaining >= BLOCK_32K && (addr % BLOCK_32K == 0)) {
106 offset += SECTOR_SIZE;
114bool Updater::verify_hash()
const {
115 auto *staging =
reinterpret_cast<uint32_t *
>(STAGING_START_ADDR);
116 utils::sha256_t actual_hash;
118 return actual_hash == m_expected_hash;
130 for (
auto idx = 0; idx <
size / 4; ++idx) {
131 alignas(4) uint32_t value = src[idx];
149void Updater::begin(
const pb_UpdateBegin &req, pb_UpdateResponse &res) {
156 if (req.size == 0 || req.size > MAX_FW_SIZE)
159 if (req.hash.size != 32)
162 m_expected_size =
static_cast<uint32_t
>(req.size);
166 auto *staging =
reinterpret_cast<uint8_t *
>(STAGING_START_ADDR);
173 memcpy(m_expected_hash.data(), req.hash.bytes, 32);
176 LOGV(
"BEGIN UPLOAD of %d bytes", m_expected_size);
182void Updater::write(
const pb_UpdateWrite &req, pb_UpdateResponse &res) {
186 auto offset =
static_cast<size_t>(req.offset);
187 size_t data_len = req.data.size;
188 auto src = req.data.bytes;
194 if (offset + data_len > m_expected_size)
195 return make_failure(res,
"chunk exceeds declared firmware size");
197 std::memcpy(m_buffer, src, data_len);
200 auto *src_buffer =
reinterpret_cast<uint32_t *
>(m_buffer);
201 auto *dst =
reinterpret_cast<uint32_t *
>(STAGING_START_ADDR + offset);
212void Updater::commit(
const pb_UpdateCommit & , pb_UpdateResponse &res,
const std::function<
void()> &&success) {
222 auto *app =
reinterpret_cast<uint32_t *
>(APP_START_ADDR);
223 auto *staging =
reinterpret_cast<uint32_t *
>(STAGING_START_ADDR);
232void Updater::abort(
const pb_UpdateAbort & , pb_UpdateResponse &res) {
242void Updater::verify(
const pb_UpdateVerify & , pb_UpdateResponse &res) {
void hash_sha256(const uint8_t *msg, size_t msg_len, uint8_t *out_hash)
Computes the SHA256 sum of an arbitrary message (large memory segment).