diff --git a/.gitignore b/.gitignore index e818d98..be632a7 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,5 @@ project/.mxproject project/project.launch -project/.cproject \ No newline at end of file +project/.cproject +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d4d1025 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) + +project(WSAA_tests LANGUAGES CXX C) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(VERSION_MAJOR 1) +set(VERSION_MINOR 0) + +include(GNUInstallDirs) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) +set(PROJECT_DIR ${CMAKE_CURRENT_LIST_DIR}) + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/project/Core/Src/tftp.c b/project/Core/Src/tftp.c index 8d085bd..863e269 100644 --- a/project/Core/Src/tftp.c +++ b/project/Core/Src/tftp.c @@ -37,6 +37,50 @@ int str_cat(char* dest, size_t dest_size, char c) return 0; } +/** + * @brief tftp custom file functions to set the offset and read the data + * @param[in,out] handle Custom file handles + * @param[in] offset The offset to set + * @param[in] whence The origin of the offset + */ +void tftp_custom_fseek(tftp_custom_file_t* handle, size_t offset, int whence) { + switch (whence) { + case SEEK_SET: + handle->ofset = offset; + break; + case SEEK_CUR: + handle->ofset += offset; + break; + case SEEK_END: + break; + } + if (handle->ofset > handle->len) { + handle->ofset = handle->len; + } +} + +/** + * @brief tftp custom file functions to read the data + * auto rolling over the offset + * if the bytes to read is bigger than the remaining bytes + * it will read the remaining bytes and set the bytes to 0 + * @param[out] buf The buffer to write the data to + * @param[in] bytes The number of bytes to read + * @param[in,out] handle Custom file handles + */ +size_t tftp_custom_fread(void* buf, size_t bytes, tftp_custom_file_t* handle) { + if (handle->ofset + bytes > handle->len) { + bytes = handle->len - handle->ofset; + } + memcpy(buf, handle->data + handle->ofset, bytes); + handle->ofset += bytes; + ((char*)buf)[bytes] = '\0'; + if (handle->ofset > handle->len) { + bytes = 0; + } + return bytes; +} + /** * @brief tftp helper functions */ @@ -94,6 +138,7 @@ void tftp_close(void* handle) { * @return int >= 0: Success; < 0: Error */ int tftp_read(void* handle, void* buf, int bytes) { + int ret = 0; LOG_INFO(TAG, "reading file"); if (handle == NULL) { LOG_CRIT(TAG, "handle is null"); @@ -102,17 +147,18 @@ int tftp_read(void* handle, void* buf, int bytes) { FILE* file = (FILE*)handle; if (file == &virt_file[0]) { - // TODO: read index.txt using tftp_custom_file - LOG_CRIT(TAG, "Reading from index.txt is not implemented yet"); - return -1; - + ret = tftp_custom_fread(buf, bytes, file); + return ret; } else if (file == &virt_file[1]) { LOG_CRIT(TAG, "Exception: Trying to read a write only file"); return -1; } // TODO: waiting on Lorentz to finish creating f* functions for LLFS - fread(buf, sizeof(uint8_t), bytes, file); - return 0; + ret = fread(buf, sizeof(uint8_t), bytes, file); + if (ret <= 0) { + return -1; + } + return ret; } /** @@ -144,7 +190,7 @@ void init_index(void) len += strlen(root->name) + 1; root = root->next; } - + len++; // +1 for the \0 virt_file[0].data = malloc(len); virt_file[0].len = len; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..3b36bc7 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,28 @@ +find_package(GTest REQUIRED) + +# Third Party +include_directories(${GTEST_INCLUDE_DIR}) + +link_directories(${GTEST_LIB_DIR}) + +# tests +file(GLOB_RECURSE TEST_SOURCES "*.cpp") +add_executable(tests ${TEST_SOURCES}) + +target_compile_options(tests PRIVATE $<$: + -Wall -Wextra -pedantic-errors -Wconversion -Wsign-conversion + >) +target_link_libraries(tests + PRIVATE + gtest + GTest::gtest_main +) + +target_include_directories(tests + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ${PROJECT_BINARY_DIR} +) + +include(GoogleTest) +gtest_discover_tests(tests) \ No newline at end of file diff --git a/tests/tfpt_tests.cpp b/tests/tfpt_tests.cpp new file mode 100644 index 0000000..e6642e2 --- /dev/null +++ b/tests/tfpt_tests.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +#include "tftp.hpp" + +tftp_custom_file_t file = { + .data = (char*)"1234567890", + .len = 11, + .name = (char*)"test.txt", + .ofset = 0 + }; + +TEST(TFTP, custom_fseek) +{ + tftp_custom_fseek(&file, 5, SEEK_SET); + EXPECT_EQ(file.ofset, 5); + tftp_custom_fseek(&file, 5, SEEK_CUR); + EXPECT_EQ(file.ofset, 10); +} + +TEST(TFTP, custom_fread) +{ + char buf[11]; + tftp_custom_fseek(&file, 0, SEEK_SET); + size_t bytes = tftp_custom_fread(buf, 11, &file); + EXPECT_EQ(bytes, 11); + EXPECT_EQ(file.ofset, 11); + + memset(buf, 0, 11); + + tftp_custom_fseek(&file, 0, SEEK_SET); + bytes = tftp_custom_fread(buf, 11, &file); + EXPECT_EQ(bytes, 11); + EXPECT_EQ(memcmp(buf, "1234567890", 10), 0); + + tftp_custom_fseek(&file, 0, SEEK_SET); + bytes = tftp_custom_fread(buf, 5, &file); + EXPECT_EQ(bytes, 5); + EXPECT_EQ(memcmp(buf, "12345", 5), 0); +} + + diff --git a/tests/tftp.cpp b/tests/tftp.cpp new file mode 100644 index 0000000..4def0eb --- /dev/null +++ b/tests/tftp.cpp @@ -0,0 +1,45 @@ +#include "tftp.hpp" + +/** + * @brief tftp custom file functions to set the offset and read the data + * @param[in,out] handle Custom file handles + * @param[in] offset The offset to set + * @param[in] whence The origin of the offset + */ +void tftp_custom_fseek(tftp_custom_file_t* handle, size_t offset, int whence) { + switch (whence) { + case SEEK_SET: + handle->ofset = offset; + break; + case SEEK_CUR: + handle->ofset += offset; + break; + case SEEK_END: + break; + } + if (handle->ofset > handle->len) { + handle->ofset = handle->len; + } +} + +/** + * @brief tftp custom file functions to read the data + * auto rolling over the offset + * if the bytes to read is bigger than the remaining bytes + * it will read the remaining bytes and set the bytes to 0 + * @param[out] buf The buffer to write the data to + * @param[in] bytes The number of bytes to read + * @param[in,out] handle Custom file handles + */ +size_t tftp_custom_fread(void* buf, size_t bytes, tftp_custom_file_t* handle) { + if (handle->ofset + bytes > handle->len) { + bytes = handle->len - handle->ofset; + } + memcpy(buf, handle->data + handle->ofset, bytes); + handle->ofset += bytes; + ((char*)buf)[bytes] = '\0'; + if (handle->ofset > handle->len) { + bytes = 0; + } + return bytes; +} \ No newline at end of file diff --git a/tests/tftp.hpp b/tests/tftp.hpp new file mode 100644 index 0000000..868b1da --- /dev/null +++ b/tests/tftp.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include +#include +#include +#include +#include + +typedef struct tftp_custom_file_s { + const char* data; + size_t len; + char*name; + size_t ofset; +}tftp_custom_file_t; + +void tftp_custom_fseek(tftp_custom_file_t* handle, size_t offset, int whence); +size_t tftp_custom_fread(void* buf, size_t bytes, tftp_custom_file_t* handle); \ No newline at end of file