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

#include <BNL_UDP.hh>

Collaboration diagram for BNL_UDP:
[legend]

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_UDPoperator= (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:63
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 459 of file BNL_UDP.cpp.

459 {
460 Clear();
461}

◆ 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 63 of file BNL_UDP.cpp.

63 {
64 //close sockets
65 if(readSocketFD != -1){
66 close(readSocketFD);
67 readSocketFD = -1;
68 }
69 if(writeSocketFD != -1){
70 close(writeSocketFD);
71 writeSocketFD = -1;
72 }
73 //Clear packet buffer
74 if(buffer != NULL){
75 delete [] buffer;
76 buffer_size = 0;
77 }
78 writeAck = false;
79 connected = false;
80
81 //Reset send/recv addr structures
82 memset(&readAddr,0,sizeof(readAddr));
83 memset(&writeAddr,0,sizeof(writeAddr));
84}
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 53 of file BNL_UDP.cpp.

53 {
54 //turn on non-blocking
55 fcntl(sock, F_SETFL, fcntl(sock, F_GETFL)| O_NONBLOCK);
56 int ret;
57 do{
58 ret = recv(sock,buffer,buffer_size,0);
59 }while(ret != -1);
60 fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) & (~O_NONBLOCK));
61}

◆ 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 391 of file BNL_UDP.cpp.

391 {
392 //Flush the socket
394
395 //build the send packet
396 WIB_packet_t packet;
397 packet.key = htonl(WIB_PACKET_KEY);
398 packet.reg_addr = htons(address);
399 packet.data_MSW = packet.data_LSW = 0;
400 packet.trailer = htons(WIB_REQUEST_PACKET_TRAILER);
401
402 //send the packet
403 ssize_t send_size = sizeof(packet);
404 ssize_t sent_size = 0;
405 if( send_size != (sent_size = send(readSocketFD,
406 &packet,send_size,0))){
407 //bad send
408 BUException::SEND_FAILED e;
409 if(sent_size == -1){
410 e.Append("BNL_UDP::Read(uint16_t)\n");
411 e.Append("Errnum: ");
412 e.Append(strerror(errno));
413 }
414 throw e;
415 }
416
417 //Get the reply packet with the register data in it.
418 ssize_t reply_size = recv(readSocketFD,
420
421 if(ssize_t(-1) == reply_size){
422 BUException::BAD_REPLY e;
423 std::stringstream ss;
424 e.Append("BNL_UDP::Read(uint16_t)\n");
425 ss << "Errnum(" << errno << "): " << strerror(errno) << "\n";
426 e.Append(ss.str().c_str());
427 e.Append(dump_packet((uint8_t *)&packet,send_size).c_str());
428 throw e;
429 }else if( reply_size < WIB_RPLY_PACKET_SIZE){
430 BUException::BAD_REPLY e;
431 std::stringstream ss;
432 ss << "Bad Size: " << reply_size << "\n";
433 e.Append("BNL_UDP::Read(uint16_t)\n");
434 e.Append(ss.str().c_str());
435 e.Append(dump_packet(buffer,reply_size).c_str());
436 throw e;
437 }
438 uint16_t reply_address = uint16_t(buffer[0] << 8 | buffer[1]);
439 if( reply_address != address){
440 BUException::BAD_REPLY e;
441 std::stringstream ss;
442 ss << "Bad address: " << uint32_t(address) << " != " << uint32_t(reply_address) << "\n";
443 e.Append("BNL_UDP::Read(uint16_t)\n");
444 e.Append(ss.str().c_str());
445 e.Append(dump_packet(buffer,reply_size).c_str());
446 throw e;
447 }
448
449
450 // }
451 uint32_t ret = ( (uint32_t(buffer[2]) << 24) |
452 (uint32_t(buffer[3]) << 16) |
453 (uint32_t(buffer[4]) << 8) |
454 (uint32_t(buffer[5]) << 0));
455 return ret;
456}
#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:37
#define WIB_PACKET_KEY
Definition BNL_UDP.cpp:21
void FlushSocket(int sock)
Definition BNL_UDP.cpp:53
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:114
uint32_t key
Definition BNL_UDP.cpp:30
uint32_t data_LSW
Definition BNL_UDP.cpp:33
uint32_t reg_addr
Definition BNL_UDP.cpp:31
uint32_t data_MSW
Definition BNL_UDP.cpp:32
uint32_t trailer
Definition BNL_UDP.cpp:34

◆ ReadWithRetry()

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

Definition at line 370 of file BNL_UDP.cpp.

370 {
371 uint32_t val;
372 while(retry_count > 1){
373 try{
374 //Do the write
375 val = Read(address);
376 usleep(10);
377 //if everything goes well, return
378 return val;
379 }catch(BUException::BAD_REPLY &e){
380 //eat the exception
381 }
382 usleep(10);
384 retry_count--;
385 }
386 //Last chance we don't catch the exception and let it fall down the stack
387 val = Read(address);
388 usleep(10);
389 return val;
390}
uint32_t Read(uint16_t address)
Definition BNL_UDP.cpp:391

◆ 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 464 of file BNL_UDP.cpp.

464 {
465 //CHeck if the requested size is larger than the already allocated size
466 // printf("before %p %zu %zd\n",buffer,buffer_size,buffer_size);
467 if(buffer_size < size){
468 //We need to re-allocate
469 if(buffer != NULL){
470 delete [] buffer;
471 }
472 buffer = new uint8_t[size];
474 }
475 // printf("after %p %zu %zd\n",buffer,buffer_size,buffer_size);
476}
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 96 of file BNL_UDP.cpp.

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

◆ 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 280 of file BNL_UDP.cpp.

280 {
281 Write(address,values.data(),values.size());
282}
void Write(uint16_t address, uint32_t value)
Definition BNL_UDP.cpp:217

◆ Write() [2/3]

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

Definition at line 283 of file BNL_UDP.cpp.

283 {
284 for(size_t iWrite = 0; iWrite < word_count;iWrite++){
285 WriteWithRetry(address,values[iWrite]);
286 address++;
287 }
288
368}
void WriteWithRetry(uint16_t address, uint32_t value, uint8_t retry_count=10)
Definition BNL_UDP.cpp:197

◆ Write() [3/3]

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

Definition at line 217 of file BNL_UDP.cpp.

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

◆ WriteWithRetry()

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

Definition at line 197 of file BNL_UDP.cpp.

197 {
198 while(retry_count > 1){
199 try{
200 //Do the write
201 Write(address,value);
202 usleep(10);
203 //if everything goes well, return
204 return;
205 }catch(BUException::BAD_REPLY &e){
206 //eat the exception
207 }
209 retry_count--;
210 usleep(10);
211 }
212 //Last chance we don't catch the exception and let it fall down the stack
213 //Do the write
214 Write(address,value);
215 usleep(10);
216}

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: