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

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers abstract_server.hpp Source File

abstract_server.hpp

00001 /*
00002  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #ifndef UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_SERVER_HPP_INCLUDED
00006 #define UAVCAN_PROTOCOL_DYNAMIC_NODE_ID_SERVER_SERVER_HPP_INCLUDED
00007 
00008 #include <uavcan/build_config.hpp>
00009 #include <uavcan/debug.hpp>
00010 #include <uavcan/protocol/dynamic_node_id_server/allocation_request_manager.hpp>
00011 #include <uavcan/protocol/dynamic_node_id_server/node_discoverer.hpp>
00012 #include <uavcan/protocol/dynamic_node_id_server/event.hpp>
00013 
00014 namespace uavcan
00015 {
00016 namespace dynamic_node_id_server
00017 {
00018 
00019 class AbstractServer : protected IAllocationRequestHandler
00020                      , protected INodeDiscoveryHandler
00021 {
00022     UniqueID own_unique_id_;
00023     MonotonicTime started_at_;
00024 
00025 protected:
00026     INode& node_;
00027     IEventTracer& tracer_;
00028     AllocationRequestManager allocation_request_manager_;
00029     NodeDiscoverer node_discoverer_;
00030 
00031     AbstractServer(INode& node,
00032                    IEventTracer& tracer) :
00033        node_(node),
00034        tracer_(tracer),
00035        allocation_request_manager_(node, tracer, *this),
00036        node_discoverer_(node, tracer, *this)
00037     { }
00038 
00039     const UniqueID& getOwnUniqueID() const { return own_unique_id_; }
00040 
00041     int init(const UniqueID& own_unique_id, const TransferPriority priority)
00042     {
00043         int res = 0;
00044 
00045         own_unique_id_ = own_unique_id;
00046 
00047         res = allocation_request_manager_.init(priority);
00048         if (res < 0)
00049         {
00050             return res;
00051         }
00052 
00053         res = node_discoverer_.init(priority);
00054         if (res < 0)
00055         {
00056             return res;
00057         }
00058 
00059         started_at_ = node_.getMonotonicTime();
00060 
00061         return 0;
00062     }
00063 
00064 public:
00065     /**
00066      * This can be used to guess if there are any un-allocated dynamic nodes left in the network.
00067      */
00068     bool guessIfAllDynamicNodesAreAllocated(
00069         const MonotonicDuration& allocation_activity_timeout =
00070             MonotonicDuration::fromMSec(Allocation::MAX_REQUEST_PERIOD_MS * 2),
00071         const MonotonicDuration& min_uptime = MonotonicDuration::fromMSec(6000)) const
00072     {
00073         const MonotonicTime ts = node_.getMonotonicTime();
00074 
00075         /*
00076          * If uptime is not large enough, the allocator may be unaware about some nodes yet.
00077          */
00078         const MonotonicDuration uptime = ts - started_at_;
00079         if (uptime < max(allocation_activity_timeout, min_uptime))
00080         {
00081             return false;
00082         }
00083 
00084         /*
00085          * If there are any undiscovered nodes, assume that allocation is still happening.
00086          */
00087         if (node_discoverer_.hasUnknownNodes())
00088         {
00089             return false;
00090         }
00091 
00092         /*
00093          * Lastly, check if there wasn't any allocation messages detected on the bus in the specified amount of time.
00094          */
00095         const MonotonicDuration since_allocation_activity =
00096             ts - allocation_request_manager_.getTimeOfLastAllocationActivity();
00097         if (since_allocation_activity < allocation_activity_timeout)
00098         {
00099             return false;
00100         }
00101 
00102         return true;
00103     }
00104 
00105     /**
00106      * This is useful for debugging/testing/monitoring.
00107      */
00108     const NodeDiscoverer& getNodeDiscoverer() const { return node_discoverer_; }
00109 };
00110 
00111 }
00112 }
00113 
00114 #endif // Include guard