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

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers transfer_receiver.hpp Source File

transfer_receiver.hpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #ifndef UAVCAN_TRANSPORT_TRANSFER_RECEIVER_HPP_INCLUDED
00006 #define UAVCAN_TRANSPORT_TRANSFER_RECEIVER_HPP_INCLUDED
00007 
00008 #include <cstdlib>
00009 #include <uavcan/build_config.hpp>
00010 #include <uavcan/transport/frame.hpp>
00011 #include <uavcan/transport/transfer_buffer.hpp>
00012 
00013 namespace uavcan
00014 {
00015 
00016 class UAVCAN_EXPORT TransferReceiver
00017 {
00018 public:
00019     enum ResultCode { ResultNotComplete, ResultComplete, ResultSingleFrame };
00020 
00021     static const uint16_t MinTransferIntervalMSec     = 1;
00022     static const uint16_t MaxTransferIntervalMSec     = 0xFFFF;
00023     static const uint16_t DefaultTransferIntervalMSec = 1000;
00024     static const uint16_t DefaultTidTimeoutMSec       = 1000;
00025 
00026     static MonotonicDuration getDefaultTransferInterval()
00027     {
00028         return MonotonicDuration::fromMSec(DefaultTransferIntervalMSec);
00029     }
00030     static MonotonicDuration getMinTransferInterval() { return MonotonicDuration::fromMSec(MinTransferIntervalMSec); }
00031     static MonotonicDuration getMaxTransferInterval() { return MonotonicDuration::fromMSec(MaxTransferIntervalMSec); }
00032 
00033 private:
00034     enum { IfaceIndexNotSet = MaxCanIfaces };
00035 
00036     enum { ErrorCntMask = 31 };
00037     enum { IfaceIndexMask = MaxCanIfaces };
00038 
00039     MonotonicTime prev_transfer_ts_;
00040     MonotonicTime this_transfer_ts_;
00041     UtcTime first_frame_ts_;
00042     uint16_t transfer_interval_msec_;
00043     uint16_t this_transfer_crc_;
00044 
00045     uint16_t buffer_write_pos_;
00046 
00047     TransferID tid_;    // 1 byte field
00048 
00049     // 1 byte aligned bitfields:
00050     uint8_t next_toggle_        : 1;
00051     uint8_t iface_index_        : 2;
00052     mutable uint8_t error_cnt_  : 5;
00053 
00054     bool isInitialized() const { return iface_index_ != IfaceIndexNotSet; }
00055 
00056     bool isMidTransfer() const { return buffer_write_pos_ > 0; }
00057 
00058     MonotonicDuration getIfaceSwitchDelay() const;
00059     MonotonicDuration getTidTimeout() const;
00060 
00061     void registerError() const;
00062 
00063     void updateTransferTimings();
00064     void prepareForNextTransfer();
00065 
00066     bool validate(const RxFrame& frame) const;
00067     bool writePayload(const RxFrame& frame, ITransferBuffer& buf);
00068     ResultCode receive(const RxFrame& frame, TransferBufferAccessor& tba);
00069 
00070 public:
00071     TransferReceiver() :
00072         transfer_interval_msec_(DefaultTransferIntervalMSec),
00073         this_transfer_crc_(0),
00074         buffer_write_pos_(0),
00075         next_toggle_(false),
00076         iface_index_(IfaceIndexNotSet),
00077         error_cnt_(0)
00078     { }
00079 
00080     bool isTimedOut(MonotonicTime current_ts) const;
00081 
00082     ResultCode addFrame(const RxFrame& frame, TransferBufferAccessor& tba);
00083 
00084     uint8_t yieldErrorCount();
00085 
00086     MonotonicTime getLastTransferTimestampMonotonic() const { return prev_transfer_ts_; }
00087     UtcTime getLastTransferTimestampUtc() const { return first_frame_ts_; }
00088 
00089     uint16_t getLastTransferCrc() const { return this_transfer_crc_; }
00090 
00091     MonotonicDuration getInterval() const { return MonotonicDuration::fromMSec(transfer_interval_msec_); }
00092 };
00093 
00094 }
00095 
00096 #endif // UAVCAN_TRANSPORT_TRANSFER_RECEIVER_HPP_INCLUDED