pebble/tests/fakes/fake_put_bytes_storage_mem.c
2025-01-27 11:38:16 -08:00

141 lines
4.6 KiB
C

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "fake_put_bytes_storage_mem.h"
#include "clar_asserts.h"
#include "kernel/pbl_malloc.h"
#include "services/common/put_bytes/put_bytes_storage_internal.h"
#include "system/passert.h"
#define FAKE_STORAGE_MAX_SIZE (512 * 1024)
typedef struct FakePutBytesStorageData {
PutBytesStorageInfo *info;
bool last_is_success;
uint32_t crc;
uint32_t total_size;
uint8_t buffer[FAKE_STORAGE_MAX_SIZE];
} FakePutBytesStorageData;
FakePutBytesStorageData s_storage_data;
bool pb_storage_raw_get_status(PutBytesObjectType obj_type, PbInstallStatus *status) {
return false;
}
static bool fake_pb_storage_mem_init(PutBytesStorage *storage, PutBytesObjectType object_type,
uint32_t total_size, PutBytesStorageInfo *info,
uint32_t append_offset) {
// This fake only supports one put bytes storage to be init'd at a time.
PBL_ASSERTN(!s_storage_data.total_size);
size_t buffer_size = total_size + sizeof(FirmwareDescription);
memset(s_storage_data.buffer, 0, sizeof(s_storage_data.buffer));
s_storage_data.total_size = buffer_size;
PutBytesStorageInfo *info_copy = NULL;
if (info) {
info_copy = (PutBytesStorageInfo *)kernel_malloc_check(sizeof(PutBytesStorageInfo));
*info_copy = *info;
}
s_storage_data.info = info_copy;
storage->impl_data = &s_storage_data;
// put_bytes_storage_raw.c is weird, it reserves space at the beginning for FirmwareDescription:
storage->current_offset = sizeof(FirmwareDescription);
return true;
}
uint32_t fake_pb_storage_mem_get_max_size(PutBytesObjectType object_type) {
return FAKE_STORAGE_MAX_SIZE;
}
static void(*s_do_before_write)(void) = NULL;
static void fake_pb_storage_mem_write(PutBytesStorage *storage, uint32_t offset,
const uint8_t *buffer, uint32_t length) {
PBL_ASSERTN(s_storage_data.total_size);
PBL_ASSERTN(offset + length <= s_storage_data.total_size);
if (s_do_before_write) {
s_do_before_write();
s_do_before_write = NULL;
}
memcpy(s_storage_data.buffer + offset, buffer, length);
}
static uint32_t fake_pb_storage_mem_calculate_crc(PutBytesStorage *storage, PutBytesCrcType crc_type) {
PBL_ASSERTN(storage->impl_data == &s_storage_data);
return s_storage_data.crc;
}
static void prv_cleanup(void) {
kernel_free(s_storage_data.info);
s_storage_data.info = NULL;
s_storage_data.total_size = 0;
}
static void fake_pb_storage_mem_deinit(PutBytesStorage *storage, bool is_success) {
PBL_ASSERTN(storage->impl_data == &s_storage_data);
prv_cleanup();
s_storage_data.last_is_success = is_success;
}
const PutBytesStorageImplementation s_raw_implementation = {
.init = fake_pb_storage_mem_init,
.get_max_size = fake_pb_storage_mem_get_max_size,
.write = fake_pb_storage_mem_write,
.calculate_crc = fake_pb_storage_mem_calculate_crc,
.deinit = fake_pb_storage_mem_deinit,
};
const PutBytesStorageImplementation s_file_implementation = {
.init = fake_pb_storage_mem_init,
.get_max_size = fake_pb_storage_mem_get_max_size,
.write = fake_pb_storage_mem_write,
.calculate_crc = fake_pb_storage_mem_calculate_crc,
.deinit = fake_pb_storage_mem_deinit,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Fake manipulation
void fake_pb_storage_register_cb_before_write(void (*cb_before_write)(void)) {
s_do_before_write = cb_before_write;
}
void fake_pb_storage_mem_reset(void) {
prv_cleanup();
s_storage_data = (FakePutBytesStorageData) {};
}
void fake_pb_storage_mem_set_crc(uint32_t crc) {
s_storage_data.crc = crc;
}
bool fake_pb_storage_mem_get_last_success(void) {
return s_storage_data.last_is_success;
}
void fake_pb_storage_mem_assert_contents_written(const uint8_t contents[], size_t size) {
cl_assert_equal_m(contents, s_storage_data.buffer + sizeof(FirmwareDescription), size);
}
void fake_pb_storage_mem_assert_fw_description_written(const FirmwareDescription *fw_descr) {
cl_assert_equal_m(fw_descr, s_storage_data.buffer, sizeof(*fw_descr));
}
#undef FAKE_STORAGE_MAX_SIZE