GCC Code Coverage Report


Directory: ./
File: pdserv/src/msrproto/Session.cpp
Date: 2024-12-15 04:08:34
Exec Total Coverage
Lines: 368 529 69.6%
Branches: 406 1034 39.3%

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