DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
BNL_UDP Class Reference

#include <BNL_UDP.hh>

Public Member Functions

 BNL_UDP ()
 ~BNL_UDP ()
void Setup (std::string const &address, uint16_t port_offset=0)
bool Ready ()
void SetWriteAck (bool val)
bool GetWriteAck ()
uint32_t ReadWithRetry (uint16_t address, uint8_t retry_count=10)
uint32_t Read (uint16_t address)
void WriteWithRetry (uint16_t address, uint32_t value, uint8_t retry_count=10)
void Write (uint16_t address, uint32_t value)
void Write (uint16_t address, std::vector< uint32_t > const &values)
void Write (uint16_t address, uint32_t const *values, size_t word_count)
std::string GetAddress ()
uint64_t GetRetryCount ()

Private Member Functions

 BNL_UDP (const BNL_UDP &other)
BNL_UDP & operator= (const BNL_UDP &)
void FlushSocket (int sock)
void Clear ()
void Reset ()
void ResizeBuffer (size_t size=WIB_RESPONSE_PACKET_BUFFER_SIZE)

Private Attributes

bool writeAck
std::string remoteAddress
int16_t readPort
int16_t writePort
int16_t replyPort
bool connected
int readSocketFD
int writeSocketFD
struct sockaddr_in readAddr
struct sockaddr_in writeAddr
size_t buffer_size
uint8_t * buffer
uint64_t total_retry_count

Detailed Description

Definition at line 14 of file BNL_UDP.hh.

Constructor & Destructor Documentation

◆ BNL_UDP() [1/2]

BNL_UDP::BNL_UDP ( )
inline

Definition at line 16 of file BNL_UDP.hh.

int writeSocketFD
Definition BNL_UDP.hh:59
uint64_t total_retry_count
Definition BNL_UDP.hh:66
void Clear()
Definition BNL_UDP.cpp:69
size_t buffer_size
Definition BNL_UDP.hh:64
int readSocketFD
Definition BNL_UDP.hh:58
uint8_t * buffer
Definition BNL_UDP.hh:65

◆ ~BNL_UDP()

BNL_UDP::~BNL_UDP ( )

Definition at line 474 of file BNL_UDP.cpp.

475{
476 Clear();
477}

◆ BNL_UDP() [2/2]

BNL_UDP::BNL_UDP ( const BNL_UDP & other)
private

Member Function Documentation

◆ Clear()

void BNL_UDP::Clear ( )
private

Definition at line 69 of file BNL_UDP.cpp.

70{
71 // close sockets
72 if (readSocketFD != -1) {
73 close(readSocketFD);
74 readSocketFD = -1;
75 }
76 if (writeSocketFD != -1) {
77 close(writeSocketFD);
78 writeSocketFD = -1;
79 }
80 // Clear packet buffer
81 if (buffer != NULL) {
82 delete[] buffer;
83 buffer_size = 0;
84 }
85 writeAck = false;
86 connected = false;
87
88 // Reset send/recv addr structures
89 memset(&readAddr, 0, sizeof(readAddr));
90 memset(&writeAddr, 0, sizeof(writeAddr));
91}
struct sockaddr_in writeAddr
Definition BNL_UDP.hh:61
bool connected
Definition BNL_UDP.hh:57
struct sockaddr_in readAddr
Definition BNL_UDP.hh:60
bool writeAck
Definition BNL_UDP.hh:48

◆ FlushSocket()

void BNL_UDP::FlushSocket ( int sock)
private

Definition at line 57 of file BNL_UDP.cpp.

58{
59 // turn on non-blocking
60 fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
61 int ret;
62 do {
63 ret = recv(sock, buffer, buffer_size, 0);
64 } while (ret != -1);
65 fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) & (~O_NONBLOCK));
66}

◆ GetAddress()

std::string BNL_UDP::GetAddress ( )
inline

Definition at line 32 of file BNL_UDP.hh.

32{return remoteAddress;};
std::string remoteAddress
Definition BNL_UDP.hh:51

◆ GetRetryCount()

uint64_t BNL_UDP::GetRetryCount ( )
inline

Definition at line 34 of file BNL_UDP.hh.

34{return total_retry_count;};

◆ GetWriteAck()

bool BNL_UDP::GetWriteAck ( )
inline

Definition at line 23 of file BNL_UDP.hh.

23{return writeAck;};

◆ operator=()

BNL_UDP & BNL_UDP::operator= ( const BNL_UDP & )
private

◆ Read()

uint32_t BNL_UDP::Read ( uint16_t address)

Definition at line 411 of file BNL_UDP.cpp.

412{
413 // Flush the socket
415
416 // build the send packet
417 WIB_packet_t packet;
418 packet.key = htonl(WIB_PACKET_KEY);
419 packet.reg_addr = htons(address);
420 packet.data_MSW = packet.data_LSW = 0;
421 packet.trailer = htons(WIB_REQUEST_PACKET_TRAILER);
422
423 // send the packet
424 ssize_t send_size = sizeof(packet);
425 ssize_t sent_size = 0;
426 if (send_size != (sent_size = send(readSocketFD, &packet, send_size, 0))) {
427 // bad send
428 BUException::SEND_FAILED e;
429 if (sent_size == -1) {
430 e.Append("BNL_UDP::Read(uint16_t)\n");
431 e.Append("Errnum: ");
432 e.Append(strerror(errno));
433 }
434 throw e;
435 }
436
437 // Get the reply packet with the register data in it.
438 ssize_t reply_size = recv(readSocketFD, buffer, buffer_size, 0);
439
440 if (ssize_t(-1) == reply_size) {
441 BUException::BAD_REPLY e;
442 std::stringstream ss;
443 e.Append("BNL_UDP::Read(uint16_t)\n");
444 ss << "Errnum(" << errno << "): " << strerror(errno) << "\n";
445 e.Append(ss.str().c_str());
446 e.Append(dump_packet((uint8_t*)&packet, send_size).c_str());
447 throw e;
448 } else if (reply_size < WIB_RPLY_PACKET_SIZE) {
449 BUException::BAD_REPLY e;
450 std::stringstream ss;
451 ss << "Bad Size: " << reply_size << "\n";
452 e.Append("BNL_UDP::Read(uint16_t)\n");
453 e.Append(ss.str().c_str());
454 e.Append(dump_packet(buffer, reply_size).c_str());
455 throw e;
456 }
457 uint16_t reply_address = uint16_t(buffer[0] << 8 | buffer[1]);
458 if (reply_address != address) {
459 BUException::BAD_REPLY e;
460 std::stringstream ss;
461 ss << "Bad address: " << uint32_t(address) << " != " << uint32_t(reply_address) << "\n";
462 e.Append("BNL_UDP::Read(uint16_t)\n");
463 e.Append(ss.str().c_str());
464 e.Append(dump_packet(buffer, reply_size).c_str());
465 throw e;
466 }
467
468 // }
469 uint32_t ret = ((uint32_t(buffer[2]) << 24) | (uint32_t(buffer[3]) << 16) | (uint32_t(buffer[4]) << 8) |
470 (uint32_t(buffer[5]) << 0));
471 return ret;
472}
#define WIB_REQUEST_PACKET_TRAILER
Definition BNL_UDP.cpp:23
#define WIB_RPLY_PACKET_SIZE
Definition BNL_UDP.cpp:25
static std::string dump_packet(uint8_t *data, size_t size)
Definition BNL_UDP.cpp:39
#define WIB_PACKET_KEY
Definition BNL_UDP.cpp:21
void FlushSocket(int sock)
Definition BNL_UDP.cpp:57
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:111
uint32_t key
Definition BNL_UDP.cpp:31
uint32_t data_LSW
Definition BNL_UDP.cpp:34
uint32_t reg_addr
Definition BNL_UDP.cpp:32
uint32_t data_MSW
Definition BNL_UDP.cpp:33
uint32_t trailer
Definition BNL_UDP.cpp:35

◆ ReadWithRetry()

uint32_t BNL_UDP::ReadWithRetry ( uint16_t address,
uint8_t retry_count = 10 )

Definition at line 388 of file BNL_UDP.cpp.

389{
390 uint32_t val;
391 while (retry_count > 1) {
392 try {
393 // Do the write
394 val = Read(address);
395 usleep(10);
396 // if everything goes well, return
397 return val;
398 } catch (BUException::BAD_REPLY& e) {
399 // eat the exception
400 }
401 usleep(10);
403 retry_count--;
404 }
405 // Last chance we don't catch the exception and let it fall down the stack
406 val = Read(address);
407 usleep(10);
408 return val;
409}
uint32_t Read(uint16_t address)
Definition BNL_UDP.cpp:411

◆ Ready()

bool BNL_UDP::Ready ( )
inline

Definition at line 20 of file BNL_UDP.hh.

20{return connected;};

◆ Reset()

void BNL_UDP::Reset ( )
private

◆ ResizeBuffer()

void BNL_UDP::ResizeBuffer ( size_t size = WIB_RESPONSE_PACKET_BUFFER_SIZE)
private

Definition at line 480 of file BNL_UDP.cpp.

481{
482 // CHeck if the requested size is larger than the already allocated size
483 // printf("before %p %zu %zd\n",buffer,buffer_size,buffer_size);
484 if (buffer_size < size) {
485 // We need to re-allocate
486 if (buffer != NULL) {
487 delete[] buffer;
488 }
489 buffer = new uint8_t[size];
491 }
492 // printf("after %p %zu %zd\n",buffer,buffer_size,buffer_size);
493}
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size

◆ Setup()

void BNL_UDP::Setup ( std::string const & address,
uint16_t port_offset = 0 )

Definition at line 104 of file BNL_UDP.cpp.

105{
106 // Reset the network structures
107 Clear();
108
109 // Allocate the recv buffer
110 ResizeBuffer();
111
112 // Check port_offset range
113 if (port_offset > 128) {
114 BUException::BNL_UDP_PORT_OUT_OF_RANGE e;
115 throw e;
116 }
117
118 // Set the ports for this device (FEMBs are iFEMB*0x10 above the base)
119 readPort = WIB_RD_BASE_PORT + port_offset;
120 writePort = WIB_WR_BASE_PORT + port_offset;
121 // replyPort = WIB_RPLY_BASE_PORT + port_offset;
122
124 // Get the sockaddr for the address
125 struct addrinfo* res;
126 if (getaddrinfo(address.c_str(), NULL, NULL, &res)) {
127 // Check if we have just one "." character and is less than 5 characters
128 if (address.size() <= 5 && 1 == std::count(address.begin(), address.end(), '.')) {
129 std::string strCrate = address.substr(0, address.find('.'));
130 std::string strSlot = address.substr(address.find('.') + 1);
131 if (strCrate.size() != 0 && strSlot.size() != 0) {
132 uint8_t crate = strtoul(strCrate.c_str(), NULL, 0);
133 uint8_t slot = strtoul(strSlot.c_str(), NULL, 0);
134 if ((((crate > 0) && (crate < 7)) || 0xF == crate) && (((slot > 0) && (slot < 7)) || 0xF == slot)) {
135 remoteAddress = std::string("192.168.");
136 // Add the crate part of the address (200 + crate number)
137 if (crate == 0xF) {
138 remoteAddress += "200.";
139 } else {
140 // generate the crate number which is 200 + crate number
141 remoteAddress += "20";
142 remoteAddress += ('0' + crate);
143 remoteAddress += '.';
144 }
145 if (slot == 0xF) {
146 remoteAddress += "50";
147 } else {
148 // crate last IP octet that is slot number
149 remoteAddress += ('0' + slot);
150 }
151 }
152 }
153 }
154 // try a second time assumin gthis is a crate.slot address, fail if this still doesn't work
155 if (getaddrinfo(address.c_str(), NULL, NULL, &res)) {
156 BUException::BAD_REMOTE_IP e;
157 e.Append("Addr: ");
158 e.Append(address.c_str());
159 e.Append(" could not be resolved.\n");
160 throw e;
161 }
162 }
163 // readAddr = *((struct sockaddr_in *) res->ai_addr);
164 // printaddress(&readAddr);
165
166 // Generate the sockets for read and write
167 if ((readSocketFD = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
168 BUException::BAD_SOCKET e;
169 e.Append("read socket\n");
170 throw e;
171 }
172 if ((writeSocketFD = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
173 BUException::BAD_SOCKET e;
174 e.Append("write socket\n");
175 throw e;
176 }
177 // Set a timeout for the recv socket so we don't hang on a reply
178 struct timeval tv;
179 tv.tv_sec = TIMEOUT_SECONDS;
180 tv.tv_usec = TIMEOUT_MICROSECONDS;
181 setsockopt(readSocketFD, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(struct timeval));
182 setsockopt(writeSocketFD, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(struct timeval));
183
184 // connect the read socket
185 readAddr = *((struct sockaddr_in*)res->ai_addr);
186 readAddr.sin_port = htons(readPort);
187 if (connect(readSocketFD, (struct sockaddr*)&readAddr, sizeof(readAddr)) < 0) {
188 BUException::CONNECTION_FAILED e;
189 e.Append("read socket connect\n");
190 e.Append(strerror(errno));
191 throw e;
192 }
193 // connect the write socket
194 writeAddr = *((struct sockaddr_in*)res->ai_addr);
195 writeAddr.sin_port = htons(writePort);
196 if (connect(writeSocketFD, (struct sockaddr*)&writeAddr, sizeof(writeAddr)) < 0) {
197 BUException::CONNECTION_FAILED e;
198 e.Append("write socket connect\n");
199 e.Append(strerror(errno));
200 throw e;
201 }
202
203 // Allocate the receive buffer to default size
204 ResizeBuffer();
205}
#define WIB_RD_BASE_PORT
Definition BNL_UDP.cpp:18
#define WIB_WR_BASE_PORT
Definition BNL_UDP.cpp:17
#define TIMEOUT_MICROSECONDS
Definition BNL_UDP.cpp:28
#define TIMEOUT_SECONDS
Definition BNL_UDP.cpp:27
int16_t readPort
Definition BNL_UDP.hh:52
void ResizeBuffer(size_t size=WIB_RESPONSE_PACKET_BUFFER_SIZE)
Definition BNL_UDP.cpp:480
int16_t writePort
Definition BNL_UDP.hh:53
Invalid address

◆ SetWriteAck()

void BNL_UDP::SetWriteAck ( bool val)
inline

Definition at line 22 of file BNL_UDP.hh.

22{writeAck=val;};

◆ Write() [1/3]

void BNL_UDP::Write ( uint16_t address,
std::vector< uint32_t > const & values )

Definition at line 293 of file BNL_UDP.cpp.

294{
295 Write(address, values.data(), values.size());
296}
void Write(uint16_t address, uint32_t value)
Definition BNL_UDP.cpp:230

◆ Write() [2/3]

void BNL_UDP::Write ( uint16_t address,
uint32_t const * values,
size_t word_count )

//Create a pointer to 16bit words that points to the parts of buffer that are after the first 32bit word (WIB key)

Definition at line 298 of file BNL_UDP.cpp.

299{
300 for (size_t iWrite = 0; iWrite < word_count; iWrite++) {
301 WriteWithRetry(address, values[iWrite]);
302 address++;
303 }
304
385}
void WriteWithRetry(uint16_t address, uint32_t value, uint8_t retry_count=10)
Definition BNL_UDP.cpp:208

◆ Write() [3/3]

void BNL_UDP::Write ( uint16_t address,
uint32_t value )

Definition at line 230 of file BNL_UDP.cpp.

231{
232
233 // Flush this socket
235
236 // Build the packet to send
237 // build the send packet
238 WIB_packet_t packet;
239 packet.key = htonl(WIB_PACKET_KEY);
240 packet.reg_addr = htons(address);
241 packet.data_MSW = htons(uint16_t((value >> 16) & 0xFFFF));
242 packet.data_LSW = htons(uint16_t((value >> 0) & 0xFFFF));
243 packet.trailer = htons(WIB_REQUEST_PACKET_TRAILER);
244
245 // send the packet
246 ssize_t send_size = sizeof(packet);
247 ssize_t sent_size = 0;
248 if (send_size != (sent_size = send(writeSocketFD, &packet, send_size, 0))) {
249 // bad send
250 BUException::SEND_FAILED e;
251 if (sent_size == -1) {
252 e.Append("BNL_UDP::Write(uint16_t,uint32_t)\n");
253 e.Append("Errnum: ");
254 e.Append(strerror(errno));
255 }
256 throw e;
257 }
258
259 // If configured, capture confirmation packet
260 if (writeAck) {
261 ssize_t reply_size = recv(writeSocketFD, buffer, buffer_size, 0);
262
263 if (-1 == reply_size) {
264 BUException::BAD_REPLY e;
265 std::stringstream ss;
266 e.Append("BNL_UDP::Write(uint16_t,uint32_t)\n");
267 ss << "Errnum(" << errno << "): " << strerror(errno) << "\n";
268 e.Append(ss.str().c_str());
269 e.Append(dump_packet((uint8_t*)&packet, send_size).c_str());
270 throw e;
271 } else if (reply_size < WIB_RPLY_PACKET_SIZE) {
272 BUException::BAD_REPLY e;
273 std::stringstream ss;
274 ss << "Bad Size: " << reply_size << "\n";
275 e.Append("BNL_UDP::Write(uint16_t,uint32_t)\n");
276 e.Append(ss.str().c_str());
277 e.Append(dump_packet(buffer, reply_size).c_str());
278 throw e;
279 }
280 uint16_t reply_address = uint16_t(buffer[0] << 8 | buffer[1]);
281 if (reply_address != address) {
282 BUException::BAD_REPLY e;
283 std::stringstream ss;
284 ss << "Bad address: " << uint32_t(address) << " != " << uint32_t(reply_address) << "\n";
285 e.Append("BNL_UDP::Write(uint16_t,uint32_t)\n");
286 e.Append(ss.str().c_str());
287 e.Append(dump_packet(buffer, reply_size).c_str());
288 throw e;
289 }
290 }
291}

◆ WriteWithRetry()

void BNL_UDP::WriteWithRetry ( uint16_t address,
uint32_t value,
uint8_t retry_count = 10 )

Definition at line 208 of file BNL_UDP.cpp.

209{
210 while (retry_count > 1) {
211 try {
212 // Do the write
213 Write(address, value);
214 usleep(10);
215 // if everything goes well, return
216 return;
217 } catch (BUException::BAD_REPLY& e) {
218 // eat the exception
219 }
221 retry_count--;
222 usleep(10);
223 }
224 // Last chance we don't catch the exception and let it fall down the stack
225 // Do the write
226 Write(address, value);
227 usleep(10);
228}

Member Data Documentation

◆ buffer

uint8_t* BNL_UDP::buffer
private

Definition at line 65 of file BNL_UDP.hh.

◆ buffer_size

size_t BNL_UDP::buffer_size
private

Definition at line 64 of file BNL_UDP.hh.

◆ connected

bool BNL_UDP::connected
private

Definition at line 57 of file BNL_UDP.hh.

◆ readAddr

struct sockaddr_in BNL_UDP::readAddr
private

Definition at line 60 of file BNL_UDP.hh.

◆ readPort

int16_t BNL_UDP::readPort
private

Definition at line 52 of file BNL_UDP.hh.

◆ readSocketFD

int BNL_UDP::readSocketFD
private

Definition at line 58 of file BNL_UDP.hh.

◆ remoteAddress

std::string BNL_UDP::remoteAddress
private

Definition at line 51 of file BNL_UDP.hh.

◆ replyPort

int16_t BNL_UDP::replyPort
private

Definition at line 54 of file BNL_UDP.hh.

◆ total_retry_count

uint64_t BNL_UDP::total_retry_count
private

Definition at line 66 of file BNL_UDP.hh.

◆ writeAck

bool BNL_UDP::writeAck
private

Definition at line 48 of file BNL_UDP.hh.

◆ writeAddr

struct sockaddr_in BNL_UDP::writeAddr
private

Definition at line 61 of file BNL_UDP.hh.

◆ writePort

int16_t BNL_UDP::writePort
private

Definition at line 53 of file BNL_UDP.hh.

◆ writeSocketFD

int BNL_UDP::writeSocketFD
private

Definition at line 59 of file BNL_UDP.hh.


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