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

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers outgoing_transfer_registry.hpp Source File

outgoing_transfer_registry.hpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #ifndef UAVCAN_TRANSPORT_OUTGOING_TRANSFER_REGISTRY_HPP_INCLUDED
00006 #define UAVCAN_TRANSPORT_OUTGOING_TRANSFER_REGISTRY_HPP_INCLUDED
00007 
00008 #include <cassert>
00009 #include <uavcan/std.hpp>
00010 #include <uavcan/build_config.hpp>
00011 #include <uavcan/util/map.hpp>
00012 #include <uavcan/debug.hpp>
00013 #include <uavcan/transport/transfer.hpp>
00014 #include <uavcan/time.hpp>
00015 
00016 namespace uavcan
00017 {
00018 
00019 class UAVCAN_EXPORT OutgoingTransferRegistryKey
00020 {
00021     DataTypeID data_type_id_;
00022     uint8_t transfer_type_;
00023     NodeID destination_node_id_;  ///< Not applicable for message broadcasting
00024 
00025 public:
00026     OutgoingTransferRegistryKey()
00027         : transfer_type_(0xFF)
00028     { }
00029 
00030     OutgoingTransferRegistryKey(DataTypeID data_type_id, TransferType transfer_type, NodeID destination_node_id)
00031         : data_type_id_(data_type_id)
00032         , transfer_type_(transfer_type)
00033         , destination_node_id_(destination_node_id)
00034     {
00035         UAVCAN_ASSERT((transfer_type == TransferTypeMessageBroadcast) == destination_node_id.isBroadcast());
00036         /*
00037          * Service response transfers must use the same Transfer ID as matching service request transfer,
00038          * so this registry is not applicable for service response transfers at all.
00039          */
00040         UAVCAN_ASSERT(transfer_type != TransferTypeServiceResponse);
00041     }
00042 
00043     DataTypeID getDataTypeID() const { return data_type_id_; }
00044     TransferType getTransferType() const { return TransferType(transfer_type_); }
00045 
00046     bool operator==(const OutgoingTransferRegistryKey& rhs) const
00047     {
00048         return
00049             (data_type_id_        == rhs.data_type_id_) &&
00050             (transfer_type_       == rhs.transfer_type_) &&
00051             (destination_node_id_ == rhs.destination_node_id_);
00052     }
00053 
00054 #if UAVCAN_TOSTRING
00055     std::string toString() const;
00056 #endif
00057 };
00058 
00059 /**
00060  * Outgoing transfer registry keeps track of Transfer ID values for all currently existing local transfer senders.
00061  * If a local transfer sender was inactive for a sufficiently long time, the outgoing transfer registry will
00062  * remove the respective Transfer ID tracking object.
00063  */
00064 class UAVCAN_EXPORT OutgoingTransferRegistry : Noncopyable
00065 {
00066     struct Value
00067     {
00068         MonotonicTime deadline;
00069         TransferID tid;
00070     };
00071 
00072     class DeadlineExpiredPredicate
00073     {
00074         const MonotonicTime ts_;
00075 
00076     public:
00077         explicit DeadlineExpiredPredicate(MonotonicTime ts)
00078             : ts_(ts)
00079         { }
00080 
00081         bool operator()(const OutgoingTransferRegistryKey& key, const Value& value) const
00082         {
00083             (void)key;
00084             UAVCAN_ASSERT(!value.deadline.isZero());
00085             const bool expired = value.deadline <= ts_;
00086             if (expired)
00087             {
00088                 UAVCAN_TRACE("OutgoingTransferRegistry", "Expired %s tid=%i",
00089                              key.toString().c_str(), int(value.tid.get()));
00090             }
00091             return expired;
00092         }
00093     };
00094 
00095     class ExistenceCheckingPredicate
00096     {
00097         const DataTypeID dtid_;
00098         const TransferType tt_;
00099 
00100     public:
00101         ExistenceCheckingPredicate(DataTypeID dtid, TransferType tt)
00102             : dtid_(dtid)
00103             , tt_(tt)
00104         { }
00105 
00106         bool operator()(const OutgoingTransferRegistryKey& key, const Value&) const
00107         {
00108             return dtid_ == key.getDataTypeID() && tt_ == key.getTransferType();
00109         }
00110     };
00111 
00112     Map<OutgoingTransferRegistryKey, Value>  map_;
00113 
00114 public:
00115     static const MonotonicDuration MinEntryLifetime;
00116 
00117     explicit OutgoingTransferRegistry(IPoolAllocator& allocator)
00118         : map_(allocator)
00119     { }
00120 
00121     TransferID* accessOrCreate(const OutgoingTransferRegistryKey& key, MonotonicTime new_deadline);
00122 
00123     bool exists(DataTypeID dtid, TransferType tt) const;
00124 
00125     void cleanup(MonotonicTime ts);
00126 };
00127 
00128 }
00129 
00130 #endif // UAVCAN_TRANSPORT_OUTGOING_TRANSFER_REGISTRY_HPP_INCLUDED