diff --git a/project/Core/Inc/tftp.h b/project/Core/Inc/tftp.h index 1e3a520..02c0683 100644 --- a/project/Core/Inc/tftp.h +++ b/project/Core/Inc/tftp.h @@ -9,6 +9,11 @@ #define LOGGER_LEVEL_ALL #include #include "log.h" +#include "llfs.h" +#include "stdlib.h" +#include "string.h" + +#define TFTP_READ 0 extern struct tftp_context tftpContext_s; diff --git a/project/Core/Src/tftp.c b/project/Core/Src/tftp.c index 0ca2083..44adf2c 100644 --- a/project/Core/Src/tftp.c +++ b/project/Core/Src/tftp.c @@ -8,23 +8,96 @@ static const char* TAG = "tftp_server"; +extern struct llfs_data_file* llfs_root; + +static llfs_file_t virt_file[2] = { + {.name = "index.txt", .data = "test", .len = 4}, + {.name = "virtImage.raw", .data = "test", .len = 4} + }; + +/** + * @brief tftp helper functions + */ + +/** + * @brief This function is called when a file is opened + * It should return a handle to the file or NULL if the file does not exist + * The handle contains a ptr to or the actual file data or a virtual file + * + * @param fname The name of the file to open + * @param mode Mode string from TFTP RFC + * @param write Flag indicating read (0) or write (!= 0) access + * @return void* File handle supplied to other functions + */ void* tftp_open(const char* fname, const char* mode, u8_t write) { LOG_INFO(TAG, "Opening %s", fname); + llfs_file_t* file; + + if (strcmp(fname, virt_file[0].name) == 0 && write == TFTP_READ) { + file = &virt_file[0]; + } else if (strcmp(fname, virt_file[1].name) == 0 && write != TFTP_READ) { + file = &virt_file[1]; + } + + file = llfs_file_open(fname); + return file; } +/** + * @brief This function is called when a file is closed + * + * @param handle The handle to the file to close + */ void tftp_close(void* handle) { LOG_INFO(TAG, "closing file"); } + +/** + * @brief This function is called when a file is read + * + * @param handle File handle returned by open() + * @param buf Target buffer to copy read data to + * @param bytes Number of bytes to copy to buf + * @return int >= 0: Success; < 0: Error + */ int tftp_read(void* handle, void* buf, int bytes) { LOG_INFO(TAG, "reading file"); + if (handle == NULL) { + LOG_ERROR(TAG, "handle is null"); + return -1; + } + llfs_file_t* file = (llfs_file_t*)handle; + LOG_INFO(TAG, "reading file: %s", file->name); + + if (file == &virt_file[0]) { + const struct llfs_data_file* root = llfs_root; + while(root != NULL) { + snprintf(buf, bytes, "%s\n", root->name); + file = root->next; + } + } else if (file == &virt_file[1]) { + LOG_CRIT(TAG, "Exception: Trying to read a write only file"); + return -1; + } + memcpy(buf, file->data, bytes); + return 0; } int tftp_write(void* handle, struct pbuf* p) { LOG_INFO(TAG, "Writing file"); + LOG_DEBUG(TAG, "Not implemented yet"); } -struct tftp_context tftpContext_s = {.open = tftp_open, .close = tftp_close, .read = tftp_read, .write = tftp_write}; +struct tftp_context tftpContext_s = { + .open = tftp_open, + .close = tftp_close, + .read = tftp_read, + .write = tftp_write + }; +/** + * @brief Initialize tftp server + */ void tftp_server_init(void) { LOG_INFO(TAG, "Initializing tftp server"); if (tftp_init(&tftpContext_s) != ERR_OK) {