From 6badf692fed506323cf6dabe0ddc4bda3c1fa16e Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Tue, 30 May 2017 11:50:30 +0200 Subject: [PATCH] - updated client example for IEC 61850 file services --- .../CMakeLists.txt | 6 +- .../iec61850_client_example_files/Makefile | 4 +- .../client_example_files.c | 107 ------- .../iec61850_client_example_files/file-tool.c | 261 ++++++++++++++++++ .../server_example_files.c | 2 +- 5 files changed, 267 insertions(+), 113 deletions(-) delete mode 100644 examples/iec61850_client_example_files/client_example_files.c create mode 100644 examples/iec61850_client_example_files/file-tool.c diff --git a/examples/iec61850_client_example_files/CMakeLists.txt b/examples/iec61850_client_example_files/CMakeLists.txt index 36cba27..9178d24 100644 --- a/examples/iec61850_client_example_files/CMakeLists.txt +++ b/examples/iec61850_client_example_files/CMakeLists.txt @@ -1,6 +1,6 @@ set(iec61850_client_example_files_SRCS - client_example_files.c + file-tool.c ) IF(MSVC) @@ -8,10 +8,10 @@ set_source_files_properties(${iec61850_client_example_files_SRCS} PROPERTIES LANGUAGE CXX) ENDIF(MSVC) -add_executable(iec61850_client_example_files +add_executable(file-tool ${iec61850_client_example_files_SRCS} ) -target_link_libraries(iec61850_client_example_files +target_link_libraries(file-tool iec61850 ) diff --git a/examples/iec61850_client_example_files/Makefile b/examples/iec61850_client_example_files/Makefile index eea5d9f..c4d0ecb 100644 --- a/examples/iec61850_client_example_files/Makefile +++ b/examples/iec61850_client_example_files/Makefile @@ -1,7 +1,7 @@ LIBIEC_HOME=../.. -PROJECT_BINARY_NAME = client_example_files -PROJECT_SOURCES = client_example_files.c +PROJECT_BINARY_NAME = file-tool +PROJECT_SOURCES = file-tool.c include $(LIBIEC_HOME)/make/target_system.mk include $(LIBIEC_HOME)/make/stack_includes.mk diff --git a/examples/iec61850_client_example_files/client_example_files.c b/examples/iec61850_client_example_files/client_example_files.c deleted file mode 100644 index f321f83..0000000 --- a/examples/iec61850_client_example_files/client_example_files.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * client_example_files.c - * - * This example demonstrates the usage of the file services - * - * - How to browse the file system of the server - * - How to download a file from the server - * - * Note: intended to be used with server_example3 - * - */ - -#include "iec61850_client.h" - -#include -#include - -#include "hal_thread.h" - -#define MAX_BUFFER_SIZE 2000000 - -static uint8_t downloadBuffer[MAX_BUFFER_SIZE]; -static int bufferPosition = 0; - -static bool -downloadHandler(void* parameter, uint8_t* buffer, uint32_t bytesRead) -{ - printf("received %i bytes\n", bytesRead); - - if (bufferPosition + bytesRead < MAX_BUFFER_SIZE) { - memcpy(downloadBuffer + bufferPosition, buffer, bytesRead); - - bufferPosition += bytesRead; - - return true; - } - else - return false; -} - -int main(int argc, char** argv) { - - char* hostname; - int tcpPort = 102; - - if (argc > 1) - hostname = argv[1]; - else - hostname = "localhost"; - - if (argc > 2) - tcpPort = atoi(argv[2]); - - IedClientError error; - - IedConnection con = IedConnection_create(); - - IedConnection_connect(con, &error, hostname, tcpPort); - - if (error == IED_ERROR_OK) { - - /* Get the root directory */ - LinkedList rootDirectory = - IedConnection_getFileDirectory(con, &error, NULL); - - if (error != IED_ERROR_OK) { - printf("Error retrieving file directory\n"); - goto abort_connection; - } - - - LinkedList directoryEntry = LinkedList_getNext(rootDirectory); - - while (directoryEntry != NULL) { - - FileDirectoryEntry entry = (FileDirectoryEntry) directoryEntry->data; - - printf("%s %i\n", FileDirectoryEntry_getFileName(entry), FileDirectoryEntry_getFileSize(entry)); - - directoryEntry = LinkedList_getNext(directoryEntry); - } - - - /* Download a file from the server */ - IedConnection_getFile(con, &error, "IEDSERVER.BIN", downloadHandler, NULL); - - if (error != IED_ERROR_OK) - printf("Failed to get file!\n"); - - /* Delete file at server */ - IedConnection_deleteFile(con, &error, "IEDSERVER.BIN"); - - if (error != IED_ERROR_OK) - printf("Failed to delete file! (code=%i)\n", error); - - abort_connection: - - IedConnection_abort(con, &error); - } - else { - printf("Failed to connect to %s:%i\n", hostname, tcpPort); - } - - IedConnection_destroy(con); -} - - diff --git a/examples/iec61850_client_example_files/file-tool.c b/examples/iec61850_client_example_files/file-tool.c new file mode 100644 index 0000000..492dd0c --- /dev/null +++ b/examples/iec61850_client_example_files/file-tool.c @@ -0,0 +1,261 @@ +/* + * file-tool.c + * + * This example demonstrates the usage of the file services + * + * - How to browse the file system of the server + * - How to download a file from the server + * + * Note: intended to be used with server_example3 or server_example_files + * + */ + +#include "iec61850_client.h" + +#include +#include +#include + +static char* hostname = "localhost"; +static int tcpPort = 102; +static char* filename = NULL; + +typedef enum { + FileOperationType_None = 0, + FileOperationType_Dir, + FileOperationType_Info, + FileOperationType_Del, + FileOperationType_Get, + FileOperationType_Set +} FileOperationType; + +static FileOperationType operation = FileOperationType_None; + + + +static bool +downloadHandler(void* parameter, uint8_t* buffer, uint32_t bytesRead) +{ + FILE* fp = (FILE*) parameter; + + printf("received %i bytes\n", bytesRead); + + if (fwrite(buffer, bytesRead, 1, fp) == 1) + return true; + else { + printf("Failed to write local file!\n"); + return false; + } + +} + +static void +printHelp() +{ + printf("file-tool [options] []\n"); + printf(" Options:\n"); + printf(" -h \n"); + printf(" -p portnumber\n"); + printf(" Operations\n"); + printf(" dir - show directory\n"); + printf(" info - show file info\n"); + printf(" del - delete file\n"); + printf(" get - get file\n"); + printf(" set - set file\n"); +} + + +static int +parseOptions(int argc, char** argv) +{ + int currentArgc = 1; + + int retVal = 0; + + while (currentArgc < argc) { + if (strcmp(argv[currentArgc], "-h") == 0) { + hostname = argv[++currentArgc]; + } + else if (strcmp(argv[currentArgc], "-p") == 0) { + tcpPort = atoi(argv[++currentArgc]); + } + else if (strcmp(argv[currentArgc], "del") == 0) { + operation = FileOperationType_Del; + filename = argv[++currentArgc]; + } + else if (strcmp(argv[currentArgc], "dir") == 0) { + operation = FileOperationType_Dir; + } + else if (strcmp(argv[currentArgc], "info") == 0) { + operation = FileOperationType_Info; + filename = argv[++currentArgc]; + } + else if (strcmp(argv[currentArgc], "get") == 0) { + operation = FileOperationType_Get; + filename = argv[++currentArgc]; + } + else if (strcmp(argv[currentArgc], "set") == 0) { + operation = FileOperationType_Set; + filename = argv[++currentArgc]; + } + else { + printf("Unknown operation!\n"); + return 1; + } + + currentArgc++; + } + + return retVal; +} + +void +showDirectory(IedConnection con) +{ + IedClientError error; + + /* Get the root directory */ + LinkedList rootDirectory = + IedConnection_getFileDirectory(con, &error, NULL); + + if (error != IED_ERROR_OK) { + printf("Error retrieving file directory\n"); + } + else { + LinkedList directoryEntry = LinkedList_getNext(rootDirectory); + + while (directoryEntry != NULL) { + + FileDirectoryEntry entry = (FileDirectoryEntry) directoryEntry->data; + + printf("%s %i\n", FileDirectoryEntry_getFileName(entry), FileDirectoryEntry_getFileSize(entry)); + + directoryEntry = LinkedList_getNext(directoryEntry); + } + + LinkedList_destroyDeep(rootDirectory, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy); + } +} + +void +getFile(IedConnection con) +{ + IedClientError error; + + char* bname = strdup(filename); + + char* localFilename = basename(bname); + + FILE* fp = fopen(localFilename, "w"); + + if (fp != NULL) { + + /* Download a file from the server */ + IedConnection_getFile(con, &error, filename, downloadHandler, (void*) fp); + + if (error != IED_ERROR_OK) + printf("Failed to get file!\n"); + + fclose(fp); + } + else + printf("Failed to open file %s\n", localFilename); + + free(bname); +} + +void +setFile(IedConnection con) +{ + IedClientError error; + + char* dirc = strdup(filename); + char* basec = strdup(filename); + + char* localDirName = dirname(dirc); + char* localFileName = basename(basec); + + printf("local dir: %s\n", localDirName); + printf("local file: %s\n", localFileName); + + /* IedConnection_setFilestoreBasepath requires the file separator at the end! */ + strcpy(dirc, localDirName); + strcat(dirc, "/"); + + printf("filestore basepath: %s\n", dirc); + + IedConnection_setFilestoreBasepath(con, dirc); + + IedConnection_setFile(con, &error, localFileName, localFileName); + + if (error != IED_ERROR_OK) + printf("Failed to set file! (code=%i)\n", error); + + free(dirc); + free(basec); +} + +void +deleteFile(IedConnection con) +{ + IedClientError error; + + /* Delete file at server */ + IedConnection_deleteFile(con, &error, filename); + + if (error != IED_ERROR_OK) + printf("Failed to delete file! (code=%i)\n", error); +} + +int +main(int argc, char** argv) +{ + if (argc < 2) { + printHelp(); + return 0; + } + + parseOptions(argc, argv); + + if (operation == FileOperationType_None) { + printHelp(); + return 0; + } + + IedClientError error; + + IedConnection con = IedConnection_create(); + + IedConnection_connect(con, &error, hostname, tcpPort); + + if (error == IED_ERROR_OK) { + + + switch (operation) { + case FileOperationType_Dir: + showDirectory(con); + break; + case FileOperationType_Get: + getFile(con); + break; + case FileOperationType_Del: + deleteFile(con); + break; + case FileOperationType_Info: + break; + case FileOperationType_Set: + setFile(con); + break; + } + + + IedConnection_abort(con, &error); + } + else { + printf("Failed to connect to %s:%i\n", hostname, tcpPort); + } + + IedConnection_destroy(con); +} + + diff --git a/examples/server_example_files/server_example_files.c b/examples/server_example_files/server_example_files.c index 9b263bb..b2a1b07 100644 --- a/examples/server_example_files/server_example_files.c +++ b/examples/server_example_files/server_example_files.c @@ -39,7 +39,7 @@ static MmsError fileAccessHandler (void* parameter, MmsServerConnection connection, MmsFileServiceType service, const char* localFilename, const char* otherFilename) { - printf("fileAccessHanlder: service = %i, local-file: %s other-file: %s\n", service, localFilename, otherFilename); + printf("fileAccessHandler: service = %i, local-file: %s other-file: %s\n", service, localFilename, otherFilename); /* Don't allow client to rename files */ if (service == MMS_FILE_ACCESS_TYPE_RENAME)