otsdaq  v1_01_03
 All Classes Namespaces Functions
UDPReceiver.hh
1 #ifndef artdaq_ots_Generators_UDPReceiver_hh
2 #define artdaq_ots_Generators_UDPReceiver_hh
3 
4 // The UDP Receiver class recieves UDP data from an OtSDAQ applicance and
5 // puts that data into UDPFragments for further ARTDAQ analysis.
6 //
7 // It currently assumes two things to be true:
8 // 1. The first word of the UDP packet is an 8-bit flag with information
9 // about the status of the sender
10 // 2. The second word is an 8-bit sequence ID, used for detecting
11 // dropped UDP datagrams
12 
13 // Some C++ conventions used:
14 
15 // -Append a "_" to every private member function and variable
16 
17 #include "fhiclcpp/fwd.h"
18 #include "artdaq-core/Data/Fragment.hh"
19 #include "artdaq/Application/CommandableFragmentGenerator.hh"
20 
21 #include <arpa/inet.h>
22 #include <netinet/in.h>
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <unistd.h>
26 
27 #include <array>
28 #include <list>
29 #include <queue>
30 #include <atomic>
31 #include <mutex>
32 #include <thread>
33 #include <chrono>
34 
35 namespace ots {
36 
37 enum class CommandType : uint8_t {
38  Read = 0,
39  Write = 1,
40  Start_Burst = 2,
41  Stop_Burst = 3,
42  };
43 
44 enum class ReturnCode : uint8_t {
45  Read = 0,
46  First = 1,
47  Middle = 2,
48  Last = 3,
49  };
50 
51  enum class DataType : uint8_t {
52  Raw = 0,
53  JSON = 1,
54  String = 2,
55  };
56 
57 struct CommandPacket {
58  CommandType type;
59  uint8_t dataSize;
60  uint64_t address;
61  uint64_t data[182];
62 };
63 
64  typedef std::array<uint8_t, 64050> packetBuffer_t;
65  typedef std::list<std::unique_ptr<packetBuffer_t>> packetBuffer_list_t;
66 
67  class UDPReceiver : public artdaq::CommandableFragmentGenerator {
68  public:
69  explicit UDPReceiver(fhicl::ParameterSet const & ps);
70  virtual ~UDPReceiver();
71 
72  protected:
73 
74  // The "getNext_" function is used to implement user-specific
75  // functionality; it's a mandatory override of the pure virtual
76  // getNext_ function declared in CommandableFragmentGenerator
77 
78  bool getNext_(artdaq::FragmentPtrs & output) override;
79  void start (void) override;
80  virtual void stop (void) override;
81  virtual void stopNoMutex (void) override;
82 
83  virtual void ProcessData_(artdaq::FragmentPtrs & output);
84 
85  DataType getDataType(uint8_t byte) { return static_cast<DataType>((byte & 0xF0) >> 4); }
86  ReturnCode getReturnCode(uint8_t byte) { return static_cast<ReturnCode>(byte & 0xF); }
87  void send(CommandType flag);
88 
89  packetBuffer_list_t packetBuffers_;
90 
91  bool rawOutput_;
92  std::string rawPath_;
93 
94  // FHiCL-configurable variables. Note that the C++ variable names
95  // are the FHiCL variable names with a "_" appended
96 
97  int dataport_;
98  std::string ip_;
99 
100  //The packet number of the next packet. Used to discover dropped packets
101  uint8_t expectedPacketNumber_;
102 
103  //Socket parameters
104  struct sockaddr_in si_data_;
105  int datasocket_;
106  bool sendCommands_;
107 
108  private:
109 
110  void receiveLoop_();
111  bool isTimerExpired_();
112 
113  std::thread receiverThread_;
114  std::mutex receiveBufferLock_;
115  packetBuffer_list_t receiveBuffers_;
116 
117  // Number of milliseconds per fragment
118  double fragmentWindow_;
119  std::chrono::high_resolution_clock::time_point lastFrag_;
120  };
121 }
122 
123 #endif /* artdaq_demo_Generators_ToySimulator_hh */