Belle II Software development
NSMCallback.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/NSMCallback.h"
9
10#include "daq/slc/system/LogFile.h"
11
12#include "daq/slc/nsm/NSMCommunicator.h"
13#include "daq/slc/nsm/NSMHandlerException.h"
14
15#include "daq/slc/version/Version.h"
16
17#include <cstdlib>
18#include <iostream>
19#include <sstream>
20#include <cstdarg>
21
22using namespace Belle2;
23
24NSMCallback::NSMCallback(const int timeout)
25 : AbstractNSMCallback(timeout)
26{
27 reg(NSMCommand::OK);
28 reg(NSMCommand::ERROR);
29 reg(NSMCommand::LOG);
30 reg(NSMCommand::VGET);
31 reg(NSMCommand::VSET);
32 reg(NSMCommand::VREPLY);
33 reg(NSMCommand::VLISTGET);
34 reg(NSMCommand::VLISTSET);
35
36 addDefaultHandlers();
37}
38
39
40int NSMCallback::reset()
41{
42 int revision = Callback::reset();
43
44 addDefaultHandlers();
45
46 return revision;
47}
48
49int NSMCallback::addDefaultHandlers()
50{
51 return add(new NSMVHandlerText("version", true, false, DAQ_SLC_VERSION::DAQ_SLC_VERSION), false, true);
52}
53
54void NSMCallback::addNode(const NSMNode& node)
55{
56 std::string name = node.getName();
57 if (m_nodes.find(name) == m_nodes.end()) {
58 m_nodes.insert(NSMNodeMap::value_type(name, node));
59 }
60}
61
62void NSMCallback::reply(const NSMMessage& msg)
63{
64 NSMMessage msg_out = msg;
65 for (NSMNodeMap::iterator it = m_nodes.begin();
66 it != m_nodes.end();) {
67 NSMNode& node(it->second);
68 msg_out.setNodeName(node.getName());
69 if (NSMCommunicator::send(msg_out)) {
70 ++it;
71 } else {
72 m_nodes.erase(it++);
73 }
74 }
75}
76
77void NSMCallback::log(LogFile::Priority pri, const char* format, ...)
78{
79 va_list ap;
80 char ss[1024 * 10];
81 va_start(ap, format);
82 vsnprintf(ss, sizeof(ss), format, ap);
83 va_end(ap);
84 log(pri, std::string(ss));
85}
86
87void NSMCallback::log(LogFile::Priority pri, const std::string& msg)
88{
89 LogFile::put(pri, msg);
90 try {
91 if (getLogNode().getName().size() > 0) {
92 NSMCommunicator::send(NSMMessage(getLogNode().getName(),
93 DAQLogMessage(getNode().getName(),
94 pri, getCategory(), msg)));
95 }
96 } catch (const NSMHandlerException& e) {
97 LogFile::error(e.what());
98 }
99}
100
101bool NSMCallback::perform(NSMCommunicator& com)
102{
103 const NSMMessage& msg(com.getMessage());
104 const NSMCommand cmd = msg.getRequestName();
105 if (cmd == NSMCommand::OK || cmd == NSMCommand::ERROR ||
106 cmd == NSMCommand::FATAL) {
107 if (msg.getLength() > 0) {
108 if (cmd == NSMCommand::OK) {
109 ok(msg.getNodeName(), msg.getData());
110 } else if (cmd == NSMCommand::ERROR) {
111 error(msg.getNodeName(), msg.getData());
112 } else if (cmd == NSMCommand::FATAL) {
113 fatal(msg.getNodeName(), msg.getData());
114 }
115 }
116 return true;
117 } else if (cmd == NSMCommand::LOG) {
118 int id = com.getNodeIdByName(msg.getNodeName());
119 DAQLogMessage lmsg;
120 lmsg.setId(id);
121 lmsg.setNodeName(msg.getNodeName());
122 if (msg.getNParams() > 0) {
123 lmsg.setPriority((LogFile::Priority)msg.getParam(0));
124 }
125 if (msg.getNParams() > 1) lmsg.setDate(msg.getParam(1));
126 if (msg.getNParams() > 2) lmsg.setCategory(msg.getParam(2));
127 lmsg.setMessage(msg.getLength() > 0 ? msg.getData() : "");
128 logset(lmsg);
129 return true;
130 } else if (cmd == NSMCommand::VGET) {
131 if (msg.getLength() > 0) {
132 vget(msg.getNodeName(), msg.getData());
133 }
134 return true;
135 } else if (cmd == NSMCommand::VSET) {
136 if (msg.getLength() > 0) {
137 NSMVar var;
138 readVar(msg, var);
139 vset(com, var);
140 }
141 return true;
142 } else if (cmd == NSMCommand::VREPLY) {
143 vreply(com, msg.getData(), msg.getParam(0));
144 return true;
145 } else if (cmd == NSMCommand::VLISTGET) {
146 vlistget(com);
147 return true;
148 } else if (cmd == NSMCommand::VLISTSET) {
149 vlistset(com);
150 return true;
151 }
152 return false;
153}
154
155void NSMCallback::notify(const NSMVar& var)
156{
157 std::string vname = var.getName();
158 NSMVar var_out = var;
159 if (var_out.getNode().size() == 0) {
160 var_out.setNode(getNode().getName());
161 }
162
163 if (m_node_v_m.find(vname) != m_node_v_m.end()) {
164 try {
165 NSMNodeMap& node_v(m_node_v_m[vname]);
166 for (NSMNodeMap::iterator inode = node_v.begin();
167 inode != node_v.end();) {
168 NSMNode& node(inode->second);
169 if (NSMCommunicator::send(NSMMessage(node, var_out))) {
170 ++inode;
171 } else {
172 node_v.erase(inode++);
173 }
174 }
175 } catch (const IOException& e) {
176 LogFile::error(e.what());
177 }
178 }
179}
180
181void NSMCallback::vget(const std::string& nodename, const std::string& vname)
182{
183 NSMNode node(nodename);
184 NSMVar var(vname);
185 try {
186 NSMVHandler* handler_p = getHandler_p(nodename, vname);
187 if (handler_p) {
188 NSMVHandler& handler(*handler_p);
189 handler.handleGet(var);
190 var.setNode(getNode().getName());
191 var.setName(vname);
192 //var.setId(i + 1);
193 var.setDate(Date());
194 NSMCommunicator::send(NSMMessage(node, var));
195 if (m_node_v_m.find(vname) == m_node_v_m.end()) {
196 m_node_v_m.insert(NSMNodeMapMap::value_type(vname, NSMNodeMap()));
197 }
198 NSMNodeMap& node_v(m_node_v_m[vname]);
199 if (node_v.find(nodename) == node_v.end()) {
200 node_v.insert(NSMNodeMap::value_type(nodename, NSMNode(nodename)));
201 std::string filename = ("/tmp/nsmvget." + StringUtil::tolower(getNode().getName()));
202 std::ofstream fout(filename.c_str(), std::ios::app);
203 fout << nodename << " " << vname << std::endl;
204 }
205 }
206 } catch (const NSMHandlerException& e) {
207 LogFile::error(e.what());
208 }
209}
210
211void NSMCallback::vset(NSMCommunicator& com, const NSMVar& var)
212{
213 try {
214 NSMMessage msg(com.getMessage());
215 NSMVHandler* handler_p = getHandler_p(var.getNode(), var.getName());
216 if (handler_p) {
217 NSMVHandler& handler(*handler_p);
218 if (var.getName() == handler.getName() &&
219 (var.getNode() == handler.getNode() ||
220 (var.getNode().size() == 0 && handler.getNode() == getNode().getName()) ||
221 (handler.getNode().size() == 0 && var.getNode() == getNode().getName())) &&
222 handler.useSet()) {
223 NSMNode node(msg.getNodeName());
224 bool result = false;
225 if ((result = handler.handleSet(var)) &&
226 (var.getNode().size() == 0 || var.getNode() == getNode().getName())) {
227 notify(var);
228 }
229 if (var.getNode().size() == 0) {
230 NSMCommunicator::send(NSMMessage(node, NSMCommand::VREPLY,
231 result, var.getName()));
232 }
233 }
234 }
235 } catch (const NSMHandlerException& e) {
236 LogFile::error(e.what());
237 }
238}
239
240void NSMCallback::vlistget(NSMCommunicator& com)
241{
242 std::stringstream ss;
243 int i = 0;
244 int count = 0;
245 for (NSMVHandlerList::iterator it = m_handler.begin();
246 it != m_handler.end(); ++it) {
247 NSMVHandler& handler(*it->second);
248 if (handler.getNode().size() == 0) {
249 ss << handler.getName() << ":"
250 << handler.get().getTypeLabel() << ":"
251 << (int)handler.useGet() << ":"
252 << (int)handler.useSet() << ":"
253 << i << "\n";
254 count++;
255 }
256 i++;
257 }
258 std::string nodename = com.getMessage().getNodeName();
259 NSMNode node(nodename);
260 try {
261 NSMCommunicator::send(NSMMessage(node, NSMCommand::VLISTSET,
262 count, ss.str()));
263 } catch (const NSMHandlerException& e) {
264 LogFile::error(e.what());
265 }
266}
267
269 std::string name;
270 std::string type;
271 bool useGet;
272 bool useSet;
273};
274
275void NSMCallback::vlistset(NSMCommunicator& com)
276{
277 std::string data = com.getMessage().getData();
278 StringList s = StringUtil::split(data, '\n');
279 std::vector<vlistentry_t> vlist;
280 size_t length = 0;
281 for (size_t i = 0; i < s.size(); i++) {
282 StringList ss = StringUtil::split(s[i], ':');
283 if (ss.size() > 4) {
284 vlistentry_t en = { ss[0],
285 ss[1], ss[2] == "1", ss[3] == "1"
286 };
287 vlist.push_back(en);
288 if (length < ss[0].size()) length = ss[0].size();
289 }
290 }
291 for (size_t i = 0; i < vlist.size(); i++) {
292 vlistentry_t& en(vlist[i]);
293 std::cout << StringUtil::form(StringUtil::form("%%-%ds ", length).c_str(), en.name.c_str())
294 << " : " << en.type << " "
295 << (en.useGet ? "get " : "")
296 << (en.useSet ? "set " : "") << std::endl;
297 }
298}
299
300void NSMCallback::alloc_open(NSMCommunicator& com)
301{
302 try {
303 if (!m_data.isAvailable() && m_data.getName().size() > 0 &&
304 m_data.getFormat().size() > 0 && m_data.getRevision() > 0) {
305 m_data.allocate(com);
306 }
307 } catch (const NSMHandlerException& e) {
308 LogFile::warning(e.what());
309 }
310 for (NSMDataMap::iterator it = m_datas.begin();
311 it != m_datas.end(); ++it) {
312 try {
313 NSMData& data(it->second);
314 if (!data.isAvailable() && data.getName().size() > 0 &&
315 data.getFormat().size() > 0) {
316 data.open(com);
317 }
318 } catch (const NSMHandlerException& e) {
319 }
320 }
321}
322
TString getName(const TObject *obj)
human-readable name (e.g.
Definition: ObjectInfo.cc:45
Abstract base class for different kinds of events.