$treeview $search $mathjax $extrastylesheet
otsdaq
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef artdaq_ots_Generators_UDPReceiver_hh 00002 #define artdaq_ots_Generators_UDPReceiver_hh 00003 00004 // The UDP Receiver class receives UDP data from an otsdaq application and 00005 // puts that data into UDPFragments for further ARTDAQ analysis. 00006 // 00007 // It currently assumes two things to be true: 00008 // 1. The first word of the UDP packet is an 8-bit flag with information 00009 // about the status of the sender 00010 // 2. The second word is an 8-bit sequence ID, used for detecting 00011 // dropped UDP datagrams 00012 00013 // Some C++ conventions used: 00014 00015 // -Append a "_" to every private member function and variable 00016 00017 #include "artdaq-core/Data/Fragment.hh" 00018 #include "artdaq/Application/CommandableFragmentGenerator.hh" 00019 #include "fhiclcpp/fwd.h" 00020 00021 #include <arpa/inet.h> 00022 #include <netinet/in.h> 00023 #include <sys/socket.h> 00024 #include <sys/types.h> 00025 #include <unistd.h> 00026 00027 #include <array> 00028 #include <atomic> 00029 #include <chrono> 00030 #include <list> 00031 #include <mutex> 00032 #include <queue> 00033 #include <thread> 00034 00035 namespace ots 00036 { 00037 enum class CommandType : uint8_t 00038 { 00039 Read = 0, 00040 Write = 1, 00041 Start_Burst = 2, 00042 Stop_Burst = 3, 00043 }; 00044 00045 enum class ReturnCode : uint8_t 00046 { 00047 Read = 0, 00048 First = 1, 00049 Middle = 2, 00050 Last = 3, 00051 }; 00052 00053 enum class DataType : uint8_t 00054 { 00055 Raw = 0, 00056 JSON = 1, 00057 String = 2, 00058 }; 00059 00060 struct CommandPacket 00061 { 00062 CommandType type; 00063 uint8_t dataSize; 00064 uint64_t address; 00065 uint64_t data[182]; 00066 }; 00067 00068 typedef std::string packetBuffer_t; 00069 typedef std::list<packetBuffer_t> packetBuffer_list_t; 00070 00071 class UDPReceiver : public artdaq::CommandableFragmentGenerator 00072 { 00073 public: 00074 explicit UDPReceiver(fhicl::ParameterSet const& ps); 00075 virtual ~UDPReceiver(); 00076 00077 protected: 00078 // The "getNext_" function is used to implement user-specific 00079 // functionality; it's a mandatory override of the pure virtual 00080 // getNext_ function declared in CommandableFragmentGenerator 00081 00082 bool getNext_(artdaq::FragmentPtrs& output) override; 00083 void start(void) override; 00084 virtual void start_(); 00085 virtual void stop(void) override; 00086 virtual void stopNoMutex(void) override; 00087 00088 virtual void ProcessData_(artdaq::FragmentPtrs& output); 00089 00090 DataType getDataType(uint8_t byte) 00091 { 00092 return static_cast<DataType>((byte & 0xF0) >> 4); 00093 } 00094 ReturnCode getReturnCode(uint8_t byte) { return static_cast<ReturnCode>(byte & 0xF); } 00095 void send(CommandType flag); 00096 00097 packetBuffer_list_t packetBuffers_; 00098 00099 bool rawOutput_; 00100 std::string rawPath_; 00101 00102 // FHiCL-configurable variables. Note that the C++ variable names 00103 // are the FHiCL variable names with a "_" appended 00104 00105 int dataport_; 00106 std::string ip_; 00107 int rcvbuf_; 00108 00109 // The packet number of the next packet. Used to discover dropped packets 00110 uint8_t expectedPacketNumber_; 00111 00112 // Socket parameters 00113 struct sockaddr_in si_data_; 00114 int datasocket_; 00115 bool sendCommands_; 00116 00117 private: 00118 void receiveLoop_(); 00119 bool isTimerExpired_(); 00120 00121 std::thread receiverThread_; 00122 std::mutex receiveBufferLock_; 00123 packetBuffer_list_t receiveBuffers_; 00124 00125 // Number of milliseconds per fragment 00126 double fragmentWindow_; 00127 std::chrono::high_resolution_clock::time_point lastFrag_; 00128 }; 00129 } // namespace ots 00130 00131 #endif /* artdaq_demo_Generators_ToySimulator_hh */