|
| 1 | +#include <fstream> |
| 2 | +#include <filesystem> |
| 3 | +#include <gtest/gtest.h> |
| 4 | +#include "wpc_test.hpp" |
| 5 | + |
| 6 | +class WpcScratchpadTest : public WpcTest |
| 7 | +{ |
| 8 | +public: |
| 9 | + static void SetUpTestSuite() |
| 10 | + { |
| 11 | + ASSERT_NO_FATAL_FAILURE(WpcTest::SetUpTestSuite()); |
| 12 | + ASSERT_NO_FATAL_FAILURE(WpcTest::StopStack()); |
| 13 | + ASSERT_EQ(APP_RES_OK, WPC_set_role(APP_ROLE_SINK)); |
| 14 | + ASSERT_TRUE(std::filesystem::exists(OTAP_UPLOAD_FILE_PATH)); |
| 15 | + } |
| 16 | + |
| 17 | +protected: |
| 18 | + inline static const std::filesystem::path OTAP_UPLOAD_FILE_PATH = "otap_files/dummy.otap"; |
| 19 | + |
| 20 | + std::vector<uint8_t> ReadUploadFile() const |
| 21 | + { |
| 22 | + const auto size = std::filesystem::file_size(OTAP_UPLOAD_FILE_PATH); |
| 23 | + std::vector<uint8_t> buffer(size); |
| 24 | + |
| 25 | + if (std::ifstream ifs(OTAP_UPLOAD_FILE_PATH, std::ios_base::binary); ifs) { |
| 26 | + if (ifs.read((char*)buffer.data(), size)) { |
| 27 | + return buffer; |
| 28 | + } |
| 29 | + } |
| 30 | + |
| 31 | + ADD_FAILURE() << "Cannot open file " << OTAP_UPLOAD_FILE_PATH << ". " |
| 32 | + << "Please update OTAP_UPLOAD_FILE_PATH to a valid OTAP image"; |
| 33 | + return {}; |
| 34 | + } |
| 35 | + |
| 36 | + void UploadScratchpadAndVerify(const std::vector<uint8_t>& buffer, const uint8_t seq_number) const |
| 37 | + { |
| 38 | + ASSERT_FALSE(buffer.empty()); |
| 39 | + |
| 40 | + ASSERT_EQ(APP_RES_OK, WPC_upload_local_scratchpad(buffer.size(), (uint8_t*)buffer.data(), seq_number)); |
| 41 | + |
| 42 | + ASSERT_NO_FATAL_FAILURE(VerifyUploadedScratchpad(seq_number, buffer.size())); |
| 43 | + } |
| 44 | + |
| 45 | + void VerifyUploadedScratchpad(const uint8_t seq_number, const uint32_t size) const |
| 46 | + { |
| 47 | + app_scratchpad_status_t status; |
| 48 | + ASSERT_EQ(APP_RES_OK, WPC_get_local_scratchpad_status(&status)); |
| 49 | + ASSERT_EQ(size, status.scrat_len); |
| 50 | + ASSERT_EQ(seq_number, status.scrat_seq_number); |
| 51 | + |
| 52 | + uint32_t reported_size = 0; |
| 53 | + ASSERT_EQ(APP_RES_OK, WPC_get_scratchpad_size(&reported_size)); |
| 54 | + ASSERT_EQ(size, reported_size); |
| 55 | + |
| 56 | + uint8_t reported_seq = 0; |
| 57 | + ASSERT_EQ(APP_RES_OK, WPC_get_scratchpad_sequence(&reported_seq)); |
| 58 | + ASSERT_EQ(seq_number, reported_seq); |
| 59 | + } |
| 60 | + |
| 61 | + void VerifyScratchpadsAreTheSame(const std::vector<uint8_t>& first, const std::vector<uint8_t>& second) const |
| 62 | + { |
| 63 | + std::vector<uint8_t> first_copy = { first }; |
| 64 | + std::vector<uint8_t> second_copy = { second }; |
| 65 | + |
| 66 | + // Scratchpad header (16 bytes starting at index 16) includes information |
| 67 | + // that can be different when downloaded, so exclude that part when |
| 68 | + // doing the comparison. |
| 69 | + ASSERT_GE(first_copy.size(), 32); |
| 70 | + ASSERT_GE(second_copy.size(), 32); |
| 71 | + std::fill_n(first_copy.begin() + 16, 16, 0); |
| 72 | + std::fill_n(second_copy.begin() + 16, 16, 0); |
| 73 | + |
| 74 | + ASSERT_EQ(first_copy, second_copy); |
| 75 | + } |
| 76 | +}; |
| 77 | + |
| 78 | +TEST_F(WpcScratchpadTest, testUploadAndClearScratchpad) |
| 79 | +{ |
| 80 | + const auto buffer = ReadUploadFile(); |
| 81 | + ASSERT_NO_FATAL_FAILURE(UploadScratchpadAndVerify(buffer, 101)); |
| 82 | + |
| 83 | + ASSERT_EQ(APP_RES_OK, WPC_clear_local_scratchpad()); |
| 84 | + |
| 85 | + app_scratchpad_status_t status; |
| 86 | + ASSERT_EQ(APP_RES_OK, WPC_get_local_scratchpad_status(&status)); |
| 87 | + ASSERT_EQ(0, status.scrat_len); |
| 88 | + ASSERT_EQ(0, status.scrat_seq_number); |
| 89 | + |
| 90 | + uint32_t size; |
| 91 | + ASSERT_EQ(APP_RES_ATTRIBUTE_NOT_SET, WPC_get_scratchpad_size(&size)); |
| 92 | + |
| 93 | + uint8_t seq; |
| 94 | + ASSERT_EQ(APP_RES_OK, WPC_get_scratchpad_sequence(&seq)); |
| 95 | + ASSERT_EQ(0, seq); |
| 96 | +} |
| 97 | + |
| 98 | +TEST_F(WpcScratchpadTest, testUploadAndDownloadScratchpadInBlocks) |
| 99 | +{ |
| 100 | + const auto upload_buffer = ReadUploadFile(); |
| 101 | + |
| 102 | + const uint32_t MAX_BLOCK_SIZE = 32; |
| 103 | + ASSERT_LT(MAX_BLOCK_SIZE, upload_buffer.size()); |
| 104 | + |
| 105 | + const uint8_t TEST_SEQ = 99; |
| 106 | + ASSERT_EQ(APP_RES_OK, WPC_start_local_scratchpad_update(upload_buffer.size(), TEST_SEQ)); |
| 107 | + |
| 108 | + for (size_t written = 0, remaining = upload_buffer.size(); remaining > 0;) |
| 109 | + { |
| 110 | + const uint32_t block_size = (remaining > MAX_BLOCK_SIZE) ? MAX_BLOCK_SIZE : remaining; |
| 111 | + const uint8_t* block_ptr = (uint8_t*) upload_buffer.data() + written; |
| 112 | + |
| 113 | + ASSERT_EQ(APP_RES_OK, WPC_upload_local_block_scratchpad(block_size, block_ptr, written)); |
| 114 | + |
| 115 | + written += block_size; |
| 116 | + remaining -= block_size; |
| 117 | + } |
| 118 | + |
| 119 | + ASSERT_NO_FATAL_FAILURE(VerifyUploadedScratchpad(TEST_SEQ, upload_buffer.size())); |
| 120 | + |
| 121 | + std::vector<uint8_t> download_buffer(upload_buffer.size()); |
| 122 | + for (size_t read = 0, remaining = upload_buffer.size(); remaining > 0;) |
| 123 | + { |
| 124 | + const uint32_t block_size = (remaining > MAX_BLOCK_SIZE) ? MAX_BLOCK_SIZE : remaining; |
| 125 | + uint8_t* block_ptr = (uint8_t*) download_buffer.data() + read; |
| 126 | + |
| 127 | + const app_res_e res = WPC_download_local_scratchpad(block_size, block_ptr, read); |
| 128 | + ASSERT_NE(APP_RES_ACCESS_DENIED, res) << "Access denied when downloading scratchpad block. " |
| 129 | + "Make sure the dual MCU application was built with scratchpad " |
| 130 | + "reading enabled."; |
| 131 | + ASSERT_EQ(APP_RES_OK, res); |
| 132 | + |
| 133 | + read += block_size; |
| 134 | + remaining -= block_size; |
| 135 | + } |
| 136 | + |
| 137 | + ASSERT_NO_FATAL_FAILURE(VerifyScratchpadsAreTheSame(upload_buffer, download_buffer)); |
| 138 | +} |
| 139 | + |
| 140 | +TEST_F(WpcScratchpadTest, testUploadAndDownloadScratchpad) |
| 141 | +{ |
| 142 | + auto upload_buffer = ReadUploadFile(); |
| 143 | + ASSERT_NO_FATAL_FAILURE(UploadScratchpadAndVerify(upload_buffer, 201)); |
| 144 | + |
| 145 | + std::vector<uint8_t> download_buffer(upload_buffer.size()); |
| 146 | + const app_res_e res = WPC_download_local_scratchpad(download_buffer.size(), (uint8_t*)download_buffer.data(), 0); |
| 147 | + ASSERT_NE(APP_RES_ACCESS_DENIED, res) << "Access denied when downloading scratchpad block. " |
| 148 | + "Make sure the dual MCU application was built with scratchpad " |
| 149 | + "reading enabled."; |
| 150 | + ASSERT_EQ(APP_RES_OK, res); |
| 151 | + |
| 152 | + ASSERT_NO_FATAL_FAILURE(VerifyScratchpadsAreTheSame(upload_buffer, download_buffer)); |
| 153 | +} |
| 154 | + |
0 commit comments