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 stop (void) override;
00081 virtual void stopNoMutex (void) override;
00082
00083 virtual void ProcessData_(artdaq::FragmentPtrs & output);
00084
00085 DataType getDataType(uint8_t byte) { return static_cast<DataType>((byte & 0xF0) >> 4); }
00086 ReturnCode getReturnCode(uint8_t byte) { return static_cast<ReturnCode>(byte & 0xF); }
00087 void send(CommandType flag);
00088
00089 packetBuffer_list_t packetBuffers_;
00090
00091 bool rawOutput_;
00092 std::string rawPath_;
00093
00094
00095
00096
00097 int dataport_;
00098 std::string ip_;
00099
00100
00101 uint8_t expectedPacketNumber_;
00102
00103
00104 struct sockaddr_in si_data_;
00105 int datasocket_;
00106 bool sendCommands_;
00107
00108 private:
00109
00110 void receiveLoop_();
00111 bool isTimerExpired_();
00112
00113 std::thread receiverThread_;
00114 std::mutex receiveBufferLock_;
00115 packetBuffer_list_t receiveBuffers_;
00116
00117
00118 double fragmentWindow_;
00119 std::chrono::high_resolution_clock::time_point lastFrag_;
00120 };
00121 }
00122
00123 #endif