GCC Code Coverage Report


Directory: ./
File: pdserv/src/msrproto/Session.cpp
Date: 2023-11-12 04:06:57
Exec Total Coverage
Lines: 366 527 69.4%
Branches: 404 1032 39.1%

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 124 Session::Session( Server *server, net::TCPServer* tcp):
69 TCPSession(tcp),
70 124 PdServ::Session(server->main, server->log), server(server),
71
4/8
✓ Branch 5 taken 124 times.
✗ Branch 6 not taken.
✓ Branch 14 taken 124 times.
✗ Branch 15 not taken.
✓ Branch 20 taken 124 times.
✗ Branch 21 not taken.
✓ Branch 30 taken 124 times.
✗ Branch 31 not taken.
248 xmlstream(static_cast<PdServ::Session*>(this))
72 {
73 124 inBytes = 0;
74 124 outBytes = 0;
75
76 124 timeTask = 0;
77
78
1/2
✓ Branch 13 taken 124 times.
✗ Branch 14 not taken.
248 std::list<const PdServ::Task*> taskList(main->getTasks());
79
1/2
✓ Branch 3 taken 124 times.
✗ Branch 4 not taken.
124 subscriptionManager.reserve(taskList.size());
80
2/2
✓ Branch 1 taken 248 times.
✓ Branch 2 taken 124 times.
620 for (; taskList.size(); taskList.pop_front()) {
81 248 const PdServ::Task *task = taskList.front();
82
83
3/6
✓ Branch 3 taken 248 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 248 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 248 times.
✗ Branch 12 not taken.
248 subscriptionManager.push_back(new SubscriptionManager(this, task));
84
85
3/4
✓ Branch 3 taken 124 times.
✓ Branch 4 taken 124 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 124 times.
248 if (!timeTask or timeTask->task->sampleTime > task->sampleTime)
86 124 timeTask = subscriptionManager.back();
87 }
88
89 // Setup some internal variables
90 124 writeAccess = false;
91 124 echoOn = false; // FIXME: echoOn is not yet implemented
92 124 quiet = false;
93 124 polite = false;
94 124 aicDelay = 0;
95 124 parameterMonitor = false;
96
1/2
✓ Branch 18 taken 124 times.
✗ Branch 19 not taken.
124 eventId = main->getCurrentEventId();
97
98
2/4
✓ Branch 2 taken 124 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 124 times.
✗ Branch 6 not taken.
124 xmlstream.imbue(std::locale::classic());
99 124 }
100
101 /////////////////////////////////////////////////////////////////////////////
102 318 Session::~Session()
103 {
104 124 server->sessionClosed(this);
105
106 372 for (SubscriptionManagerVector::iterator it = subscriptionManager.begin();
107
2/2
✓ Branch 6 taken 248 times.
✓ Branch 7 taken 124 times.
372 it != subscriptionManager.end(); ++it)
108
1/2
✓ Branch 2 taken 248 times.
✗ Branch 3 not taken.
248 delete *it;
109 194 }
110
111 /////////////////////////////////////////////////////////////////////////////
112 void Session::close()
113 {
114 TCPSession::close();
115 }
116
117 /////////////////////////////////////////////////////////////////////////////
118 240 size_t Session::getReceiveBufSize() const
119 {
120
1/2
✓ Branch 19 taken 240 times.
✗ Branch 20 not taken.
240 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 124 void Session::initial()
189 {
190 124 TCPSession::initial();
191
192
1/2
✓ Branch 8 taken 124 times.
✗ Branch 9 not taken.
124 log4cplus::getNDC().push(LOG4CPLUS_STRING_TO_TSTRING(getAddr()));
193
194
3/6
✓ Branch 9 taken 124 times.
✗ Branch 10 not taken.
✓ Branch 18 taken 124 times.
✗ Branch 19 not taken.
✓ Branch 26 taken 124 times.
✗ Branch 27 not taken.
124 LOG4CPLUS_INFO(server->log,
195 LOG4CPLUS_TEXT("New session from ")
196 << LOG4CPLUS_STRING_TO_TSTRING(getPeerName()));
197 124 }
198
199 120 void Session::sendGreeting()
200 {
201 // Get the hostname
202 120 char hostname[HOST_NAME_MAX+1];
203
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
120 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 120 times.
✗ Branch 3 not taken.
240 XmlElement greeting(createElement("connected"));
213
2/4
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 120 times.
✗ Branch 7 not taken.
120 XmlElement::Attribute(greeting, "name") << "MSR";
214
1/2
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
240 XmlElement::Attribute(greeting, "host")
215
1/2
✓ Branch 3 taken 120 times.
✗ Branch 4 not taken.
240 << reinterpret_cast<const char*>(hostname);
216
2/4
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 13 taken 120 times.
✗ Branch 14 not taken.
120 XmlElement::Attribute(greeting, "app") << main->name;
217
2/4
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 13 taken 120 times.
✗ Branch 14 not taken.
120 XmlElement::Attribute(greeting, "appversion") << main->version;
218
2/4
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 120 times.
✗ Branch 9 not taken.
120 XmlElement::Attribute(greeting, "version") << MSR_VERSION;
219
2/4
✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 120 times.
✗ Branch 7 not taken.
120 XmlElement::Attribute(greeting, "features") << MSR_FEATURES;
220
221
1/2
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
240 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 120 times.
✗ Branch 4 not taken.
240 << "little"
227 #endif
228 ;
229
230
3/4
✓ Branch 16 taken 120 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 22 times.
✓ Branch 19 taken 98 times.
120 if (main->loginMandatory())
231
2/4
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
22 XmlElement::Attribute(greeting, "login") << "mandatory";
232
233
1/2
✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
240 XmlElement::Attribute(greeting, "recievebufsize")
234
2/4
✓ Branch 7 taken 120 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 120 times.
✗ Branch 12 not taken.
240 << getReceiveBufSize();
235 }
236
237
3/4
✓ Branch 16 taken 120 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 22 times.
✓ Branch 19 taken 98 times.
120 if (main->loginMandatory())
238
1/2
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
22 authenticate(0);
239 120 }
240
241 /////////////////////////////////////////////////////////////////////////////
242 124 void Session::final()
243 {
244
3/6
✓ Branch 9 taken 124 times.
✗ Branch 10 not taken.
✓ Branch 15 taken 124 times.
✗ Branch 16 not taken.
✓ Branch 19 taken 124 times.
✗ Branch 20 not taken.
124 LOG4CPLUS_INFO_STR(server->log, LOG4CPLUS_TEXT("Finished session"));
245 124 log4cplus::getNDC().remove();
246 124 }
247
248 /////////////////////////////////////////////////////////////////////////////
249 120 void Session::run()
250 {
251
1/2
✓ Branch 16 taken 120 times.
✗ Branch 17 not taken.
120 server->sessionReady(this);
252
1/2
✓ Branch 4 taken 120 times.
✗ Branch 5 not taken.
120 sendGreeting();
253
4/6
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 120 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 27 times.
✓ Branch 12 taken 93 times.
147 XmlParser parser(getReceiveBufSize());
254
255 120 p_running = true;
256
257
8/10
✓ Branch 16 taken 6474 times.
✓ Branch 17 taken 27 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 6474 times.
✓ Branch 23 taken 6474 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 6474 times.
✓ Branch 26 taken 27 times.
✓ Branch 28 taken 27 times.
✓ Branch 29 taken 93 times.
12882 while (server->active() and p_running) {
258
2/4
✓ Branch 4 taken 6474 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6474 times.
6474 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 6474 times.
✗ Branch 5 not taken.
6474 xmlstream.flush();
265
266
3/4
✓ Branch 4 taken 6474 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6134 times.
✓ Branch 7 taken 340 times.
6474 if (isPendingRead(40)) {
267
3/4
✓ Branch 1 taken 6134 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 93 times.
✓ Branch 4 taken 6041 times.
6134 if (!parser.read(static_cast<PdServ::Session*>(this))) {
268
2/4
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 93 times.
✗ Branch 7 not taken.
93 if (PdServ::Session::eof())
269 93 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 6513 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 472 times.
✓ Branch 4 taken 6041 times.
6985 while (parser) {
284
1/2
✓ Branch 2 taken 472 times.
✗ Branch 3 not taken.
472 parser.getString("id", commandId);
285
1/2
✓ Branch 4 taken 472 times.
✗ Branch 5 not taken.
472 processCommand(&parser);
286
287
2/2
✓ Branch 2 taken 303 times.
✓ Branch 3 taken 169 times.
472 if (!commandId.empty()) {
288
1/2
✓ Branch 2 taken 303 times.
✗ Branch 3 not taken.
606 XmlElement ack(createElement("ack"));
289
1/2
✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
606 XmlElement::Attribute(ack,"id")
290
1/2
✓ Branch 4 taken 303 times.
✗ Branch 5 not taken.
606 .setEscaped(commandId);
291
292 303 struct timespec time;
293
1/2
✓ Branch 1 taken 303 times.
✗ Branch 2 not taken.
303 if (!clock_gettime(CLOCK_REALTIME, &time))
294
2/4
✓ Branch 2 taken 303 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 303 times.
✗ Branch 7 not taken.
303 XmlElement::Attribute(ack, "time") << time;
295
296 303 commandId.clear();
297 }
298 }
299 }
300
301 // Collect all asynchronous events while holding mutex
302
2/2
✓ Branch 6 taken 6381 times.
✓ Branch 7 taken 93 times.
12762 ParameterSet cp;
303 12762 BroadcastList bl;
304
1/2
✓ Branch 2 taken 6381 times.
✗ Branch 3 not taken.
12762 std::queue<ParameterData*> pmd;
305
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 6381 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6381 times.
6381 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 12762 pthread::MutexLock lock(mutex);
323
324
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 6381 times.
6381 if (aicDelay)
325 --aicDelay;
326
327 12762 ParameterSet::iterator it2, it = changedParameter.begin();
328
2/2
✓ Branch 6 taken 134 times.
✓ Branch 7 taken 6381 times.
6649 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 6381 times.
6381 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 6381 std::swap(broadcastList, bl);
348 }
349
350 // Write all asynchronous events to the client
351 {
352 6515 for ( ParameterSet::iterator it = cp.begin();
353
2/2
✓ Branch 6 taken 134 times.
✓ Branch 7 taken 6381 times.
6515 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 6381 times.
6381 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 6403 for ( BroadcastList::const_iterator it = bl.begin();
372
2/2
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 6381 times.
6403 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 19143 for (SubscriptionManagerVector::iterator it = subscriptionManager.begin();
391
2/2
✓ Branch 6 taken 12762 times.
✓ Branch 7 taken 6381 times.
19143 it != subscriptionManager.end(); ++it)
392
2/4
✗ Branch 8 not taken.
✓ Branch 9 taken 12762 times.
✓ Branch 11 taken 12762 times.
✗ Branch 12 not taken.
12762 (*it)->rxPdo(quiet);
393
394
4/6
✓ Branch 20 taken 6405 times.
✗ Branch 21 not taken.
✓ Branch 24 taken 6405 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 24 times.
✓ Branch 28 taken 6381 times.
6429 while (Event::toXml(this, main->getEvent(eventId)))
395 24 eventId++;
396 }
397 }
398
399 /////////////////////////////////////////////////////////////////////////////
400 472 void Session::processCommand(const XmlParser* parser)
401 {
402
1/2
✓ Branch 2 taken 472 times.
✗ Branch 3 not taken.
472 const char *command = parser->tag();
403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 472 times.
472 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 5247 times.
✗ Branch 3 not taken.
5247 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 1481 times.
✓ Branch 3 taken 3766 times.
5247 if (commandLen == cmds[idx].len
443
4/6
✗ Branch 2 not taken.
✓ Branch 3 taken 1481 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1481 times.
✓ Branch 6 taken 472 times.
✓ Branch 7 taken 1009 times.
1481 and !strcmp(cmds[idx].name, command)) {
444
445
5/8
✓ Branch 9 taken 472 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 430 times.
✓ Branch 12 taken 42 times.
✓ Branch 19 taken 430 times.
✗ Branch 20 not taken.
✓ Branch 23 taken 430 times.
✗ Branch 24 not taken.
472 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 472 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 51 times.
✓ Branch 9 taken 372 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 51 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 472 times.
✗ Branch 19 not taken.
1367 if (loggedIn() or cmds[idx].func == &Session::authenticate
450
4/6
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 49 times.
✓ Branch 18 taken 372 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 372 times.
✗ Branch 21 not taken.
844 or !main->loginMandatory())
451
2/4
✗ Branch 7 not taken.
✓ Branch 8 taken 472 times.
✓ Branch 18 taken 472 times.
✗ Branch 19 not taken.
472 (this->*cmds[idx].func)(parser);
452 else
453 p_running = false;
454
455 // Finished
456 472 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 71 void Session::readChannel(const XmlParser* parser)
504 {
505 71 const Channel *c = 0;
506
1/2
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
71 bool shortReply = parser->isTrue("short");
507
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 66 times.
76 std::string name;
508 71 unsigned int index;
509
510
3/4
✓ Branch 2 taken 71 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 59 times.
✓ Branch 5 taken 12 times.
71 if (parser->getString("name", name)) {
511
1/2
✓ Branch 16 taken 59 times.
✗ Branch 17 not taken.
59 c = server->find<Channel>(name);
512
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 18 times.
59 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 30 times.
✗ Branch 3 not taken.
30 bool hex = parser->isTrue("hex");
522
523 // A single signal was requested
524
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 5 times.
30 if (c) {
525
1/2
✗ Branch 12 not taken.
✓ Branch 13 taken 25 times.
25 char buf[c->signal->memSize];
526 25 struct timespec time;
527 75 int rv = static_cast<const PdServ::Variable*>(c->signal)
528
1/2
✓ Branch 6 taken 25 times.
✗ Branch 7 not taken.
75 ->getValue(this, buf, &time);
529
530
1/2
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
50 XmlElement channel(createElement("channel"));
531
2/4
✓ Branch 3 taken 25 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 25 times.
✗ Branch 7 not taken.
25 c->setXmlAttributes(
532 channel, shortReply, hex, false, rv ? 0 : buf, 16, &time);
533
534
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (!shortReply)
535
1/2
✓ Branch 7 taken 25 times.
✗ Branch 8 not taken.
25 knownVariables.insert(c->signal);
536
537 50 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 66 times.
10 XmlElement channels(createElement("channels"));
543 85 for (Server::Channels::const_iterator it = chanList.begin();
544
2/2
✓ Branch 6 taken 80 times.
✓ Branch 7 taken 5 times.
85 it != chanList.end(); it++) {
545 80 c = *it;
546
2/4
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
80 if (c->hidden)
547 continue;
548
549
2/4
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
160 XmlElement el(channels.createChild("channel"));
550
1/2
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
80 c->setXmlAttributes( el, shortReply, false, false, 0, 16, 0);
551
552
1/2
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
80 if (!shortReply)
553
1/2
✓ Branch 7 taken 80 times.
✗ Branch 8 not taken.
80 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 105 void Session::readParameter(const XmlParser* parser)
575 {
576
1/2
✓ Branch 2 taken 105 times.
✗ Branch 3 not taken.
105 bool shortReply = parser->isTrue("short");
577
1/2
✓ Branch 2 taken 105 times.
✗ Branch 3 not taken.
105 bool hex = parser->isTrue("hex");
578
2/2
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 100 times.
110 std::string name;
579 105 unsigned int index;
580
581 105 const Parameter *p = 0;
582
3/4
✓ Branch 2 taken 105 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 59 times.
✓ Branch 5 taken 46 times.
105 if (parser->getString("name", name)) {
583
1/2
✓ Branch 16 taken 59 times.
✗ Branch 17 not taken.
59 p = server->find<Parameter>(name);
584
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 33 times.
59 if (!p)
585 26 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 100 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 115 void Session::remoteHost(const XmlParser* parser)
715 {
716 115 parser->getString("name", remoteHostName);
717
718 115 parser->getString("applicationname", client);
719
720
1/2
✓ Branch 2 taken 115 times.
✗ Branch 3 not taken.
115 if (parser->find("access"))
721 230 writeAccess = parser->isEqual("access", "allow")
722
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
115 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 115 parser->getBool("polite", &polite);
729
730
3/6
✓ Branch 9 taken 115 times.
✗ Branch 10 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 115 times.
✓ Branch 33 taken 115 times.
✗ Branch 34 not taken.
115 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 115 }
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 12 void Session::xsad(const XmlParser* parser)
798 {
799 12 unsigned int reduction, blocksize, precision, group;
800
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 bool base64 = parser->isEqual("coding", "Base64");
801
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 bool event = parser->isTrue("event");
802 12 bool foundReduction = false;
803
1/2
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 std::list<unsigned int> indexList;
804
1/2
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
12 const Server::Channels& channel = server->getChannels();
805
806
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 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 12 times.
✗ Branch 5 not taken.
12 quiet = parser->isTrue("quiet");
816 }
817
818
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 if (!parser->getUnsignedList("channels", indexList))
819 return;
820
821
3/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 2 times.
12 if (parser->getUnsigned("reduction", reduction)) {
822
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 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 10 foundReduction = true;
832 }
833
834 // Discover blocksize
835
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
12 if (event) {
836 // blocksize of zero is for event channels
837 2 blocksize = 0;
838 }
839
2/4
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 else if (parser->getUnsigned("blocksize", blocksize)) {
840
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 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 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 if (!parser->getUnsigned("precision", precision))
855 12 precision = 16;
856
857
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 if (!parser->getUnsigned("group", group))
858 group = 0;
859
860
1/2
✓ Branch 14 taken 12 times.
✗ Branch 15 not taken.
24 for (std::list<unsigned int>::const_iterator it = indexList.begin();
861
2/2
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 12 times.
24 it != indexList.end(); it++) {
862
1/2
✗ Branch 4 not taken.
✓ Branch 5 taken 12 times.
12 if (*it >= channel.size())
863 continue;
864
865 12 const Channel *c = channel[*it];
866 12 const PdServ::Signal *mainSignal = c->signal;
867
868
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
12 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 10 times.
10 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
1/2
✓ Branch 46 taken 12 times.
✗ Branch 47 not taken.
12 subscriptionManager[c->signal->task->index]->subscribe(
882 c, group, reduction, blocksize, base64, precision);
883 }
884 }
885
886 /////////////////////////////////////////////////////////////////////////////
887 void Session::xsod(const XmlParser* parser)
888 {
889 std::list<unsigned int> intList;
890
891 //cout << __LINE__ << "xsod: " << endl;
892
893 if (parser->getUnsignedList("channels", intList)) {
894 const Server::Channels& channel = server->getChannels();
895 unsigned int group;
896
897 if (!parser->getUnsigned("group", group))
898 group = 0;
899
900 for (std::list<unsigned int>::const_iterator it = intList.begin();
901 it != intList.end(); it++) {
902 if (*it < channel.size()) {
903 size_t taskIdx = channel[*it]->signal->task->index;
904 subscriptionManager[taskIdx]->unsubscribe(channel[*it], group);
905 }
906 }
907 }
908 else
909 for (SubscriptionManagerVector::iterator it = subscriptionManager.begin();
910 it != subscriptionManager.end(); ++it)
911 (*it)->clear();
912 }
913
914 /////////////////////////////////////////////////////////////////////////////
915 void Session::xsap(const XmlParser* parser)
916 {
917 pthread::MutexLock lock(mutex);
918
919 if (parser->isTrue("monitor"))
920 parameterMonitor = true;
921
922 std::list<unsigned int> indexList;
923 if (parser->getUnsignedList("parameters", indexList)) {
924 const Server::Parameters& parameter = server->getParameters();
925
926 for (std::list<unsigned int>::const_iterator it = indexList.begin();
927 it != indexList.end(); it++) {
928 unsigned int idx = *it;
929 if (idx < parameter.size())
930 parameterMonitorSet.insert(parameter[idx]);
931 }
932 }
933 }
934
935 /////////////////////////////////////////////////////////////////////////////
936 void Session::xsop(const XmlParser* parser)
937 {
938 pthread::MutexLock lock(mutex);
939
940 std::list<unsigned int> indexList;
941 if (!parser->getBool("monitor", &parameterMonitor)
942 and !parser->getUnsignedList("parameters", indexList)) {
943 parameterMonitor = false;
944 parameterMonitorSet.clear();
945 }
946 else {
947 const Server::Parameters& parameter = server->getParameters();
948
949 for (std::list<unsigned int>::const_iterator it = indexList.begin();
950 it != indexList.end(); it++) {
951 unsigned int idx = *it;
952 if (idx < parameter.size())
953 parameterMonitorSet.erase(parameter[idx]);
954 }
955 }
956 }
957
958 /////////////////////////////////////////////////////////////////////////////
959 74 void Session::authenticate(const XmlParser* parser)
960 {
961
1/2
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
148 XmlElement auth(createElement("saslauth"));
962
963 74 const char* mech = 0;
964 74 const char* clientdata = 0;
965 74 bool logout = false;
966
967
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 22 times.
74 if (parser) {
968
1/2
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 parser->find("clientdata", &clientdata);
969
1/2
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 parser->find("mech", &mech);
970
1/2
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
52 logout = parser->isTrue("logout");
971 }
972
973
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 27 times.
74 if (mech or clientdata) {
974 47 const std::string* serverdata;
975
1/2
✓ Branch 5 taken 47 times.
✗ Branch 6 not taken.
47 bool result = saslProcess(mech, clientdata, &serverdata);
976
977
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 25 times.
47 if (result or !serverdata)
978
2/4
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
22 XmlElement::Attribute(auth, "success") << result;
979
980
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 22 times.
47 if (serverdata)
981
2/4
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
✓ Branch 7 taken 25 times.
✗ Branch 8 not taken.
25 XmlElement::Attribute(auth, "serverdata") << *serverdata;
982 }
983
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
27 else if (logout) {
984
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 saslDispose();
985
986
2/4
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
1 if (main->loginMandatory())
987 p_running = false;
988 }
989 else {
990
1/2
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
26 const char *mechs = saslMechanisms();
991
992
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (mechs)
993
2/4
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 26 times.
✗ Branch 7 not taken.
26 XmlElement::Attribute(auth, "mechlist") << mechs;
994 else
995 XmlElement::Attribute(auth, "success") << 0;
996 }
997 74 }
998
999 /////////////////////////////////////////////////////////////////////////////
1000 880 XmlElement Session::createElement(const char* name)
1001 {
1002 880 return XmlElement(name, xmlstream, 0, &commandId);
1003 }
1004
1005 ///////////////////////////////////////////////////////////////////////////
1006 24 std::string Session::peerAddr(char sep) const
1007 {
1008 24 return getAddr(sep);
1009 }
1010
1011 ///////////////////////////////////////////////////////////////////////////
1012 24 std::string Session::localAddr(char sep) const
1013 {
1014 24 return server->getAddr(sep);
1015 }
1016
1017 /////////////////////////////////////////////////////////////////////////////
1018 11230 ssize_t Session::read(void* buf, size_t count)
1019 {
1020 11230 int rv = readData(buf, count);
1021
2/2
✓ Branch 0 taken 11157 times.
✓ Branch 1 taken 73 times.
11230 if (rv > 0)
1022 11157 inBytes += rv;
1023 11230 return rv;
1024 }
1025
1026 /////////////////////////////////////////////////////////////////////////////
1027 1011 ssize_t Session::write(const void* buf, size_t count)
1028 {
1029 1011 int rv = writeData(buf, count);
1030
1/2
✓ Branch 0 taken 1011 times.
✗ Branch 1 not taken.
1011 if (rv > 0)
1031 1011 outBytes += rv;
1032 1011 return rv;
1033 }
1034