GCC Code Coverage Report


Directory: ./
File: pdserv/src/msrproto/Session.cpp
Date: 2025-08-17 04:10:43
Exec Total Coverage
Lines: 369 532 69.4%
Branches: 406 1034 39.3%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright 2010 Richard Hacker (lerichi at gmx dot net)
4 *
5 * This file is part of the pdserv library.
6 *
7 * The pdserv library is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation, either version 3 of the License, or (at
10 * your option) any later version.
11 *
12 * The pdserv library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ****************************************************************************/
21
22 #include <streambuf>
23 #include <cerrno> // ENAMETOOLONG
24 #include <climits> // HOST_NAME_MAX
25 #include <unistd.h> // gethostname
26 #include <log4cplus/ndc.h>
27 #include <log4cplus/loggingmacros.h>
28 #include <endian.h>
29
30 #include "config.h"
31
32 #include "../Debug.h"
33
34 #include "../Main.h"
35 #include "../Task.h"
36 #include "../Signal.h"
37 #include "../Parameter.h"
38 #include "../DataType.h"
39 #include "../Event.h"
40
41 #include "Session.h"
42 #include "Server.h"
43 #include "Event.h"
44 #include "Channel.h"
45 #include "Parameter.h"
46 #include "XmlElement.h"
47 #include "XmlParser.h"
48 #include "SubscriptionManager.h"
49
50 using namespace MsrProto;
51
52 struct ParameterData {
53 ParameterData(const Parameter* p,
54 const char* buf, const struct timespec* t)
55 : parameter(p), data(new char[p->memSize]), time(*t) {
56 std::copy(buf, buf + p->memSize, data);
57 }
58 ~ParameterData() { delete[] data; }
59
60 const Parameter* const parameter;
61 char * const data;
62 const struct timespec time;
63 };
64
65 /////////////////////////////////////////////////////////////////////////////
66 148 Session::Session( Server *server, net::TCPServer* tcp):
67 TCPSession(tcp),
68 148 PdServ::Session(server->main, server->log), server(server),
69
4/8
✓ Branch 5 taken 148 times.
✗ Branch 6 not taken.
✓ Branch 14 taken 148 times.
✗ Branch 15 not taken.
✓ Branch 20 taken 148 times.
✗ Branch 21 not taken.
✓ Branch 30 taken 148 times.
✗ Branch 31 not taken.
296 xmlstream(static_cast<PdServ::Session*>(this))
70 {
71 148 inBytes = 0;
72 148 outBytes = 0;
73
74 148 timeTask = 0;
75
76
1/2
✓ Branch 13 taken 148 times.
✗ Branch 14 not taken.
296 std::list<const PdServ::Task*> taskList(main->getTasks());
77
1/2
✓ Branch 3 taken 148 times.
✗ Branch 4 not taken.
148 subscriptionManager.reserve(taskList.size());
78
2/2
✓ Branch 1 taken 296 times.
✓ Branch 2 taken 148 times.
740 for (; taskList.size(); taskList.pop_front()) {
79 296 const PdServ::Task *task = taskList.front();
80
81
3/6
✓ Branch 3 taken 296 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 296 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 296 times.
✗ Branch 12 not taken.
296 subscriptionManager.push_back(new SubscriptionManager(this, task));
82
83
3/4
✓ Branch 3 taken 148 times.
✓ Branch 4 taken 148 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 148 times.
296 if (!timeTask or timeTask->task->sampleTime > task->sampleTime)
84 148 timeTask = subscriptionManager.back();
85 }
86
87 // Setup some internal variables
88 148 writeAccess = false;
89 148 echoOn = false; // FIXME: echoOn is not yet implemented
90 148 quiet = false;
91 148 polite = false;
92 148 aicDelay = 0;
93 148 parameterMonitor = false;
94
1/2
✓ Branch 18 taken 148 times.
✗ Branch 19 not taken.
148 eventId = main->getCurrentEventId();
95
96
2/4
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 148 times.
✗ Branch 6 not taken.
148 xmlstream.imbue(std::locale::classic());
97 148 }
98
99 /////////////////////////////////////////////////////////////////////////////
100 378 Session::~Session()
101 {
102 148 server->sessionClosed(this);
103
104 444 for (SubscriptionManagerVector::iterator it = subscriptionManager.begin();
105
2/2
✓ Branch 6 taken 296 times.
✓ Branch 7 taken 148 times.
444 it != subscriptionManager.end(); ++it)
106
1/2
✓ Branch 2 taken 296 times.
✗ Branch 3 not taken.
296 delete *it;
107 230 }
108
109 /////////////////////////////////////////////////////////////////////////////
110 void Session::close()
111 {
112 TCPSession::close();
113 }
114
115 /////////////////////////////////////////////////////////////////////////////
116 288 size_t Session::getReceiveBufSize() const
117 {
118
1/2
✓ Branch 19 taken 288 times.
✗ Branch 20 not taken.
288 return std::max(server->getMaxInputBufferSize() + 1024UL, 8192UL);
119 }
120
121 /////////////////////////////////////////////////////////////////////////////
122 5 void Session::getSessionStatistics(PdServ::SessionStatistics &stats) const
123 {
124
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 std::ostringstream os;
125
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if (remoteHostName.empty())
126
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 stats.remote = getAddr();
127 else
128 stats.remote = remoteHostName + " (" + getAddr() +')';
129
1/2
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
5 stats.client = client;
130 5 stats.countIn = inBytes;
131 5 stats.countOut = outBytes;
132 5 stats.connectedTime = connectedTime;
133 5 }
134
135 /////////////////////////////////////////////////////////////////////////////
136 const struct timespec *Session::getTaskTime (const PdServ::Task* task) const
137 {
138 return subscriptionManager[task->index]->taskTime;
139 }
140
141 /////////////////////////////////////////////////////////////////////////////
142 const PdServ::TaskStatistics *Session::getTaskStatistics (
143 const PdServ::Task* task) const
144 {
145 return subscriptionManager[task->index]->taskStatistics;
146 }
147
148 /////////////////////////////////////////////////////////////////////////////
149 22 void Session::broadcast(Session *, const struct timespec& ts,
150 const std::string& action, const std::string &message)
151 {
152 44 pthread::MutexLock lock(mutex);
153
154
1/2
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
22 Broadcast *b = new Broadcast;
155 22 b->ts = ts;
156
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
22 b->action = action;
157
1/2
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
22 b->message = message;
158
1/2
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
22 broadcastList.push_back(b);
159 22 }
160
161 /////////////////////////////////////////////////////////////////////////////
162 void Session::setAIC(const Parameter *p)
163 {
164 pthread::MutexLock lock(mutex);
165 aic.insert(p->mainParam);
166
167 if (!aicDelay)
168 aicDelay = 5; // 2Hz AIC
169 }
170
171 /////////////////////////////////////////////////////////////////////////////
172 134 void Session::parameterChanged(const Parameter *p,
173 const char* data, const struct timespec* time)
174 {
175 268 pthread::MutexLock lock(mutex);
176
177
4/8
✗ Branch 3 not taken.
✓ Branch 4 taken 134 times.
✓ Branch 5 taken 134 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 134 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 134 times.
✗ Branch 12 not taken.
134 if (!parameterMonitor and parameterMonitorSet.empty())
178
1/2
✓ Branch 2 taken 134 times.
✗ Branch 3 not taken.
134 changedParameter.insert(p);
179 else if (p->memSize == p->variable->memSize
180 and (parameterMonitorSet.find(p) != parameterMonitorSet.end()
181 or parameterMonitor))
182 parameterMonitorData.push(new ParameterData(p, data, time));
183 134 }
184
185 /////////////////////////////////////////////////////////////////////////////
186 148 void Session::initial()
187 {
188 148 TCPSession::initial();
189
190
1/2
✓ Branch 8 taken 148 times.
✗ Branch 9 not taken.
148 log4cplus::getNDC().push(LOG4CPLUS_STRING_TO_TSTRING(getAddr()));
191
192
3/6
✓ Branch 9 taken 148 times.
✗ Branch 10 not taken.
✓ Branch 18 taken 148 times.
✗ Branch 19 not taken.
✓ Branch 26 taken 148 times.
✗ Branch 27 not taken.
148 LOG4CPLUS_INFO(server->log,
193 LOG4CPLUS_TEXT("New session from ")
194 << LOG4CPLUS_STRING_TO_TSTRING(getPeerName()));
195 148 }
196
197 144 void Session::sendGreeting()
198 {
199 // Get the hostname
200 144 char hostname[HOST_NAME_MAX+1];
201
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
144 if (gethostname(hostname, HOST_NAME_MAX)) {
202 if (errno == ENAMETOOLONG)
203 hostname[HOST_NAME_MAX] = '\0';
204 else
205 strcpy(hostname,"unknown");
206 }
207
208 // Greet the new client
209 {
210
1/2
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
288 XmlElement greeting(createElement("connected"));
211
2/4
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 144 times.
✗ Branch 7 not taken.
144 XmlElement::Attribute(greeting, "name") << "MSR";
212
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
288 XmlElement::Attribute(greeting, "host")
213
1/2
✓ Branch 3 taken 144 times.
✗ Branch 4 not taken.
288 << reinterpret_cast<const char*>(hostname);
214
2/4
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 13 taken 144 times.
✗ Branch 14 not taken.
144 XmlElement::Attribute(greeting, "app") << main->name;
215
2/4
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 13 taken 144 times.
✗ Branch 14 not taken.
144 XmlElement::Attribute(greeting, "appversion") << main->version;
216
2/4
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 144 times.
✗ Branch 9 not taken.
144 XmlElement::Attribute(greeting, "version") << MSR_VERSION;
217
2/4
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 144 times.
✗ Branch 7 not taken.
144 XmlElement::Attribute(greeting, "features") << MSR_FEATURES;
218
219
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
288 XmlElement::Attribute(greeting, "endian")
220 #if __BYTE_ORDER == __BIG_ENDIAN
221 << "big"
222 #endif
223 #if __BYTE_ORDER == __LITTLE_ENDIAN
224
1/2
✓ Branch 3 taken 144 times.
✗ Branch 4 not taken.
288 << "little"
225 #endif
226 ;
227
228
3/4
✓ Branch 16 taken 144 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 28 times.
✓ Branch 19 taken 116 times.
144 if (main->loginMandatory())
229
2/4
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 28 times.
✗ Branch 7 not taken.
28 XmlElement::Attribute(greeting, "login") << "mandatory";
230
231
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
288 XmlElement::Attribute(greeting, "recievebufsize")
232
2/4
✓ Branch 7 taken 144 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 144 times.
✗ Branch 12 not taken.
288 << getReceiveBufSize();
233 }
234
235
3/4
✓ Branch 16 taken 144 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 28 times.
✓ Branch 19 taken 116 times.
144 if (main->loginMandatory())
236
1/2
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
28 authenticate(0);
237 144 }
238
239 /////////////////////////////////////////////////////////////////////////////
240 148 void Session::final()
241 {
242
3/6
✓ Branch 9 taken 148 times.
✗ Branch 10 not taken.
✓ Branch 15 taken 148 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 148 times.
✗ Branch 20 not taken.
148 LOG4CPLUS_INFO_STR(server->log, LOG4CPLUS_TEXT("Finished session"));
243 148 log4cplus::getNDC().remove();
244 148 }
245
246 /////////////////////////////////////////////////////////////////////////////
247 144 void Session::run()
248 {
249
1/2
✓ Branch 16 taken 144 times.
✗ Branch 17 not taken.
144 server->sessionReady(this);
250
1/2
✓ Branch 4 taken 144 times.
✗ Branch 5 not taken.
144 sendGreeting();
251
4/6
✓ Branch 5 taken 144 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 144 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 39 times.
✓ Branch 12 taken 105 times.
183 XmlParser parser(getReceiveBufSize());
252
253 144 p_running = true;
254
255
8/10
✓ Branch 16 taken 9680 times.
✓ Branch 17 taken 39 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 9680 times.
✓ Branch 23 taken 9680 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 9680 times.
✓ Branch 26 taken 39 times.
✓ Branch 28 taken 39 times.
✓ Branch 29 taken 105 times.
19294 while (server->active() and p_running) {
256
2/4
✓ Branch 4 taken 9680 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9680 times.
9680 if (!xmlstream.good()) {
257 LOG4CPLUS_FATAL_STR(server->log,
258 LOG4CPLUS_TEXT("Error occurred in output stream"));
259 return;
260 }
261
262
1/2
✓ Branch 4 taken 9680 times.
✗ Branch 5 not taken.
9680 xmlstream.flush();
263
264
3/4
✓ Branch 4 taken 9680 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8868 times.
✓ Branch 7 taken 812 times.
9680 if (isPendingRead(40)) {
265
3/4
✓ Branch 1 taken 8868 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 105 times.
✓ Branch 4 taken 8763 times.
8868 if (!parser.read(static_cast<PdServ::Session*>(this))) {
266
2/4
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
105 if (PdServ::Session::eof())
267 105 return;
268
269 if (parser.invalid()) {
270 LOG4CPLUS_FATAL_STR(server->log,
271 LOG4CPLUS_TEXT(
272 "Input buffer overflow in XML parser"));
273 return;
274 }
275 }
276 // LOG4CPLUS_TRACE(server->log,
277 // LOG4CPLUS_TEXT("Rx: ")
278 // << LOG4CPLUS_STRING_TO_TSTRING(
279 // std::string(inbuf.bufptr(), n)));
280
281
3/4
✓ Branch 1 taken 9367 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 604 times.
✓ Branch 4 taken 8763 times.
9971 while (parser) {
282
1/2
✓ Branch 2 taken 604 times.
✗ Branch 3 not taken.
604 parser.getString("id", commandId);
283
1/2
✓ Branch 4 taken 604 times.
✗ Branch 5 not taken.
604 processCommand(&parser);
284
285
2/2
✓ Branch 2 taken 407 times.
✓ Branch 3 taken 197 times.
604 if (!commandId.empty()) {
286
1/2
✓ Branch 2 taken 407 times.
✗ Branch 3 not taken.
814 XmlElement ack(createElement("ack"));
287
1/2
✓ Branch 1 taken 407 times.
✗ Branch 2 not taken.
814 XmlElement::Attribute(ack,"id")
288
1/2
✓ Branch 4 taken 407 times.
✗ Branch 5 not taken.
814 .setEscaped(commandId);
289
290 407 struct timespec time;
291
1/2
✓ Branch 1 taken 407 times.
✗ Branch 2 not taken.
407 if (!clock_gettime(CLOCK_REALTIME, &time))
292
2/4
✓ Branch 2 taken 407 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 407 times.
✗ Branch 7 not taken.
407 XmlElement::Attribute(ack, "time") << time;
293
294 407 commandId.clear();
295 }
296 }
297 }
298
299 // Collect all asynchronous events while holding mutex
300
2/2
✓ Branch 6 taken 9575 times.
✓ Branch 7 taken 105 times.
19150 ParameterSet cp;
301 19150 BroadcastList bl;
302
1/2
✓ Branch 2 taken 9575 times.
✗ Branch 3 not taken.
19150 std::queue<ParameterData*> pmd;
303
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 9575 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9575 times.
9575 if (polite) {
304 pthread::MutexLock lock(mutex);
305 changedParameter.clear();
306 aic.clear();
307 while (!broadcastList.empty()) {
308 delete broadcastList.front();
309 broadcastList.pop_front();
310 }
311 while (!parameterMonitorData.empty()) {
312 delete parameterMonitorData.front();
313 parameterMonitorData.pop();
314 }
315 }
316 else {
317 // Create an environment for mutex lock. This lock should be kept
318 // as short as possible, and especially not when writing to the
319 // output stream
320 19150 pthread::MutexLock lock(mutex);
321
322
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 9575 times.
9575 if (aicDelay)
323 --aicDelay;
324
325 19150 ParameterSet::iterator it2, it = changedParameter.begin();
326
2/2
✓ Branch 6 taken 134 times.
✓ Branch 7 taken 9575 times.
9843 while (it != changedParameter.end()) {
327 134 it2 = it++;
328
6/24
✗ Branch 3 not taken.
✓ Branch 4 taken 134 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 134 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 134 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 134 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 134 times.
✓ Branch 31 taken 134 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
134 if (!aicDelay or aic.find((*it2)->mainParam) == aic.end()) {
329
1/2
✓ Branch 4 taken 134 times.
✗ Branch 5 not taken.
134 cp.insert(*it2);
330
1/2
✓ Branch 4 taken 134 times.
✗ Branch 5 not taken.
134 changedParameter.erase(it2);
331 }
332 }
333
334
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 9575 times.
9575 while (!parameterMonitorData.empty()) {
335 ParameterData* d = parameterMonitorData.front();
336 if (parameterMonitor
337 or (parameterMonitorSet.find(d->parameter)
338 != parameterMonitorSet.end()))
339 pmd.push(d);
340 else
341 delete d;
342 parameterMonitorData.pop();
343 }
344
345 9575 std::swap(broadcastList, bl);
346 }
347
348 // Write all asynchronous events to the client
349 {
350 9709 for ( ParameterSet::iterator it = cp.begin();
351
2/2
✓ Branch 6 taken 134 times.
✓ Branch 7 taken 9575 times.
9709 it != cp.end(); ++it) {
352
1/2
✓ Branch 2 taken 134 times.
✗ Branch 3 not taken.
268 XmlElement pu(createElement("pu"));
353
2/4
✓ Branch 2 taken 134 times.
✗ Branch 3 not taken.
✓ Branch 9 taken 134 times.
✗ Branch 10 not taken.
134 XmlElement::Attribute(pu, "index") << (*it)->index;
354 }
355
356
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9575 times.
9575 while (!pmd.empty()) {
357 ParameterData* d = pmd.front();
358
359 XmlElement xml(createElement("parameter"));
360 bool shortReply =
361 !knownVariables.insert(d->parameter->variable).second;
362 d->parameter->setXmlAttributes(xml, d->data, d->time,
363 shortReply, true, false, 16);
364 XmlElement::Attribute(xml, "pm") << 1;
365 delete d;
366 pmd.pop();
367 }
368
369 9597 for ( BroadcastList::const_iterator it = bl.begin();
370
2/2
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 9575 times.
9597 it != bl.end(); ++it) {
371
372
1/2
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
44 XmlElement broadcast(createElement("broadcast"));
373
374
2/4
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 9 taken 22 times.
✗ Branch 10 not taken.
22 XmlElement::Attribute(broadcast, "time") << (*it)->ts;
375
376
2/2
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 11 times.
22 if (!(*it)->action.empty())
377
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
22 XmlElement::Attribute(broadcast, "action")
378
1/2
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
22 .setEscaped((*it)->action);
379
380
2/2
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 11 times.
22 if (!(*it)->message.empty())
381
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
22 XmlElement::Attribute(broadcast, "text")
382
1/2
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
22 .setEscaped((*it)->message);
383
384
1/2
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
22 delete *it;
385 }
386 }
387
388 28725 for (SubscriptionManagerVector::iterator it =
389 19150 subscriptionManager.begin();
390
2/2
✓ Branch 6 taken 19150 times.
✓ Branch 7 taken 9575 times.
28725 it != subscriptionManager.end(); ++it)
391
2/4
✗ Branch 8 not taken.
✓ Branch 9 taken 19150 times.
✓ Branch 11 taken 19150 times.
✗ Branch 12 not taken.
19150 (*it)->rxPdo(quiet);
392
393
4/6
✓ Branch 20 taken 9599 times.
✗ Branch 21 not taken.
✓ Branch 24 taken 9599 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 24 times.
✓ Branch 28 taken 9575 times.
9623 while (Event::toXml(this, main->getEvent(eventId)))
394 24 eventId++;
395 }
396 }
397
398 /////////////////////////////////////////////////////////////////////////////
399 604 void Session::processCommand(const XmlParser* parser)
400 {
401
1/2
✓ Branch 2 taken 604 times.
✗ Branch 3 not taken.
604 const char *command = parser->tag();
402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 604 times.
604 size_t commandLen = strlen(command);
403
404 static const struct {
405 size_t len;
406 const char *name;
407 void (Session::*func)(const XmlParser*);
408 } cmds[] = {
409 // First list most common commands
410 { 4, "ping", &Session::ping },
411 { 2, "rs", &Session::readStatistics },
412 { 2, "wp", &Session::writeParameter },
413 { 2, "rp", &Session::readParameter },
414 { 4, "xsad", &Session::xsad },
415 { 4, "xsod", &Session::xsod },
416 { 4, "xsap", &Session::xsap },
417 { 4, "xsop", &Session::xsop },
418 { 4, "echo", &Session::echo },
419
420 // Now comes the rest
421 { 2, "rc", &Session::readChannel },
422 { 2, "rk", &Session::readChannel },
423 { 3, "rpv", &Session::readParamValues },
424 { 4, "list", &Session::listDirectory },
425 { 4, "auth", &Session::authenticate },
426 { 9, "broadcast", &Session::broadcast },
427 {11, "remote_host", &Session::remoteHost },
428 {12, "read_kanaele", &Session::readChannel },
429 {12, "read_statics", &Session::readStatistics },
430 {14, "read_parameter", &Session::readParameter },
431 {15, "read_statistics", &Session::readStatistics },
432 {15, "message_history", &Session::messageHistory },
433 {15, "write_parameter", &Session::writeParameter },
434 {17, "read_param_values", &Session::readParamValues },
435 {0, 0, 0},
436 };
437
438 // Go through the command list
439
1/2
✓ Branch 2 taken 6439 times.
✗ Branch 3 not taken.
6439 for (size_t idx = 0; cmds[idx].len; idx++) {
440 // Check whether the lengths fit and the string matches
441
2/2
✓ Branch 2 taken 1921 times.
✓ Branch 3 taken 4518 times.
6439 if (commandLen == cmds[idx].len
442
4/6
✗ Branch 2 not taken.
✓ Branch 3 taken 1921 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1921 times.
✓ Branch 6 taken 604 times.
✓ Branch 7 taken 1317 times.
1921 and !strcmp(cmds[idx].name, command)) {
443
444
5/8
✓ Branch 9 taken 604 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 562 times.
✓ Branch 12 taken 42 times.
✓ Branch 19 taken 562 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 562 times.
✗ Branch 24 not taken.
604 LOG4CPLUS_TRACE_STR(server->log,
445 LOG4CPLUS_C_STR_TO_TSTRING(cmds[idx].name));
446
447 // Call the method
448
5/10
✓ Branch 4 taken 604 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 63 times.
✓ Branch 9 taken 462 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 63 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 604 times.
✗ Branch 19 not taken.
1733 if (loggedIn() or cmds[idx].func == &Session::authenticate
449
4/6
✓ Branch 0 taken 525 times.
✓ Branch 1 taken 79 times.
✓ Branch 18 taken 462 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 462 times.
✗ Branch 21 not taken.
1066 or !main->loginMandatory())
450
2/4
✗ Branch 7 not taken.
✓ Branch 8 taken 604 times.
✓ Branch 18 taken 604 times.
✗ Branch 19 not taken.
604 (this->*cmds[idx].func)(parser);
451 else
452 p_running = false;
453
454 // Finished
455 604 return;
456 }
457 }
458
459 LOG4CPLUS_WARN(server->log,
460 LOG4CPLUS_TEXT("Unknown command <")
461 << LOG4CPLUS_C_STR_TO_TSTRING(command)
462 << LOG4CPLUS_TEXT(">"));
463
464
465 // Unknown command warning
466 XmlElement warn(createElement("warn"));
467 XmlElement::Attribute(warn, "num") << 1000;
468 XmlElement::Attribute(warn, "text") << "unknown command";
469 XmlElement::Attribute(warn, "command").setEscaped(command);
470 }
471
472 /////////////////////////////////////////////////////////////////////////////
473 20 void Session::broadcast(const XmlParser* parser)
474 {
475 20 struct timespec ts;
476 40 std::string action, text;
477
478
1/2
✓ Branch 24 taken 20 times.
✗ Branch 25 not taken.
20 main->gettime(&ts);
479
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 parser->getString("action", action);
480
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 parser->getString("text", text);
481
482
1/2
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
20 server->broadcast(this, ts, action, text);
483 20 }
484
485 /////////////////////////////////////////////////////////////////////////////
486 void Session::echo(const XmlParser* parser)
487 {
488 echoOn = parser->isTrue("value");
489 }
490
491 /////////////////////////////////////////////////////////////////////////////
492 3 void Session::ping(const XmlParser* /*parser*/)
493 {
494 3 struct timespec time;
495
496
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 XmlElement e(createElement("ping"));
497
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (!clock_gettime(CLOCK_REALTIME, &time))
498
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
3 XmlElement::Attribute(e, "time") << time;
499 3 }
500
501 /////////////////////////////////////////////////////////////////////////////
502 103 void Session::readChannel(const XmlParser* parser)
503 {
504 103 const Channel *c = 0;
505
1/2
✓ Branch 2 taken 103 times.
✗ Branch 3 not taken.
103 bool shortReply = parser->isTrue("short");
506
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 98 times.
108 std::string name;
507 103 unsigned int index;
508
509
3/4
✓ Branch 2 taken 103 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
✓ Branch 5 taken 12 times.
103 if (parser->getString("name", name)) {
510
1/2
✓ Branch 16 taken 91 times.
✗ Branch 17 not taken.
91 c = server->find<Channel>(name);
511
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 50 times.
91 if (!c)
512 41 return;
513 }
514
3/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 5 times.
12 else if (parser->getUnsigned("index", index)) {
515
1/2
✓ Branch 16 taken 7 times.
✗ Branch 17 not taken.
7 c = server->getChannel(index);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (!c)
517 return;
518 }
519
520
1/2
✓ Branch 2 taken 62 times.
✗ Branch 3 not taken.
62 bool hex = parser->isTrue("hex");
521
522 // A single signal was requested
523
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 5 times.
62 if (c) {
524
1/2
✗ Branch 12 not taken.
✓ Branch 13 taken 57 times.
57 char buf[c->signal->memSize];
525 57 struct timespec time;
526 171 int rv = static_cast<const PdServ::Variable*>(c->signal)
527
1/2
✓ Branch 6 taken 57 times.
✗ Branch 7 not taken.
171 ->getValue(this, buf, &time);
528
529
1/2
✓ Branch 2 taken 57 times.
✗ Branch 3 not taken.
114 XmlElement channel(createElement("channel"));
530
2/4
✓ Branch 3 taken 57 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 57 times.
✗ Branch 7 not taken.
57 c->setXmlAttributes(
531 channel, shortReply, hex, false, rv ? 0 : buf, 16, &time);
532
533
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if (!shortReply)
534
1/2
✓ Branch 7 taken 57 times.
✗ Branch 8 not taken.
57 knownVariables.insert(c->signal);
535
536 114 return;
537 }
538
539 // A list of all channels
540
1/2
✓ Branch 16 taken 5 times.
✗ Branch 17 not taken.
5 const Server::Channels& chanList = server->getChannels();
541
3/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 98 times.
10 XmlElement channels(createElement("channels"));
542 95 for (Server::Channels::const_iterator it = chanList.begin();
543
2/2
✓ Branch 6 taken 90 times.
✓ Branch 7 taken 5 times.
95 it != chanList.end(); it++) {
544 90 c = *it;
545
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 90 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 90 times.
90 if (c->hidden)
546 continue;
547
548
2/4
✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 90 times.
✗ Branch 7 not taken.
180 XmlElement el(channels.createChild("channel"));
549
1/2
✓ Branch 4 taken 90 times.
✗ Branch 5 not taken.
90 c->setXmlAttributes( el, shortReply, false, false, 0, 16, 0);
550
551
1/2
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
90 if (!shortReply)
552
1/2
✓ Branch 7 taken 90 times.
✗ Branch 8 not taken.
90 knownVariables.insert(c->signal);
553 }
554 }
555
556 /////////////////////////////////////////////////////////////////////////////
557 10 void Session::listDirectory(const XmlParser* parser)
558 {
559 10 const char *path;
560
561
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
10 if (!parser->find("path", &path))
562 return;
563
564
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 bool hex = parser->isTrue("hex");
565 10 bool noderived = false;
566
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 parser->getBool("noderived", &noderived);
567
568
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 10 times.
✗ Branch 9 not taken.
20 XmlElement element(createElement("listing"));
569
3/6
✗ Branch 15 not taken.
✓ Branch 16 taken 10 times.
✓ Branch 21 taken 10 times.
✗ Branch 22 not taken.
✓ Branch 25 taken 10 times.
✗ Branch 26 not taken.
10 server->listDir(this, element, path, hex, !noderived);
570 }
571
572 /////////////////////////////////////////////////////////////////////////////
573 137 void Session::readParameter(const XmlParser* parser)
574 {
575
1/2
✓ Branch 2 taken 137 times.
✗ Branch 3 not taken.
137 bool shortReply = parser->isTrue("short");
576
1/2
✓ Branch 2 taken 137 times.
✗ Branch 3 not taken.
137 bool hex = parser->isTrue("hex");
577
2/2
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 132 times.
142 std::string name;
578 137 unsigned int index;
579
580 137 const Parameter *p = 0;
581
3/4
✓ Branch 2 taken 137 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
✓ Branch 5 taken 46 times.
137 if (parser->getString("name", name)) {
582
1/2
✓ Branch 16 taken 91 times.
✗ Branch 17 not taken.
91 p = server->find<Parameter>(name);
583
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 33 times.
91 if (!p)
584 58 return;
585 }
586
3/4
✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 41 times.
✓ Branch 5 taken 5 times.
46 else if (parser->getUnsigned("index", index)) {
587
1/2
✓ Branch 16 taken 41 times.
✗ Branch 17 not taken.
41 p = server->getParameter(index);
588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!p)
589 return;
590 }
591
592
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 5 times.
79 if (p) {
593
1/2
✗ Branch 12 not taken.
✓ Branch 13 taken 74 times.
74 char buf[p->mainParam->memSize];
594 74 struct timespec ts;
595
596
1/2
✓ Branch 24 taken 74 times.
✗ Branch 25 not taken.
74 p->mainParam->getValue(this, buf, &ts);
597
598 148 std::string id;
599
1/2
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
74 parser->getString("id", id);
600
601
1/2
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
148 XmlElement xml(createElement("parameter"));
602
1/2
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
74 p->setXmlAttributes(xml, buf, ts, shortReply, hex, false, 16);
603
604
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 41 times.
74 if (!shortReply)
605
1/2
✓ Branch 7 taken 33 times.
✗ Branch 8 not taken.
33 knownVariables.insert(p->mainParam);
606
607 148 return;
608 }
609
610
3/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 132 times.
10 XmlElement parametersElement(createElement("parameters"));
611
612
1/2
✓ Branch 16 taken 5 times.
✗ Branch 17 not taken.
5 const Server::Parameters& parameters = server->getParameters();
613 10 Server::Parameters::const_iterator it = parameters.begin();
614
2/2
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 5 times.
65 while ( it != parameters.end()) {
615 30 const PdServ::Parameter* mainParam = (*it)->mainParam;
616
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
30 char buf[mainParam->memSize];
617 30 struct timespec ts;
618
619
2/4
✗ Branch 5 not taken.
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 30 times.
30 if ((*it)->hidden) {
620 ++it;
621 continue;
622 }
623
624
1/2
✓ Branch 6 taken 30 times.
✗ Branch 7 not taken.
30 mainParam->getValue(this, buf, &ts);
625
626
8/10
✓ Branch 4 taken 105 times.
✓ Branch 5 taken 5 times.
✓ Branch 11 taken 80 times.
✓ Branch 12 taken 25 times.
✓ Branch 13 taken 110 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 110 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 80 times.
✓ Branch 20 taken 30 times.
110 while (it != parameters.end() and mainParam == (*it)->mainParam) {
627
1/2
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
160 XmlElement xml(parametersElement.createChild("parameter"));
628
1/2
✓ Branch 9 taken 80 times.
✗ Branch 10 not taken.
80 (*it++)->setXmlAttributes(
629 xml, buf, ts, shortReply, hex, false, 16);
630 }
631
632
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (!shortReply)
633
2/4
✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 30 times.
✗ Branch 11 not taken.
30 knownVariables.insert(mainParam);
634 30 }
635 }
636
637 /////////////////////////////////////////////////////////////////////////////
638 void Session::readParamValues(const XmlParser* /*parser*/)
639 {
640 XmlElement param_values(createElement("param_values"));
641 XmlElement::Attribute values(param_values, "value");
642
643 const Server::Parameters& parameters = server->getParameters();
644 Server::Parameters::const_iterator it = parameters.begin();
645 while ( it != parameters.end()) {
646 const PdServ::Parameter* mainParam = (*it)->mainParam;
647 char buf[mainParam->memSize];
648 struct timespec ts;
649
650 mainParam->getValue(this, buf, &ts);
651
652 if (it != parameters.begin())
653 values << ';';
654 values.csv(*it, buf, 1, 16);
655
656 while (it != parameters.end() and mainParam == (*it)->mainParam)
657 ++it;
658 }
659 }
660
661 /////////////////////////////////////////////////////////////////////////////
662 36 void Session::messageHistory(const XmlParser* parser)
663 {
664 36 uint32_t seqNo;
665
666
3/4
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 21 times.
36 if (parser->getUnsigned("seq", seqNo)) {
667
2/4
✓ Branch 17 taken 15 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 15 times.
✗ Branch 22 not taken.
15 Event::toXml(this, main->getEvent(seqNo));
668 } else {
669 // <message_history>
670 // ... list of all active messages
671 // </message_history>
672 typedef std::list<PdServ::EventData> EventList;
673 42 EventList list;
674
675
1/2
✓ Branch 16 taken 21 times.
✗ Branch 17 not taken.
21 main->getActiveEvents(&list);
676
677
1/2
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
42 XmlElement xml(createElement("message_history"));
678 39 for (EventList::iterator it = list.begin();
679
2/2
✓ Branch 6 taken 18 times.
✓ Branch 7 taken 21 times.
39 it != list.end(); ++it)
680
1/2
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
18 Event::toXml(this, *it, &xml);
681 }
682 36 }
683
684 /////////////////////////////////////////////////////////////////////////////
685 5 void Session::readStatistics(const XmlParser* /*parser*/)
686 {
687 // <clients>
688 // <client name="lansim"
689 // apname="Persistent Manager, Version: 0.3.1"
690 // countin="19908501" countout="27337577"
691 // connectedtime="1282151176.659208"/>
692 // <client index="1" .../>
693 // </clients>
694 typedef std::list<PdServ::SessionStatistics> StatList;
695 10 StatList stats;
696
1/2
✓ Branch 16 taken 5 times.
✗ Branch 17 not taken.
5 server->getSessionStatistics(stats);
697
698
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 XmlElement clients(createElement("clients"));
699 10 for (StatList::const_iterator it = stats.begin();
700
2/2
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 5 times.
10 it != stats.end(); it++) {
701
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 XmlElement client(clients.createChild("client"));
702
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 XmlElement::Attribute(client,"name")
703
5/16
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 20 taken 5 times.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 5 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 5 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
10 .setEscaped((*it).remote.size() ? (*it).remote : "unknown");
704
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 XmlElement::Attribute(client,"apname")
705
5/16
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 20 taken 5 times.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 5 times.
✗ Branch 27 not taken.
✓ Branch 28 taken 5 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
10 .setEscaped((*it).client.size() ? (*it).client : "unknown");
706
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
5 XmlElement::Attribute(client,"countin") << (*it).countIn;
707
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
5 XmlElement::Attribute(client,"countout") << (*it).countOut;
708
2/4
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
5 XmlElement::Attribute(client,"connectedtime") << (*it).connectedTime;
709 }
710 5 }
711
712 /////////////////////////////////////////////////////////////////////////////
713 139 void Session::remoteHost(const XmlParser* parser)
714 {
715 139 parser->getString("name", remoteHostName);
716
717 139 parser->getString("applicationname", client);
718
719
1/2
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
139 if (parser->find("access"))
720 278 writeAccess = parser->isEqual("access", "allow")
721
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
139 or parser->isTrue("access");
722
723 // Check whether stream should be polite, i.e. not send any data
724 // when not requested by the client.
725 // This is used for passive clients that do not check their streams
726 // on a regular basis causing the TCP stream to congest.
727 139 parser->getBool("polite", &polite);
728
729
3/6
✓ Branch 9 taken 139 times.
✗ Branch 10 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 139 times.
✓ Branch 33 taken 139 times.
✗ Branch 34 not taken.
139 LOG4CPLUS_INFO(server->log,
730 LOG4CPLUS_TEXT("Logging in ")
731 << LOG4CPLUS_STRING_TO_TSTRING(remoteHostName)
732 << LOG4CPLUS_TEXT(" application ")
733 << LOG4CPLUS_STRING_TO_TSTRING(client)
734 << LOG4CPLUS_TEXT(" writeaccess=")
735 << writeAccess);
736 139 }
737
738 /////////////////////////////////////////////////////////////////////////////
739 43 void Session::writeParameter(const XmlParser* parser)
740 {
741
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43 times.
43 if (!writeAccess) {
742 XmlElement warn(createElement("warn"));
743 XmlElement::Attribute(warn, "command") << "write_parameter";
744 XmlElement::Attribute(warn, "text") << "No write access";
745 return;
746 }
747
748 43 const Parameter *p = 0;
749
750 43 unsigned int index;
751
1/2
✓ Branch 6 taken 43 times.
✗ Branch 7 not taken.
86 std::string name;
752
2/4
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 43 times.
43 if (parser->getString("name", name)) {
753 p = server->find<Parameter>(name);
754 }
755
2/4
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
43 else if (parser->getUnsigned("index", index)) {
756
1/2
✓ Branch 16 taken 43 times.
✗ Branch 17 not taken.
43 p = server->getParameter(index);
757 }
758
759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (!p)
760 return;
761
762 43 unsigned int startindex = 0;
763
3/4
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 31 times.
43 if (parser->getUnsigned("startindex", startindex)) {
764
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
12 if (startindex >= p->dim.nelem)
765 return;
766 }
767
768
2/4
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 43 times.
43 if (parser->isTrue("aic"))
769 server->setAic(p);
770
771 int errnum;
772 43 const char *s;
773
2/4
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
43 if (parser->find("hexvalue", &s)) {
774
1/2
✓ Branch 4 taken 43 times.
✗ Branch 5 not taken.
43 errnum = p->setHexValue(this, s, startindex);
775 }
776 else if (parser->find("value", &s)) {
777 errnum = p->setDoubleValue(this, s, startindex);
778 }
779 else
780 return;
781
782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
43 if (errnum) {
783 XmlElement warn(createElement("warn"));
784 XmlElement::Attribute(warn, "command") << "write_parameter";
785 XmlElement::Attribute(warn, "text") << strerror(-errnum);
786
787 // If an error occurred, tell this client to reread the value
788 char buf[p->memSize];
789 struct timespec time;
790 p->mainParam->getValue(this, buf, &time);
791 parameterChanged(p, buf, &time);
792 }
793 }
794
795 /////////////////////////////////////////////////////////////////////////////
796 44 void Session::xsad(const XmlParser* parser)
797 {
798 44 unsigned int reduction, blocksize, precision, group;
799
1/2
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
44 bool base64 = parser->isEqual("coding", "Base64");
800
1/2
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
44 bool event = parser->isTrue("event");
801 44 bool foundReduction = false;
802
1/2
✓ Branch 7 taken 44 times.
✗ Branch 8 not taken.
88 std::list<unsigned int> indexList;
803
1/2
✓ Branch 16 taken 44 times.
✗ Branch 17 not taken.
44 const Server::Channels& channel = server->getChannels();
804
805
2/4
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
44 if (parser->isTrue("sync")) {
806 for (SubscriptionManagerVector::iterator it =
807 subscriptionManager.begin();
808 it != subscriptionManager.end(); ++it)
809 (*it)->sync();
810 quiet = false;
811 }
812 else {
813 // Quiet will stop all transmission of <data> tags until
814 // sync is called
815
1/2
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
44 quiet = parser->isTrue("quiet");
816 }
817
818
2/4
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
44 if (!parser->getUnsignedList("channels", indexList))
819 return;
820
821
3/4
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42 times.
✓ Branch 5 taken 2 times.
44 if (parser->getUnsigned("reduction", reduction)) {
822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (!reduction) {
823 XmlElement warn(createElement("warn"));
824 XmlElement::Attribute(warn, "command") << "xsad";
825 XmlElement::Attribute(warn, "text")
826 << "specified reduction=0, choosing reduction=1";
827
828 reduction = 1;
829 }
830
831 42 foundReduction = true;
832 }
833
834 // Discover blocksize
835
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 42 times.
44 if (event) {
836 // blocksize of zero is for event channels
837 2 blocksize = 0;
838 }
839
2/4
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
42 else if (parser->getUnsigned("blocksize", blocksize)) {
840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (!blocksize) {
841 XmlElement warn(createElement("warn"));
842 XmlElement::Attribute(warn, "command") << "xsad";
843 XmlElement::Attribute(warn, "text")
844 << "specified blocksize=0, choosing blocksize=1";
845
846 blocksize = 1;
847 }
848 }
849 else {
850 // blocksize was not supplied, possibly human input
851 blocksize = 1;
852 }
853
854
2/4
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
44 if (!parser->getUnsigned("precision", precision))
855 44 precision = 16;
856
857
2/4
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
44 if (!parser->getUnsigned("group", group))
858 group = 0;
859
860
1/2
✓ Branch 14 taken 44 times.
✗ Branch 15 not taken.
88 for (std::list<unsigned int>::const_iterator it = indexList.begin();
861
2/2
✓ Branch 6 taken 44 times.
✓ Branch 7 taken 44 times.
88 it != indexList.end(); it++) {
862
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 44 times.
44 if (*it >= channel.size())
863 continue;
864
865 44 const Channel *c = channel[*it];
866 44 const PdServ::Signal *mainSignal = c->signal;
867
868
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 42 times.
44 if (event) {
869
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!foundReduction)
870 // If user did not supply a reduction, limit to a
871 // max of 10Hz automatically
872 2 reduction = static_cast<unsigned>(
873
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 0.1/mainSignal->sampleTime() + 0.5);
874 }
875
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 else if (!foundReduction) {
876 // Quite possibly user input; choose reduction for 1Hz
877 reduction = static_cast<unsigned>(
878 1.0/mainSignal->sampleTime() / blocksize + 0.5);
879 }
880
881
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 2 times.
44 if (!event) {
882 // Signals are updated without respect to the decimation given
883 // by the RT application in pdserv_signal()
884 // so we must consider the RT decimation too
885 42 reduction = reduction * c->signal->decimation;
886 }
887
888
1/2
✓ Branch 46 taken 44 times.
✗ Branch 47 not taken.
44 subscriptionManager[c->signal->task->index]->subscribe(
889 c, group, reduction, blocksize, base64, precision);
890 }
891 }
892
893 /////////////////////////////////////////////////////////////////////////////
894 void Session::xsod(const XmlParser* parser)
895 {
896 std::list<unsigned int> intList;
897
898 //cout << __LINE__ << "xsod: " << endl;
899
900 if (parser->getUnsignedList("channels", intList)) {
901 const Server::Channels& channel = server->getChannels();
902 unsigned int group;
903
904 if (!parser->getUnsigned("group", group))
905 group = 0;
906
907 for (std::list<unsigned int>::const_iterator it = intList.begin();
908 it != intList.end(); it++) {
909 if (*it < channel.size()) {
910 size_t taskIdx = channel[*it]->signal->task->index;
911 subscriptionManager[taskIdx]->unsubscribe(channel[*it],
912 group);
913 }
914 }
915 }
916 else
917 for (SubscriptionManagerVector::iterator it =
918 subscriptionManager.begin();
919 it != subscriptionManager.end(); ++it)
920 (*it)->clear();
921 }
922
923 /////////////////////////////////////////////////////////////////////////////
924 void Session::xsap(const XmlParser* parser)
925 {
926 pthread::MutexLock lock(mutex);
927
928 if (parser->isTrue("monitor"))
929 parameterMonitor = true;
930
931 std::list<unsigned int> indexList;
932 if (parser->getUnsignedList("parameters", indexList)) {
933 const Server::Parameters& parameter = server->getParameters();
934
935 for (std::list<unsigned int>::const_iterator it = indexList.begin();
936 it != indexList.end(); it++) {
937 unsigned int idx = *it;
938 if (idx < parameter.size())
939 parameterMonitorSet.insert(parameter[idx]);
940 }
941 }
942 }
943
944 /////////////////////////////////////////////////////////////////////////////
945 void Session::xsop(const XmlParser* parser)
946 {
947 pthread::MutexLock lock(mutex);
948
949 std::list<unsigned int> indexList;
950 if (!parser->getBool("monitor", &parameterMonitor)
951 and !parser->getUnsignedList("parameters", indexList)) {
952 parameterMonitor = false;
953 parameterMonitorSet.clear();
954 }
955 else {
956 const Server::Parameters& parameter = server->getParameters();
957
958 for (std::list<unsigned int>::const_iterator it = indexList.begin();
959 it != indexList.end(); it++) {
960 unsigned int idx = *it;
961 if (idx < parameter.size())
962 parameterMonitorSet.erase(parameter[idx]);
963 }
964 }
965 }
966
967 /////////////////////////////////////////////////////////////////////////////
968 92 void Session::authenticate(const XmlParser* parser)
969 {
970
1/2
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
184 XmlElement auth(createElement("saslauth"));
971
972 92 const char* mech = 0;
973 92 const char* clientdata = 0;
974 92 bool logout = false;
975
976
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 28 times.
92 if (parser) {
977
1/2
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
64 parser->find("clientdata", &clientdata);
978
1/2
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
64 parser->find("mech", &mech);
979
1/2
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
64 logout = parser->isTrue("logout");
980 }
981
982
4/4
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 33 times.
92 if (mech or clientdata) {
983 59 const std::string* serverdata;
984
1/2
✓ Branch 5 taken 59 times.
✗ Branch 6 not taken.
59 bool result = saslProcess(mech, clientdata, &serverdata);
985
986
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 31 times.
59 if (result or !serverdata)
987
2/4
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 28 times.
✗ Branch 7 not taken.
28 XmlElement::Attribute(auth, "success") << result;
988
989
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 28 times.
59 if (serverdata)
990
2/4
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 31 times.
✗ Branch 8 not taken.
31 XmlElement::Attribute(auth, "serverdata") << *serverdata;
991 }
992
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 32 times.
33 else if (logout) {
993
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 saslDispose();
994
995
2/4
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
1 if (main->loginMandatory())
996 p_running = false;
997 }
998 else {
999
1/2
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
32 const char *mechs = saslMechanisms();
1000
1001
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (mechs)
1002
2/4
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
32 XmlElement::Attribute(auth, "mechlist") << mechs;
1003 else
1004 XmlElement::Attribute(auth, "success") << 0;
1005 }
1006 92 }
1007
1008 /////////////////////////////////////////////////////////////////////////////
1009 1351 XmlElement Session::createElement(const char* name)
1010 {
1011 1351 return XmlElement(name, xmlstream, 0, &commandId);
1012 }
1013
1014 ///////////////////////////////////////////////////////////////////////////
1015 30 std::string Session::peerAddr(char sep) const
1016 {
1017 30 return getAddr(sep);
1018 }
1019
1020 ///////////////////////////////////////////////////////////////////////////
1021 30 std::string Session::localAddr(char sep) const
1022 {
1023 30 return server->getAddr(sep);
1024 }
1025
1026 /////////////////////////////////////////////////////////////////////////////
1027 15604 ssize_t Session::read(void* buf, size_t count)
1028 {
1029 15604 int rv = readData(buf, count);
1030
2/2
✓ Branch 0 taken 15531 times.
✓ Branch 1 taken 73 times.
15604 if (rv > 0)
1031 15531 inBytes += rv;
1032 15604 return rv;
1033 }
1034
1035 /////////////////////////////////////////////////////////////////////////////
1036 1537 ssize_t Session::write(const void* buf, size_t count)
1037 {
1038 1537 int rv = writeData(buf, count);
1039
1/2
✓ Branch 0 taken 1537 times.
✗ Branch 1 not taken.
1537 if (rv > 0)
1040 1537 outBytes += rv;
1041 1537 return rv;
1042 }
1043