Eclipse SUMO - Simulation of Urban MObility
TraCIServer.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2007-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
25 // TraCI server used to control sumo by a remote TraCI client (e.g., ns2)
26 /****************************************************************************/
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #include <config.h>
32 
33 #ifdef HAVE_VERSION_H
34 #include <version.h>
35 #endif
36 
37 #include <string>
38 #include <cmath>
39 #include <map>
40 #include <iostream>
41 #include <algorithm>
42 #include <foreign/tcpip/socket.h>
43 #include <foreign/tcpip/storage.h>
44 #include <utils/common/SUMOTime.h>
52 #include <utils/xml/XMLSubSys.h>
53 #include <microsim/MSNet.h>
54 #include <microsim/MSVehicle.h>
55 #include <microsim/MSEdge.h>
58 #include <microsim/MSJunction.h>
59 #include <microsim/MSEdgeControl.h>
60 #include <microsim/MSLane.h>
61 #include <microsim/MSGlobals.h>
63 #include <libsumo/Simulation.h>
64 #include <libsumo/Subscription.h>
65 #include <libsumo/TraCIConstants.h>
66 #include "TraCIServer.h"
69 #include "TraCIServerAPI_Lane.h"
73 #include "TraCIServerAPI_Vehicle.h"
75 #include "TraCIServerAPI_Route.h"
76 #include "TraCIServerAPI_POI.h"
77 #include "TraCIServerAPI_Polygon.h"
78 #include "TraCIServerAPI_Edge.h"
80 #include "TraCIServerAPI_Person.h"
81 
82 
83 // ===========================================================================
84 // debug constants
85 // ===========================================================================
86 //#define DEBUG_MULTI_CLIENTS
87 //#define DEBUG_SUBSCRIPTIONS
88 //#define DEBUG_SUBSCRIPTION_FILTERS
89 //#define DEBUG_RAW_INPUT
90 
91 
92 // ===========================================================================
93 // static member definitions
94 // ===========================================================================
97 
98 
99 // ===========================================================================
100 // method definitions
101 // ===========================================================================
102 void
103 TraCIServer::initWrapper(const int domainID, const int variable, const std::string& objID) {
108 }
109 
110 
111 bool
112 TraCIServer::wrapDouble(const std::string& /* objID */, const int /* variable */, const double value) {
115  return true;
116 }
117 
118 
119 bool
120 TraCIServer::wrapInt(const std::string& /* objID */, const int /* variable */, const int value) {
122  myWrapperStorage.writeInt(value);
123  return true;
124 }
125 
126 
127 bool
128 TraCIServer::wrapString(const std::string& /* objID */, const int /* variable */, const std::string& value) {
131  return true;
132 }
133 
134 
135 bool
136 TraCIServer::wrapStringList(const std::string& /* objID */, const int /* variable */, const std::vector<std::string>& value) {
139  return true;
140 }
141 
142 
143 bool
144 TraCIServer::wrapPosition(const std::string& /* objID */, const int variable, const libsumo::TraCIPosition& value) {
145  const bool includeZ = variable == libsumo::VAR_POSITION3D;
149  if (includeZ) {
151  }
152  return true;
153 }
154 
155 
156 bool
157 TraCIServer::wrapColor(const std::string& /* objID */, const int /* variable */, const libsumo::TraCIColor& value) {
163  return true;
164 }
165 
166 
167 bool
168 TraCIServer::wrapRoadPosition(const std::string& /* objID */, const int /* variable */, const libsumo::TraCIRoadPosition& /* value */) {
169  // this is currently only a placeholder to allow vehicle.subscribeLeader to work with libsumo
170  return false;
171 }
172 
173 
176  return myWrapperStorage;
177 }
178 
179 
180 
181 TraCIServer::TraCIServer(const SUMOTime begin, const int port, const int numClients)
182  : myServerSocket(nullptr), myTargetTime(begin), myLastContextSubscription(nullptr) {
183 #ifdef DEBUG_MULTI_CLIENTS
184  std::cout << "Creating new TraCIServer for " << numClients << " clients on port " << port << "." << std::endl;
185 #endif
186  myVehicleStateChanges[MSNet::VEHICLE_STATE_BUILT] = std::vector<std::string>();
187  myVehicleStateChanges[MSNet::VEHICLE_STATE_DEPARTED] = std::vector<std::string>();
189  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_TELEPORT] = std::vector<std::string>();
190  myVehicleStateChanges[MSNet::VEHICLE_STATE_ARRIVED] = std::vector<std::string>();
191  myVehicleStateChanges[MSNet::VEHICLE_STATE_NEWROUTE] = std::vector<std::string>();
192  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_PARKING] = std::vector<std::string>();
193  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_PARKING] = std::vector<std::string>();
194  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_STOP] = std::vector<std::string>();
195  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_STOP] = std::vector<std::string>();
196  myVehicleStateChanges[MSNet::VEHICLE_STATE_COLLISION] = std::vector<std::string>();
197  myVehicleStateChanges[MSNet::VEHICLE_STATE_EMERGENCYSTOP] = std::vector<std::string>();
198 
202 
224 
226 
227  myDoCloseConnection = false;
228 
229  // display warning if internal lanes are not used
231  WRITE_WARNING("Starting TraCI without using internal lanes!");
232  MsgHandler::getWarningInstance()->inform("Vehicles will jump over junctions.", false);
233  MsgHandler::getWarningInstance()->inform("Use without option --no-internal-links to avoid unexpected behavior", false);
234  }
235 
236  try {
237  WRITE_MESSAGE("***Starting server on port " + toString(port) + " ***");
238  myServerSocket = new tcpip::Socket(port);
239  if (numClients > 1) {
240  WRITE_MESSAGE(" waiting for " + toString(numClients) + " clients...");
241  }
242  while ((int)mySockets.size() < numClients) {
243  int index = (int)mySockets.size() + libsumo::MAX_ORDER + 1;
244  mySockets[index] = new SocketInfo(myServerSocket->accept(true), begin);
245  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_BUILT] = std::vector<std::string>();
246  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_DEPARTED] = std::vector<std::string>();
247  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_TELEPORT] = std::vector<std::string>();
248  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_TELEPORT] = std::vector<std::string>();
249  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ARRIVED] = std::vector<std::string>();
250  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_NEWROUTE] = std::vector<std::string>();
251  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_PARKING] = std::vector<std::string>();
252  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_PARKING] = std::vector<std::string>();
253  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_STOP] = std::vector<std::string>();
254  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_STOP] = std::vector<std::string>();
255  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_COLLISION] = std::vector<std::string>();
256  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_EMERGENCYSTOP] = std::vector<std::string>();
257  if (numClients > 1) {
258  WRITE_MESSAGE(" client connected");
259  }
260  }
261  // When got here, all clients have connected
262  if (numClients > 1) {
264  }
265  // set myCurrentSocket != mySockets.end() to indicate that this is the first step in processCommandsUntilSimStep()
266  myCurrentSocket = mySockets.begin();
267  } catch (tcpip::SocketException& e) {
268  throw ProcessError(e.what());
269  }
270 }
271 
272 
274  for (myCurrentSocket = mySockets.begin(); myCurrentSocket != mySockets.end(); ++myCurrentSocket) {
275  delete myCurrentSocket->second;
276  }
277  delete myServerSocket;
278  cleanup();
279 }
280 
281 
282 // ---------- Initialisation and Shutdown
283 void
284 TraCIServer::openSocket(const std::map<int, CmdExecutor>& execs) {
285  if (myInstance == nullptr && !myDoCloseConnection && (OptionsCont::getOptions().getInt("remote-port") != 0)) {
286  myInstance = new TraCIServer(string2time(OptionsCont::getOptions().getString("begin")),
287  OptionsCont::getOptions().getInt("remote-port"),
288  OptionsCont::getOptions().getInt("num-clients"));
289  for (std::map<int, CmdExecutor>::const_iterator i = execs.begin(); i != execs.end(); ++i) {
290  myInstance->myExecutors[i->first] = i->second;
291  }
292  }
293  if (myInstance != nullptr) {
294  // maybe net was deleted and built again
297  }
298 }
299 
300 
301 void
303  if (myInstance == nullptr) {
304  return;
305  }
306  delete myInstance;
307  myInstance = nullptr;
308  myDoCloseConnection = true;
309 }
310 
311 
312 bool
314  return myDoCloseConnection;
315 }
316 
317 
318 // ---------- Initialisation and Shutdown
319 
320 
321 void
322 TraCIServer::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& /*info*/) {
323  if (!myDoCloseConnection) {
324  myVehicleStateChanges[to].push_back(vehicle->getID());
325  for (std::map<int, SocketInfo*>::iterator i = mySockets.begin(); i != mySockets.end(); ++i) {
326  i->second->vehicleStateChanges[to].push_back(vehicle->getID());
327  }
328  }
329 }
330 
331 
332 void
334 #ifdef DEBUG_MULTI_CLIENTS
335  std::cout << "Checking client order requests." << std::endl;
336 #endif
337  // check for SET_ORDER commands queued by connected clients
338  // In multiclient cas it is mandatory that SET_ORDER is sent as the first command (or directly after GET_VERSION)
339  myCurrentSocket = mySockets.begin();
340  while (myCurrentSocket != mySockets.end()) {
341 #ifdef DEBUG_MULTI_CLIENTS
342  std::cout << " Socket " << myCurrentSocket->second->socket << ":" << std::endl;
343 #endif
344 // bool clientUnordered = true;
345 #ifdef _MSC_VER
346 #pragma warning(push)
347 #pragma warning(disable: 4127) // do not warn about constant conditional expression
348 #endif
349  while (true) {
350 #ifdef _MSC_VER
351 #pragma warning(pop)
352 #endif
354  myCurrentSocket->second->socket->receiveExact(myInputStorage);
355  int commandStart, commandLength;
356  int commandId = readCommandID(commandStart, commandLength);
357 #ifdef DEBUG_MULTI_CLIENTS
358  std::cout << " received command " << commandId << std::endl;
359 #endif
360  // Whether the received command is a permitted command for the initialization phase.
361  // Currently, getVersion and setOrder are permitted.
362  bool initCommand = commandId == libsumo::CMD_SETORDER || commandId == libsumo::CMD_GETVERSION;
363  if (initCommand) {
364 #ifdef DEBUG_MULTI_CLIENTS
365  std::cout << " Init command. Sending response." << std::endl;
366 #endif
367  // reset input storage to initial state before reading the commandId
368  // (ugly, but we can't just reset the store's iter_ from here)
369  // Giving the commandId to dispatch command didn't work either
370  tcpip::Storage tmp;
373  // we don't know whether the command was set with extended
374  // length syntax or not so we hardcode the length here (#5037)
378 
379  // Handle initialization command completely
380  dispatchCommand();
381  myCurrentSocket->second->socket->sendExact(myOutputStorage);
383  } else {
384 #ifdef DEBUG_MULTI_CLIENTS
385  std::cout << " Client " << myCurrentSocket->second->socket << " did not set order initially." << std::endl;
386 #endif
387  throw ProcessError("Execution order (libsumo::CMD_SETORDER) was not set for all TraCI clients in pre-execution phase.");
388  }
389  if (commandId == libsumo::CMD_SETORDER) {
390  // This is what we have waited for.
391  break;
392  }
393  }
394  ++myCurrentSocket;
395  }
396 }
397 
398 
399 void
401  // Process reordering requests
402  if (mySocketReorderRequests.size() > 0) {
403  // process reordering requests
404  std::map<int, SocketInfo*>::const_iterator i = mySocketReorderRequests.begin();
405  std::map<int, SocketInfo*>::iterator j;
406 #ifdef DEBUG_MULTI_CLIENTS
407  std::cout << SIMTIME << " Current socket ordering:\n";
408  for (j = mySockets.begin(); j != mySockets.end(); ++j) {
409  std::cout << " " << j->first << ": " << j->second->socket << "\n";
410  }
411  std::cout << "Reordering requests:\n";
412  for (i = mySocketReorderRequests.begin(); i != mySocketReorderRequests.end(); ++i) {
413  std::cout << " Socket " << i->second->socket << " -> " << i->first << "\n";
414  }
415  i = mySocketReorderRequests.begin();
416 #endif
417  while (i != mySocketReorderRequests.end()) {
418  j = mySockets.begin();
419  while (j != mySockets.end()) {
420  if (j->second->socket == i->second->socket) {
421  break;
422  } else {
423  j++;
424  }
425  }
426  assert(j != mySockets.end());
427  mySockets.erase(j);
428  mySockets[i->first] = i->second;
429  ++i;
430  }
431  mySocketReorderRequests.clear();
432 #ifdef DEBUG_MULTI_CLIENTS
433  std::cout << "New socket ordering:\n";
434  for (j = mySockets.begin(); j != mySockets.end(); ++j) {
435  std::cout << " " << j->first << ": " << j->second->socket << "\n";
436  }
437  std::cout << std::endl;
438 #endif
439  }
440 }
441 
442 
443 SUMOTime
445 #ifdef DEBUG_MULTI_CLIENTS
446  std::cout << "\n Determining new target time..." << std::endl;
447  if (mySockets.size() == 0) {
448  std::cout << " All clients have disconnected." << std::endl;
449  }
450 #endif
451  std::map<int, SocketInfo*>::const_iterator i;
452  SUMOTime targetTime = std::numeric_limits<SUMOTime>::max();
453  for (i = mySockets.begin(); i != mySockets.end(); ++i) {
454 #ifdef DEBUG_MULTI_CLIENTS
455  std::cout << " target time for client " << i->second->socket << ": " << i->second->targetTime << "\n";
456 #endif
457  targetTime = MIN2(targetTime, i->second->targetTime);
458  }
459 #ifdef DEBUG_MULTI_CLIENTS
460  std::cout << std::endl;
461 #endif
462  return targetTime;
463 }
464 
465 
466 // send out subscription results to clients which will act in this step (i.e. with client target time <= myTargetTime)
467 void
469 #ifdef DEBUG_MULTI_CLIENTS
470  std::cout << "\n Sending subscription results to clients:\n";
471 #endif
472  std::map<int, SocketInfo*>::const_iterator i = mySockets.begin();
473  while (i != mySockets.end()) {
474  if (i->second->targetTime <= MSNet::getInstance()->getCurrentTimeStep()) {
475  // this client will become active before the next SUMO step. Provide subscription results.
476  i->second->socket->sendExact(myOutputStorage);
477 #ifdef DEBUG_MULTI_CLIENTS
478  std::cout << i->second->socket << "\n";
479 #endif
480  }
481  ++i;
482  }
483 #ifdef DEBUG_MULTI_CLIENTS
484  std::cout << std::endl;
485 #endif
486 }
487 
488 
489 void
491 #ifdef DEBUG_MULTI_CLIENTS
492  std::cout << SIMTIME << " processCommandsUntilSimStep(step = " << step << "):\n" << std::endl;
493 #endif
494  try {
495  const bool firstStep = myCurrentSocket != mySockets.end();
496  // update client order if requested
498  if (!firstStep) {
499  // This is the entry point after performing a SUMO step (block is skipped before first SUMO step since then no simulation results have to be sent)
500  // update subscription results
502  // Send out subscription results to clients which will act in this SUMO step (i.e. with client target time <= current sumo timestep end)
503  sendOutputToAll();
505  }
506 
507  // determine minimal next target time among clients
509 
510  if (step < myTargetTime) {
511 #ifdef DEBUG_MULTI_CLIENTS
512  if (step < myTargetTime) {
513  std::cout << " next target time is larger than next SUMO simstep (" << step << "). Returning from processCommandsUntilSimStep()." << std::endl;
514  }
515 #endif
516  return;
517  }
518 
519  // Simulation should run until
520  // 1. end time reached or
521  // 2. got libsumo::CMD_CLOSE or
522  // 3. got libsumo::CMD_LOAD or
523  // 4. Client closes socket connection
524  while (!myDoCloseConnection && myTargetTime <= (MSNet::getInstance()->getCurrentTimeStep())) {
525 #ifdef DEBUG_MULTI_CLIENTS
526  std::cout << " Next target time: " << myTargetTime << std::endl;
527 #endif
528  // Iterate over clients and process communication for the ones with target time == myTargetTime
529  myCurrentSocket = mySockets.begin();
530  while (myCurrentSocket != mySockets.end()) {
531 #ifdef DEBUG_MULTI_CLIENTS
532  std::cout << " current socket: " << myCurrentSocket->second->socket
533  << " with target time " << myCurrentSocket->second->targetTime
534  << std::endl;
535 #endif
536 
537  if (myCurrentSocket->second->targetTime > myTargetTime) {
538  // this client must wait
539 #ifdef DEBUG_MULTI_CLIENTS
540  std::cout << " skipping client " << myCurrentSocket->second->socket
541  << " with target time " << myCurrentSocket->second->targetTime << std::endl;
542 #endif
543  myCurrentSocket++;
544  continue;
545  }
546  bool done = false;
547  bool closed = false;
548  bool load = false;
549  while (!done && !closed && !load) {
550  if (!myInputStorage.valid_pos()) {
551  // have read request completely, send response if adequate
552  if (myOutputStorage.size() > 0) {
553 #ifdef DEBUG_MULTI_CLIENTS
554  std::cout << " sending response..." << std::endl;
555 #endif
556  // send response to previous query
557  myCurrentSocket->second->socket->sendExact(myOutputStorage);
559  } else {
560 #ifdef DEBUG_MULTI_CLIENTS
561  std::cout << " No input and no output stored (This is the next client)." << std::endl;
562 #endif
563  }
564 #ifdef DEBUG_MULTI_CLIENTS
565  std::cout << " resetting input storage and reading next command..." << std::endl;
566 #endif
567  // Read next request
569  myCurrentSocket->second->socket->receiveExact(myInputStorage);
570  }
571 
573  // dispatch command
574  const int cmd = dispatchCommand();
575 #ifdef DEBUG_MULTI_CLIENTS
576  std::cout << " Received command " << cmd << std::endl;
577 #endif
578  if (cmd == libsumo::CMD_SIMSTEP) {
579 #ifdef DEBUG_MULTI_CLIENTS
580  std::cout << " Received command SIM_STEP, end turn for client " << myCurrentSocket->second->socket << std::endl;
581 #endif
582  done = true;
583  } else if (cmd == libsumo::CMD_LOAD) {
584 #ifdef DEBUG_MULTI_CLIENTS
585  std::cout << " Received command LOAD." << std::endl;
586 #endif
587  load = true;
588  } else if (cmd == libsumo::CMD_CLOSE) {
589 #ifdef DEBUG_MULTI_CLIENTS
590  std::cout << " Received command CLOSE." << std::endl;
591 #endif
592  closed = true;
593  }
594  }
595  }
596  if (done) {
597  // Clear vehicleStateChanges for this client -> For subsequent TraCI stepping
598  // that is performed within this SUMO step, no updates on vehicle states
599  // belonging to the last SUMO simulation step will be received by this client.
600  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myCurrentSocket->second->vehicleStateChanges.begin(); i != myCurrentSocket->second->vehicleStateChanges.end(); ++i) {
601  (*i).second.clear();
602  }
603  myCurrentSocket++;
604  } else if (load) {
605  myCurrentSocket = mySockets.end();
606  } else {
607  assert(closed);
608  // remove current socket and increment to next socket in ordering
610  }
611  }
612  if (!myLoadArgs.empty()) {
613 #ifdef DEBUG_MULTI_CLIENTS
614  std::cout << " Breaking loop to load new simulation." << std::endl;
615 #endif
616  break;
617  } else if (myDoCloseConnection) {
618 #ifdef DEBUG_MULTI_CLIENTS
619  std::cout << " Breaking loop because last client closed connection." << std::endl;
620 #endif
621  break;
622  }
623  SUMOTime nextT = nextTargetTime();
624  // minimal target time among clients should have been increased during the last loop through mySockets
625  // XXX: The assert below is disabled since many tests do sth. like simulationStep(step). Such that for a first call step=0,
626  // leading to targetTime==1000 (increased by DELTA_T in dispatchCommand()),
627  // the next call is then usually simulationStep(step=1000) leading to no further increase
628  // and thus a failing assertion here.
629  //assert(myTargetTime < nextT || myDoCloseConnection);
630  myTargetTime = nextT;
631  }
632  // All clients are done with the current time step
633  // Reset myVehicleStateChanges
634  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myVehicleStateChanges.begin(); i != myVehicleStateChanges.end(); ++i) {
635  (*i).second.clear();
636  }
637  } catch (std::invalid_argument& e) {
638  throw ProcessError(e.what());
639  } catch (libsumo::TraCIException& e) {
640  throw ProcessError(e.what());
641  } catch (tcpip::SocketException& e) {
642  throw ProcessError(e.what());
643  }
644 }
645 
646 
647 void
649  mySubscriptions.clear();
650  myTargetTime = string2time(OptionsCont::getOptions().getString("begin"));
651  for (myCurrentSocket = mySockets.begin(); myCurrentSocket != mySockets.end(); ++myCurrentSocket) {
652  myCurrentSocket->second->targetTime = myTargetTime;
653  }
657  std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i;
658  for (i = myVehicleStateChanges.begin(); i != myVehicleStateChanges.end(); i++) {
659  i->second.clear();
660  }
661  myCurrentSocket = mySockets.begin();
662 }
663 
664 
665 std::map<int, TraCIServer::SocketInfo*>::iterator
667 #ifdef DEBUG_MULTI_CLIENTS
668  std::cout << " Removing socket " << myCurrentSocket->second->socket
669  << " (order " << myCurrentSocket->first << ")" << std::endl;
670 #endif
671 
672  if (mySockets.size() == 1) {
673  // Last client has disconnected
674  delete myCurrentSocket->second->socket;
675  mySockets.clear();
676  myCurrentSocket = mySockets.end();
677  return myCurrentSocket;
678  }
679 
680  const int currOrder = myCurrentSocket->first;
681  delete myCurrentSocket->second->socket;
682  myCurrentSocket++;
683  if (myCurrentSocket != mySockets.end()) {
684  const int nextOrder = myCurrentSocket->first;
685  mySockets.erase(currOrder);
686  myCurrentSocket = mySockets.find(nextOrder);
687  } else {
688  mySockets.erase(currOrder);
689  myCurrentSocket = mySockets.end();
690  }
691  return myCurrentSocket;
692 }
693 
694 
695 int
696 TraCIServer::readCommandID(int& commandStart, int& commandLength) {
697  commandStart = myInputStorage.position();
698  commandLength = myInputStorage.readUnsignedByte();
699  if (commandLength == 0) {
700  commandLength = myInputStorage.readInt();
701  }
702 #ifdef DEBUG_RAW_INPUT
703  std::cout << " commandStart=" << commandStart << " commandLength=" << commandLength << " pos=" << myInputStorage.position() << " raw=";
704  for (auto it = myInputStorage.begin(); it != myInputStorage.end(); ++it) {
705  std::cout << (int)*it << " ";
706  }
707  std::cout << "\n";
708 #endif
710 }
711 
712 
713 int
715  int commandStart, commandLength;
716  int commandId = readCommandID(commandStart, commandLength);
717 #ifdef DEBUG_MULTI_CLIENTS
718  std::cout << " dispatchCommand() called for client " << myCurrentSocket->second->socket
719  << ", commandId = " << commandId << std::endl;
720 #endif
721  bool success = false;
722  // dispatch commands
723  if (myExecutors.find(commandId) != myExecutors.end()) {
724  success = myExecutors[commandId](*this, myInputStorage, myOutputStorage);
725  } else {
726  switch (commandId) {
728  success = commandGetVersion();
729  break;
730  case libsumo::CMD_LOAD: {
731  std::vector<std::string> args;
733  return writeErrorStatusCmd(libsumo::CMD_LOAD, "A load command needs a list of string arguments.", myOutputStorage);
734  }
735 #ifdef DEBUG_MULTI_CLIENTS
736  std::cout << " commandId == libsumo::CMD_LOAD"
737  << ", args = " << toString(args) << std::endl;
738 #endif
739  try {
740  myLoadArgs = args;
741  success = true;
743  // XXX: This only cares for the client that issued the load command.
744  // Multiclient-load functionality is still to be implemented. Refs #3146.
745  myCurrentSocket->second->socket->sendExact(myOutputStorage);
747  } catch (libsumo::TraCIException& e) {
749  }
750  break;
751  }
752  case libsumo::CMD_SIMSTEP: {
753  const double nextT = myInputStorage.readDouble();
754  if (nextT == 0.) {
755  myCurrentSocket->second->targetTime += DELTA_T;
756  } else {
757  myCurrentSocket->second->targetTime = TIME2STEPS(nextT);
758  }
759 #ifdef DEBUG_MULTI_CLIENTS
760  std::cout << " commandId == libsumo::CMD_SIMSTEP"
761  << ", next target time for client is " << myCurrentSocket->second->targetTime << std::endl;
762 #endif
763  if (myCurrentSocket->second->targetTime <= MSNet::getInstance()->getCurrentTimeStep()) {
764  // This is not the last TraCI simstep in the current SUMO simstep -> send single simstep response.
765  // @note: In the other case the simstep results are sent to all after the SUMO step was performed, see entry point for processCommandsUntilSimStep()
767  }
768  return commandId;
769  }
770  case libsumo::CMD_CLOSE:
772  myCurrentSocket->second->socket->sendExact(myOutputStorage);
774  if (mySockets.size() == 1) {
775  // Last client has closed connection
776  myDoCloseConnection = true;
777  }
778  success = true;
779  break;
780  case libsumo::CMD_SETORDER: {
781  const int order = myInputStorage.readInt();
782 #ifdef DEBUG_MULTI_CLIENTS
783  std::cout << " commandId == libsumo::CMD_SETORDER"
784  << ", order index is " << order << std::endl;
785 #endif
786  if (order > libsumo::MAX_ORDER) {
787  return writeErrorStatusCmd(libsumo::CMD_SETORDER, "A set order command needs an int argument below " + toString(libsumo::MAX_ORDER) + ".", myOutputStorage);
788  }
789  if (mySockets.count(order) > 0 || mySocketReorderRequests.count(order) > 0) {
790  return writeErrorStatusCmd(libsumo::CMD_SETORDER, "Order '" + toString(order) + "' is already taken.", myOutputStorage);
791  }
792  // memorize reorder request (will only take effect in the next step)
793  mySocketReorderRequests[order] = myCurrentSocket->second;
794  success = true;
796  break;
797  }
813  success = addObjectVariableSubscription(commandId, false);
814  break;
830  success = addObjectVariableSubscription(commandId, true);
831  break;
833  success = addSubscriptionFilter();
834  break;
835  default:
836  if (commandId == libsumo::CMD_GET_GUI_VARIABLE || commandId == libsumo::CMD_SET_GUI_VARIABLE) {
837  writeStatusCmd(commandId, libsumo::RTYPE_NOTIMPLEMENTED, "GUI is not running, command not implemented in command line sumo");
838  } else {
839  writeStatusCmd(commandId, libsumo::RTYPE_NOTIMPLEMENTED, "Command not implemented in sumo");
840  }
841  }
842  }
843  if (!success) {
844  while (myInputStorage.valid_pos() && (int)myInputStorage.position() < commandStart + commandLength) {
846  }
847  }
848  if ((int)myInputStorage.position() != commandStart + commandLength) {
849  std::ostringstream msg;
850  msg << "Wrong position in requestMessage after dispatching command " << commandId << ".";
851  msg << " Expected command length was " << commandLength;
852  msg << " but " << myInputStorage.position() - commandStart << " Bytes were read.";
853  writeStatusCmd(commandId, libsumo::RTYPE_ERR, msg.str());
854  myDoCloseConnection = true;
855  }
856  return commandId;
857 }
858 
859 
860 // ---------- Server-internal command handling
861 bool
863  std::string sumoVersion = VERSION_STRING;
864  // Prepare response
865  tcpip::Storage answerTmp;
866  answerTmp.writeInt(libsumo::TRACI_VERSION);
867  answerTmp.writeString(std::string("SUMO ") + sumoVersion);
868  // When we get here, the response is stored in answerTmp -> put into myOutputStorage
870  // command length
871  myOutputStorage.writeUnsignedByte(1 + 1 + static_cast<int>(answerTmp.size()));
872  // command type
874  // and the parameter dependant part
875  myOutputStorage.writeStorage(answerTmp);
876  return true;
877 }
878 
879 
880 void
883 #ifdef DEBUG_MULTI_CLIENTS
884  std::cout << " postProcessSimulationStep() at time " << t << std::endl;
885 #endif
887  int noActive = 0;
888  for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
889  const libsumo::Subscription& s = *i;
893  if ((s.endTime < t) || isArrivedVehicle || isArrivedPerson) {
894  i = mySubscriptions.erase(i);
895  continue;
896  }
897  ++i;
898  if (s.beginTime > t) {
899  continue;
900  }
901  ++noActive;
902  }
904 #ifdef DEBUG_SUBSCRIPTIONS
905  std::cout << " Initial size of mySubscriptionCache is " << mySubscriptionCache.size()
906  << "\n Nr. of active subscriptions = " << noActive << std::endl;
907 #endif
908  mySubscriptionCache.writeInt(noActive);
909 #ifdef DEBUG_SUBSCRIPTIONS
910  std::cout << " Size after writing an int is " << mySubscriptionCache.size() << std::endl;
911 #endif
912  for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
913  const libsumo::Subscription& s = *i;
914  if (s.beginTime > t) {
915  ++i;
916  continue;
917  }
918  tcpip::Storage into;
919  std::string errors;
920  bool ok = processSingleSubscription(s, into, errors);
921 #ifdef DEBUG_SUBSCRIPTIONS
922  std::cout << " Size of into-store for subscription " << s.id
923  << ": " << into.size() << std::endl;
924 #endif
926  if (ok) {
927  ++i;
928  } else {
929  i = mySubscriptions.erase(i);
930  }
931  }
933 #ifdef DEBUG_SUBSCRIPTIONS
934  std::cout << " Size after writing subscriptions is " << mySubscriptionCache.size() << std::endl;
935 #endif
936 }
937 
938 
939 void
941 #ifdef DEBUG_MULTI_CLIENTS
942  std::cout << " Sending cached simstep response to current client " << myCurrentSocket->second->socket
943  << " (-> intermediate TraCI step)."
944  << "\n Size of mySubscriptionCache is " << mySubscriptionCache.size()
945  << std::endl;
946 #endif
948 
949 // NOTE: the commented code would send an empty response
950 // myOutputStorage.writeInt(0);
951 // myCurrentSocket->second->socket->sendExact(myOutputStorage);
952 // myOutputStorage.reset();
954  // send results to active client
955  myCurrentSocket->second->socket->sendExact(myOutputStorage);
957 }
958 
959 
960 void
961 TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description) {
962  writeStatusCmd(commandId, status, description, myOutputStorage);
963 }
964 
965 
966 void
967 TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description, tcpip::Storage& outputStorage) {
968  if (status == libsumo::RTYPE_ERR) {
969  WRITE_ERROR("Answered with error to command " + toHex(commandId, 2) + ": " + description);
970  } else if (status == libsumo::RTYPE_NOTIMPLEMENTED) {
971  WRITE_ERROR("Requested command not implemented (" + toHex(commandId, 2) + "): " + description);
972  }
973  outputStorage.writeUnsignedByte(1 + 1 + 1 + 4 + static_cast<int>(description.length())); // command length
974  outputStorage.writeUnsignedByte(commandId); // command type
975  outputStorage.writeUnsignedByte(status); // status
976  outputStorage.writeString(description); // description
977 }
978 
979 
980 bool
981 TraCIServer::writeErrorStatusCmd(int commandId, const std::string& description, tcpip::Storage& outputStorage) {
982  writeStatusCmd(commandId, libsumo::RTYPE_ERR, description, outputStorage);
983  return false;
984 }
985 
986 
987 void
989  tcpip::Storage writeInto;
990  std::string errors;
991  libsumo::Subscription* modifiedSubscription = nullptr;
992  if (processSingleSubscription(s, writeInto, errors)) {
994  writeStatusCmd(s.commandId, libsumo::RTYPE_ERR, "Subscription has ended.");
995  } else {
996  bool needNewSubscription = true;
998  if (s.commandId == o.commandId && s.id == o.id &&
999  s.beginTime == o.beginTime && s.endTime == o.endTime &&
1000  s.contextDomain == o.contextDomain && s.range == o.range) {
1001  std::vector<std::vector<unsigned char> >::const_iterator k = s.parameters.begin();
1002  for (std::vector<int>::const_iterator j = s.variables.begin(); j != s.variables.end(); ++j, ++k) {
1003  const int offset = (int)(std::find(o.variables.begin(), o.variables.end(), *j) - o.variables.begin());
1004  if (offset == (int)o.variables.size() || o.parameters[offset] != *k) {
1005  o.variables.push_back(*j);
1006  o.parameters.push_back(*k);
1007  }
1008  }
1009  needNewSubscription = false;
1010  modifiedSubscription = &o;
1011  break;
1012  }
1013  }
1014  if (needNewSubscription) {
1015  mySubscriptions.push_back(s);
1016  modifiedSubscription = &mySubscriptions.back();
1017  // Add new subscription to subscription cache (note: seems a bit inefficient)
1019  // copy new subscription into cache
1020  int noActive = 1 + (mySubscriptionCache.size() > 0 ? mySubscriptionCache.readInt() : 0);
1021  tcpip::Storage tmp;
1022  tmp.writeInt(noActive);
1023  while (mySubscriptionCache.valid_pos()) {
1025  }
1026  tmp.writeStorage(writeInto);
1029  }
1030  }
1032  }
1033  if (modifiedSubscription != nullptr && isVehicleToVehicleContextSubscription(*modifiedSubscription)) {
1034  // Set last modified vehicle context subscription active for filter modifications
1035  myLastContextSubscription = modifiedSubscription;
1036  } else {
1037  // adding other subscriptions deactivates the activation for filter addition
1038  myLastContextSubscription = nullptr;
1039  }
1040  } else {
1041  writeStatusCmd(s.commandId, libsumo::RTYPE_ERR, "Could not add subscription. " + errors);
1042  }
1043  myOutputStorage.writeStorage(writeInto);
1044 }
1045 
1046 
1047 void
1048 TraCIServer::removeSubscription(int commandId, const std::string& id, int domain) {
1049  bool found = false;
1050  std::vector<libsumo::Subscription>::iterator j;
1051  for (j = mySubscriptions.begin(); j != mySubscriptions.end();) {
1052  if (j->id == id && j->commandId == commandId && (domain < 0 || j->contextDomain == domain)) {
1053  j = mySubscriptions.erase(j);
1054  if (j != mySubscriptions.end() && myLastContextSubscription == &(*j)) {
1055  // Remove also reference for filter additions
1056  myLastContextSubscription = nullptr;
1057  }
1058  found = true;
1059  continue;
1060  }
1061  ++j;
1062  }
1063  // try unsubscribe
1064  if (found) {
1065  writeStatusCmd(commandId, libsumo::RTYPE_OK, "");
1066  } else {
1067  writeStatusCmd(commandId, libsumo::RTYPE_ERR, "The subscription to remove was not found.");
1068  }
1069 }
1070 
1071 bool
1074 }
1075 
1076 
1077 bool
1079  std::string& errors) {
1080  bool ok = true;
1081  tcpip::Storage outputStorage;
1082  const int getCommandId = s.contextDomain > 0 ? s.contextDomain : s.commandId - 0x30;
1083  std::set<std::string> objIDs;
1084  if (s.contextDomain > 0) {
1086  PositionVector shape;
1089  }
1091  } else {
1092  objIDs.insert(s.id);
1093  }
1094  const int numVars = s.contextDomain > 0 && s.variables.size() == 1 && s.variables[0] == libsumo::TRACI_ID_LIST ? 0 : (int)s.variables.size();
1095  int skipped = 0;
1096  for (std::set<std::string>::iterator j = objIDs.begin(); j != objIDs.end(); ++j) {
1097  if (s.contextDomain > 0) {
1098  //if (centralObject(s, *j)) {
1099  // skipped++;
1100  // continue;
1101  //}
1102  outputStorage.writeString(*j);
1103  }
1104  if (numVars > 0) {
1105  std::vector<std::vector<unsigned char> >::const_iterator k = s.parameters.begin();
1106  for (std::vector<int>::const_iterator i = s.variables.begin(); i != s.variables.end(); ++i, ++k) {
1107  tcpip::Storage message;
1108  message.writeUnsignedByte(*i);
1109  message.writeString(*j);
1110  message.writePacket(*k);
1111  tcpip::Storage tmpOutput;
1112  if (myExecutors.find(getCommandId) != myExecutors.end()) {
1113  ok &= myExecutors[getCommandId](*this, message, tmpOutput);
1114  } else {
1115  writeStatusCmd(s.commandId, libsumo::RTYPE_NOTIMPLEMENTED, "Unsupported command specified", tmpOutput);
1116  ok = false;
1117  }
1118  // copy response part
1119  if (ok) {
1120  int length = tmpOutput.readUnsignedByte();
1121  while (--length > 0) {
1122  tmpOutput.readUnsignedByte();
1123  }
1124  int lengthLength = 1;
1125  length = tmpOutput.readUnsignedByte();
1126  if (length == 0) {
1127  lengthLength = 5;
1128  length = tmpOutput.readInt();
1129  }
1130  //read responseType
1131  tmpOutput.readUnsignedByte();
1132  int variable = tmpOutput.readUnsignedByte();
1133  std::string id = tmpOutput.readString();
1134  outputStorage.writeUnsignedByte(variable);
1135  outputStorage.writeUnsignedByte(libsumo::RTYPE_OK);
1136  length -= (lengthLength + 1 + 4 + (int)id.length());
1137  while (--length > 0) {
1138  outputStorage.writeUnsignedByte(tmpOutput.readUnsignedByte());
1139  }
1140  } else {
1141  //read length
1142  tmpOutput.readUnsignedByte();
1143  //read cmd
1144  tmpOutput.readUnsignedByte();
1145  //read status
1146  tmpOutput.readUnsignedByte();
1147  std::string msg = tmpOutput.readString();
1148  outputStorage.writeUnsignedByte(*i);
1149  outputStorage.writeUnsignedByte(libsumo::RTYPE_ERR);
1150  outputStorage.writeUnsignedByte(libsumo::TYPE_STRING);
1151  outputStorage.writeString(msg);
1152  errors = errors + msg;
1153  }
1154  }
1155  }
1156  }
1157  int length = (1 + 4) + 1 + (4 + (int)(s.id.length())) + 1 + (int)outputStorage.size();
1158  if (s.contextDomain > 0) {
1159  length += 4;
1160  }
1161  writeInto.writeUnsignedByte(0); // command length -> extended
1162  writeInto.writeInt(length);
1163  writeInto.writeUnsignedByte(s.commandId + 0x10);
1164  writeInto.writeString(s.id);
1165  if (s.contextDomain > 0) {
1166  writeInto.writeUnsignedByte(s.contextDomain);
1167  }
1168  writeInto.writeUnsignedByte(numVars);
1169  if (s.contextDomain > 0) {
1170  writeInto.writeInt((int)objIDs.size() - skipped);
1171  }
1172  if (s.contextDomain == 0 || objIDs.size() != 0) {
1173  writeInto.writeStorage(outputStorage);
1174  }
1175  return ok;
1176 }
1177 
1178 
1179 bool
1180 TraCIServer::addObjectVariableSubscription(const int commandId, const bool hasContext) {
1181  const double beginTime = myInputStorage.readDouble();
1182  const double endTime = myInputStorage.readDouble();
1183  const SUMOTime begin = beginTime == libsumo::INVALID_DOUBLE_VALUE ? 0 : TIME2STEPS(beginTime);
1184  const SUMOTime end = endTime == libsumo::INVALID_DOUBLE_VALUE || endTime > STEPS2TIME(SUMOTime_MAX) ? SUMOTime_MAX : TIME2STEPS(endTime);
1185  const std::string id = myInputStorage.readString();
1186  const int domain = hasContext ? myInputStorage.readUnsignedByte() : 0;
1187  const double range = hasContext ? myInputStorage.readDouble() : 0.;
1188  const int num = myInputStorage.readUnsignedByte();
1189  std::vector<int> variables;
1190  std::vector<std::vector<unsigned char> > parameters;
1191  for (int i = 0; i < num; ++i) {
1192  const int varID = myInputStorage.readUnsignedByte();
1193  variables.push_back(varID);
1194  parameters.push_back(std::vector<unsigned char>());
1195  for (int j = 0; j < myParameterSizes[varID]; j++) {
1196  parameters.back().push_back(myInputStorage.readChar());
1197  }
1198  }
1199  // check subscribe/unsubscribe
1200  if (variables.size() == 0) {
1201  removeSubscription(commandId, id, -1);
1202  return true;
1203  }
1204  // process subscription
1205  libsumo::Subscription s(commandId, id, variables, parameters, begin, end, domain, range);
1207  return true;
1208 }
1209 
1210 
1211 
1212 bool
1214  bool success = true;
1215  if (myLastContextSubscription == nullptr) {
1216  WRITE_WARNING("addSubscriptionFilter: No previous vehicle context subscription exists to apply the context filter.");
1217  return true;
1218  }
1219  // Read filter type
1220  int filterType = myInputStorage.readUnsignedByte();
1221 
1222  // dispatch according to filter type
1223  switch (filterType) {
1225  // Remove all filters
1226  removeFilters();
1227  break;
1229  // Read relative lanes to consider for context filter
1230  int nrLanes = (int)myInputStorage.readByte();
1231  std::vector<int> lanes;
1232  for (int i = 0; i < nrLanes; ++i) {
1233  lanes.push_back((int) myInputStorage.readByte());
1234  }
1236  }
1237  break;
1239  // Add no-opposite filter
1241  break;
1243  myInputStorage.readByte(); // read type double
1244  double dist = myInputStorage.readDouble();
1246  }
1247  break;
1249  myInputStorage.readByte(); // read type double
1250  double dist = myInputStorage.readDouble();
1252  }
1253  break;
1255  // Read relative lanes to consider for context filter
1257  }
1258  break;
1261  break;
1263  myInputStorage.readByte(); // read type stringlist
1265  addSubscriptionFilterVClass(vClasses);
1266  }
1267  break;
1269  myInputStorage.readByte(); // read type stringlist
1270  std::vector<std::string> vTypesVector = myInputStorage.readStringList();
1271  std::set<std::string> vTypesSet;
1272  vTypesSet.insert(vTypesVector.begin(), vTypesVector.end());
1273  addSubscriptionFilterVType(vTypesSet);
1274  }
1275  break;
1276  default:
1277  writeStatusCmd(filterType, libsumo::RTYPE_NOTIMPLEMENTED, "'" + toString(filterType) + "' is no valid filter type code.");
1278  success = false;
1279  }
1280 
1281  if (success) {
1282  // acknowledge filter addition
1284  }
1285 
1286  return success;
1287 }
1288 
1289 
1290 void
1292 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1293  std::cout << "Removing filters" << std::endl;
1294 #endif
1296 }
1297 
1298 void
1300 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1301  std::cout << "Adding lane filter (lanes=" << toString(lanes) << ")" << std::endl;
1302 #endif
1305 }
1306 
1307 void
1309 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1310  std::cout << "Adding no opposite filter" << std::endl;
1311 #endif
1313 }
1314 
1315 void
1317 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1318  std::cout << "Adding downstream dist filter (dist=" << toString(dist) << ")" << std::endl;
1319 #endif
1322 }
1323 
1324 void
1326 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1327  std::cout << "Adding upstream dist filter (dist=" << toString(dist) << ")" << std::endl;
1328 #endif
1331 }
1332 
1333 void
1335 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1336  std::cout << "Adding Lead/Follow-maneuver filter" << std::endl;
1337 #endif
1339 }
1340 
1341 void
1343 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1344  std::cout << "Adding turn-maneuver filter" << std::endl;
1345 #endif
1347 }
1348 
1349 void
1351 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1352  std::cout << "Adding vClass filter (vClasses=" << toString(vClasses) << ")" << std::endl;
1353 #endif
1356 }
1357 
1358 void
1359 TraCIServer::addSubscriptionFilterVType(std::set<std::string> vTypes) {
1360 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1361  std::cout << "Adding vType filter (vTypes=" << toString(vTypes) << ")" << std::endl;
1362 #endif
1365 }
1366 
1367 void
1369  if (tempMsg.size() < 254) {
1370  outputStorage.writeUnsignedByte(1 + (int)tempMsg.size()); // command length -> short
1371  } else {
1372  outputStorage.writeUnsignedByte(0); // command length -> extended
1373  outputStorage.writeInt(1 + 4 + (int)tempMsg.size());
1374  }
1375  outputStorage.writeStorage(tempMsg);
1376 }
1377 
1378 
1379 void
1382  if (shape.size() < 256) {
1383  outputStorage.writeUnsignedByte((int)shape.size());
1384  } else {
1385  outputStorage.writeUnsignedByte(0);
1386  outputStorage.writeInt((int)shape.size());
1387  }
1388  for (const libsumo::TraCIPosition& pos : shape) {
1389  outputStorage.writeDouble(pos.x);
1390  outputStorage.writeDouble(pos.y);
1391  }
1392 }
1393 
1394 
1395 bool
1397  if (inputStorage.readUnsignedByte() != libsumo::TYPE_INTEGER) {
1398  return false;
1399  }
1400  into = inputStorage.readInt();
1401  return true;
1402 }
1403 
1404 
1405 bool
1407  if (inputStorage.readUnsignedByte() != libsumo::TYPE_DOUBLE) {
1408  return false;
1409  }
1410  into = inputStorage.readDouble();
1411  return true;
1412 }
1413 
1414 
1415 bool
1416 TraCIServer::readTypeCheckingString(tcpip::Storage& inputStorage, std::string& into) {
1417  if (inputStorage.readUnsignedByte() != libsumo::TYPE_STRING) {
1418  return false;
1419  }
1420  into = inputStorage.readString();
1421  return true;
1422 }
1423 
1424 
1425 bool
1426 TraCIServer::readTypeCheckingStringList(tcpip::Storage& inputStorage, std::vector<std::string>& into) {
1427  if (inputStorage.readUnsignedByte() != libsumo::TYPE_STRINGLIST) {
1428  return false;
1429  }
1430  into = inputStorage.readStringList();
1431  return true;
1432 }
1433 
1434 
1435 bool
1436 TraCIServer::readTypeCheckingDoubleList(tcpip::Storage& inputStorage, std::vector<double>& into) {
1437  if (inputStorage.readUnsignedByte() != libsumo::TYPE_DOUBLELIST) {
1438  return false;
1439  }
1440  into = inputStorage.readDoubleList();
1441  return true;
1442 }
1443 
1444 
1445 bool
1447  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COLOR) {
1448  return false;
1449  }
1450  into.r = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1451  into.g = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1452  into.b = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1453  into.a = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1454  return true;
1455 }
1456 
1457 
1458 bool
1460  if (inputStorage.readUnsignedByte() != libsumo::POSITION_2D) {
1461  return false;
1462  }
1463  into.x = inputStorage.readDouble();
1464  into.y = inputStorage.readDouble();
1465  into.z = 0;
1466  return true;
1467 }
1468 
1469 
1470 bool
1472  if (inputStorage.readByte() != libsumo::TYPE_BYTE) {
1473  return false;
1474  }
1475  into = inputStorage.readByte();
1476  return true;
1477 }
1478 
1479 
1480 bool
1482  if (inputStorage.readUnsignedByte() != libsumo::TYPE_UBYTE) {
1483  return false;
1484  }
1485  into = inputStorage.readUnsignedByte();
1486  return true;
1487 }
1488 
1489 
1490 bool
1492  if (inputStorage.readUnsignedByte() != libsumo::TYPE_POLYGON) {
1493  return false;
1494  }
1495  into.clear();
1496  int size = inputStorage.readUnsignedByte();
1497  if (size == 0) {
1498  size = inputStorage.readInt();
1499  }
1500  PositionVector shape;
1501  for (int i = 0; i < size; ++i) {
1502  double x = inputStorage.readDouble();
1503  double y = inputStorage.readDouble();
1504  if (std::isnan(x) || std::isnan(y)) {
1505  throw libsumo::TraCIException("NaN-Value in shape.");
1506  }
1507  into.push_back(Position(x, y));
1508  }
1509  return true;
1510 }
1511 
1512 
1513 void
1515  myTargetTime = targetTime;
1516  for (auto& s : mySockets) {
1517  s.second->targetTime = targetTime;
1518  }
1519 }
1520 
1521 
1522 bool
1523 TraCIServer::centralObject(const libsumo::Subscription& s, const std::string& objID) {
1524  return (s.id == objID && s.commandId + 32 == s.contextDomain);
1525 }
1526 
1527 
1528 /****************************************************************************/
libsumo::CMD_SUBSCRIBE_VEHICLETYPE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_VEHICLETYPE_VARIABLE
Definition: TraCIConstants.h:171
libsumo::CMD_GET_TL_VARIABLE
TRACI_CONST int CMD_GET_TL_VARIABLE
Definition: TraCIConstants.h:120
libsumo::FILTER_TYPE_VCLASS
TRACI_CONST int FILTER_TYPE_VCLASS
Definition: TraCIConstants.h:487
TraCIServer::addSubscriptionFilterUpstreamDistance
void addSubscriptionFilterUpstreamDistance(double dist)
Definition: TraCIServer.cpp:1325
libsumo::RTYPE_OK
TRACI_CONST int RTYPE_OK
Definition: TraCIConstants.h:353
TraCIServerAPI_Route::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change Route State)
Definition: TraCIServerAPI_Route.cpp:69
tcpip::Storage::readDouble
virtual double readDouble()
libsumo::Subscription::activeFilters
int activeFilters
Active filters for the subscription (bitset,.
Definition: Subscription.h:101
TraCIServer::wrapRoadPosition
bool wrapRoadPosition(const std::string &objID, const int variable, const libsumo::TraCIRoadPosition &value)
Definition: TraCIServer.cpp:168
libsumo::CMD_GET_POLYGON_VARIABLE
TRACI_CONST int CMD_GET_POLYGON_VARIABLE
Definition: TraCIConstants.h:210
TraCIServerAPI_TrafficLight.h
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:74
libsumo::CMD_SET_GUI_VARIABLE
TRACI_CONST int CMD_SET_GUI_VARIABLE
Definition: TraCIConstants.h:274
TraCIServer::myVehicleStateChanges
std::map< MSNet::VehicleState, std::vector< std::string > > myVehicleStateChanges
Changes in the states of simulated vehicles.
Definition: TraCIServer.h:397
TraCIServerAPI_Route.h
libsumo::TYPE_COLOR
TRACI_CONST int TYPE_COLOR
Definition: TraCIConstants.h:346
TraCIServerAPI_Vehicle.h
MSNet::VEHICLE_STATE_DEPARTED
The vehicle has departed (was inserted into the network)
Definition: MSNet.h:540
TraCIServer::setTargetTime
void setTargetTime(SUMOTime targetTime)
Sets myTargetTime on server and sockets to the given value.
Definition: TraCIServer.cpp:1514
TraCIServerAPI_Vehicle::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
Definition: TraCIServerAPI_Vehicle.cpp:295
libsumo::Subscription::filterUpstreamDist
double filterUpstreamDist
Upstream distance specified by the upstream distance filter.
Definition: Subscription.h:107
TraCIServer::checkClientOrdering
void checkClientOrdering()
Called once after connection of all clients for executing SET_ORDER (and possibly prior GET_VERSION) ...
Definition: TraCIServer.cpp:333
TraCIServer::TraCIServer
TraCIServer(const SUMOTime begin, const int port, const int numClients)
Constructor.
Definition: TraCIServer.cpp:181
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
libsumo::CMD_SUBSCRIBE_VEHICLE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_VARIABLE
Definition: TraCIConstants.h:156
tcpip::Socket
Definition: socket.h:59
SUMOTime.h
MSTLLogicControl.h
MSNet.h
libsumo::INVALID_DOUBLE_VALUE
TRACI_CONST double INVALID_DOUBLE_VALUE
Definition: TraCIConstants.h:363
TraCIServerAPI_VehicleType::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa5: Get Vehicle Type Variable)
Definition: TraCIServerAPI_VehicleType.cpp:42
libsumo::POSITION_3D
TRACI_CONST int POSITION_3D
Definition: TraCIConstants.h:319
TraCIServer::readTypeCheckingUnsignedByte
bool readTypeCheckingUnsignedByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and an unsigned byte, verifying the type.
Definition: TraCIServer.cpp:1481
TraCIServer::addSubscriptionFilter
bool addSubscriptionFilter()
Definition: TraCIServer.cpp:1213
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
libsumo::TraCIPosition
A 3D-position.
Definition: TraCIDefs.h:110
libsumo::Subscription::filterDownstreamDist
double filterDownstreamDist
Downstream distance specified by the downstream distance filter.
Definition: Subscription.h:105
libsumo::TraCIPosition::x
double x
Definition: TraCIDefs.h:116
TraCIServer::removeFilters
void removeFilters()
Definition: TraCIServer.cpp:1291
libsumo::CMD_CLOSE
TRACI_CONST int CMD_CLOSE
Definition: TraCIConstants.h:83
libsumo::CMD_SUBSCRIBE_ROUTE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_ROUTE_CONTEXT
Definition: TraCIConstants.h:176
tcpip::Storage::writeUnsignedByte
virtual void writeUnsignedByte(int)
TraCIServer::dispatchCommand
int dispatchCommand()
Handles command, writes response to myOutputStorage.
Definition: TraCIServer.cpp:714
TraCIServer::myInstance
static TraCIServer * myInstance
Singleton instance of the server.
Definition: TraCIServer.h:343
libsumo::SUBS_FILTER_VCLASS
Definition: Subscription.h:51
TraCIServerAPI_Simulation::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xab: Get Simulation Variable)
Definition: TraCIServerAPI_Simulation.cpp:48
TraCIServerAPI_InductionLoop.h
TraCIServer::readTypeCheckingColor
bool readTypeCheckingColor(tcpip::Storage &inputStorage, libsumo::TraCIColor &into)
Reads the value type and a color, verifying the type.
Definition: TraCIServer.cpp:1446
TraCIServer::addSubscriptionFilterNoOpposite
void addSubscriptionFilterNoOpposite()
Definition: TraCIServer.cpp:1308
TraCIServer::addObjectVariableSubscription
bool addObjectVariableSubscription(const int commandId, const bool hasContext)
Definition: TraCIServer.cpp:1180
SUMOTrafficObject::getID
virtual const std::string & getID() const =0
Get the vehicle's ID.
MsgHandler.h
TraCIServer::mySocketReorderRequests
std::map< int, SocketInfo * > mySocketReorderRequests
This stores the setOrder(int) requests of the clients.
Definition: TraCIServer.h:356
libsumo::CMD_GET_PERSON_VARIABLE
TRACI_CONST int CMD_GET_PERSON_VARIABLE
Definition: TraCIConstants.h:298
libsumo::TraCIColor::a
int a
Definition: TraCIDefs.h:144
tcpip::Storage::readStringList
virtual std::vector< std::string > readStringList()
libsumo::CMD_SET_POI_VARIABLE
TRACI_CONST int CMD_SET_POI_VARIABLE
Definition: TraCIConstants.h:199
TraCIServer::commandGetVersion
bool commandGetVersion()
Returns the TraCI-version.
Definition: TraCIServer.cpp:862
TraCIServerAPI_Simulation.h
TraCIServer::readTypeCheckingString
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
Definition: TraCIServer.cpp:1416
libsumo::TraCIColor::g
int g
Definition: TraCIDefs.h:144
TraCIServerAPI_Polygon.h
libsumo::CMD_SET_POLYGON_VARIABLE
TRACI_CONST int CMD_SET_POLYGON_VARIABLE
Definition: TraCIConstants.h:214
TraCIServer::writeResponseWithLength
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
Definition: TraCIServer.cpp:1368
TraCIServerAPI_Polygon::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc8: Change Polygon State)
Definition: TraCIServerAPI_Polygon.cpp:75
libsumo::Subscription::filterLanes
std::vector< int > filterLanes
lanes specified by the lanes filter
Definition: Subscription.h:103
MsgHandler::inform
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:118
libsumo::CMD_GET_LANEAREA_VARIABLE
TRACI_CONST int CMD_GET_LANEAREA_VARIABLE
Definition: TraCIConstants.h:285
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:35
SUMOVehicle
Representation of a vehicle.
Definition: SUMOVehicle.h:61
tcpip::Storage::valid_pos
virtual bool valid_pos()
libsumo::Subscription::id
std::string id
The id of the object that is subscribed.
Definition: Subscription.h:86
libsumo::CMD_SET_SIM_VARIABLE
TRACI_CONST int CMD_SET_SIM_VARIABLE
Definition: TraCIConstants.h:259
TraCIServer::wrapDouble
bool wrapDouble(const std::string &objID, const int variable, const double value)
Definition: TraCIServer.cpp:112
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
tcpip::Storage::writePacket
virtual void writePacket(unsigned char *packet, int length)
tcpip::Storage::end
StorageType::const_iterator end() const
Definition: storage.h:120
libsumo::TYPE_DOUBLELIST
TRACI_CONST int TYPE_DOUBLELIST
Definition: TraCIConstants.h:344
MSJunctionControl.h
libsumo::CMD_SUBSCRIBE_PERSON_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_PERSON_CONTEXT
Definition: TraCIConstants.h:294
libsumo::TYPE_BYTE
TRACI_CONST int TYPE_BYTE
Definition: TraCIConstants.h:332
libsumo::CMD_SUBSCRIBE_JUNCTION_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_JUNCTION_VARIABLE
Definition: TraCIConstants.h:231
libsumo::Subscription::endTime
SUMOTime endTime
The end time of the subscription.
Definition: Subscription.h:94
TraCIServer::mySubscriptions
std::vector< libsumo::Subscription > mySubscriptions
The list of known, still valid subscriptions.
Definition: TraCIServer.h:385
TraCIServerAPI_MultiEntryExit::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa1: Get MeMeDetector Variable)
Definition: TraCIServerAPI_MultiEntryExit.cpp:35
tcpip::Socket::accept
Socket * accept(const bool create=false)
Wait for a incoming connection to port_.
Definition: socket.cpp:265
libsumo::Helper::applySubscriptionFilters
static void applySubscriptionFilters(const Subscription &s, std::set< std::string > &objIDs)
Filter the given ID-Set (which was obtained from an R-Tree search) according to the filters set by th...
Definition: Helper.cpp:484
MSEdge.h
libsumo::TraCIColor
A color.
Definition: TraCIDefs.h:136
TraCIServer::addSubscriptionFilterLeadFollow
void addSubscriptionFilterLeadFollow()
Definition: TraCIServer.cpp:1334
tcpip::Storage::readChar
virtual unsigned char readChar()
libsumo::CMD_SUBSCRIBE_POI_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_POI_CONTEXT
Definition: TraCIConstants.h:191
libsumo::CMD_SUBSCRIBE_PERSON_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_PERSON_VARIABLE
Definition: TraCIConstants.h:304
libsumo::VAR_LEADER
TRACI_CONST int VAR_LEADER
Definition: TraCIConstants.h:817
libsumo::CMD_SUBSCRIBE_LANEAREA_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_CONTEXT
Definition: TraCIConstants.h:281
libsumo::CMD_GET_LANE_VARIABLE
TRACI_CONST int CMD_GET_LANE_VARIABLE
Definition: TraCIConstants.h:135
TraCIServer::myTargetTime
SUMOTime myTargetTime
The time step to reach until processing the next commands.
Definition: TraCIServer.h:362
PositionVector
A list of positions.
Definition: PositionVector.h:46
MSNet::VEHICLE_STATE_ARRIVED
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:546
libsumo::CMD_SUBSCRIBE_VEHICLE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_CONTEXT
Definition: TraCIConstants.h:146
libsumo::TraCIColor::b
int b
Definition: TraCIDefs.h:144
TraCIServer::close
static void close()
request termination of connection
Definition: TraCIServer.cpp:302
MSNet::VEHICLE_STATE_NEWROUTE
The vehicle got a new route.
Definition: MSNet.h:548
TraCIServer::getWrapperStorage
tcpip::Storage & getWrapperStorage()
Definition: TraCIServer.cpp:175
TraCIServer::removeCurrentSocket
std::map< int, SocketInfo * >::iterator removeCurrentSocket()
removes myCurrentSocket from mySockets and returns an iterator pointing to the next member according ...
Definition: TraCIServer.cpp:666
TraCIServerAPI_VehicleType.h
libsumo::CMD_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_GET_VEHICLE_VARIABLE
Definition: TraCIConstants.h:150
libsumo::CMD_SET_VEHICLE_VARIABLE
TRACI_CONST int CMD_SET_VEHICLE_VARIABLE
Definition: TraCIConstants.h:154
libsumo::CMD_GET_VEHICLETYPE_VARIABLE
TRACI_CONST int CMD_GET_VEHICLETYPE_VARIABLE
Definition: TraCIConstants.h:165
TraCIServer::addSubscriptionFilterLanes
void addSubscriptionFilterLanes(std::vector< int > lanes)
Definition: TraCIServer.cpp:1299
libsumo::Subscription::variables
std::vector< int > variables
The subscribed variables.
Definition: Subscription.h:88
libsumo::CMD_ADD_SUBSCRIPTION_FILTER
TRACI_CONST int CMD_ADD_SUBSCRIPTION_FILTER
Definition: TraCIConstants.h:86
TraCIServer::readCommandID
int readCommandID(int &commandStart, int &commandLength)
Reads the next command ID from the input storage.
Definition: TraCIServer.cpp:696
TraCIServer::readTypeCheckingDouble
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
Definition: TraCIServer.cpp:1406
libsumo::SUBS_FILTER_NOOPPOSITE
Definition: Subscription.h:41
MSNet::VEHICLE_STATE_EMERGENCYSTOP
The vehicle had to brake harder than permitted.
Definition: MSNet.h:560
TraCIServer::initialiseSubscription
void initialiseSubscription(libsumo::Subscription &s)
Definition: TraCIServer.cpp:988
MSVehicle.h
libsumo::SUBS_FILTER_NONE
Definition: Subscription.h:37
SUMOVehicleParameter.h
libsumo::FILTER_TYPE_UPSTREAM_DIST
TRACI_CONST int FILTER_TYPE_UPSTREAM_DIST
Definition: TraCIConstants.h:478
TraCIServer::mySubscriptionCache
tcpip::Storage mySubscriptionCache
The last timestep's subscription results.
Definition: TraCIServer.h:374
tcpip::Storage::writeByte
virtual void writeByte(int)
TraCIServer::writeStatusCmd
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
Definition: TraCIServer.cpp:967
libsumo::Subscription::parameters
std::vector< std::vector< unsigned char > > parameters
The parameters for the subscribed variables.
Definition: Subscription.h:90
TraCIServer::~TraCIServer
virtual ~TraCIServer()
Destructor.
Definition: TraCIServer.cpp:273
libsumo::CMD_SUBSCRIBE_EDGE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_EDGE_VARIABLE
Definition: TraCIConstants.h:246
libsumo::FILTER_TYPE_LEAD_FOLLOW
TRACI_CONST int FILTER_TYPE_LEAD_FOLLOW
Definition: TraCIConstants.h:481
parseVehicleClasses
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
Definition: SUMOVehicleClass.cpp:223
libsumo::FILTER_TYPE_NOOPPOSITE
TRACI_CONST int FILTER_TYPE_NOOPPOSITE
Definition: TraCIConstants.h:472
MSTransportableControl::get
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
Definition: MSTransportableControl.cpp:76
TraCIServerAPI_POI::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc7: Change PoI State)
Definition: TraCIServerAPI_POI.cpp:71
TraCIServer::initWrapper
void initWrapper(const int domainID, const int variable, const std::string &objID)
Definition: TraCIServer.cpp:103
TraCIServerAPI_Simulation::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xcb: Set Simulation Variable)
Definition: TraCIServerAPI_Simulation.cpp:288
libsumo::CMD_SUBSCRIBE_POLYGON_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_POLYGON_CONTEXT
Definition: TraCIConstants.h:206
libsumo::CMD_SETORDER
TRACI_CONST int CMD_SETORDER
Definition: TraCIConstants.h:56
TraCIServer::SocketInfo
Definition: TraCIServer.h:279
libsumo::Subscription::commandId
int commandId
commandIdArg The command id of the subscription
Definition: Subscription.h:84
TraCIServer::myInputStorage
tcpip::Storage myInputStorage
The storage to read from.
Definition: TraCIServer.h:365
libsumo::CMD_SUBSCRIBE_SIM_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_SIM_CONTEXT
Definition: TraCIConstants.h:251
libsumo::SUBS_FILTER_TURN
Definition: Subscription.h:49
TraCIServer::centralObject
bool centralObject(const libsumo::Subscription &s, const std::string &objID)
check whether a found objID refers to the central object of a context subscription
Definition: TraCIServer.cpp:1523
TraCIServer::addSubscriptionFilterVType
void addSubscriptionFilterVType(std::set< std::string > vTypes)
Definition: TraCIServer.cpp:1359
tcpip::Storage::readUnsignedByte
virtual int readUnsignedByte()
TraCIServer::readTypeCheckingDoubleList
bool readTypeCheckingDoubleList(tcpip::Storage &inputStorage, std::vector< double > &into)
Reads the value type and a double list, verifying the type.
Definition: TraCIServer.cpp:1436
Simulation.h
tcpip::Storage::writeInt
virtual void writeInt(int)
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:64
libsumo::CMD_GETVERSION
TRACI_CONST int CMD_GETVERSION
Definition: TraCIConstants.h:47
TraCIServer::readTypeCheckingPolygon
bool readTypeCheckingPolygon(tcpip::Storage &inputStorage, PositionVector &into)
Reads the value type and a polygon, verifying the type.
Definition: TraCIServer.cpp:1491
libsumo::FILTER_TYPE_TURN
TRACI_CONST int FILTER_TYPE_TURN
Definition: TraCIConstants.h:484
MSNet::VEHICLE_STATE_STARTING_PARKING
The vehicles starts to park.
Definition: MSNet.h:550
libsumo::TYPE_DOUBLE
TRACI_CONST int TYPE_DOUBLE
Definition: TraCIConstants.h:336
libsumo::TYPE_POLYGON
TRACI_CONST int TYPE_POLYGON
Definition: TraCIConstants.h:328
tcpip::Storage::position
virtual unsigned int position() const
libsumo::CMD_GET_POI_VARIABLE
TRACI_CONST int CMD_GET_POI_VARIABLE
Definition: TraCIConstants.h:195
TraCIServerAPI_Vehicle::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
Definition: TraCIServerAPI_Vehicle.cpp:59
tcpip::Storage::readString
virtual std::string readString()
TraCIConstants.h
TraCIServer::readTypeCheckingByte
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
Definition: TraCIServer.cpp:1471
libsumo::CMD_SUBSCRIBE_GUI_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_GUI_VARIABLE
Definition: TraCIConstants.h:276
TraCIServer::wrapPosition
bool wrapPosition(const std::string &objID, const int variable, const libsumo::TraCIPosition &value)
Definition: TraCIServer.cpp:144
libsumo::SUBS_FILTER_UPSTREAM_DIST
Definition: Subscription.h:45
libsumo::CMD_SUBSCRIBE_SIM_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_SIM_VARIABLE
Definition: TraCIConstants.h:261
libsumo::Subscription
Representation of a subscription.
Definition: Subscription.h:65
tcpip::Storage::readInt
virtual int readInt()
libsumo::FILTER_TYPE_VTYPE
TRACI_CONST int FILTER_TYPE_VTYPE
Definition: TraCIConstants.h:490
SVCPermissions
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
Definition: SUMOVehicleClass.h:219
libsumo::TYPE_INTEGER
TRACI_CONST int TYPE_INTEGER
Definition: TraCIConstants.h:334
MSTransportableControl.h
TIME2STEPS
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
MSNet::VehicleState
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:536
MSJunction.h
MsgHandler::getWarningInstance
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:72
libsumo::CMD_SET_VEHICLETYPE_VARIABLE
TRACI_CONST int CMD_SET_VEHICLETYPE_VARIABLE
Definition: TraCIConstants.h:169
tcpip::Storage::writeStorage
virtual void writeStorage(tcpip::Storage &store)
TraCIServer::myOutputStorage
tcpip::Storage myOutputStorage
The storage to write to.
Definition: TraCIServer.h:368
MSNet::getCurrentTimeStep
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:284
TraCIServer::addSubscriptionFilterDownstreamDistance
void addSubscriptionFilterDownstreamDistance(double dist)
Definition: TraCIServer.cpp:1316
libsumo::Subscription::filterVClasses
int filterVClasses
vClasses specified by the vClasses filter,
Definition: Subscription.h:111
tcpip::Storage::writeStringList
virtual void writeStringList(const std::vector< std::string > &s)
STEPS2TIME
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
libsumo::CMD_SUBSCRIBE_VEHICLETYPE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_VEHICLETYPE_CONTEXT
Definition: TraCIConstants.h:161
TraCIServer::postProcessSimulationStep
void postProcessSimulationStep()
Handles subscriptions to send after a simstep2 command.
Definition: TraCIServer.cpp:881
libsumo::CMD_SET_LANE_VARIABLE
TRACI_CONST int CMD_SET_LANE_VARIABLE
Definition: TraCIConstants.h:139
libsumo::FILTER_TYPE_NONE
TRACI_CONST int FILTER_TYPE_NONE
Definition: TraCIConstants.h:466
TraCIServerAPI_InductionLoop::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa0: Get Induction Loop Variable)
Definition: TraCIServerAPI_InductionLoop.cpp:38
libsumo::RTYPE_ERR
TRACI_CONST int RTYPE_ERR
Definition: TraCIConstants.h:357
TraCIServer::vehicleStateChanged
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to, const std::string &info="")
Called if a vehicle changes its state.
Definition: TraCIServer.cpp:322
TraCIServer::myDoCloseConnection
static bool myDoCloseConnection
Whether the connection was set to be to close.
Definition: TraCIServer.h:346
libsumo::TraCIPosition::z
double z
Definition: TraCIDefs.h:116
TraCIServer::myLoadArgs
std::vector< std::string > myLoadArgs
Definition: TraCIServer.h:382
libsumo::CMD_SUBSCRIBE_POLYGON_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_POLYGON_VARIABLE
Definition: TraCIConstants.h:216
MSNet::addVehicleStateListener
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:865
libsumo::CMD_SUBSCRIBE_LANEAREA_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_VARIABLE
Definition: TraCIConstants.h:289
ProcessError
Definition: UtilExceptions.h:40
MSNet::VEHICLE_STATE_COLLISION
The vehicle is involved in a collision.
Definition: MSNet.h:558
toHex
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:58
MSNet::VEHICLE_STATE_STARTING_TELEPORT
The vehicle started to teleport.
Definition: MSNet.h:542
libsumo::CMD_SET_TL_VARIABLE
TRACI_CONST int CMD_SET_TL_VARIABLE
Definition: TraCIConstants.h:124
libsumo::CMD_SET_PERSON_VARIABLE
TRACI_CONST int CMD_SET_PERSON_VARIABLE
Definition: TraCIConstants.h:302
MSNet::VEHICLE_STATE_BUILT
The vehicle was built, but has not yet departed.
Definition: MSNet.h:538
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
libsumo::CMD_GET_SIM_VARIABLE
TRACI_CONST int CMD_GET_SIM_VARIABLE
Definition: TraCIConstants.h:255
MSNet::VEHICLE_STATE_STARTING_STOP
The vehicles starts to stop.
Definition: MSNet.h:554
TraCIServer::wrapColor
bool wrapColor(const std::string &objID, const int variable, const libsumo::TraCIColor &value)
Definition: TraCIServer.cpp:157
libsumo::TRACI_ID_LIST
TRACI_CONST int TRACI_ID_LIST
Definition: TraCIConstants.h:496
TraCIServer::myParameterSizes
std::map< int, int > myParameterSizes
Map of variable ids to the size of the parameter in bytes.
Definition: TraCIServer.h:380
MSGlobals.h
TraCIServerAPI_LaneArea.h
TraCIServerAPI_VehicleType::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc5: Change Vehicle Type State)
Definition: TraCIServerAPI_VehicleType.cpp:76
libsumo::TraCIColor::r
int r
Definition: TraCIDefs.h:144
libsumo::Subscription::beginTime
SUMOTime beginTime
The begin time of the subscription.
Definition: Subscription.h:92
tcpip::Storage::reset
void reset()
libsumo::CMD_SUBSCRIBE_JUNCTION_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_JUNCTION_CONTEXT
Definition: TraCIConstants.h:221
TraCIServerAPI_Route::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get Route Variable)
Definition: TraCIServerAPI_Route.cpp:38
TraCIServer::processReorderingRequests
void processReorderingRequests()
checks for and processes reordering requests (relevant for multiple clients)
Definition: TraCIServer.cpp:400
TraCIServer::myWrapperStorage
tcpip::Storage myWrapperStorage
A temporary storage to let the wrapper write to.
Definition: TraCIServer.h:371
TraCIServer::mySockets
std::map< int, SocketInfo * > mySockets
The socket connections to the clients the first component (index) determines the client's order (lowe...
Definition: TraCIServer.h:353
TraCIServer::cleanup
void cleanup()
clean up subscriptions
Definition: TraCIServer.cpp:648
TraCIServer::processSingleSubscription
bool processSingleSubscription(const libsumo::Subscription &s, tcpip::Storage &writeInto, std::string &errors)
Definition: TraCIServer.cpp:1078
libsumo::SUBS_FILTER_LANES
Definition: Subscription.h:39
TraCIServer::readTypeCheckingStringList
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
Definition: TraCIServer.cpp:1426
TraCIServer::processCommandsUntilSimStep
void processCommandsUntilSimStep(SUMOTime step)
process all commands until the next SUMO simulation step. It is guaranteed that t->getTargetTime() >=...
Definition: TraCIServer.cpp:490
string2time
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
libsumo::CMD_SUBSCRIBE_GUI_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_GUI_CONTEXT
Definition: TraCIConstants.h:266
libsumo::TraCIException
Definition: TraCIDefs.h:90
libsumo::CMD_SUBSCRIBE_POI_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_POI_VARIABLE
Definition: TraCIConstants.h:201
TraCIServer::openSocket
static void openSocket(const std::map< int, CmdExecutor > &execs)
Initialises the server.
Definition: TraCIServer.cpp:284
libsumo::SUBS_FILTER_NO_RTREE
Definition: Subscription.h:55
TraCIServer::writePositionVector
void writePositionVector(tcpip::Storage &outputStorage, const libsumo::TraCIPositionVector &shape)
Definition: TraCIServer.cpp:1380
TraCIServerAPI_Person::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xce: Change Person State)
Definition: TraCIServerAPI_Person.cpp:92
libsumo::TYPE_STRINGLIST
TRACI_CONST int TYPE_STRINGLIST
Definition: TraCIConstants.h:340
tcpip::SocketException
Definition: socket.h:53
MSGlobals::gUsingInternalLanes
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:69
TraCIServerAPI_MultiEntryExit.h
TraCIServerAPI_Edge::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xca: Change Edge State)
Definition: TraCIServerAPI_Edge.cpp:103
libsumo::CMD_SUBSCRIBE_TL_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_TL_CONTEXT
Definition: TraCIConstants.h:116
NamedObjectCont.h
TraCIServerAPI_Lane.h
tcpip::Storage::writeString
virtual void writeString(const std::string &s)
MSEdgeControl.h
TraCIServerAPI_Lane::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc3: Change Lane State)
Definition: TraCIServerAPI_Lane.cpp:138
libsumo::CMD_SUBSCRIBE_ROUTE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_ROUTE_VARIABLE
Definition: TraCIConstants.h:186
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
TraCIServer::myCurrentSocket
std::map< int, SocketInfo * >::iterator myCurrentSocket
The currently active client socket.
Definition: TraCIServer.h:359
libsumo::CMD_GET_GUI_VARIABLE
TRACI_CONST int CMD_GET_GUI_VARIABLE
Definition: TraCIConstants.h:270
libsumo::Helper::collectObjectsInRange
static void collectObjectsInRange(int domain, const PositionVector &shape, double range, std::set< std::string > &into)
Definition: Helper.cpp:425
PointOfInterest.h
TraCIServer::myLastContextSubscription
libsumo::Subscription * myLastContextSubscription
The last modified context subscription (the one to add a filter to, see @addSubscriptionFilter(),...
Definition: TraCIServer.h:388
TraCIServer::addSubscriptionFilterVClass
void addSubscriptionFilterVClass(SVCPermissions vClasses)
Definition: TraCIServer.cpp:1350
TraCIServer::readTypeCheckingInt
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
Definition: TraCIServer.cpp:1396
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
MSNet::getPersonControl
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:798
libsumo::CMD_GET_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int CMD_GET_MULTIENTRYEXIT_VARIABLE
Definition: TraCIConstants.h:107
TraCIServerAPI_POI.h
tcpip::Storage::begin
StorageType::const_iterator begin() const
Definition: storage.h:119
libsumo::FILTER_TYPE_DOWNSTREAM_DIST
TRACI_CONST int FILTER_TYPE_DOWNSTREAM_DIST
Definition: TraCIConstants.h:475
libsumo::CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT
Definition: TraCIConstants.h:90
TraCIServerAPI_TrafficLight::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa2: Get Traffic Lights Variable)
Definition: TraCIServerAPI_TrafficLight.cpp:40
storage.h
libsumo::POSITION_2D
TRACI_CONST int POSITION_2D
Definition: TraCIConstants.h:315
libsumo::Subscription::range
double range
The range of the context.
Definition: Subscription.h:98
libsumo::CMD_GET_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_GET_INDUCTIONLOOP_VARIABLE
Definition: TraCIConstants.h:94
TraCIServer::sendOutputToAll
void sendOutputToAll() const
send out subscription results (actually just the content of myOutputStorage) to clients which will ac...
Definition: TraCIServer.cpp:468
TraCIServerAPI_LaneArea::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa1: Get AreaDetector Variable)
Definition: TraCIServerAPI_LaneArea.cpp:38
libsumo::TYPE_STRING
TRACI_CONST int TYPE_STRING
Definition: TraCIConstants.h:338
Subscription.h
TraCIServerAPI_Polygon::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa8: Get Polygon Variable)
Definition: TraCIServerAPI_Polygon.cpp:42
libsumo::MAX_ORDER
TRACI_CONST int MAX_ORDER
Definition: TraCIConstants.h:367
TraCIServerAPI_Junction.h
libsumo::CMD_SUBSCRIBE_LANE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_LANE_CONTEXT
Definition: TraCIConstants.h:131
libsumo::VAR_POSITION3D
TRACI_CONST int VAR_POSITION3D
Definition: TraCIConstants.h:619
MSNet::VEHICLE_STATE_ENDING_PARKING
The vehicle ends to park.
Definition: MSNet.h:552
libsumo::SUBS_FILTER_DOWNSTREAM_DIST
Definition: Subscription.h:43
libsumo::Helper::findObjectShape
static void findObjectShape(int domain, const std::string &id, PositionVector &shape)
Definition: Helper.cpp:392
TraCIServerAPI_Lane::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa3: Get Lane Variable)
Definition: TraCIServerAPI_Lane.cpp:45
libsumo::CMD_SET_EDGE_VARIABLE
TRACI_CONST int CMD_SET_EDGE_VARIABLE
Definition: TraCIConstants.h:244
libsumo::FILTER_TYPE_LANES
TRACI_CONST int FILTER_TYPE_LANES
Definition: TraCIConstants.h:469
libsumo::TYPE_UBYTE
TRACI_CONST int TYPE_UBYTE
Definition: TraCIConstants.h:330
libsumo::CMD_SUBSCRIBE_EDGE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_EDGE_CONTEXT
Definition: TraCIConstants.h:236
libsumo::CMD_SUBSCRIBE_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_VARIABLE
Definition: TraCIConstants.h:111
socket.h
MSNet::VEHICLE_STATE_ENDING_TELEPORT
The vehicle ended being teleported.
Definition: MSNet.h:544
TraCIServer.h
tcpip::Storage::size
StorageType::size_type size() const
Definition: storage.h:117
tcpip::Storage::readByte
virtual int readByte()
libsumo::CMD_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
Definition: TraCIConstants.h:98
libsumo::TraCIRoadPosition
An edgeId, position and laneIndex.
Definition: TraCIDefs.h:122
libsumo::Subscription::contextDomain
int contextDomain
The domain ID of the context.
Definition: Subscription.h:96
config.h
TraCIServer::wrapStringList
bool wrapStringList(const std::string &objID, const int variable, const std::vector< std::string > &value)
Definition: TraCIServer.cpp:136
TraCIServer::nextTargetTime
SUMOTime nextTargetTime() const
get the minimal next target time among all clients
Definition: TraCIServer.cpp:444
ShapeContainer.h
TraCIServerAPI_Person.h
TraCIServerAPI_Junction::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa9: Get Junction Variable)
Definition: TraCIServerAPI_Junction.cpp:38
libsumo::TRACI_VERSION
TRACI_CONST int TRACI_VERSION
Definition: TraCIConstants.h:41
RandHelper.h
DijkstraRouter.h
libsumo::CMD_SUBSCRIBE_MULTIENTRYEXIT_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_CONTEXT
Definition: TraCIConstants.h:103
libsumo::CMD_SUBSCRIBE_LANE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_LANE_VARIABLE
Definition: TraCIConstants.h:141
TraCIServer::myServerSocket
tcpip::Socket * myServerSocket
The server socket.
Definition: TraCIServer.h:349
TraCIServer::removeSubscription
void removeSubscription(int commandId, const std::string &identity, int domain)
Definition: TraCIServer.cpp:1048
tcpip::Storage::writeDouble
virtual void writeDouble(double)
libsumo::TraCIPositionVector
std::vector< TraCIPosition > TraCIPositionVector
Definition: TraCIDefs.h:150
TraCIServer::wrapInt
bool wrapInt(const std::string &objID, const int variable, const int value)
Definition: TraCIServer.cpp:120
TraCIServerAPI_TrafficLight::processSet
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc2: Change Traffic Lights State)
Definition: TraCIServerAPI_TrafficLight.cpp:203
TraCIServer::wasClosed
static bool wasClosed()
check whether close was requested
Definition: TraCIServer.cpp:313
TraCIServer
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:62
SUMOTime_MAX
#define SUMOTime_MAX
Definition: SUMOTime.h:36
MSLane.h
TraCIServerAPI_Person::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xae: Get Person Variable)
Definition: TraCIServerAPI_Person.cpp:43
TraCIServer::addSubscriptionFilterTurn
void addSubscriptionFilterTurn()
Definition: TraCIServer.cpp:1342
TraCIServerAPI_Edge.h
libsumo::SUBS_FILTER_LEAD_FOLLOW
Definition: Subscription.h:47
TraCIServerAPI_Edge::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xaa: Get Edge Variable)
Definition: TraCIServerAPI_Edge.cpp:48
TraCIServer::isVehicleToVehicleContextSubscription
bool isVehicleToVehicleContextSubscription(const libsumo::Subscription &s)
Definition: TraCIServer.cpp:1072
TraCIServer::sendSingleSimStepResponse
void sendSingleSimStepResponse()
sends an empty response to a simstep command to the current client. (This applies to a situation wher...
Definition: TraCIServer.cpp:940
libsumo::SUBS_FILTER_VTYPE
Definition: Subscription.h:53
TraCIServerAPI_POI::processGet
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa7: Get PoI Variable)
Definition: TraCIServerAPI_POI.cpp:40
libsumo::CMD_SUBSCRIBE_TL_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_TL_VARIABLE
Definition: TraCIConstants.h:126
tcpip::Storage::readDoubleList
virtual std::vector< double > readDoubleList()
libsumo::CMD_SET_ROUTE_VARIABLE
TRACI_CONST int CMD_SET_ROUTE_VARIABLE
Definition: TraCIConstants.h:184
VERSION_STRING
#define VERSION_STRING
Definition: config.h:207
libsumo::CMD_LOAD
TRACI_CONST int CMD_LOAD
Definition: TraCIConstants.h:50
TraCIServer::myExecutors
std::map< int, CmdExecutor > myExecutors
Map of commandIds -> their executors; applicable if the executor applies to the method footprint.
Definition: TraCIServer.h:377
libsumo::CMD_GET_EDGE_VARIABLE
TRACI_CONST int CMD_GET_EDGE_VARIABLE
Definition: TraCIConstants.h:240
TraCIServer::readTypeCheckingPosition2D
bool readTypeCheckingPosition2D(tcpip::Storage &inputStorage, libsumo::TraCIPosition &into)
Reads the value type and a 2D position, verifying the type.
Definition: TraCIServer.cpp:1459
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
MSNet::VEHICLE_STATE_ENDING_STOP
The vehicle ends to stop.
Definition: MSNet.h:556
WRITE_MESSAGE
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:240
libsumo::RTYPE_NOTIMPLEMENTED
TRACI_CONST int RTYPE_NOTIMPLEMENTED
Definition: TraCIConstants.h:355
tcpip::Storage
Definition: storage.h:36
TraCIServer::wrapString
bool wrapString(const std::string &objID, const int variable, const std::string &value)
Definition: TraCIServer.cpp:128
libsumo::CMD_SIMSTEP
TRACI_CONST int CMD_SIMSTEP
Definition: TraCIConstants.h:53
XMLSubSys.h
libsumo::Subscription::filterVTypes
std::set< std::string > filterVTypes
vTypes specified by the vTypes filter
Definition: Subscription.h:109
libsumo::CMD_GET_JUNCTION_VARIABLE
TRACI_CONST int CMD_GET_JUNCTION_VARIABLE
Definition: TraCIConstants.h:225
libsumo::CMD_GET_ROUTE_VARIABLE
TRACI_CONST int CMD_GET_ROUTE_VARIABLE
Definition: TraCIConstants.h:180
libsumo::TraCIPosition::y
double y
Definition: TraCIDefs.h:116
TraCIServer::writeErrorStatusCmd
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
Definition: TraCIServer.cpp:981