00001 #ifndef artdaq_ots_Generators_UDPReceiver_hh
00002 #define artdaq_ots_Generators_UDPReceiver_hh
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "fhiclcpp/fwd.h"
00018 #include "artdaq-core/Data/Fragment.hh"
00019 #include "artdaq/Application/CommandableFragmentGenerator.hh"
00020
00021 #include <arpa/inet.h>
00022 #include <netinet/in.h>
00023 #include <sys/types.h>
00024 #include <sys/socket.h>
00025 #include <unistd.h>
00026
00027 #include <array>
00028 #include <list>
00029 #include <queue>
00030 #include <atomic>
00031 #include <mutex>
00032 #include <thread>
00033 #include <chrono>
00034
00035 namespace ots {
00036
00037 enum class CommandType : uint8_t {
00038 Read = 0,
00039 Write = 1,
00040 Start_Burst = 2,
00041 Stop_Burst = 3,
00042 };
00043
00044 enum class ReturnCode : uint8_t {
00045 Read = 0,
00046 First = 1,
00047 Middle = 2,
00048 Last = 3,
00049 };
00050
00051 enum class DataType : uint8_t {
00052 Raw = 0,
00053 JSON = 1,
00054 String = 2,
00055 };
00056
00057 struct CommandPacket {
00058 CommandType type;
00059 uint8_t dataSize;
00060 uint64_t address;
00061 uint64_t data[182];
00062 };
00063
00064 typedef std::string packetBuffer_t;
00065 typedef std::list<packetBuffer_t> packetBuffer_list_t;
00066
00067 class UDPReceiver : public artdaq::CommandableFragmentGenerator {
00068 public:
00069 explicit UDPReceiver(fhicl::ParameterSet const & ps);
00070 virtual ~UDPReceiver();
00071
00072 protected:
00073
00074
00075
00076
00077
00078 bool getNext_(artdaq::FragmentPtrs & output) override;
00079 void start(void) override;
00080 virtual void start_();
00081 virtual void stop(void) override;
00082 virtual void stopNoMutex(void) override;
00083
00084 virtual void ProcessData_(artdaq::FragmentPtrs & output);
00085
00086 DataType getDataType(uint8_t byte) { return static_cast<DataType>((byte & 0xF0) >> 4); }
00087 ReturnCode getReturnCode(uint8_t byte) { return static_cast<ReturnCode>(byte & 0xF); }
00088 void send(CommandType flag);
00089
00090 packetBuffer_list_t packetBuffers_;
00091
00092 bool rawOutput_;
00093 std::string rawPath_;
00094
00095
00096
00097
00098 int dataport_;
00099 std::string ip_;
00100 int rcvbuf_;
00101
00102
00103 uint8_t expectedPacketNumber_;
00104
00105
00106 struct sockaddr_in si_data_;
00107 int datasocket_;
00108 bool sendCommands_;
00109
00110 private:
00111
00112 void receiveLoop_();
00113 bool isTimerExpired_();
00114
00115 std::thread receiverThread_;
00116 std::mutex receiveBufferLock_;
00117 packetBuffer_list_t receiveBuffers_;
00118
00119
00120 double fragmentWindow_;
00121 std::chrono::high_resolution_clock::time_point lastFrag_;
00122 };
00123 }
00124
00125 #endif