18#include "daq/slc/nsm/NSMCommunicator.h"
20#include <daq/slc/base/TimeoutException.h>
21#include <daq/slc/nsm/NSMCallback.h>
22#include <daq/slc/nsm/NSMHandlerException.h>
23#include <daq/slc/nsm/NSMNotConnectedException.h>
27#include <nsm2/nsmlib2.h>
28#include <nsm2/belle2nsm.h>
35#include <sys/select.h>
38#include <netinet/in.h>
40#include <daq/slc/system/LockGuard.h>
42#define NSM_DEBUGMODE 1
46NSMCommunicatorList NSMCommunicator::g_comm;
47Mutex NSMCommunicator::g_mutex;
48Mutex NSMCommunicator::g_mutex_select;
57 for (NSMCommunicatorList::iterator it = g_comm.begin();
58 it != g_comm.end(); ++it) {
60 if (com.m_nsmc != NULL) {
61 FD_SET(com.m_nsmc->sock, &fds);
62 if (highest < com.m_nsmc->sock)
63 highest = com.m_nsmc->sock;
70 double us = modf(usec, &s);
71 timeval t = {(long)s, (
long)(us * 1000000)};
72 ret = ::select(highest + 1, &fds, NULL, NULL, &t);
74 ret = ::select(highest + 1, &fds, NULL, NULL, NULL);
76 if (ret != -1 || (errno != EINTR && errno != EAGAIN))
break;
81 for (NSMCommunicatorList::iterator it = g_comm.begin();
82 it != g_comm.end(); ++it) {
84 if (com.m_nsmc != NULL) {
85 if (FD_ISSET(com.m_nsmc->sock, &fds)) {
86 com.m_message.read(com.m_nsmc);
87 com.m_message.setRequestName();
88 b2nsm_context(com.m_nsmc);
98 for (NSMCommunicatorList::iterator it = g_comm.begin();
99 it != g_comm.end(); ++it) {
101 if (com.isConnected(node))
return com;
106bool NSMCommunicator::send(
const NSMMessage& msg)
109#if NSM_PACKAGE_VERSION >= 1914
113 for (NSMCommunicatorList::iterator it = g_comm.begin();
114 it != g_comm.end(); ++it) {
116 const char* node = msg.getNodeName();
117 if (com.isConnected(node)) {
119 const char* req = msg.getRequestName();
120 if (node != NULL && req != NULL &&
121 strlen(node) > 0 && strlen(req) > 0) {
122 b2nsm_context(com.m_nsmc);
123 if (b2nsm_sendany(node, req, msg.getNParams(), (
int*)msg.getParams(),
124 msg.getLength(), msg.getData(), NULL) < 0) {
125 emsg = b2nsm_strerror();
131 if (alive && !sent) {
135#warning "Wrong version of nsm2. try source daq/slc/extra/nsm2/export.sh"
140NSMCommunicator::NSMCommunicator(
const std::string& host,
int port)
149NSMCommunicator::NSMCommunicator(
NSMcontext* nsmc)
152 m_id = m_nsmc->nodeid;
156void NSMCommunicator::init(
const NSMNode& node,
157 const std::string& host,
int port)
159#if NSM_PACKAGE_VERSION >= 1914
161 if (host.size() > 0) m_host = host;
162 if (port > 0) m_port = port;
163 if (node.getName().size() == 0) {
166 m_nsmc = b2nsm_init2(node.getName().c_str(), 0, host.c_str(), port, port);
167 if (m_nsmc == NULL) {
170 node.getName().c_str(), host.c_str(),
171 m_port, b2nsm_strerror()));
173 g_comm.push_back(
this);
174 nsmlib_usesig(m_nsmc, 0);
175 m_id = m_nsmc->nodeid;
178#warning "Wrong version of nsm2. try source daq/slc/extra/nsm2/export.sh"
187 throw (std::out_of_range(
"No callback was registered"));
190void NSMCommunicator::setCallback(
NSMCallback* callback)
192 b2nsm_context(m_nsmc);
193 if (callback != NULL) {
194 m_callback = callback;
195 NSMCallback::NSMCommandList& req_v(callback->getCommandList());
196 for (NSMCallback::NSMCommandList::iterator it = req_v.begin();
197 it != req_v.end(); ++it) {
199 if (b2nsm_callback(command.getLabel(), NULL) < 0) {
202 command.getLabel()));
208int NSMCommunicator::getNodeIdByName(
const std::string& name)
210#if NSM_PACKAGE_VERSION >= 1914
211 b2nsm_context(m_nsmc);
212 return b2nsm_nodeid(name.c_str());
218const std::string NSMCommunicator::getNodeNameById(
int id)
220 const char* name = nsmlib_nodename(m_nsmc,
id);
221 if (name == NULL)
return "";
225int NSMCommunicator::getNodePidByName(
const std::string& name)
227#if NSM_PACKAGE_VERSION >= 1914
228 b2nsm_context(m_nsmc);
229 return b2nsm_nodepid(name.c_str());
235bool NSMCommunicator::isConnected(
const std::string& node)
237 bool is_online = getNodeIdByName(node) >= 0 &&
238 getNodePidByName(node) > 0;
249void NSMCommunicator::setMessage(
const NSMMessage& msg)
Lock Guard for a Mutex instance.
Abstract base class for different kinds of events.