Belle II Software development
NSMMessage.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include "daq/slc/nsm/NSMMessage.h"
9
10// 20191004
11// duplicating the NSM2 library function in a user function
12// NSMMessage::read(NSMcontext* nsmc)
13// is really a bad idea, need to be revised.
14// Until then, nsmsys2.h is needed.
15#include <nsm2/nsmsys2.h>
16
17#include <string.h>
18#include <unistd.h>
19#include <errno.h>
20#include <stdlib.h>
21
22#include <daq/slc/nsm/NSMData.h>
23#include <daq/slc/nsm/NSMHandlerException.h>
24
25#include <daq/slc/base/Reader.h>
26#include <daq/slc/base/Writer.h>
27
28#include <nsm2/nsmlib2.h>
29#include <nsm2/nsmsys2.h>
30
31#include <arpa/inet.h>
32
33using namespace Belle2;
34
35const unsigned int NSMMessage::DATA_SIZE = NSM_TCPDATSIZ;
36
37void NSMMessage::init()
38{
39 m_nsmc = NULL;
40 memset(&m_nsm_msg, 0, sizeof(NSMmsg));
41 m_hasobj = false;
42}
43
44void NSMMessage::init(const NSMNode& node, const NSMVar& var)
45{
46 init();
47 m_nodename = node.getName();
48 m_reqname = NSMCommand::VSET.getLabel();
49 m_nsm_msg.npar = 6;
50 m_nsm_msg.pars[0] = (int)var.getType();
51 m_nsm_msg.pars[1] = (int)var.getLength();
52 m_nsm_msg.pars[2] = var.getNode().size();
53 m_nsm_msg.pars[3] = var.getName().size();
54 m_nsm_msg.pars[4] = var.getId();
55 m_nsm_msg.pars[5] = var.getDate();
56 if (var.getType() != NSMVar::NONE) {
57 int size = var.getNode().size() + 1 + var.getName().size() + 1 + var.size();
58 m_data = Buffer(size);
59 char* pdata = (char*)m_data.ptr();
60 memset(pdata, 0, size);
61 memcpy(pdata, var.getNode().c_str(), var.getNode().size());
62 pdata += var.getNode().size();
63 *pdata = '\0';
64 pdata++;
65 memcpy(pdata, var.getName().c_str(), var.getName().size());
66 pdata += var.getName().size();
67 *pdata = '\0';
68 pdata++;
69 memcpy(pdata, var.get(), var.size());
70 m_hasobj = false;
71 m_nsm_msg.len = size;
72 }
73}
74
75void NSMMessage::init(const NSMNode& node, const DAQLogMessage& log)
76{
77 init();
78 m_nodename = node.getName();
79 m_reqname = NSMCommand::LOG.getLabel();
80 setNParams(3);
81 setParam(0, (int)log.getPriority());
82 setParam(1, log.getDateInt());
83 setParam(2, log.getId());
84 setData(log.getMessage());
85}
86
87void NSMMessage::init(const NSMNode& node, const DAQLogMessage& log,
88 const NSMCommand& cmd)
89{
90 init();
91 m_nodename = node.getName();
92 m_reqname = cmd.getLabel();
93 setNParams(3);
94 setParam(0, (int)log.getPriority());
95 setParam(1, log.getDateInt());
96 setParam(2, log.getId());
97 setData(log.getMessage());
98}
99
100void NSMMessage::init(const NSMNode& node, const NSMData& data)
101{
102 init();
103 m_nodename = node.getName();
104 m_reqname = NSMCommand::DATASET.getLabel();
105 setNParams(2);
106 setParam(0, data.getRevision());
107 setParam(1, data.getSize());
108 std::string s = data.getName() + "\n" + data.getFormat();
109 int len = s.size() + 1 + data.getSize();
110 m_nsm_msg.len = len;
111 m_data = Buffer(len);
112 memcpy(m_data.ptr(), s.c_str(), s.size());
113 memcpy(m_data.ptr() + s.size() + 1, data.get(), data.getSize());
114 m_hasobj = false;
115}
116
117NSMMessage::NSMMessage()
118{
119 init();
120}
121
122NSMMessage::NSMMessage(const NSMNode& node)
123{
124 init();
125 m_nodename = node.getName();
126}
127
128NSMMessage::NSMMessage(const NSMNode& node,
129 const NSMCommand& cmd)
130{
131 init();
132 m_nodename = node.getName();
133 m_reqname = cmd.getLabel();
134}
135
136NSMMessage::NSMMessage(const NSMNode& node,
137 const NSMCommand& cmd,
138 int npar, int* pars)
139{
140 init();
141 m_nodename = node.getName();
142 m_reqname = cmd.getLabel();
143 m_nsm_msg.npar = npar;
144 memcpy(m_nsm_msg.pars, pars, sizeof(int) * npar);
145}
146
147NSMMessage::NSMMessage(const NSMNode& node,
148 const NSMCommand& cmd,
149 int npar, int* pars,
150 const std::string& data)
151{
152 init();
153 m_nodename = node.getName();
154 m_reqname = cmd.getLabel();
155 m_nsm_msg.npar = npar;
156 memcpy(m_nsm_msg.pars, pars, sizeof(int) * npar);
157 setData(data);
158}
159
160NSMMessage::NSMMessage(const NSMNode& node,
161 const NSMCommand& cmd,
162 int par, const std::string& obj)
163{
164 init();
165 m_nodename = node.getName();
166 m_reqname = cmd.getLabel();
167 m_nsm_msg.npar = 1;
168 m_nsm_msg.pars[0] = par;
169 setData(obj);
170}
171
172NSMMessage::NSMMessage(const NSMCommand& cmd,
173 int par)
174{
175 init();
176 m_reqname = cmd.getLabel();
177 m_nsm_msg.npar = 1;
178 m_nsm_msg.pars[0] = par;
179}
180
181NSMMessage::NSMMessage(const NSMCommand& cmd,
182 const std::string& data)
183{
184 init();
185 m_reqname = cmd.getLabel();
186 setData(data);
187}
188
189NSMMessage::NSMMessage(const NSMNode& node,
190 const NSMCommand& cmd, int par)
191{
192 init();
193 m_nodename = node.getName();
194 m_reqname = cmd.getLabel();
195 m_nsm_msg.npar = 1;
196 m_nsm_msg.pars[0] = par;
197}
198
199NSMMessage::NSMMessage(const NSMNode& node,
200 const NSMCommand& cmd,
201 const std::string& data)
202{
203 init();
204 m_nodename = node.getName();
205 m_reqname = cmd.getLabel();
206 setData(data);
207}
208
209NSMMessage::NSMMessage(const NSMCommand& cmd)
210{
211 init();
212 m_reqname = cmd.getLabel();
213}
214
215NSMMessage::NSMMessage(const NSMMessage& msg)
216{
217 init();
218 *this = msg;
219}
220
221NSMMessage::NSMMessage(const NSMNode& node, const NSMVar& var)
222{
223 init(node, var);
224}
225
226NSMMessage::NSMMessage(const NSMNode& node, const NSMData& data)
227{
228 init(node, data);
229}
230
231NSMMessage::NSMMessage(const NSMNode& node, const DAQLogMessage& log)
232{
233 init(node, log);
234}
235
236NSMMessage::NSMMessage(const NSMNode& node, const DAQLogMessage& log,
237 const NSMCommand& cmd)
238{
239 init(node, log, cmd);
240}
241
242NSMMessage::NSMMessage(const NSMVar& var)
243{
244 init(NSMNode(), var);
245}
246
247NSMMessage::NSMMessage(const NSMData& data)
248{
249 init(NSMNode(), data);
250}
251
252NSMMessage::NSMMessage(const DAQLogMessage& log)
253{
254 init(NSMNode(), log);
255}
256
257NSMMessage::NSMMessage(const NSMCommand& cmd,
258 int npar, int* pars)
259{
260 init();
261 m_reqname = cmd.getLabel();
262 m_nsm_msg.npar = npar;
263 memcpy(m_nsm_msg.pars, pars, sizeof(int) * npar);
264}
265
266const NSMMessage& NSMMessage::operator=(const NSMMessage& msg)
267{
268 m_nsmc = msg.m_nsmc;
269 memcpy(&m_nsm_msg, &(msg.m_nsm_msg), sizeof(m_nsm_msg));
270 m_nsm_msg.npar = msg.m_nsm_msg.npar;
271 m_nsm_msg.len = msg.m_nsm_msg.len;
272 m_nodename = msg.m_nodename;
273 m_reqname = msg.m_reqname;
274 m_hasobj = msg.m_hasobj;
275 //m_data = msg.m_data;
276 m_data = Buffer(m_nsm_msg.len);
277 memcpy(m_data.ptr(), msg.m_data.ptr(), m_nsm_msg.len);
278 return *this;
279}
280
281const char* NSMMessage::getRequestName() const
282{
283 if (m_reqname.size() > 0) return m_reqname.c_str();
284 if (m_nsmc != NULL) {
285 const char* reqname = nsmlib_reqname(m_nsmc, m_nsm_msg.req);
286 if (reqname != NULL) {
287 m_reqname = reqname;
288 }
289 return m_reqname.c_str();
290 } else {
291 m_reqname = "";
292 return m_reqname.c_str();
293 }
294}
295
296void NSMMessage::setRequestName()
297{
298 if (m_nsmc != NULL) {
299 const char* reqname = nsmlib_reqname(m_nsmc, m_nsm_msg.req);
300 if (reqname != NULL) {
301 m_reqname = reqname;
302 }
303 }
304}
305
306void NSMMessage::setRequestName(const std::string& reqname)
307{
308 m_reqname = reqname;
309}
310
311void NSMMessage::setRequestName(const NSMCommand& cmd)
312{
313 m_reqname = cmd.getLabel();
314}
315
316void NSMMessage::setNodeName(const std::string& nodename)
317{
318 m_nodename = nodename;
319}
320
321void NSMMessage::setNodeName(const NSMNode& node)
322{
323 m_nodename = node.getName();
324}
325
326const char* NSMMessage::getNodeName() const
327{
328 if (m_nodename.size() > 0) return m_nodename.c_str();
329 if (m_nsmc != NULL)
330 return nsmlib_nodename(m_nsmc, m_nsm_msg.node);
331 else
332 return m_nodename.c_str();
333}
334
335unsigned short NSMMessage::getRequestId() const
336{
337 return m_nsm_msg.req;
338}
339
340unsigned short NSMMessage::getSequenceId() const
341{
342 return m_nsm_msg.seq;
343}
344
345unsigned short NSMMessage::getNodeId() const
346{
347 return m_nsm_msg.node;
348}
349
350unsigned short NSMMessage::getNParams() const
351{
352 return m_nsm_msg.npar;
353}
354
355int NSMMessage::getParam(int i) const
356{
357 return m_nsm_msg.pars[i];
358}
359
360#if NSM_PACKAGE_VERSION >= 1914
361const int* NSMMessage::getParams() const
362{
363 return m_nsm_msg.pars;
364}
365
366int* NSMMessage::getParams()
367{
368 return m_nsm_msg.pars;
369}
370#else
371const unsigned int* NSMMessage::getParams() const
372{
373 return m_nsm_msg.pars;
374}
375
376unsigned int* NSMMessage::getParams()
377{
378 return m_nsm_msg.pars;
379}
380#warning "Wrong version of nsm2. try source daq/slc/extra/nsm2/export.sh"
381#endif
382
383unsigned int NSMMessage::getLength() const
384{
385 return m_nsm_msg.len;
386}
387
388const char* NSMMessage::getData() const
389{
390 if (m_nsm_msg.len > 0) return (const char*)m_data.ptr();
391 else return NULL;
392}
393
394void NSMMessage::setRequestId(unsigned short id)
395{
396 m_nsm_msg.req = id;
397}
398
399void NSMMessage::setSequenceId(unsigned short id)
400{
401 m_nsm_msg.seq = id;
402}
403
404void NSMMessage::setNodeId(unsigned short id)
405{
406 m_nsm_msg.node = id;
407}
408
409void NSMMessage::setNParams(unsigned short npar)
410{
411 m_nsm_msg.npar = npar;
412}
413
414void NSMMessage::setParam(int i, unsigned int v)
415{
416 m_nsm_msg.pars[i] = v;
417}
418
419void NSMMessage::setData(int len, const char* data)
420{
421 m_nsm_msg.len = len;
422 if (len > 0 && data != NULL) {
423 m_data = Buffer(len);
424 memcpy(m_data.ptr(), data, len);
425 }
426 m_hasobj = false;
427}
428
429void NSMMessage::setData(const std::string& text)
430{
431 setData(text.size() + 1, text.c_str());
432}
433
434int NSMMessage::try_read(int sock, char* buf, int datalen)
435{
436 int recvlen = 0;
437 while (recvlen < datalen) {
438 int ret;
439 if ((ret = ::read(sock, buf + recvlen, datalen)) <= 0) {
440 if (ret == -1 && errno == EINTR) continue;
441 if (ret < 0) return -1;
442 }
443 recvlen += ret;
444 }
445 return recvlen;
446}
447
448size_t NSMMessage::read(NSMcontext* nsmc)
449{
450 if (nsmc == NULL) return 0;
451 m_nsmc = nsmc;
452 int sock = nsmc->sock;
453 size_t count = 0;
454 int ret = 0;
455 NSMtcphead hp;
456 int datalen = sizeof(NSMtcphead);
457 if ((ret = try_read(sock, (char*)&hp, datalen)) < 0) {
458 throw (NSMHandlerException("Failed to read header"));
459 }
460 count += ret;
461 m_nsm_msg.req = ntohs(hp.req);
462 m_nsm_msg.seq = ntohs(hp.seq);
463 m_nsm_msg.node = ntohs(hp.src);
464 m_nsm_msg.npar = hp.npar;
465 m_nsm_msg.len = ntohs(hp.len);
466 m_nsm_msg.pars[0] = m_nsm_msg.pars[1] = 0;
467
468 datalen = sizeof(int32) * m_nsm_msg.npar;
469 if (datalen > 0) {
470 if ((ret = try_read(sock, (char*)(m_nsm_msg.pars), datalen)) < 0) {
471 throw (NSMHandlerException("Failed to read params"));
472 }
473 count += ret;
474 for (int i = 0; i < m_nsm_msg.npar; i++) {
475 m_nsm_msg.pars[i] = ntohl(m_nsm_msg.pars[i]);
476 }
477 }
478
479 datalen = m_nsm_msg.len;
480 if (datalen > 0) {
481 m_data = Buffer(datalen);
482 if ((ret = try_read(sock, (char*)m_data.ptr(), datalen)) < 0) {
483 throw (NSMHandlerException("Failed to read data"));
484 }
485 count += ret;
486 }
487 return count;
488}
489
490void NSMMessage::readObject(Reader& reader)
491{
492 setRequestName(reader.readString());
493 setNodeName(reader.readString());
494 setNParams(reader.readInt());
495 for (int i = 0; i < getNParams(); i++) {
496 setParam(i, reader.readInt());
497 }
498 size_t len = reader.readInt();
499 m_nsm_msg.len = len;
500 if (len > 0) {
501 m_data = Buffer(len);
502 reader.read(m_data.ptr(), len);
503 }
504}
505
506void NSMMessage::writeObject(Writer& writer) const
507{
508 writer.writeString(getRequestName());
509 writer.writeString(getNodeName());
510 writer.writeInt(getNParams());
511 for (int i = 0; i < getNParams(); i++) {
512 writer.writeInt(getParam(i));
513 }
514 if (m_hasobj) {
515 writer.writeInt(-1);
516 } else {
517 writer.writeInt(getLength());
518 }
519 if (getLength() > 0) {
520 writer.write(m_data.ptr(), getLength());
521 }
522}
Abstract base class for different kinds of events.
Definition: nsm2.h:224