diff --git a/CMakeLists.txt b/CMakeLists.txt index b889336f0d..6636e188d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,5 +33,6 @@ add_subdirectory(libuavcan) # if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") message(STATUS "Adding Linux support library") + add_subdirectory(libuavcan_drivers/posix) add_subdirectory(libuavcan_drivers/linux) endif () diff --git a/libuavcan_drivers/linux/CMakeLists.txt b/libuavcan_drivers/linux/CMakeLists.txt index a88c7da13a..fd8ed5eef1 100644 --- a/libuavcan_drivers/linux/CMakeLists.txt +++ b/libuavcan_drivers/linux/CMakeLists.txt @@ -25,6 +25,8 @@ if (TARGET uavcan) set(UAVCAN_LIB uavcan) include_directories(${libuavcan_SOURCE_DIR}/include ${libuavcan_SOURCE_DIR}/include/dsdlc_generated) + message(STATUS "POSIX source dir: ${libuavcan_posix_SOURCE_DIR}") + include_directories(${libuavcan_posix_SOURCE_DIR}/include) else () message(STATUS "Using installed uavcan library") find_library(UAVCAN_LIB uavcan REQUIRED) @@ -55,6 +57,9 @@ target_link_libraries(test_time_sync ${UAVCAN_LIB} rt ${CMAKE_THREAD_LIBS_INIT}) add_executable(test_system_utils apps/test_system_utils.cpp) target_link_libraries(test_system_utils ${UAVCAN_LIB} rt ${CMAKE_THREAD_LIBS_INIT}) +add_executable(test_posix apps/test_posix.cpp) +target_link_libraries(test_posix ${UAVCAN_LIB} rt ${CMAKE_THREAD_LIBS_INIT}) + # # Tools # diff --git a/libuavcan_drivers/linux/apps/test_posix.cpp b/libuavcan_drivers/linux/apps/test_posix.cpp new file mode 100644 index 0000000000..a59aa1c3ef --- /dev/null +++ b/libuavcan_drivers/linux/apps/test_posix.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015 Pavel Kirienko + */ + +#include +#include +#include +#include +#include +#include "debug.hpp" + +int main(int argc, const char** argv) +{ + (void)argc; + (void)argv; + try + { + ENFORCE(0 == std::system("mkdir -p /tmp/uavcan_posix/dynamic_node_id_server")); + + /* + * Event tracer test + */ + { + using namespace uavcan::dynamic_node_id_server; + + const std::string event_log_file("/tmp/uavcan_posix/dynamic_node_id_server/event.log"); + + uavcan_posix::dynamic_node_id_server::FileEventTracer tracer; + ENFORCE(0 <= tracer.init(event_log_file.c_str())); + + // Adding a line + static_cast(tracer).onEvent(TraceError, 123456); + ENFORCE(0 == std::system(("cat " + event_log_file).c_str())); + + // Removing the log file + ENFORCE(0 == std::system(("rm -f " + event_log_file).c_str())); + + // Adding another line + static_cast(tracer).onEvent(TraceError, 789123); + ENFORCE(0 == std::system(("cat " + event_log_file).c_str())); + } + + /* + * Storage backend test + */ + { + using namespace uavcan::dynamic_node_id_server; + + uavcan_posix::dynamic_node_id_server::FileStorageBackend backend; + ENFORCE(0 <= backend.init("/tmp/uavcan_posix/dynamic_node_id_server/storage")); + + auto print_key = [&](const char* key) { + std::cout << static_cast(backend).get(key).c_str() << std::endl; + }; + + print_key("foobar"); + + static_cast(backend).set("foobar", "0123456789abcdef0123456789abcdef"); + static_cast(backend).set("the_answer", "42"); + + print_key("foobar"); + print_key("the_answer"); + print_key("nonexistent"); + } + + return 0; + } + catch (const std::exception& ex) + { + std::cerr << "Exception: " << ex.what() << std::endl; + return 1; + } +} diff --git a/libuavcan_drivers/posix/CMakeLists.txt b/libuavcan_drivers/posix/CMakeLists.txt new file mode 100644 index 0000000000..49fbbfb8e1 --- /dev/null +++ b/libuavcan_drivers/posix/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (C) 2015 Pavel Kirienko +# + +cmake_minimum_required(VERSION 2.8) + +project(libuavcan_posix) + +# +# Library (header only) +# +install(DIRECTORY include/uavcan_posix DESTINATION include) diff --git a/libuavcan_drivers/posix_tools/include.mk b/libuavcan_drivers/posix/include.mk similarity index 100% rename from libuavcan_drivers/posix_tools/include.mk rename to libuavcan_drivers/posix/include.mk diff --git a/libuavcan_drivers/posix_tools/include/posix_tools/file_event_tracer.hpp b/libuavcan_drivers/posix/include/uavcan_posix/dynamic_node_id_server/file_event_tracer.hpp similarity index 51% rename from libuavcan_drivers/posix_tools/include/posix_tools/file_event_tracer.hpp rename to libuavcan_drivers/posix/include/uavcan_posix/dynamic_node_id_server/file_event_tracer.hpp index 719e34694d..c8e97244dd 100644 --- a/libuavcan_drivers/posix_tools/include/posix_tools/file_event_tracer.hpp +++ b/libuavcan_drivers/posix/include/uavcan_posix/dynamic_node_id_server/file_event_tracer.hpp @@ -1,11 +1,19 @@ -/* - * Copyright (C) 2015 Pavel Kirienko - */ +/**************************************************************************** +* +* Copyright (c) 2015 PX4 Development Team. All rights reserved. +* Author: Pavel Kirienko +* David Sidrane +* +****************************************************************************/ -#pragma once +#ifndef UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_EVENT_TRACER_HPP_INCLUDED +#define UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_EVENT_TRACER_HPP_INCLUDED #include +#include #include +#include +#include namespace uavcan_posix { @@ -19,9 +27,9 @@ class FileEventTracer : public uavcan::dynamic_node_id_server::IEventTracer /** * Maximum length of full path to log file */ + enum { MaxPathLength = 128 }; - enum { MaxPathLength = 128, FormatBufferLength = 64 }; - + enum { FilePermissions = 438 }; ///< 0o666 /** * This type is used for the path @@ -29,32 +37,32 @@ class FileEventTracer : public uavcan::dynamic_node_id_server::IEventTracer typedef uavcan::Array, uavcan::ArrayModeDynamic, MaxPathLength> PathString; - PathString path_; - -public: - - FileEventTracer() { } - virtual void onEvent(uavcan::dynamic_node_id_server::TraceCode code, uavcan::int64_t argument) { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - int fd = open(path_.c_str(), O_WRONLY | O_CREAT | O_APPEND); - if (fd >= 0 ) + using namespace std; + + timespec ts = timespec(); // If clock_gettime() fails, zero time will be used + (void)clock_gettime(CLOCK_REALTIME, &ts); + + int fd = open(path_.c_str(), O_WRONLY | O_CREAT | O_APPEND, FilePermissions); + if (fd >= 0) { + const int FormatBufferLength = 63; char buffer[FormatBufferLength + 1]; - int n = snprintf(buffer, FormatBufferLength, "%d.%ld,%d,%lld\n", ts.tv_sec, ts.tv_nsec, code, argument); + int n = snprintf(buffer, FormatBufferLength, "%ld.%06ld\t%d\t%lld\n", + static_cast(ts.tv_sec), static_cast(ts.tv_nsec / 1000L), + static_cast(code), static_cast(argument)); write(fd, buffer, n); close(fd); } } - /** - * Initializes the File based event trace - * - */ +public: + /** + * Initializes the file based event tracer. + */ int init(const PathString & path) { using namespace std; @@ -65,16 +73,17 @@ public: { rv = 0; path_ = path.c_str(); - int fd = open(path_.c_str(), O_RDWR | O_CREAT | O_TRUNC); - if ( fd >= 0) + int fd = open(path_.c_str(), O_RDWR | O_CREAT | O_TRUNC, FilePermissions); + if (fd >= 0) { close(fd); } } return rv; } - }; } } + +#endif // Include guard diff --git a/libuavcan_drivers/posix_tools/include/posix_tools/file_storage_backend.hpp b/libuavcan_drivers/posix/include/uavcan_posix/dynamic_node_id_server/file_storage_backend.hpp similarity index 86% rename from libuavcan_drivers/posix_tools/include/posix_tools/file_storage_backend.hpp rename to libuavcan_drivers/posix/include/uavcan_posix/dynamic_node_id_server/file_storage_backend.hpp index e5233420cf..e4ce8c8e23 100644 --- a/libuavcan_drivers/posix_tools/include/posix_tools/file_storage_backend.hpp +++ b/libuavcan_drivers/posix/include/uavcan_posix/dynamic_node_id_server/file_storage_backend.hpp @@ -6,15 +6,17 @@ * ****************************************************************************/ -#pragma once +#ifndef UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_STORAGE_BACKEND_HPP_INCLUDED +#define UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_STORAGE_BACKEND_HPP_INCLUDED #include -#include +#include #include #include -#include #include #include +#include +#include #include @@ -30,9 +32,9 @@ class FileStorageBackend : public uavcan::dynamic_node_id_server::IStorageBacken /** * Maximum length of full path including / and key max */ - enum { MaxPathLength = 128 }; + enum { FilePermissions = 438 }; ///< 0o666 /** * This type is used for the path @@ -40,14 +42,8 @@ class FileStorageBackend : public uavcan::dynamic_node_id_server::IStorageBacken typedef uavcan::Array, uavcan::ArrayModeDynamic, MaxPathLength> PathString; - PathString base_path; -public: - - FileStorageBackend() { } - - virtual String get(const String& key) const { using namespace std; @@ -75,7 +71,6 @@ public: } } return value; - } virtual void set(const String& key, const String& value) @@ -83,7 +78,7 @@ public: using namespace std; PathString path = base_path.c_str(); path += key; - int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC); + int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, FilePermissions); if (fd >= 0) { write(fd, value.c_str(), value.size()); @@ -91,16 +86,15 @@ public: } } +public: /** - * Initializes the File based back end storage by passing to a path to + * Initializes the file based backend storage by passing a path to * the directory where the key named files will be stored. - * This the return result should be 0 on success. + * The return value should be 0 on success. * If it is -ErrInvalidConfiguration then the the path name is too long to - * Accommodate the trailing slash and max key length; - * + * accommodate the trailing slash and max key length. */ - - int init(const PathString & path) + int init(const PathString& path) { using namespace std; @@ -108,7 +102,6 @@ public: if (path.size() > 0) { - base_path = path.c_str(); if (base_path.back() == '/') @@ -132,10 +125,10 @@ public: } } return rv; - } - }; } } + +#endif // Include guard