Belle II Software  release-08-01-10
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 
33 using namespace Belle2;
34 
35 const unsigned int NSMMessage::DATA_SIZE = NSM_TCPDATSIZ;
36 
37 void NSMMessage::init()
38 {
39  m_nsmc = NULL;
40  memset(&m_nsm_msg, 0, sizeof(NSMmsg));
41  m_hasobj = false;
42 }
43 
44 void 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 
75 void 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 
87 void 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 
100 void 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 
117 NSMMessage::NSMMessage()
118 {
119  init();
120 }
121 
122 NSMMessage::NSMMessage(const NSMNode& node)
123 {
124  init();
125  m_nodename = node.getName();
126 }
127 
128 NSMMessage::NSMMessage(const NSMNode& node,
129  const NSMCommand& cmd)
130 {
131  init();
132  m_nodename = node.getName();
133  m_reqname = cmd.getLabel();
134 }
135 
136 NSMMessage::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 
147 NSMMessage::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 
160 NSMMessage::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 
172 NSMMessage::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 
181 NSMMessage::NSMMessage(const NSMCommand& cmd,
182  const std::string& data)
183 {
184  init();
185  m_reqname = cmd.getLabel();
186  setData(data);
187 }
188 
189 NSMMessage::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 
199 NSMMessage::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 
209 NSMMessage::NSMMessage(const NSMCommand& cmd)
210 {
211  init();
212  m_reqname = cmd.getLabel();
213 }
214 
215 NSMMessage::NSMMessage(const NSMMessage& msg)
216 {
217  init();
218  *this = msg;
219 }
220 
221 NSMMessage::NSMMessage(const NSMNode& node, const NSMVar& var)
222 {
223  init(node, var);
224 }
225 
226 NSMMessage::NSMMessage(const NSMNode& node, const NSMData& data)
227 {
228  init(node, data);
229 }
230 
231 NSMMessage::NSMMessage(const NSMNode& node, const DAQLogMessage& log)
232 {
233  init(node, log);
234 }
235 
236 NSMMessage::NSMMessage(const NSMNode& node, const DAQLogMessage& log,
237  const NSMCommand& cmd)
238 {
239  init(node, log, cmd);
240 }
241 
242 NSMMessage::NSMMessage(const NSMVar& var)
243 {
244  init(NSMNode(), var);
245 }
246 
247 NSMMessage::NSMMessage(const NSMData& data)
248 {
249  init(NSMNode(), data);
250 }
251 
252 NSMMessage::NSMMessage(const DAQLogMessage& log)
253 {
254  init(NSMNode(), log);
255 }
256 
257 NSMMessage::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 
266 const 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 
281 const 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 
296 void 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 
306 void NSMMessage::setRequestName(const std::string& reqname)
307 {
308  m_reqname = reqname;
309 }
310 
311 void NSMMessage::setRequestName(const NSMCommand& cmd)
312 {
313  m_reqname = cmd.getLabel();
314 }
315 
316 void NSMMessage::setNodeName(const std::string& nodename)
317 {
318  m_nodename = nodename;
319 }
320 
321 void NSMMessage::setNodeName(const NSMNode& node)
322 {
323  m_nodename = node.getName();
324 }
325 
326 const 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 
335 unsigned short NSMMessage::getRequestId() const
336 {
337  return m_nsm_msg.req;
338 }
339 
340 unsigned short NSMMessage::getSequenceId() const
341 {
342  return m_nsm_msg.seq;
343 }
344 
345 unsigned short NSMMessage::getNodeId() const
346 {
347  return m_nsm_msg.node;
348 }
349 
350 unsigned short NSMMessage::getNParams() const
351 {
352  return m_nsm_msg.npar;
353 }
354 
355 int NSMMessage::getParam(int i) const
356 {
357  return m_nsm_msg.pars[i];
358 }
359 
360 #if NSM_PACKAGE_VERSION >= 1914
361 const int* NSMMessage::getParams() const
362 {
363  return m_nsm_msg.pars;
364 }
365 
366 int* NSMMessage::getParams()
367 {
368  return m_nsm_msg.pars;
369 }
370 #else
371 const unsigned int* NSMMessage::getParams() const
372 {
373  return m_nsm_msg.pars;
374 }
375 
376 unsigned 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 
383 unsigned int NSMMessage::getLength() const
384 {
385  return m_nsm_msg.len;
386 }
387 
388 const char* NSMMessage::getData() const
389 {
390  if (m_nsm_msg.len > 0) return (const char*)m_data.ptr();
391  else return NULL;
392 }
393 
394 void NSMMessage::setRequestId(unsigned short id)
395 {
396  m_nsm_msg.req = id;
397 }
398 
399 void NSMMessage::setSequenceId(unsigned short id)
400 {
401  m_nsm_msg.seq = id;
402 }
403 
404 void NSMMessage::setNodeId(unsigned short id)
405 {
406  m_nsm_msg.node = id;
407 }
408 
409 void NSMMessage::setNParams(unsigned short npar)
410 {
411  m_nsm_msg.npar = npar;
412 }
413 
414 void NSMMessage::setParam(int i, unsigned int v)
415 {
416  m_nsm_msg.pars[i] = v;
417 }
418 
419 void 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 
429 void NSMMessage::setData(const std::string& text)
430 {
431  setData(text.size() + 1, text.c_str());
432 }
433 
434 int 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 
448 size_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 
490 void 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 
506 void 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