Skip to content

Commit

Permalink
suit: Split fetch implementation
Browse files Browse the repository at this point in the history
Split suit_plat_fetch implementation into app-specific and sdfw-specific
parts.

Ref: NCSDK-30809

Signed-off-by: Tomasz Chyrowicz <[email protected]>
  • Loading branch information
tomchy committed Jan 27, 2025
1 parent 987b0b3 commit f995034
Show file tree
Hide file tree
Showing 4 changed files with 785 additions and 462 deletions.
219 changes: 153 additions & 66 deletions subsys/suit/platform/app/src/suit_plat_fetch_app_specific.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,109 +4,196 @@
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <stdbool.h>
#include <zephyr/logging/log.h>
#include <suit_plat_error_convert.h>
#include <suit_plat_fetch_domain_specific.h>

#ifdef CONFIG_SUIT_STREAM
#include <suit_platform_internal.h>
#include <suit_plat_decode_util.h>
#include <suit_plat_fetch_domain_specific.h>
#include <suit_plat_err.h>
#include <suit_plat_error_convert.h>

#ifdef CONFIG_SUIT_STREAM_SINK_CACHE
#include <suit_dfu_cache_sink.h>
#include <suit_dfu_cache_streamer.h>
#include <suit_generic_address_streamer.h>
#endif /* CONFIG_SUIT_STREAM_SINK_CACHE */

#ifdef CONFIG_SUIT_STREAM_FETCH_SOURCE_MGR
#include "suit_fetch_source_streamer.h"
#endif /* CONFIG_SUIT_STREAM_FETCH_SOURCE_MGR */
#ifdef CONFIG_SUIT_STREAM_SOURCE_CACHE
#include <suit_dfu_cache_streamer.h>
#endif /* CONFIG_SUIT_STREAM_SOURCE_CACHE */

LOG_MODULE_REGISTER(suit_plat_fetch_app, CONFIG_SUIT_LOG_LEVEL);

bool suit_plat_fetch_domain_specific_is_type_supported(suit_component_type_t component_type)
#ifdef CONFIG_SUIT_STREAM_SINK_CACHE
static int suit_plat_fetch_cache(suit_component_t dst_handle, struct zcbor_string *uri,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info, bool dry_run)
{
if ((component_type == SUIT_COMPONENT_TYPE_CAND_IMG) ||
(component_type == SUIT_COMPONENT_TYPE_CAND_MFST) ||
(component_type == SUIT_COMPONENT_TYPE_CACHE_POOL)) {
return true;
#ifndef CONFIG_SUIT_STREAM_FETCH_SOURCE_MGR
return SUIT_ERR_UNSUPPORTED_COMMAND;
#else
suit_plat_err_t plat_ret = SUIT_PLAT_SUCCESS;
struct stream_sink dst_sink = {0};
struct zcbor_string *component_id = NULL;
int ret = SUIT_SUCCESS;
uint32_t number;

/*
* Validate streaming operation.
*/
ret = suit_plat_component_id_get(dst_handle, &component_id);
if (ret != SUIT_SUCCESS) {
LOG_ERR("Failed to parse component ID from handle: %d", ret);
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

return false;
if (suit_plat_decode_component_number(component_id, &number) != SUIT_PLAT_SUCCESS) {
LOG_ERR("Missing component id number in cache pool component");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

if (enc_info != NULL) {
LOG_ERR("Decryption while streaming to cache pool is not supported");
(void)manifest_component_id;
return SUIT_ERR_UNSUPPORTED_PARAMETER;
}

/*
* Construct the stream.
*/

plat_ret = suit_dfu_cache_sink_get(&dst_sink, number, uri->value, uri->len, !dry_run);
if (plat_ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Unable to create cache sink: %d", plat_ret);
ret = suit_plat_err_to_processor_err_convert(plat_ret);
}

if (!dry_run) {
/*
* Stream the data.
*/

/* Erase the destination memory area. */
if ((ret == SUIT_SUCCESS) && (dst_sink.erase != NULL)) {
plat_ret = dst_sink.erase(dst_sink.ctx);
if (plat_ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Sink erase failed: %d", plat_ret);
ret = suit_plat_err_to_processor_err_convert(plat_ret);
}
}

/* Start streaming the data. */
if (ret == SUIT_SUCCESS) {
plat_ret = suit_fetch_source_stream(uri->value, uri->len, &dst_sink);
if (plat_ret == SUIT_PLAT_SUCCESS) {
suit_dfu_cache_sink_commit(dst_sink.ctx);
} else {
LOG_ERR("Streaming to cache failed: %d", plat_ret);
}

/* Failures of fetch_source streamer are treated as "unavailable payload"
* failures. These are cases where suit-condition-image-match will detect
* the failure, however suit-plat-fetch should return success to allow
* soft failures.
*/
ret = SUIT_SUCCESS;
}

if ((ret == SUIT_SUCCESS) && (dst_sink.flush != NULL)) {
plat_ret = dst_sink.flush(dst_sink.ctx);
if (plat_ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Sink flush failed: %d", plat_ret);
ret = suit_plat_err_to_processor_err_convert(plat_ret);
}
}
}

/*
* Destroy the stream.
*/

plat_ret = release_sink(&dst_sink);
if (plat_ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Sink release failed: %d", plat_ret);
}

if (ret == SUIT_SUCCESS) {
ret = suit_plat_err_to_processor_err_convert(plat_ret);
}

return ret;
#endif /* CONFIG_SUIT_STREAM_FETCH_SOURCE_MGR */
}
#endif /* CONFIG_SUIT_STREAM_SINK_CACHE */

bool suit_plat_fetch_integrated_domain_specific_is_type_supported(
suit_component_type_t component_type)
bool suit_plat_fetch_domain_specific_is_type_supported(suit_component_type_t dst_component_type)
{
if ((component_type == SUIT_COMPONENT_TYPE_CAND_IMG) ||
(component_type == SUIT_COMPONENT_TYPE_CAND_MFST)) {
#ifdef CONFIG_SUIT_STREAM_SINK_CACHE
if (dst_component_type == SUIT_COMPONENT_TYPE_CACHE_POOL) {
return true;
}
#endif /* CONFIG_SUIT_STREAM_SINK_CACHE */

return false;
}

int suit_plat_check_fetch_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct zcbor_string *uri,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info)
{
switch (dst_component_type) {
#ifdef CONFIG_SUIT_STREAM_SINK_CACHE
case SUIT_COMPONENT_TYPE_CACHE_POOL:
return suit_plat_fetch_cache(dst_handle, uri, manifest_component_id, enc_info,
true);
#endif /* CONFIG_SUIT_STREAM_SINK_CACHE */
default:
break;
}

return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

int suit_plat_fetch_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct stream_sink *dst_sink, struct zcbor_string *uri)
struct zcbor_string *uri,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info)
{
int ret = SUIT_SUCCESS;
bool hard_failure = false;

/* Select streamer */
switch (dst_component_type) {
#ifdef CONFIG_SUIT_STREAM_FETCH_SOURCE_MGR
#ifdef CONFIG_SUIT_STREAM_SINK_CACHE
case SUIT_COMPONENT_TYPE_CACHE_POOL:
case SUIT_COMPONENT_TYPE_MEM: {
ret = suit_fetch_source_stream(uri->value, uri->len, dst_sink);
ret = suit_plat_err_to_processor_err_convert(ret);
} break;
#endif /* SUIT_STREAM_FETCH_SOURCE_MGR */
#if defined(CONFIG_SUIT_CACHE_RW) || defined(SUIT_CACHE)
case SUIT_COMPONENT_TYPE_CAND_MFST:
case SUIT_COMPONENT_TYPE_CAND_IMG: {
ret = suit_dfu_cache_streamer_stream(uri->value, uri->len, dst_sink);
ret = suit_plat_err_to_processor_err_convert(ret);
} break;
#endif
return suit_plat_fetch_cache(dst_handle, uri, manifest_component_id, enc_info,
false);
#endif /* CONFIG_SUIT_STREAM_SINK_CACHE */
default:
ret = SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
hard_failure = true;
break;
}

if (ret == SUIT_SUCCESS && dst_component_type == SUIT_COMPONENT_TYPE_CACHE_POOL) {
suit_dfu_cache_sink_commit(dst_sink->ctx);
}
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

if (!hard_failure) {
/* Failures without hard_failure flag set are treated as "unavailable payload"
* failures. These are cases where suit-condition-image-match will detect
* the failure, however suit-plat-fetch should return success to allow
* soft failures.
*/
ret = SUIT_SUCCESS;
}
bool suit_plat_fetch_integrated_domain_specific_is_type_supported(
suit_component_type_t component_type)
{
return false;
}

return ret;
int suit_plat_check_fetch_integrated_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct zcbor_string *payload,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info)
{
return SUIT_ERR_UNSUPPORTED_COMMAND;
}

int suit_plat_fetch_integrated_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct stream_sink *dst_sink,
struct zcbor_string *payload)
struct zcbor_string *payload,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info)
{
suit_plat_err_t ret = SUIT_PLAT_SUCCESS;

(void)dst_handle;
(void)dst_component_type;

if (payload == NULL) {
return SUIT_ERR_UNAVAILABLE_PAYLOAD;
}

ret = suit_generic_address_streamer_stream(payload->value, payload->len, dst_sink);

return suit_plat_err_to_processor_err_convert(ret);
return SUIT_ERR_UNSUPPORTED_COMMAND;
}

#endif /* CONFIG_SUIT_STREAM */
30 changes: 24 additions & 6 deletions subsys/suit/platform/include/suit_plat_fetch_domain_specific.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#include <stdint.h>
#include <suit_types.h>
#include <suit_platform_internal.h>
#ifdef CONFIG_SUIT_STREAM
#include <suit_sink.h>

#ifdef __cplusplus
extern "C" {
Expand All @@ -28,24 +26,44 @@ bool suit_plat_fetch_domain_specific_is_type_supported(suit_component_type_t com
bool suit_plat_fetch_integrated_domain_specific_is_type_supported(
suit_component_type_t component_type);

/**
* @brief Domain specific part of the core part of the suit_plat_fetch function.
*/
int suit_plat_check_fetch_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct zcbor_string *uri,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info);

/**
* @brief Domain specific part of the core part of the suit_plat_fetch function.
*/
int suit_plat_fetch_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct stream_sink *dst_sink, struct zcbor_string *uri);
struct zcbor_string *uri,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info);

/**
* @brief Domain specific part of the core part of the suit_plat_fetch_integrated function
*/
int suit_plat_check_fetch_integrated_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct zcbor_string *payload,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info);

/**
* @brief Domain specific part of the core part of the suit_plat_fetch_integrated function
*/
int suit_plat_fetch_integrated_domain_specific(suit_component_t dst_handle,
suit_component_type_t dst_component_type,
struct stream_sink *dst_sink,
struct zcbor_string *payload);
struct zcbor_string *payload,
struct zcbor_string *manifest_component_id,
struct suit_encryption_info *enc_info);

#ifdef __cplusplus
}
#endif

#endif /* CONFIG_SUIT_STREAM */
#endif /* SUIT_PLAT_FETCH_DOMAIN_SPECIFIC_H__ */
Loading

0 comments on commit f995034

Please sign in to comment.