Files
templates/c/set-protocol/src/set_firmware.c

174 lines
6.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Кодирование метаданных и сообщений обновления SETProtocol v2. Размер образа, совместимость и
* параметры начала передачи передаются явно; сериализация команды сама по себе не выполняет
* запись Flash.
*/
#include "set_firmware.h"
#include <string.h>
size_t setp_fw_begin_encode(const setp_fw_begin_t *value, uint8_t *out, size_t capacity)
{
size_t total;
if ((value == NULL) || (out == NULL)
|| (value->block_size == 0U)
|| (value->block_size > SETP_MAX_PAYLOAD - SETP_FW_DATA_HEADER_SIZE)
|| ((value->signature_length != 0U) && (value->signature == NULL))) {
return 0U;
}
total = (size_t)SETP_FW_BEGIN_FIXED_SIZE + value->signature_length;
if ((total > SETP_MAX_PAYLOAD) || (capacity < total)
|| (((value->flags & SETP_FW_FLAG_SIGNED) != 0U)
&& (value->signature_length == 0U))) {
return 0U;
}
setp_put_u32(&out[0], value->image_size);
setp_put_u32(&out[4], value->image_crc32);
setp_put_u32(&out[8], value->image_version);
setp_put_u32(&out[12], value->base_address);
out[16] = value->slot;
out[17] = value->flags;
setp_put_u16(&out[18], value->block_size);
(void)memcpy(&out[20], value->sha256, SETP_SHA256_SIZE);
setp_put_u32(&out[52], value->signing_key_id);
setp_put_u16(&out[56], value->signature_length);
if (value->signature_length != 0U) {
(void)memcpy(&out[SETP_FW_BEGIN_FIXED_SIZE], value->signature,
value->signature_length);
}
return total;
}
bool setp_fw_begin_decode(const uint8_t *payload, uint16_t length, setp_fw_begin_t *out)
{
uint16_t signature_length;
if ((payload == NULL) || (out == NULL) || (length < SETP_FW_BEGIN_FIXED_SIZE)) {
return false;
}
out->image_size = setp_get_u32(&payload[0]);
out->image_crc32 = setp_get_u32(&payload[4]);
out->image_version = setp_get_u32(&payload[8]);
out->base_address = setp_get_u32(&payload[12]);
out->slot = payload[16];
out->flags = payload[17];
out->block_size = setp_get_u16(&payload[18]);
(void)memcpy(out->sha256, &payload[20], SETP_SHA256_SIZE);
out->signing_key_id = setp_get_u32(&payload[52]);
signature_length = setp_get_u16(&payload[56]);
if (length != SETP_FW_BEGIN_FIXED_SIZE + signature_length) {
return false;
}
out->signature_length = signature_length;
out->signature = signature_length != 0U ? &payload[SETP_FW_BEGIN_FIXED_SIZE] : NULL;
return (out->block_size != 0U)
&& (out->block_size <= SETP_MAX_PAYLOAD - SETP_FW_DATA_HEADER_SIZE)
&& (((out->flags & SETP_FW_FLAG_SIGNED) == 0U) || (signature_length != 0U));
}
size_t setp_fw_data_encode(uint32_t offset, uint16_t flags,
const uint8_t *data, uint16_t data_length,
uint8_t *out, size_t capacity)
{
size_t total = (size_t)SETP_FW_DATA_HEADER_SIZE + data_length;
if ((data == NULL) || (out == NULL) || (data_length == 0U)
|| (total > SETP_MAX_PAYLOAD) || (capacity < total)) {
return 0U;
}
setp_put_u32(&out[0], offset);
setp_put_u16(&out[4], data_length);
setp_put_u16(&out[6], flags);
setp_put_u32(&out[8], setp_crc32(data, data_length));
(void)memcpy(&out[SETP_FW_DATA_HEADER_SIZE], data, data_length);
return total;
}
bool setp_fw_data_decode(const uint8_t *payload, uint16_t length, setp_fw_data_t *out)
{
uint16_t data_length;
if ((payload == NULL) || (out == NULL) || (length < SETP_FW_DATA_HEADER_SIZE)) {
return false;
}
data_length = setp_get_u16(&payload[4]);
if ((data_length == 0U) || (length != SETP_FW_DATA_HEADER_SIZE + data_length)) {
return false;
}
out->offset = setp_get_u32(&payload[0]);
out->data_length = data_length;
out->flags = setp_get_u16(&payload[6]);
out->data_crc32 = setp_get_u32(&payload[8]);
out->data = &payload[SETP_FW_DATA_HEADER_SIZE];
return setp_crc32(out->data, out->data_length) == out->data_crc32;
}
size_t setp_fw_end_encode(const setp_fw_end_t *value, uint8_t *out, size_t capacity)
{
if ((value == NULL) || (out == NULL) || (capacity < SETP_FW_END_SIZE)) {
return 0U;
}
setp_put_u32(&out[0], value->image_size);
setp_put_u32(&out[4], value->image_crc32);
(void)memcpy(&out[8], value->sha256, SETP_SHA256_SIZE);
return SETP_FW_END_SIZE;
}
bool setp_fw_end_decode(const uint8_t *payload, uint16_t length, setp_fw_end_t *out)
{
if ((payload == NULL) || (out == NULL) || (length != SETP_FW_END_SIZE)) {
return false;
}
out->image_size = setp_get_u32(&payload[0]);
out->image_crc32 = setp_get_u32(&payload[4]);
(void)memcpy(out->sha256, &payload[8], SETP_SHA256_SIZE);
return true;
}
size_t setp_fw_status_encode(const setp_fw_status_t *value, uint8_t *out, size_t capacity)
{
if ((value == NULL) || (out == NULL) || (capacity < SETP_FW_STATUS_SIZE)) {
return 0U;
}
out[0] = value->state;
out[1] = value->active_slot;
setp_put_u16(&out[2], value->max_block_size);
setp_put_u32(&out[4], value->next_offset);
setp_put_u32(&out[8], value->image_size);
setp_put_u16(&out[12], value->last_error);
setp_put_u16(&out[14], value->flags);
return SETP_FW_STATUS_SIZE;
}
bool setp_fw_status_decode(const uint8_t *payload, uint16_t length, setp_fw_status_t *out)
{
if ((payload == NULL) || (out == NULL) || (length != SETP_FW_STATUS_SIZE)) {
return false;
}
out->state = payload[0];
out->active_slot = payload[1];
out->max_block_size = setp_get_u16(&payload[2]);
out->next_offset = setp_get_u32(&payload[4]);
out->image_size = setp_get_u32(&payload[8]);
out->last_error = setp_get_u16(&payload[12]);
out->flags = setp_get_u16(&payload[14]);
return true;
}
size_t setp_fw_manifest_encode(const setp_fw_begin_t *value,
uint8_t *out, size_t capacity)
{
static const uint8_t prefix[8] = {
'S', 'E', 'T', 'P', 'F', 'W', '2', 0U
};
if ((value == NULL) || (out == NULL) || (capacity < SETP_FW_MANIFEST_SIZE)) {
return 0U;
}
(void)memcpy(out, prefix, sizeof(prefix));
setp_put_u32(&out[8], value->image_size);
setp_put_u32(&out[12], value->image_crc32);
setp_put_u32(&out[16], value->image_version);
setp_put_u32(&out[20], value->base_address);
out[24] = value->slot;
(void)memcpy(&out[25], value->sha256, SETP_SHA256_SIZE);
return SETP_FW_MANIFEST_SIZE;
}