Руслан Урядинский / libuavcan

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers file_event_tracer.hpp Source File

file_event_tracer.hpp

00001 /****************************************************************************
00002 *
00003 *   Copyright (c) 2015 PX4 Development Team. All rights reserved.
00004 *      Author: Pavel Kirienko <pavel.kirienko@gmail.com>
00005 *              David Sidrane <david_s5@usa.net>
00006 *
00007 ****************************************************************************/
00008 
00009 #ifndef UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_EVENT_TRACER_HPP_INCLUDED
00010 #define UAVCAN_POSIX_DYNAMIC_NODE_ID_SERVER_FILE_EVENT_TRACER_HPP_INCLUDED
00011 
00012 #include <uavcan/protocol/dynamic_node_id_server/event.hpp>
00013 #include <cstdio>
00014 #include <time.h>
00015 #include <fcntl.h>
00016 #include <unistd.h>
00017 
00018 namespace uavcan_posix
00019 {
00020 namespace dynamic_node_id_server
00021 {
00022 /**
00023  * This interface implements a POSIX compliant file based IEventTracer interface
00024  */
00025 class FileEventTracer : public uavcan::dynamic_node_id_server::IEventTracer
00026 {
00027     /**
00028      * Maximum length of full path to log file
00029      */
00030     enum { MaxPathLength = 128 };
00031 
00032     enum { FilePermissions = 438 };     ///< 0o666
00033 
00034     /**
00035      * This type is used for the path
00036      */
00037     typedef uavcan::MakeString<MaxPathLength>::Type PathString;
00038 
00039     PathString path_;
00040 
00041 protected:
00042     virtual void onEvent(uavcan::dynamic_node_id_server::TraceCode code, uavcan::int64_t argument)
00043     {
00044         using namespace std;
00045 
00046         timespec ts = timespec();               // If clock_gettime() fails, zero time will be used
00047         (void)clock_gettime(CLOCK_REALTIME, &ts);
00048 
00049         int fd = open(path_.c_str(), O_WRONLY | O_CREAT | O_APPEND, FilePermissions);
00050         if (fd >= 0)
00051         {
00052             const int FormatBufferLength = 63;
00053             char buffer[FormatBufferLength + 1];
00054             ssize_t remaining = snprintf(buffer, FormatBufferLength, "%ld.%06ld\t%d\t%lld\n",
00055                                          static_cast<long>(ts.tv_sec), static_cast<long>(ts.tv_nsec / 1000L),
00056                                          static_cast<int>(code), static_cast<long long>(argument));
00057 
00058             ssize_t total_written = 0;
00059             ssize_t written = 0;
00060             do
00061             {
00062                 written = write(fd, &buffer[total_written], remaining);
00063                 if (written > 0)
00064                 {
00065                     total_written += written;
00066                     remaining -=  written;
00067                 }
00068             }
00069             while (written > 0 && remaining > 0);
00070             (void)close(fd);
00071         }
00072     }
00073 
00074 public:
00075     /**
00076      * Initializes the file based event tracer.
00077      */
00078     int init(const PathString& path)
00079     {
00080         using namespace std;
00081 
00082         int rv = -uavcan::ErrInvalidParam;
00083 
00084         if (path.size() > 0)
00085         {
00086             rv = 0;
00087             path_ = path.c_str();
00088             int fd = open(path_.c_str(), O_RDWR | O_CREAT | O_TRUNC, FilePermissions);
00089             if (fd >= 0)
00090             {
00091                 (void)close(fd);
00092             }
00093         }
00094         return rv;
00095     }
00096 };
00097 }
00098 }
00099 
00100 #endif // Include guard