DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::daphnemodules::DaphneV2Interface Class Reference

#include <DaphneV2Interface.hpp>

Public Member Functions

 DaphneV2Interface (const char *ipaddr, int port, std::chrono::milliseconds timeout=std::chrono::milliseconds(500))
 
 ~DaphneV2Interface ()
 
 DaphneV2Interface (const DaphneV2Interface &)=delete
 
DaphneV2Interfaceoperator= (const DaphneV2Interface &)=delete
 
 DaphneV2Interface (DaphneV2Interface &&)=delete
 
DaphneV2Interfaceoperator= (DaphneV2Interface &&)=delete
 
std::vector< uint64_t > read_register (uint64_t addr, uint8_t size) const
 
void write_register (uint64_t addr, std::vector< uint64_t > &&data) const
 
std::vector< uint64_t > read_buffer (uint64_t addr, uint8_t size) const
 
void write_buffer (uint64_t addr, std::vector< uint64_t > &&data) const
 
bool validate_connection () const
 
command_result send_command (std::string cmd) const
 
command_result send_command_retry (std::string cmd, size_t retry=std::numeric_limits< size_t >::max()) const
 
command_result send_command_interruptible (std::string cmd, std::function< bool()> can_retry) const
 

Protected Member Functions

void close ()
 
void write (uint8_t command_id, uint64_t addr, std::vector< uint64_t > &&data) const
 
std::vector< uint64_t > read (uint8_t command_id, uint64_t addr, uint8_t size) const
 

Private Attributes

std::string m_ip
 
int m_connection_id = -1
 
sockaddr_in m_target
 
std::chrono::milliseconds m_timeout {5}
 
std::mutex m_access_mutex
 
std::mutex m_command_mutex
 

Detailed Description

Definition at line 78 of file DaphneV2Interface.hpp.

Constructor & Destructor Documentation

◆ DaphneV2Interface() [1/3]

DaphneV2Interface::DaphneV2Interface ( const char * ipaddr,
int port,
std::chrono::milliseconds timeout = std::chrono::milliseconds(500) )

Definition at line 15 of file DaphneV2Interface.cpp.

17 : m_timeout(timeout) {
18
19 m_connection_id = socket(AF_INET, SOCK_DGRAM, 0);
20
21 if ( m_connection_id < 0 )
22 throw SocketCreationError(ERS_HERE);
23
24 m_target.sin_family = AF_INET;
25 m_target.sin_port = htons(port);
26 auto ret = inet_pton(AF_INET, ipaddr, &(m_target.sin_addr));
27 if ( ret <= 0 )
28 throw InvalidIPAddress(ERS_HERE, ipaddr);
29
30 m_ip = ipaddr;
31
32 if ( ! validate_connection() )
33 throw FailedPing(ERS_HERE, ipaddr, port );
34
35}
#define ERS_HERE

◆ ~DaphneV2Interface()

dunedaq::daphnemodules::DaphneV2Interface::~DaphneV2Interface ( )
inline

◆ DaphneV2Interface() [2/3]

dunedaq::daphnemodules::DaphneV2Interface::DaphneV2Interface ( const DaphneV2Interface & )
delete

◆ DaphneV2Interface() [3/3]

dunedaq::daphnemodules::DaphneV2Interface::DaphneV2Interface ( DaphneV2Interface && )
delete

Member Function Documentation

◆ close()

void DaphneV2Interface::close ( )
protected

Definition at line 38 of file DaphneV2Interface.cpp.

38 {
39
41}

◆ operator=() [1/2]

DaphneV2Interface & dunedaq::daphnemodules::DaphneV2Interface::operator= ( const DaphneV2Interface & )
delete

◆ operator=() [2/2]

DaphneV2Interface & dunedaq::daphnemodules::DaphneV2Interface::operator= ( DaphneV2Interface && )
delete

◆ read()

std::vector< uint64_t > DaphneV2Interface::read ( uint8_t command_id,
uint64_t addr,
uint8_t size ) const
protected

Definition at line 172 of file DaphneV2Interface.cpp.

173 {
174
175 const std::lock_guard<std::mutex> lock(m_access_mutex);
176
177 uint8_t cmd[10];
178 cmd[0] = command_id;
179 cmd[1] = size;
180 memcpy(cmd + 2, &addr, sizeof(uint64_t));
181 auto result = sendto(m_connection_id, cmd, sizeof(cmd), 0, (struct sockaddr*)&m_target, sizeof(m_target));
182
183 if ( result < 0 ) throw FailedSocketInteraction(ERS_HERE, "sendto") ;
184
185
186 struct timeval timeout;
187 timeout.tv_sec = m_timeout.count() / 1000 ;
188 timeout.tv_usec = (m_timeout.count() % 1000) * 1000 ;
189 fd_set readfds, masterfds;
190
191 FD_ZERO(&masterfds);
192 FD_SET(m_connection_id, &masterfds);
193
194 memcpy(&readfds, &masterfds, sizeof(fd_set));
195
196 auto start_time = std::chrono::high_resolution_clock::now();
197
198 if (select(m_connection_id+1, &readfds, NULL, NULL, &timeout) < 0) {
199 throw FailedSocketInteraction(ERS_HERE, "select") ;
200 }
201
202 std::vector<uint64_t> ret_value;
203
204 if (FD_ISSET(m_connection_id, &readfds)) {
205 uint8_t buffer[2 + (8 * size)];
206 socklen_t addrlen = sizeof(m_target);
207 result = recvfrom(m_connection_id, buffer, sizeof(buffer), 0, (struct sockaddr*)&m_target, &addrlen);
208
209 if ( result <= 0 ) throw FailedSocketInteraction(ERS_HERE, "recvfrom") ;
210
211 uint8_t fmt[4 + size];
212 fmt[0] = '<';
213 fmt[1] = 'B';
214 fmt[2] = 'B';
215 fmt[3] = size;
216 for (int i = 0; i < size; i++) {
217 fmt[4 + i] = 'Q';
218 }
219
220 for (int i = 0; i < size; i++) {
221 uint64_t value;
222 memcpy(&value, buffer + 2 + (8 * i), sizeof(uint64_t));
223 ret_value.push_back(value);
224 }
225
226 }
227 else {
228 // the socket timedout
229 auto end_time = std::chrono::high_resolution_clock::now();
230 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
231
232 throw SocketTimeout(ERS_HERE, duration.count() );
233 }
234
235 return ret_value;
236}
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
Cannot add TPSet with start_time
Invalid std::string ip FailedSocketInteraction

◆ read_buffer()

std::vector< uint64_t > dunedaq::daphnemodules::DaphneV2Interface::read_buffer ( uint64_t addr,
uint8_t size ) const
inline

Definition at line 94 of file DaphneV2Interface.hpp.

94{ return read(0x08, addr, size) ; }
std::vector< uint64_t > read(uint8_t command_id, uint64_t addr, uint8_t size) const

◆ read_register()

std::vector< uint64_t > dunedaq::daphnemodules::DaphneV2Interface::read_register ( uint64_t addr,
uint8_t size ) const
inline

Definition at line 91 of file DaphneV2Interface.hpp.

91{ return read(0x00, addr, size) ; }

◆ send_command()

command_result DaphneV2Interface::send_command ( std::string cmd) const

Definition at line 98 of file DaphneV2Interface.cpp.

98 {
99
100 TLOG() << "Board: " << m_ip << ", sending command " << cmd;
101 std::vector<uint64_t> bytes;
102 for (char ch : cmd) {
103 bytes.push_back(static_cast<uint64_t>(ch));
104 }
105 bytes.push_back(0x0d); // dedicated command flag
106
107 const std::lock_guard<std::mutex> lock(m_command_mutex);
108
109 // we send the bytes in chunks of 50 words
110 for (size_t i = 0; i < (bytes.size() + 49) / 50; ++i) {
111 std::vector<uint64_t> part(bytes.begin() + i*50,
112 bytes.begin() + std::min((i+1)*50, bytes.size()));
113 write_buffer(0x90000000, std::move(part));
114 }
115
116 TLOG() << "Board: " << m_ip << ", Command sent, waiting for result";
117
118
119 command_result res;
120 std::string * writing_pointer = nullptr;
121
122 auto start_time = std::chrono::high_resolution_clock::now();
123
124 int more = 40;
125 while (more > 0) {
126 auto data_block = read_buffer(0x90000000, 50);
127 for (size_t i = 0; i < data_block.size(); ++i) {
128 if (data_block[i] == 255) {
129 break;
130 } else if (data_block[i] == 1) {
131 // the following data are returning the command that was issued
132 writing_pointer = & res.command;
133 } else if (data_block[i] == 2) {
134 // the following data are the immediate command response
135 writing_pointer = & res.result;
136 } else if (data_block[i] == 3) {
137 // this is the message end
138 writing_pointer = nullptr;
139 } else if (isprint(static_cast<int>(data_block[i]))) {
140 more = 40;
141 char c = static_cast<char>(data_block[i]);
142 if ( writing_pointer ) {
143 *writing_pointer += static_cast<char>(data_block[i]);
144 }
145 else {
146 TLOG() << "Failed adding charachter " << c;
147 }
148 }
149 }
150 auto now = std::chrono::high_resolution_clock::now();
151
152 auto delay = now - start_time;
153
154 if ( delay > m_timeout ) {
155 TLOG() << "Details of timeout";
156 for ( size_t i = 0; i < data_block.size(); ++i ) {
157 TLOG() << i << "\t" << std::hex << data_block[i] << std::dec;
158 }
159 TLOG() << "Received so far: " << res.result;
160 auto delay_us = std::chrono::duration_cast<std::chrono::microseconds>(delay);
161 throw CommandTimeout(ERS_HERE, cmd, delay_us.count());
162 }
163
164 std::this_thread::sleep_for(std::chrono::milliseconds(1));
165 --more;
166 }
167
168 return res;
169}
std::vector< uint64_t > read_buffer(uint64_t addr, uint8_t size) const
void write_buffer(uint64_t addr, std::vector< uint64_t > &&data) const
static int64_t now()
#define TLOG(...)
Definition macro.hpp:22
PDS Frame with unphysical timestamp detected with ch

◆ send_command_interruptible()

command_result DaphneV2Interface::send_command_interruptible ( std::string cmd,
std::function< bool()> can_retry ) const

Definition at line 77 of file DaphneV2Interface.cpp.

78 {
79
80 do {
81 try {
82 auto ret = send_command(cmd);
83 return ret;
84 }
85 catch ( const CommandTimeout & e ) {
86 ers::warning( e );
87 }
88 catch ( const ers::Issue & e ) {
89 throw FailedSocketInteraction(ERS_HERE, cmd, e);
90 }
91
92 } while (can_retry());
93
94}
command_result send_command(std::string cmd) const
Base class for any user define issue.
Definition Issue.hpp:69
void warning(const Issue &issue)
Definition ers.hpp:115

◆ send_command_retry()

command_result DaphneV2Interface::send_command_retry ( std::string cmd,
size_t retry = std::numeric_limits<size_t>::max() ) const

Definition at line 54 of file DaphneV2Interface.cpp.

55 {
56
57 do {
58 try {
59 auto ret = send_command(cmd);
60 return ret;
61 }
62 catch ( const CommandTimeout & e ) {
63 ers::warning( e );
64 --retry;
65 }
66 catch ( const ers::Issue & e ) {
67 throw FailedSocketInteraction(ERS_HERE, cmd, e);
68 }
69
70 } while (retry>0);
71
73
74}

◆ validate_connection()

bool DaphneV2Interface::validate_connection ( ) const

Definition at line 44 of file DaphneV2Interface.cpp.

44 {
45
46 auto ret = read_register( 0xaa55, 1);
47
48 static const uint64_t good_value = 0xdeadbeef;
49 return ret[0] == good_value ;
50
51}
std::vector< uint64_t > read_register(uint64_t addr, uint8_t size) const

◆ write()

void DaphneV2Interface::write ( uint8_t command_id,
uint64_t addr,
std::vector< uint64_t > && data ) const
protected

Definition at line 239 of file DaphneV2Interface.cpp.

239 {
240
241 const std::lock_guard<std::mutex> lock(m_access_mutex);
242
243 uint8_t cmd[10 + (8 * data.size())];
244 cmd[0] = command_id;
245 cmd[1] = data.size();
246 memcpy(cmd + 2, &addr, sizeof(uint64_t));
247 for (size_t i = 0; i < data.size(); i++) {
248 memcpy(cmd + 10 + (8 * i), &(data[i]), sizeof(uint64_t));
249 }
250
251 auto result = sendto(m_connection_id, cmd, sizeof(cmd), 0, (struct sockaddr*)&m_target, sizeof(m_target));
252 if ( result < 0 ) throw FailedSocketInteraction(ERS_HERE, "sendto") ;
253}

◆ write_buffer()

void dunedaq::daphnemodules::DaphneV2Interface::write_buffer ( uint64_t addr,
std::vector< uint64_t > && data ) const
inline

Definition at line 95 of file DaphneV2Interface.hpp.

95{ write(0x09, addr, std::move(data)) ; }
void write(uint8_t command_id, uint64_t addr, std::vector< uint64_t > &&data) const

◆ write_register()

void dunedaq::daphnemodules::DaphneV2Interface::write_register ( uint64_t addr,
std::vector< uint64_t > && data ) const
inline

Definition at line 92 of file DaphneV2Interface.hpp.

92{ write(0x01, addr, std::move(data)) ; }

Member Data Documentation

◆ m_access_mutex

std::mutex dunedaq::daphnemodules::DaphneV2Interface::m_access_mutex
mutableprivate

Definition at line 121 of file DaphneV2Interface.hpp.

◆ m_command_mutex

std::mutex dunedaq::daphnemodules::DaphneV2Interface::m_command_mutex
mutableprivate

Definition at line 122 of file DaphneV2Interface.hpp.

◆ m_connection_id

int dunedaq::daphnemodules::DaphneV2Interface::m_connection_id = -1
private

Definition at line 118 of file DaphneV2Interface.hpp.

◆ m_ip

std::string dunedaq::daphnemodules::DaphneV2Interface::m_ip
private

Definition at line 117 of file DaphneV2Interface.hpp.

◆ m_target

sockaddr_in dunedaq::daphnemodules::DaphneV2Interface::m_target
private

Definition at line 119 of file DaphneV2Interface.hpp.

◆ m_timeout

std::chrono::milliseconds dunedaq::daphnemodules::DaphneV2Interface::m_timeout {5}
private

Definition at line 120 of file DaphneV2Interface.hpp.

120{5};

The documentation for this class was generated from the following files: