BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnDataReceiver.cxx
Go to the documentation of this file.
1/*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6
7/*
8 * File: BmnDataReceiver.cxx
9 * Author: ilnur
10 *
11 * Created on October 18, 2016, 5:22 PM
12 */
13
14#include "BmnDataReceiver.h"
15
16#include "libxml/tree.h"
17
18#include </usr/include/netdb.h>
19#include <arpa/inet.h>
20#include <netinet/in.h>
21#include <signal.h>
22#include <string>
23#include <sys/socket.h>
24#include <sys/types.h>
25#include <thread>
26#include <vector>
27#include <zmq.h>
28// for old fairsoft
29#define ZMQ_XSUB 10
30#define ZMQ_STREAM 11
31#define ZMQ_ROUTER_RAW 41
32
34{
35 // gSystem->Load("libxml2");
36 // gSystem->Load("libzmq");
37 InitSocks();
38}
39
44
46//_ctx(1),
47//_socket_mcast(_ctx, ZMQ_SUB)
48{
49 _ctx = zmq_ctx_new();
50 _socket_mcast = zmq_socket(_ctx, ZMQ_XSUB);
51 _socket_data = zmq_socket(_ctx, ZMQ_STREAM);
52}
53
55{
56 //_socket_mcast.close();
57 zmq_close(_socket_mcast);
58 zmq_close(_socket_data);
59 zmq_ctx_destroy(_ctx);
60}
61
62/*void BmnDataReceiver::HandleSignal(int signal){
63 switch (signal)
64 {
65 case SIGINT:
66 {
67 isListening = kFALSE;
68 printf("SIGINT received\n");
69 break;
70 }
71 default:
72 {
73
74 }
75 }
76}*/
77
79{
80 xmlDocPtr doc = xmlParseDoc((xmlChar*)msgStr);
81 xmlNodePtr root = xmlDocGetRootElement(doc);
82 xmlNodePtr cur_node = root;
83 while (cur_node) {
84 if ((cur_node->type == XML_ELEMENT_NODE) || (cur_node->type == XML_TEXT_NODE)) {
85 if (strcmp((Char_t*)cur_node->name, "program") == 0) {
86 strcpy(sInfo->hostName, (Char_t*)xmlGetProp(cur_node, (xmlChar*)"hostName"));
87 strcpy(sInfo->index, (Char_t*)xmlGetProp(cur_node, (xmlChar*)"index"));
88 strcpy(sInfo->name, (Char_t*)xmlGetProp(cur_node, (xmlChar*)"name"));
89 strcpy(sInfo->type, (Char_t*)xmlGetProp(cur_node, (xmlChar*)"type"));
90 cur_node = cur_node->children;
91 continue;
92 }
93 if (strcmp((Char_t*)cur_node->name, "interfaces") == 0) {
94 sInfo->interfaces.clear();
95 cur_node = cur_node->children;
96 continue;
97 }
98 if (strcmp((Char_t*)cur_node->name, "interface") == 0) {
99 serverIface newPort;
100 Char_t* portStr = (Char_t*)xmlGetProp(cur_node, (xmlChar*)"port");
101 if (portStr != NULL)
102 newPort.port = atoi(portStr);
103 newPort.isFree = strcmp(((Char_t*)xmlGetProp(cur_node, (xmlChar*)"isFree")), "1") == 0 ? 1 : 0;
104 newPort.enabled = strcmp(((Char_t*)xmlGetProp(cur_node, (xmlChar*)"enabled")), "1") == 0 ? 1 : 0;
105 strcpy(newPort.type, (Char_t*)xmlGetProp(cur_node, (xmlChar*)"type"));
106 // if (newPort.type == "data flow")
107 sInfo->interfaces.push_back(newPort);
108 if (cur_node->next == NULL)
109 cur_node = cur_node->parent->next;
110 else
111 cur_node = cur_node->next;
112 continue;
113 }
114 cur_node = cur_node->next;
115 }
116 }
117 xmlFreeDoc(doc);
118 return 0;
119}
120
122{
123 DBG("started")
124 socklen_t addrlen = 0;
125 struct ip_mreq mreq;
126 mreq.imr_interface.s_addr = htons(INADDR_ANY);
127 mreq.imr_multiaddr.s_addr = inet_addr(PNP_DISCOVER_IP_ADDR);
128 struct sockaddr_in mcast_addr;
129 mcast_addr.sin_family = AF_INET;
130 mcast_addr.sin_port = htons(PNP_DISCOVER_PORT);
131 mcast_addr.sin_addr.s_addr = htonl(INADDR_ANY);
132 memset(&mcast_addr.sin_zero, 0, sizeof(mcast_addr.sin_zero));
133
134 _sfd = socket(AF_INET, SOCK_DGRAM, 0);
135 if (_sfd == -1) {
136 fprintf(stderr, "Error: %s\n", strerror(errno));
137 return -1;
138 }
139 UInt_t reusable = 1;
140 if (setsockopt(_sfd, SOL_SOCKET, SO_REUSEADDR, &reusable, sizeof(reusable))) {
141 close(_sfd);
142 fprintf(stderr, "Setting reusable error: %s\n", strerror(errno));
143 return -1;
144 }
145 addrlen = sizeof(mcast_addr);
146 if (bind(_sfd, (sockaddr*)&mcast_addr, addrlen) == -1) {
147 close(_sfd);
148 fprintf(stderr, "Bind error: %s\n", strerror(errno));
149 return -1;
150 }
151 if (setsockopt(_sfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) {
152 close(_sfd);
153 fprintf(stderr, "Adding multicast group error: %s\n", strerror(errno));
154 return -1;
155 }
156 Int_t nbytes;
157 Char_t buf[MAX_BUF_LEN];
158 // signal(SIGINT, HandleSignal);
160 while (isListening) {
161 if ((nbytes = recvfrom(_sfd, buf, MAX_BUF_LEN, 0, (sockaddr*)&mcast_addr, &addrlen)) == -1) {
162 close(_sfd);
163 fprintf(stderr, "Receive error: %s\n", strerror(errno));
164 return -1;
165 }
166 buf[nbytes] = '\0';
167 // printf("%s\n", buf);
169 printf("index = %s\n", _dataServer.index);
170 printf("type = %s\n", _dataServer.type);
171 if ((strcmp(_dataServer.index, "Glob") == 0) && (_dataServer.interfaces.size() > 0)) {
172 isAddr = true;
173 DBG("Glob EvB found")
174 break;
175 }
176 }
177 RecvData();
178
179 close(_sfd);
180 return 0;
181}
182
184{
185 // Int_t isRaw = 1;
186 // if (zmq_setsockopt(_socket_data, ZMQ_ROUTER_RAW, &isRaw, sizeof(isRaw)) == -1)
187 // DBGERR("zmq_setsockopt of ZMQ_ROUTER_RAW")
188 Char_t endpoint_addr[MAX_ADDR_LEN];
189 struct addrinfo hints;
190 struct addrinfo *info, *p;
191 memset(&hints, 0, sizeof(hints));
192 hints.ai_family = AF_UNSPEC;
193 hints.ai_socktype = SOCK_STREAM;
194 Int_t g = 0;
195 if ((g = getaddrinfo(_dataServer.hostName, NULL, &hints, &info)) != 0) {
196 printf("getaddrinfo error: %s\n", strerror(errno));
197 return -1;
198 }
199 Char_t* ip = NULL;
200 for (p = info; p != NULL; p = p->ai_next) {
201 ip = inet_ntoa(((sockaddr_in*)(p->ai_addr))->sin_addr);
202 printf("found family %d %s addr: %s\n", p->ai_family, p->ai_canonname, ip);
203 Int_t port = 0;
204 for (auto iface : _dataServer.interfaces)
205 if (strcmp(iface.type, "Monitor output data flow") == 0) {
206 port = iface.port;
207 break;
208 }
209 snprintf(endpoint_addr, MAX_ADDR_LEN, "tcp://%s:%d", ip, port);
210 if (zmq_connect(_socket_data, endpoint_addr) != 0) {
211 DBGERR("zmq connect")
212 continue;
213 } else {
214 printf("%s\n", endpoint_addr);
215 break;
216 }
217 }
218 if (p == NULL) {
219 printf("Valid address not found\n");
220 return -1;
221 }
222 Int_t rcvBuf = MAX_BUF_LEN;
223 size_t vl = sizeof(rcvBuf);
224 if (zmq_setsockopt(_socket_data, ZMQ_RCVBUF, &rcvBuf, sizeof(rcvBuf)) == -1)
225 DBGERR("zmq_setsockopt of ZMQ_RCVBUF")
226 if (zmq_setsockopt(_socket_data, ZMQ_SNDBUF, &rcvBuf, sizeof(rcvBuf)) == -1)
227 DBGERR("zmq_setsockopt of ZMQ_SNDBUF")
228 rcvBuf = 0;
229 if (zmq_getsockopt(_socket_data, ZMQ_RCVBUF, &rcvBuf, &vl) == -1)
230 DBGERR("zmq_getsockopt of ZMQ_RCVBUF")
231 printf("rcvbuf = %d\n", rcvBuf);
232 // Char_t id[MAX_ADDR_LEN];
233
234 return 0;
235}
236
238{
239 freeaddrinfo(dataAddrInfo);
240}
241
243{
244 // while ((isListening) && (msg_len < MAX_BUF_LEN)) {
245 // id_size = zmq_recv(_socket_data, &id, sizeof (id), 0);
246 // if (id_size == -1) {
247 // printf("Receive error #%s\n", zmq_strerror(errno));
248 // if (errno == EAGAIN)
249 // usleep(MSG_TIMEOUT);
250 // else
251 // return -1;
252 // } else {
253 // printf("ID size = %d\n Id:%x\n", id_size, id);
254 // }
255 // zmq_msg_t msg;
256 // zmq_msg_init(&msg);
257 // Int_t recv_more = 0;
258 // UInt_t *msgPtr;
259 // do {
260 // frame_size = zmq_msg_recv(&msg, _socket_data, 0); // ZMQ_DONTWAIT
261 // //frame_size = zmq_recv(_socket_data, buf, MAX_BUF_LEN, 0);
262 // if (frame_size == -1) {
263 // printf("Receive error № %d #%s\n", errno, zmq_strerror(errno));
264 // if (errno == EAGAIN)
265 // usleep(MSG_TIMEOUT);
266 // else
267 // return -1;
268 // } else {
269 // // UChar_t *str = (UChar_t*) malloc((frame_size + 1) * sizeof (UChar_t));
270 // msgPtr = (UInt_t*) zmq_msg_data(&msg);
271 // // memcpy(buf, zmq_msg_data(&msg), frame_size);
272 // // ((mutex*)_deque_mutex)->lock();
273 // for (Int_t offset = 0; offset < frame_size; offset++)
274 // data_queue.push_back(*(msgPtr + offset));
275 // // ((mutex*)_deque_mutex)->unlock();
276 // // memcpy(str, zmq_msg_data(&msg), frame_size);
277 // // str[frame_size] = '\0';
278 // msg_len += frame_size;
279 // // printf("Frame size = %d\n Msg:%x\n", frame_size, str);
280 // // free(str);
281 // }
282 // size_t opt_size = sizeof (recv_more);
283 // if (zmq_getsockopt(_socket_data, ZMQ_RCVMORE, &recv_more, &opt_size) == -1) {
284 // printf("ZMQ socket options error #%s\n", zmq_strerror(errno));
285 // return -1;
286 // }
287 // printf("ZMQ rcvmore = %d\n", recv_more);
288 //
289 // zmq_msg_close(&msg);
290 // } while (recv_more);
291 // }
292 return 0;
293}
294
296{
297 // Int_t isRaw = 1;
298 // if (zmq_setsockopt(_socket_data, ZMQ_ROUTER_RAW, &isRaw, sizeof(isRaw)) == -1)
299 // DBGERR("zmq_setsockopt of ZMQ_ROUTER_RAW")
300 Char_t endpoint_addr[MAX_ADDR_LEN];
301 struct addrinfo hints;
302 struct addrinfo* p;
303 memset(&hints, 0, sizeof(hints));
304 hints.ai_family = AF_UNSPEC;
305 hints.ai_socktype = SOCK_STREAM;
306 Int_t g = 0;
307 if ((g = getaddrinfo(_dataServer.hostName, NULL, &hints, &dataAddrInfo)) != 0) {
308 printf("getaddrinfo error: %s\n", strerror(errno));
309 return -1;
310 }
311 Char_t* ip = NULL;
312 for (p = dataAddrInfo; p != NULL; p = p->ai_next) {
313 ip = inet_ntoa(((sockaddr_in*)(p->ai_addr))->sin_addr);
314 printf("found family %d %s addr: %s\n", p->ai_family, p->ai_canonname, ip);
315 Int_t port = 0;
316 for (auto iface : _dataServer.interfaces)
317 if (strcmp(iface.type, "Monitor output data flow") == 0) {
318 port = iface.port;
319 break;
320 }
321 snprintf(endpoint_addr, MAX_ADDR_LEN, "tcp://%s:%d", ip, port);
322 if (zmq_connect(_socket_data, endpoint_addr) != 0) {
323 DBGERR("zmq")
324 continue;
325 } else {
326 printf("%s\n", endpoint_addr);
327 break;
328 }
329 }
330 if (p == NULL) {
331 printf("Valid address not found\n");
332 return -1;
333 }
334 Int_t rcvBufLen = MAX_BUF_LEN;
335 size_t vl = sizeof(rcvBufLen);
336 if (zmq_setsockopt(_socket_data, ZMQ_RCVBUF, &rcvBufLen, sizeof(rcvBufLen)) == -1)
337 DBGERR("zmq_setsockopt of ZMQ_RCVBUF")
338 if (zmq_setsockopt(_socket_data, ZMQ_SNDBUF, &rcvBufLen, sizeof(rcvBufLen)) == -1)
339 DBGERR("zmq_setsockopt of ZMQ_SNDBUF")
340 rcvBufLen = 0;
341 if (zmq_getsockopt(_socket_data, ZMQ_RCVBUF, &rcvBufLen, &vl) == -1)
342 DBGERR("zmq_getsockopt of ZMQ_RCVBUF")
343 printf("rcvbuf = %d\n", rcvBufLen);
344 // UInt_t *buf = (UInt_t*) malloc(MAX_BUF_LEN);
345 Char_t conID[MAX_ADDR_LEN];
346 Int_t conID_size;
347 Int_t msg_len = 0;
348 Int_t frame_size = 0;
350 while ((isListening) && (msg_len < MAX_BUF_LEN)) {
351 conID_size = zmq_recv(_socket_data, &conID, sizeof(conID), 0);
352 if (conID_size == -1) {
353 printf("Receive error #%s\n", zmq_strerror(errno));
354 if (errno == EAGAIN)
355 usleep(MSG_TIMEOUT);
356 else
357 return -1;
358 } else {
359 printf("ID size = %d\n Id:%s\n", conID_size, conID);
360 }
361 zmq_msg_t msg;
362 zmq_msg_init(&msg);
363 Int_t recv_more = 0;
364 UInt_t* msgPtr;
365 do {
366 frame_size = zmq_msg_recv(&msg, _socket_data, 0); // ZMQ_DONTWAIT
367 // frame_size = zmq_recv(_socket_data, buf, MAX_BUF_LEN, 0);
368 if (frame_size == -1) {
369 printf("Receive error № %d #%s\n", errno, zmq_strerror(errno));
370 if (errno == EAGAIN)
371 usleep(MSG_TIMEOUT);
372 else
373 return -1;
374 } else {
375 // UChar_t *str = (UChar_t*) malloc((frame_size + 1) * sizeof (UChar_t));
376 msgPtr = (UInt_t*)zmq_msg_data(&msg);
377 // memcpy(buf, zmq_msg_data(&msg), frame_size);
378 // ((mutex*)_deque_mutex)->lock();
379 for (Int_t offset = 0; offset < frame_size; offset++)
380 data_queue.push_back(*(msgPtr + offset));
381 // ((mutex*)_deque_mutex)->unlock();
382 // memcpy(str, zmq_msg_data(&msg), frame_size);
383 // str[frame_size] = '\0';
384 msg_len += frame_size;
385 // printf("Frame size = %d\n Msg:%x\n", frame_size, str);
386 // free(str);
387 }
388 size_t opt_size = sizeof(recv_more);
389 if (zmq_getsockopt(_socket_data, ZMQ_RCVMORE, &recv_more, &opt_size) == -1) {
390 printf("ZMQ socket options error #%s\n", zmq_strerror(errno));
391 return -1;
392 }
393 printf("ZMQ rcvmore = %d\n", recv_more);
394
395 zmq_msg_close(&msg);
396 } while (recv_more);
397 }
398 // free(buf);
399 freeaddrinfo(dataAddrInfo);
400 return 0;
401}
402
404{
405 Char_t endpoint_addr[MAX_ADDR_LEN];
406 snprintf(endpoint_addr, MAX_ADDR_LEN, "epgm://%s;%s:%d", INPUT_IFACE, PNP_DISCOVER_IP_ADDR, PNP_DISCOVER_PORT);
407 Int_t rc = 0;
408 rc = zmq_connect(_socket_mcast, endpoint_addr);
409 if (rc != 0)
410 printf("Error: %s\n", zmq_strerror(errno));
411 else
412 printf("%s\n", endpoint_addr);
413 // Char_t * buf = (Char_t*) malloc(255);
414 Int_t frame_size = 0;
415 for (Int_t i = 0; i < 10; i++) {
416 zmq_msg_t msg;
417 zmq_msg_init(&msg);
418 Int_t recv_more = 0;
419 do {
420 frame_size = zmq_msg_recv(&msg, _socket_mcast, 0);
421 // frame_size = zmq_recv(_socket_mcast, buf, 255, 0);
422 if (frame_size == -1) {
423 printf("Receive error #%s\n", zmq_strerror(errno));
424 break;
425 } else {
426 Char_t* str = (Char_t*)malloc((frame_size + 1) * sizeof(Char_t));
427 memcpy(str, zmq_msg_data(&msg), frame_size);
428 str[frame_size] = '\0';
429 printf("Frame size = %d\n Msg:%s\n", frame_size, str);
430 }
431 size_t opt_size = sizeof(Int_t);
432 if (zmq_getsockopt(_socket_mcast, ZMQ_RCVMORE, &recv_more, &opt_size) == -1) {
433 printf("ZMQ socket options error #%s\n", zmq_strerror(errno));
434 break;
435 }
436
437 } while (recv_more);
438 printf("Received msg # %d\n", i);
439 zmq_msg_close(&msg);
440 }
441 return 0;
442}
443
445{
446 void* sender = zmq_socket(_ctx, ZMQ_XPUB);
447 const int maxlen = 255;
448 Char_t s[maxlen];
449 snprintf(s, maxlen, "epgm://%s;%s:%d", INPUT_IFACE, PNP_DISCOVER_IP_ADDR, PNP_DISCOVER_PORT); // enp3s0
450 Int_t rc = 0;
451 //_socket_mcast.connect(s);
452 rc = zmq_bind(sender, s);
453 printf("%s\n", s);
454 if (rc != 0)
455 printf("Error: %s\n", zmq_strerror(errno));
456
457 Char_t text[11] = "Hello port";
458 int len = strlen(text);
459 text[len] = '\0';
460 for (int i = 0; i < 5; i++) {
461 zmq_msg_t msg;
462 zmq_msg_init_size(&msg, len);
463 memcpy(zmq_msg_data(&msg), text, len);
464 rc = zmq_msg_send(&msg, sender, 0);
465 if (rc == -1)
466 printf("Send error: %s\n", zmq_strerror(errno));
467 else
468 printf("Sended bytes: %d\n", rc);
469 zmq_msg_close(&msg);
470 usleep(1000000);
471 }
472 zmq_close(sender);
473
474 return 0;
475}
#define ZMQ_STREAM
#define ZMQ_XSUB
void memset(T *dest, T i, size_t num)
Copy to memory block [@dest, @dest+@num] num number of times the value of i of type @T with size @typ...
Definition L1Grid.h:27
int i
Definition P4_F32vec4.h:22
int Int_t
char Char_t
constexpr Bool_t kTRUE
#define DBGERR(a)
Definition BmnMath.h:25
#define DBG(a)
Definition BmnMath.h:24
virtual ~BmnDataReceiver()
struct serverInfo _dataServer
struct addrinfo * dataAddrInfo
deque< UInt_t > data_queue
static Int_t ParsePNPMsg(char *msgStr, serverInfo *sInfo)
#define PNP_DISCOVER_PORT
#define MAX_ADDR_LEN
#define INPUT_IFACE
#define MAX_BUF_LEN
#define MSG_TIMEOUT
#define PNP_DISCOVER_IP_ADDR
Char_t type[MAX_ADDR_LEN]
Char_t index[MAX_ADDR_LEN]
Char_t hostName[MAX_ADDR_LEN]
vector< serverIface > interfaces
Char_t name[MAX_ADDR_LEN]
Char_t type[MAX_ADDR_LEN]