SUMO - Simulation of Urban MObility
TraCITestClient.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00012 /****************************************************************************/
00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00014 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00015 /****************************************************************************/
00016 //
00017 //   This file is part of SUMO.
00018 //   SUMO is free software: you can redistribute it and/or modify
00019 //   it under the terms of the GNU General Public License as published by
00020 //   the Free Software Foundation, either version 3 of the License, or
00021 //   (at your option) any later version.
00022 //
00023 /****************************************************************************/
00024 /* =========================================================================
00025  * included modules
00026  * ======================================================================= */
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include <vector>
00034 #include <iostream>
00035 #include <iomanip>
00036 #include <fstream>
00037 #include <sstream>
00038 #include <ctime>
00039 #include <cstdlib>
00040 
00041 #define BUILD_TCPIP
00042 #include <foreign/tcpip/storage.h>
00043 #include <foreign/tcpip/socket.h>
00044 
00045 #include <traci-server/TraCIConstants.h>
00046 #include <utils/common/SUMOTime.h>
00047 #include "TraCITestClient.h"
00048 
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052 
00053 
00054 // ===========================================================================
00055 // used namespaces
00056 // ===========================================================================
00057 using namespace testclient;
00058 
00059 
00060 // ===========================================================================
00061 // method definitions
00062 // ===========================================================================
00063 
00064 TraCITestClient::TraCITestClient(std::string outputFileName)
00065     : socket(NULL),
00066       outputFileName(outputFileName),
00067       answerLog("") {
00068     answerLog.setf(std::ios::fixed , std::ios::floatfield); // use decimal format
00069     answerLog.setf(std::ios::showpoint); // print decimal point
00070     answerLog << std::setprecision(2);
00071 }
00072 
00073 
00074 TraCITestClient::~TraCITestClient() {
00075     writeResult();
00076     delete socket;
00077 }
00078 
00079 
00080 void
00081 TraCITestClient::writeResult() {
00082     time_t seconds;
00083     tm* locTime;
00084 
00085     std::ofstream outFile(outputFileName.c_str());
00086     if (!outFile) {
00087         std::cerr << "Unable to write result file" << std::endl;
00088     }
00089     time(&seconds);
00090     locTime = localtime(&seconds);
00091     outFile << "TraCITestClient output file. Date: " << asctime(locTime) << std::endl;
00092     outFile << answerLog.str();
00093     outFile.close();
00094 }
00095 
00096 
00097 void
00098 TraCITestClient::errorMsg(std::stringstream& msg) {
00099     std::cerr << msg.str() << std::endl;
00100     answerLog << "----" << std::endl << msg.str() << std::endl;
00101 }
00102 
00103 
00104 bool
00105 TraCITestClient::connect(int port, std::string host) {
00106     std::stringstream msg;
00107     socket = new tcpip::Socket(host, port);
00108 
00109     //socket->set_blocking(true);
00110 
00111     try {
00112         socket->connect();
00113     } catch (tcpip::SocketException& e) {
00114         msg << "#Error while connecting: " << e.what();
00115         errorMsg(msg);
00116         return false;
00117     }
00118 
00119     return true;
00120 }
00121 
00122 
00123 bool
00124 TraCITestClient::close() {
00125     if (socket != NULL) {
00126         socket->close();
00127     }
00128     return true;
00129 }
00130 
00131 
00132 bool
00133 TraCITestClient::run(std::string fileName, int port, std::string host) {
00134     std::ifstream defFile;
00135     std::string fileContentStr;
00136     std::stringstream fileContent;
00137     std::string lineCommand;
00138     std::stringstream msg;
00139     int repNo = 1;
00140     bool commentRead = false;
00141 
00142     if (!connect(port, host)) {
00143         return false;
00144     }
00145 
00146     // read definition file and trigger commands according to it
00147     defFile.open(fileName.c_str());
00148 
00149     if (!defFile) {
00150         msg << "Can not open definition file " << fileName << std::endl;
00151         errorMsg(msg);
00152         return false;
00153     }
00154     defFile.unsetf(std::ios::dec);
00155 
00156     while (defFile >> lineCommand) {
00157         repNo = 1;
00158         if (lineCommand.compare("%") == 0) {
00159             // a comment was read
00160             commentRead = !commentRead;
00161             continue;
00162         }
00163         if (commentRead) {
00164             // wait until end of comment is reached
00165             continue;
00166         }
00167         if (lineCommand.compare("repeat") == 0) {
00168             defFile >> repNo;
00169             defFile >> lineCommand;
00170         }
00171         if (lineCommand.compare("simstep2") == 0) {
00172             // read parameter for command simulation step and trigger command
00173             std::string time;
00174             defFile >> time;
00175             for (int i = 0; i < repNo; i++) {
00176                 commandSimulationStep2(string2time(time));
00177             }
00178         } else if (lineCommand.compare("posconversion2d") == 0) {
00179             // trigger command PositionConversion for a 2d position
00180             testclient::Position pos;
00181             int destFormat;
00182 
00183             defFile >> pos.x;
00184             defFile >> pos.y;
00185             defFile >> destFormat;
00186             commandPositionConversion(pos, destFormat);
00187         } else if (lineCommand.compare("posconversion3d") == 0) {
00188             // trigger command PositionConversion for a 3d position
00189             testclient::Position3D pos;
00190             int destFormat;
00191 
00192             defFile >> pos.x;
00193             defFile >> pos.y;
00194             defFile >> pos.z;
00195             defFile >> destFormat;
00196             commandPositionConversion(pos, destFormat);
00197         } else if (lineCommand.compare("posconversion_roadpos") == 0) {
00198             // trigger command PositionConversion for a road map position
00199             testclient::PositionRoadMap pos;
00200             int destFormat;
00201 
00202             defFile >> pos.roadId;
00203             defFile >> pos.pos;
00204             defFile >> pos.laneId;
00205             defFile >> destFormat;
00206             commandPositionConversion(pos, destFormat);
00207         } else if (lineCommand.compare("distancerequest_3d_3d") == 0) {
00208             // trigger command DistanceRequest for 2 3D positions
00209             testclient::Position3D pos1;
00210             testclient::Position3D pos2;
00211             int flag;
00212 
00213             defFile >> pos1.x;
00214             defFile >> pos1.y;
00215             defFile >> pos1.z;
00216             defFile >> pos2.x;
00217             defFile >> pos2.y;
00218             defFile >> pos2.z;
00219             defFile >> flag;
00220             commandDistanceRequest(pos1, pos2, flag);
00221         } else if (lineCommand.compare("distancerequest_3d_roadpos") == 0) {
00222             // trigger command DistanceRequest for 3D and road map position
00223             testclient::Position3D pos1;
00224             testclient::PositionRoadMap pos2;
00225             int flag;
00226 
00227             defFile >> pos1.x;
00228             defFile >> pos1.y;
00229             defFile >> pos1.z;
00230             defFile >> pos2.roadId;
00231             defFile >> pos2.pos;
00232             defFile >> pos2.laneId;
00233             defFile >> flag;
00234             commandDistanceRequest(pos1, pos2, flag);
00235         } else if (lineCommand.compare("distancerequest_roadpos_3d") == 0) {
00236             // trigger command DistanceRequest for road map and 3D position
00237             testclient::PositionRoadMap pos1;
00238             testclient::Position3D pos2;
00239             int flag;
00240 
00241             defFile >> pos1.roadId;
00242             defFile >> pos1.pos;
00243             defFile >> pos1.laneId;
00244             defFile >> pos2.x;
00245             defFile >> pos2.y;
00246             defFile >> pos2.z;
00247             defFile >> flag;
00248             commandDistanceRequest(pos1, pos2, flag);
00249         } else if (lineCommand.compare("distancerequest_roadpos_roadpos") == 0) {
00250             // trigger command DistanceRequest for 2 road map positions
00251             testclient::PositionRoadMap pos1;
00252             testclient::PositionRoadMap pos2;
00253             int flag;
00254 
00255             defFile >> pos1.roadId;
00256             defFile >> pos1.pos;
00257             defFile >> pos1.laneId;
00258             defFile >> pos2.roadId;
00259             defFile >> pos2.pos;
00260             defFile >> pos2.laneId;
00261             defFile >> flag;
00262             commandDistanceRequest(pos1, pos2, flag);
00263         } else if (lineCommand.compare("getvariable") == 0) {
00264             // trigger command GetXXXVariable
00265             int domID, varID;
00266             std::string objID;
00267             defFile >> domID >> varID >> objID;
00268             commandGetVariable(domID, varID, objID);
00269         } else if (lineCommand.compare("getvariable_plus") == 0) {
00270             // trigger command GetXXXVariable with one parameter
00271             int domID, varID;
00272             std::string objID;
00273             defFile >> domID >> varID >> objID;
00274             commandGetVariablePlus(domID, varID, objID, defFile);
00275         } else if (lineCommand.compare("subscribevariable") == 0) {
00276             // trigger command SubscribeXXXVariable
00277             int domID, varNo;
00278             std::string beginTime, endTime;
00279             std::string objID;
00280             defFile >> domID >> objID >> beginTime >> endTime >> varNo;
00281             commandSubscribeVariable(domID, objID, string2time(beginTime), string2time(endTime), varNo, defFile);
00282         }  else if (lineCommand.compare("setvalue") == 0) {
00283             // trigger command SetXXXValue
00284             int domID, varID;
00285             std::string objID;
00286             defFile >> domID >> varID >> objID;
00287             commandSetValue(domID, varID, objID, defFile);
00288         } else {
00289             msg << "Error in definition file: " << lineCommand
00290                 << " is not a valid command";
00291             errorMsg(msg);
00292             commandClose();
00293             close();
00294             return false;
00295         }
00296     }
00297     defFile.close();
00298     commandClose();
00299     close();
00300     return true;
00301 }
00302 
00303 
00304 bool
00305 TraCITestClient::reportResultState(tcpip::Storage& inMsg, int command, bool ignoreCommandId) {
00306     int cmdLength;
00307     int cmdId;
00308     int resultType;
00309     int cmdStart;
00310     std::string msg;
00311 
00312     try {
00313         cmdStart = inMsg.position();
00314         cmdLength = inMsg.readUnsignedByte();
00315         cmdId = inMsg.readUnsignedByte();
00316         if (cmdId != command && !ignoreCommandId) {
00317             answerLog << "#Error: received status response to command: " << cmdId
00318                       << " but expected: " << command << std::endl;
00319             return false;
00320         }
00321         resultType = inMsg.readUnsignedByte();
00322         msg = inMsg.readString();
00323     } catch (std::invalid_argument&) {
00324         answerLog << "#Error: an exception was thrown while reading result state message" << std::endl;
00325         return false;
00326     }
00327     switch (resultType) {
00328         case RTYPE_ERR:
00329             answerLog << ".. Answered with error to command (" << cmdId << "), [description: " << msg << "]" << std::endl;
00330             return false;
00331         case RTYPE_NOTIMPLEMENTED:
00332             answerLog << ".. Sent command is not implemented (" << cmdId << "), [description: " << msg << "]" << std::endl;
00333             return false;
00334         case RTYPE_OK:
00335             answerLog << ".. Command acknowledged (" << cmdId << "), [description: " << msg << "]" << std::endl;
00336             break;
00337         default:
00338             answerLog << ".. Answered with unknown result code(" << resultType << ") to command(" << cmdId
00339                       << "), [description: " << msg << "]" << std::endl;
00340             return false;
00341     }
00342     if ((cmdStart + cmdLength) != inMsg.position()) {
00343         answerLog << "#Error: command at position " << cmdStart << " has wrong length" << std::endl;
00344         return false;
00345     }
00346 
00347     return true;
00348 }
00349 
00350 
00351 void
00352 TraCITestClient::commandSimulationStep2(SUMOTime time) {
00353     tcpip::Storage outMsg;
00354     tcpip::Storage inMsg;
00355     std::stringstream msg;
00356 
00357     if (socket == NULL) {
00358         msg << "#Error while sending command: no connection to server";
00359         errorMsg(msg);
00360         return;
00361     }
00362 
00363     // command length
00364     outMsg.writeUnsignedByte(1 + 1 + 4);
00365     // command id
00366     outMsg.writeUnsignedByte(CMD_SIMSTEP2);
00367     outMsg.writeInt(time);
00368     // send request message
00369     try {
00370         socket->sendExact(outMsg);
00371     } catch (tcpip::SocketException& e) {
00372         msg << "Error while sending command: " << e.what();
00373         errorMsg(msg);
00374         return;
00375     }
00376     answerLog << std::endl << "-> Command sent: <SimulationStep2>:" << std::endl;
00377     // receive answer message
00378     try {
00379         socket->receiveExact(inMsg);
00380     } catch (tcpip::SocketException& e) {
00381         msg << "Error while receiving command: " << e.what();
00382         errorMsg(msg);
00383         return;
00384     }
00385     // validate result state
00386     if (!reportResultState(inMsg, CMD_SIMSTEP2)) {
00387         return;
00388     }
00389     // validate answer message
00390     validateSimulationStep2(inMsg);
00391 }
00392 
00393 
00394 void
00395 TraCITestClient::commandPositionConversion(testclient::Position pos, int posId) {
00396     commandPositionConversion(&pos, NULL, NULL, posId);
00397 }
00398 
00399 
00400 void
00401 TraCITestClient::commandPositionConversion(testclient::Position3D pos, int posId) {
00402     commandPositionConversion(NULL, &pos, NULL, posId);
00403 }
00404 
00405 
00406 void
00407 TraCITestClient::commandPositionConversion(testclient::PositionRoadMap pos, int posId) {
00408     commandPositionConversion(NULL, NULL, &pos, posId);
00409 }
00410 
00411 
00412 void
00413 TraCITestClient::commandPositionConversion(testclient::Position* pos2D,
00414         testclient::Position3D* pos3D,
00415         testclient::PositionRoadMap* posRoad,
00416         int posId) {
00417     tcpip::Storage outMsg;
00418     tcpip::Storage inMsg;
00419     tcpip::Storage tempMsg;
00420     std::stringstream msg;
00421 
00422     if (socket == NULL) {
00423         msg << "#Error while sending command: no connection to server" ;
00424         errorMsg(msg);
00425         return;
00426     }
00427 
00428     // command id
00429     tempMsg.writeUnsignedByte(CMD_POSITIONCONVERSION);
00430     // position
00431     if (pos2D != NULL) {
00432         tempMsg.writeUnsignedByte(POSITION_2D);
00433         tempMsg.writeDouble(pos2D->x);
00434         tempMsg.writeDouble(pos2D->y);
00435     } else if (pos3D != NULL) {
00436         tempMsg.writeUnsignedByte(POSITION_3D);
00437         tempMsg.writeDouble(pos3D->x);
00438         tempMsg.writeDouble(pos3D->y);
00439         tempMsg.writeDouble(pos3D->z);
00440     } else if (posRoad != NULL) {
00441         tempMsg.writeUnsignedByte(POSITION_ROADMAP);
00442         tempMsg.writeString(posRoad->roadId);
00443         tempMsg.writeDouble(posRoad->pos);
00444         tempMsg.writeUnsignedByte(posRoad->laneId);
00445     } else {
00446         std::cerr << "Error in method commandPositionConversion: position is NULL" << std::endl;
00447         return;
00448     }
00449     // destination position id
00450     tempMsg.writeUnsignedByte(posId);
00451     // command length
00452     outMsg.writeUnsignedByte(1 + (int) tempMsg.size());
00453     outMsg.writeStorage(tempMsg);
00454 
00455     // send request message
00456     try {
00457         socket->sendExact(outMsg);
00458     } catch (tcpip::SocketException& e) {
00459         msg << "Error while sending command: " << e.what();
00460         errorMsg(msg);
00461         return;
00462     }
00463 
00464     answerLog << std::endl << "-> Command sent: <PositionConversion>:" << std::endl;
00465     if (pos2D != NULL) {
00466         answerLog << " DestPosition-2D: x=" << pos2D->x << " y=" << pos2D->y ;
00467     } else if (pos3D != NULL) {
00468         answerLog << " DestPosition-3D: x=" << pos3D->x << " y=" << pos3D->y << " z=" << pos3D->z;
00469     } else if (posRoad != NULL) {
00470         answerLog << " DestPosition-RoadMap: roadId=" << posRoad->roadId << " pos=" << posRoad->pos << " laneId=" << (int)posRoad->laneId ;
00471     }
00472     answerLog << " posId=" << posId << std::endl;
00473 
00474     // receive answer message
00475     try {
00476         socket->receiveExact(inMsg);
00477     } catch (tcpip::SocketException& e) {
00478         msg << "Error while receiving command: " << e.what();
00479         errorMsg(msg);
00480         return;
00481     }
00482 
00483     // validate result state
00484     if (!reportResultState(inMsg, CMD_POSITIONCONVERSION)) {
00485         return;
00486     }
00487 
00488     // validate answer message
00489     validatePositionConversion(inMsg);
00490 }
00491 
00492 
00493 void
00494 TraCITestClient::commandDistanceRequest(testclient::Position pos1, testclient::Position pos2, int flag) {
00495     commandDistanceRequest(&pos1, NULL, NULL, &pos2, NULL, NULL, flag);
00496 }
00497 
00498 
00499 void
00500 TraCITestClient::commandDistanceRequest(testclient::Position pos1, testclient::Position3D pos2, int flag) {
00501     commandDistanceRequest(&pos1, NULL, NULL, NULL, &pos2, NULL, flag);
00502 }
00503 
00504 
00505 void
00506 TraCITestClient::commandDistanceRequest(testclient::Position3D pos1, testclient::Position3D pos2, int flag) {
00507     commandDistanceRequest(NULL, &pos1, NULL, NULL, &pos2, NULL, flag);
00508 }
00509 
00510 
00511 void
00512 TraCITestClient::commandDistanceRequest(testclient::Position3D pos1, testclient::Position pos2, int flag) {
00513     commandDistanceRequest(NULL, &pos1, NULL, &pos2, NULL, NULL, flag);
00514 }
00515 
00516 
00517 void
00518 TraCITestClient::commandDistanceRequest(testclient::PositionRoadMap pos1, testclient::Position pos2, int flag) {
00519     commandDistanceRequest(NULL, NULL, &pos1, &pos2, NULL, NULL, flag);
00520 }
00521 
00522 
00523 void
00524 TraCITestClient::commandDistanceRequest(testclient::PositionRoadMap pos1, testclient::Position3D pos2, int flag) {
00525     commandDistanceRequest(NULL, NULL, &pos1, NULL, &pos2, NULL, flag);
00526 }
00527 
00528 
00529 void
00530 TraCITestClient::commandDistanceRequest(testclient::PositionRoadMap pos1, testclient::PositionRoadMap pos2, int flag) {
00531     commandDistanceRequest(NULL, NULL, &pos1, NULL, NULL, &pos2, flag);
00532 }
00533 
00534 
00535 void
00536 TraCITestClient::commandDistanceRequest(testclient::Position pos1, testclient::PositionRoadMap pos2, int flag) {
00537     commandDistanceRequest(&pos1, NULL, NULL, NULL, NULL, &pos2, flag);
00538 }
00539 
00540 
00541 void
00542 TraCITestClient::commandDistanceRequest(testclient::Position3D pos1, testclient::PositionRoadMap pos2, int flag) {
00543     commandDistanceRequest(NULL, &pos1, NULL, NULL, NULL, &pos2, flag);
00544 }
00545 
00546 
00547 
00548 void
00549 TraCITestClient::commandDistanceRequest(testclient::Position* pos1_2D,
00550                                         testclient::Position3D* pos1_3D,
00551                                         testclient::PositionRoadMap* pos1_Road,
00552                                         testclient::Position* pos2_2D,
00553                                         testclient::Position3D* pos2_3D,
00554                                         testclient::PositionRoadMap* pos2_Road,
00555                                         int flag) {
00556     tcpip::Storage outMsg;
00557     tcpip::Storage inMsg;
00558     tcpip::Storage tempMsg;
00559     std::stringstream msg;
00560 
00561     if (socket == NULL) {
00562         msg << "#Error while sending command: no connection to server" ;
00563         errorMsg(msg);
00564         return;
00565     }
00566 
00567     // command id
00568     tempMsg.writeUnsignedByte(CMD_DISTANCEREQUEST);
00569     // position1
00570     if (pos1_2D != NULL) {
00571         tempMsg.writeUnsignedByte(POSITION_2D);
00572         tempMsg.writeDouble(pos1_2D->x);
00573         tempMsg.writeDouble(pos1_2D->y);
00574     } else if (pos1_3D != NULL) {
00575         tempMsg.writeUnsignedByte(POSITION_3D);
00576         tempMsg.writeDouble(pos1_3D->x);
00577         tempMsg.writeDouble(pos1_3D->y);
00578         tempMsg.writeDouble(pos1_3D->z);
00579     } else if (pos1_Road != NULL) {
00580         tempMsg.writeUnsignedByte(POSITION_ROADMAP);
00581         tempMsg.writeString(pos1_Road->roadId);
00582         tempMsg.writeDouble(pos1_Road->pos);
00583         tempMsg.writeUnsignedByte(pos1_Road->laneId);
00584     } else {
00585         std::cerr << "Error in method commandDistanceRequest: position1 is NULL" << std::endl;
00586         return;
00587     }
00588     // position2
00589     if (pos2_2D != NULL) {
00590         tempMsg.writeUnsignedByte(POSITION_2D);
00591         tempMsg.writeDouble(pos2_2D->x);
00592         tempMsg.writeDouble(pos2_2D->y);
00593     } else if (pos2_3D != NULL) {
00594         tempMsg.writeUnsignedByte(POSITION_3D);
00595         tempMsg.writeDouble(pos2_3D->x);
00596         tempMsg.writeDouble(pos2_3D->y);
00597         tempMsg.writeDouble(pos2_3D->z);
00598     } else if (pos2_Road != NULL) {
00599         tempMsg.writeUnsignedByte(POSITION_ROADMAP);
00600         tempMsg.writeString(pos2_Road->roadId);
00601         tempMsg.writeDouble(pos2_Road->pos);
00602         tempMsg.writeUnsignedByte(pos2_Road->laneId);
00603     } else {
00604         std::cerr << "Error in method commandDistanceRequest: position2 is NULL" << std::endl;
00605         return;
00606     }
00607     // flag
00608     tempMsg.writeUnsignedByte(flag);
00609     // command length
00610     outMsg.writeUnsignedByte(1 + (int) tempMsg.size());
00611     outMsg.writeStorage(tempMsg);
00612 
00613     // send request message
00614     try {
00615         socket->sendExact(outMsg);
00616     } catch (tcpip::SocketException& e) {
00617         msg << "Error while sending command: " << e.what();
00618         errorMsg(msg);
00619         return;
00620     }
00621 
00622     answerLog << std::endl << "-> Command sent: <DistanceRequest>:" << std::endl;
00623     if (pos1_2D != NULL) {
00624         answerLog << " FirstPosition-2D: x=" << pos1_2D->x << " y=" << pos1_2D->y ;
00625     } else if (pos1_3D != NULL) {
00626         answerLog << " FirstPosition-3D: x=" << pos1_3D->x << " y=" << pos1_3D->y << " z=" << pos1_3D->z;
00627     } else if (pos1_Road != NULL) {
00628         answerLog << " FirstPosition-RoadMap: roadId=" << pos1_Road->roadId << " pos=" << pos1_Road->pos << " laneId=" << (int)pos1_Road->laneId ;
00629     }
00630     if (pos2_2D != NULL) {
00631         answerLog << " SecondPosition-2D: x=" << pos2_2D->x << " y=" << pos2_2D->y ;
00632     } else if (pos2_3D != NULL) {
00633         answerLog << " SecondPosition-3D: x=" << pos2_3D->x << " y=" << pos2_3D->y << " z=" << pos2_3D->z;
00634     } else if (pos2_Road != NULL) {
00635         answerLog << " SecondPosition-RoadMap: roadId=" << pos2_Road->roadId << " pos=" << pos2_Road->pos << " laneId=" << (int)pos2_Road->laneId ;
00636     }
00637     answerLog << " Flag=" << flag << std::endl;
00638 
00639     // receive answer message
00640     try {
00641         socket->receiveExact(inMsg);
00642     } catch (tcpip::SocketException& e) {
00643         msg << "Error while receiving command: " << e.what();
00644         errorMsg(msg);
00645         return;
00646     }
00647 
00648     // validate result state
00649     if (!reportResultState(inMsg, CMD_DISTANCEREQUEST)) {
00650         return;
00651     }
00652 
00653     // validate answer message
00654     validateDistanceRequest(inMsg);
00655 }
00656 
00657 
00658 void
00659 TraCITestClient::commandGetVariable(int domID, int varID, const std::string& objID) {
00660     tcpip::Storage outMsg, inMsg;
00661     std::stringstream msg;
00662     if (socket == NULL) {
00663         msg << "#Error while sending command: no connection to server" ;
00664         errorMsg(msg);
00665         return;
00666     }
00667     // command length
00668     outMsg.writeUnsignedByte(1 + 1 + 1 + 4 + (int) objID.length());
00669     // command id
00670     outMsg.writeUnsignedByte(domID);
00671     // variable id
00672     outMsg.writeUnsignedByte(varID);
00673     // object id
00674     outMsg.writeString(objID);
00675 
00676     // send request message
00677     try {
00678         socket->sendExact(outMsg);
00679     } catch (tcpip::SocketException& e) {
00680         msg << "Error while sending command: " << e.what();
00681         errorMsg(msg);
00682         return;
00683     }
00684     answerLog << std::endl << "-> Command sent: <GetVariable>:" << std::endl
00685               << "  domID=" << domID << " varID=" << varID
00686               << " objID=" << objID << std::endl;
00687 
00688     // receive answer message
00689     try {
00690         socket->receiveExact(inMsg);
00691         if (!reportResultState(inMsg, domID)) {
00692             return;
00693         }
00694     } catch (tcpip::SocketException& e) {
00695         msg << "Error while receiving command: " << e.what();
00696         errorMsg(msg);
00697         return;
00698     }
00699     // validate result state
00700     try {
00701         int respStart = inMsg.position();
00702         int length = inMsg.readUnsignedByte();
00703         if (length == 0) {
00704             length = inMsg.readInt();
00705         }
00706         int cmdId = inMsg.readUnsignedByte();
00707         if (cmdId != (domID + 0x10)) {
00708             answerLog << "#Error: received response with command id: " << cmdId
00709                       << "but expected: " << (int)(domID + 0x10) << std::endl;
00710             return;
00711         }
00712         answerLog << "  CommandID=" << cmdId;
00713         answerLog << "  VariableID=" << inMsg.readUnsignedByte();
00714         answerLog << "  ObjectID=" << inMsg.readString();
00715         int valueDataType = inMsg.readUnsignedByte();
00716         answerLog << " valueDataType=" << valueDataType;
00717         readAndReportTypeDependent(inMsg, valueDataType);
00718     } catch (tcpip::SocketException& e) {
00719         msg << "Error while receiving command: " << e.what();
00720         errorMsg(msg);
00721         return;
00722     }
00723 }
00724 
00725 
00726 void
00727 TraCITestClient::commandGetVariablePlus(int domID, int varID, const std::string& objID, std::ifstream& defFile) {
00728     std::stringstream msg;
00729     if (socket == NULL) {
00730         msg << "#Error while sending command: no connection to server" ;
00731         errorMsg(msg);
00732         return;
00733     }
00734     tcpip::Storage outMsg, inMsg, tmp;
00735     const int dataLength = setValueTypeDependant(tmp, defFile, msg);
00736     std::string msgS = msg.str();
00737     if (msgS != "") {
00738         errorMsg(msg);
00739     }
00740     // command length (domID, varID, objID, dataType, data)
00741     outMsg.writeUnsignedByte(1 + 1 + 1 + 4 + (int) objID.length() + dataLength);
00742     // command id
00743     outMsg.writeUnsignedByte(domID);
00744     // variable id
00745     outMsg.writeUnsignedByte(varID);
00746     // object id
00747     outMsg.writeString(objID);
00748     // data type
00749     outMsg.writeStorage(tmp);
00750     // send request message
00751     try {
00752         socket->sendExact(outMsg);
00753     } catch (tcpip::SocketException& e) {
00754         msg << "Error while sending command: " << e.what();
00755         errorMsg(msg);
00756         return;
00757     }
00758     answerLog << std::endl << "-> Command sent: <GetVariable>:" << std::endl
00759               << "  domID=" << domID << " varID=" << varID
00760               << " objID=" << objID << std::endl;
00761 
00762     // receive answer message
00763     try {
00764         socket->receiveExact(inMsg);
00765         if (!reportResultState(inMsg, domID)) {
00766             return;
00767         }
00768     } catch (tcpip::SocketException& e) {
00769         msg << "Error while receiving command: " << e.what();
00770         errorMsg(msg);
00771         return;
00772     }
00773     // validate result state
00774     try {
00775         int respStart = inMsg.position();
00776         int length = inMsg.readUnsignedByte();
00777         if (length == 0) {
00778             length = inMsg.readInt();
00779         }
00780         int cmdId = inMsg.readUnsignedByte();
00781         if (cmdId != (domID + 0x10)) {
00782             answerLog << "#Error: received response with command id: " << cmdId
00783                       << "but expected: " << (int)(domID + 0x10) << std::endl;
00784             return;
00785         }
00786         answerLog << "  CommandID=" << cmdId;
00787         answerLog << "  VariableID=" << inMsg.readUnsignedByte();
00788         answerLog << "  ObjectID=" << inMsg.readString();
00789         int valueDataType = inMsg.readUnsignedByte();
00790         answerLog << " valueDataType=" << valueDataType;
00791         readAndReportTypeDependent(inMsg, valueDataType);
00792     } catch (tcpip::SocketException& e) {
00793         msg << "Error while receiving command: " << e.what();
00794         errorMsg(msg);
00795         return;
00796     }
00797 }
00798 
00799 
00800 void
00801 TraCITestClient::commandSubscribeVariable(int domID, const std::string& objID, int beginTime, int endTime, int varNo, std::ifstream& defFile) {
00802     std::stringstream msg;
00803     if (socket == NULL) {
00804         msg << "#Error while sending command: no connection to server" ;
00805         errorMsg(msg);
00806         return;
00807     }
00808     tcpip::Storage outMsg, inMsg, tmp;
00809     std::string msgS = msg.str();
00810     if (msgS != "") {
00811         errorMsg(msg);
00812     }
00813     // command length (domID, beginTime, endTime, objID, varNo, <vars>)
00814     outMsg.writeUnsignedByte(0);
00815     outMsg.writeInt(/*1 + 4 +*/ 5 + 1 + 4 + 4 + 4 + (int) objID.length() + 1 + varNo);
00816     // command id
00817     outMsg.writeUnsignedByte(domID);
00818     // time
00819     outMsg.writeInt(beginTime);
00820     outMsg.writeInt(endTime);
00821     // object id
00822     outMsg.writeString(objID);
00823     // command id
00824     outMsg.writeUnsignedByte(varNo);
00825     for (int i = 0; i < varNo; ++i) {
00826         int var;
00827         defFile >> var;
00828         // variable id
00829         outMsg.writeUnsignedByte(var);
00830     }
00831     // send request message
00832     try {
00833         socket->sendExact(outMsg);
00834     } catch (tcpip::SocketException& e) {
00835         msg << "Error while sending command: " << e.what();
00836         errorMsg(msg);
00837         return;
00838     }
00839     answerLog << std::endl << "-> Command sent: <SubscribeVariable>:" << std::endl
00840               << "  domID=" << domID << " objID=" << objID << " with " << varNo << " variables" << std::endl;
00841 
00842     // receive answer message
00843     try {
00844         socket->receiveExact(inMsg);
00845         if (!reportResultState(inMsg, domID)) {
00846             return;
00847         }
00848     } catch (tcpip::SocketException& e) {
00849         msg << "Error while receiving command: " << e.what();
00850         errorMsg(msg);
00851         return;
00852     }
00853     // validate result state
00854     try {
00855         validateSubscription(inMsg);
00856     } catch (tcpip::SocketException& e) {
00857         msg << "Error while receiving command: " << e.what();
00858         errorMsg(msg);
00859         return;
00860     }
00861 }
00862 
00863 
00864 
00865 int
00866 TraCITestClient::setValueTypeDependant(tcpip::Storage& into, std::ifstream& defFile, std::stringstream& msg) {
00867     std::string dataTypeS, valueS;
00868     defFile >> dataTypeS;
00869     if (dataTypeS == "<airDist>") {
00870         into.writeUnsignedByte(REQUEST_AIRDIST);
00871         return 1;
00872     } else if (dataTypeS == "<drivingDist>") {
00873         into.writeUnsignedByte(REQUEST_DRIVINGDIST);
00874         return 1;
00875     }
00876     defFile >> valueS;
00877     if (dataTypeS == "<int>") {
00878         into.writeUnsignedByte(TYPE_INTEGER);
00879         into.writeInt(atoi(valueS.c_str()));
00880         return 4 + 1;
00881     } else if (dataTypeS == "<byte>") {
00882         into.writeUnsignedByte(TYPE_BYTE);
00883         into.writeByte(atoi(valueS.c_str()));
00884         return 1 + 1;
00885     }  else if (dataTypeS == "<ubyte>") {
00886         into.writeUnsignedByte(TYPE_UBYTE);
00887         into.writeByte(atoi(valueS.c_str()));
00888         return 1 + 1;
00889     } else if (dataTypeS == "<float>") {
00890         into.writeUnsignedByte(TYPE_FLOAT);
00891         into.writeFloat(float(atof(valueS.c_str())));
00892         return 4 + 1;
00893     } else if (dataTypeS == "<double>") {
00894         into.writeUnsignedByte(TYPE_DOUBLE);
00895         into.writeDouble(atof(valueS.c_str()));
00896         return 8 + 1;
00897     } else if (dataTypeS == "<string>") {
00898         into.writeUnsignedByte(TYPE_STRING);
00899         into.writeString(valueS);
00900         return 4 + 1 + (int) valueS.length();
00901     } else if (dataTypeS == "<string*>") {
00902         std::vector<std::string> slValue;
00903         int number = atoi(valueS.c_str());
00904         int length = 1 + 4;
00905         for (int i = 0; i < number; ++i) {
00906             std::string tmp;
00907             defFile >> tmp;
00908             slValue.push_back(tmp);
00909             length += 4 + int(tmp.length());
00910         }
00911         into.writeUnsignedByte(TYPE_STRINGLIST);
00912         into.writeStringList(slValue);
00913         return length;
00914     } else if (dataTypeS == "<compound>") {
00915         into.writeUnsignedByte(TYPE_COMPOUND);
00916         int number = atoi(valueS.c_str());
00917         into.writeInt(number);
00918         int length = 1 + 4;
00919         for (int i = 0; i < number; ++i) {
00920             length += setValueTypeDependant(into, defFile, msg);
00921         }
00922         return length;
00923     } else if (dataTypeS == "<color>") {
00924         into.writeUnsignedByte(TYPE_COLOR);
00925         into.writeUnsignedByte(atoi(valueS.c_str()));
00926         for (int i = 0; i < 3; ++i) {
00927             defFile >> valueS;
00928             into.writeUnsignedByte(atoi(valueS.c_str()));
00929         }
00930         return 1 + 4;
00931     } else if (dataTypeS == "<position2D>") {
00932         into.writeUnsignedByte(POSITION_2D);
00933         into.writeDouble(atof(valueS.c_str()));
00934         defFile >> valueS;
00935         into.writeDouble(atof(valueS.c_str()));
00936         return 1 + 8 + 8;
00937     } else if (dataTypeS == "<position3D>") {
00938         into.writeUnsignedByte(POSITION_3D);
00939         into.writeDouble(atof(valueS.c_str()));
00940         defFile >> valueS;
00941         into.writeDouble(atof(valueS.c_str()));
00942         defFile >> valueS;
00943         into.writeDouble(atof(valueS.c_str()));
00944         return 1 + 8 + 8 + 8;
00945     } else if (dataTypeS == "<positionRoadmap>") {
00946         into.writeUnsignedByte(POSITION_ROADMAP);
00947         into.writeString(valueS);
00948         int length = 1 + 8 + (int) valueS.length();
00949         defFile >> valueS;
00950         into.writeDouble(atof(valueS.c_str()));
00951         defFile >> valueS;
00952         into.writeUnsignedByte(atoi(valueS.c_str()));
00953         return length + 4 + 1;
00954     } else if (dataTypeS == "<shape>") {
00955         into.writeUnsignedByte(TYPE_POLYGON);
00956         int number = atoi(valueS.c_str());
00957         into.writeUnsignedByte(number);
00958         int length = 1 + 1;
00959         for (int i = 0; i < number; ++i) {
00960             std::string x, y;
00961             defFile >> x >> y;
00962             into.writeDouble(atof(x.c_str()));
00963             into.writeDouble(atof(y.c_str()));
00964             length += 8 + 8;
00965         }
00966         return length;
00967     }
00968     msg << "## Unknown data type: " << dataTypeS;
00969     return 0;
00970 }
00971 
00972 void
00973 TraCITestClient::commandSetValue(int domID, int varID, const std::string& objID, std::ifstream& defFile) {
00974     std::stringstream msg;
00975     if (socket == NULL) {
00976         msg << "#Error while sending command: no connection to server" ;
00977         errorMsg(msg);
00978         return;
00979     }
00980     tcpip::Storage outMsg, inMsg, tmp;
00981     int dataLength = setValueTypeDependant(tmp, defFile, msg);
00982     std::string msgS = msg.str();
00983     if (msgS != "") {
00984         errorMsg(msg);
00985     }
00986     // command length (domID, varID, objID, dataType, data)
00987     outMsg.writeUnsignedByte(1 + 1 + 1 + 4 + (int) objID.length() + dataLength);
00988     // command id
00989     outMsg.writeUnsignedByte(domID);
00990     // variable id
00991     outMsg.writeUnsignedByte(varID);
00992     // object id
00993     outMsg.writeString(objID);
00994     // data type
00995     outMsg.writeStorage(tmp);
00996     // send request message
00997     try {
00998         socket->sendExact(outMsg);
00999     } catch (tcpip::SocketException& e) {
01000         msg << "Error while sending command: " << e.what();
01001         errorMsg(msg);
01002         return;
01003     }
01004     answerLog << std::endl << "-> Command sent: <SetValue>:" << std::endl
01005               << "  domID=" << domID << " varID=" << varID
01006               << " objID=" << objID << std::endl;
01007 
01008     // receive answer message
01009     try {
01010         socket->receiveExact(inMsg);
01011         if (!reportResultState(inMsg, domID)) {
01012             return;
01013         }
01014     } catch (tcpip::SocketException& e) {
01015         msg << "Error while receiving command: " << e.what();
01016         errorMsg(msg);
01017         return;
01018     }
01019 }
01020 
01021 
01022 
01023 
01024 void
01025 TraCITestClient::commandClose() {
01026     tcpip::Storage outMsg;
01027     tcpip::Storage inMsg;
01028     std::stringstream msg;
01029 
01030     if (socket == NULL) {
01031         msg << "#Error while sending command: no connection to server" ;
01032         errorMsg(msg);
01033         return;
01034     }
01035 
01036     // command length
01037     outMsg.writeUnsignedByte(1 + 1);
01038     // command id
01039     outMsg.writeUnsignedByte(CMD_CLOSE);
01040 
01041     // send request message
01042     try {
01043         socket->sendExact(outMsg);
01044     } catch (tcpip::SocketException& e) {
01045         msg << "Error while sending command: " << e.what();
01046         errorMsg(msg);
01047         return;
01048     }
01049 
01050     answerLog << std::endl << "-> Command sent: <Close>:" << std::endl;
01051 
01052     // receive answer message
01053     try {
01054         socket->receiveExact(inMsg);
01055     } catch (tcpip::SocketException& e) {
01056         msg << "Error while receiving command: " << e.what();
01057         errorMsg(msg);
01058         return;
01059     }
01060 
01061     // validate result state
01062     if (!reportResultState(inMsg, CMD_CLOSE)) {
01063         return;
01064     }
01065 }
01066 
01067 
01068 bool
01069 TraCITestClient::validateSimulationStep2(tcpip::Storage& inMsg) {
01070     try {
01071         int noSubscriptions = inMsg.readInt();
01072         for (int s = 0; s < noSubscriptions; ++s) {
01073             /*
01074             if (!reportResultState(inMsg, CMD_SIMSTEP2, true)) {
01075                 return false;
01076             }
01077             */
01078             if (!validateSubscription(inMsg)) {
01079                 return false;
01080             }
01081         }
01082     } catch (std::invalid_argument& e) {
01083         answerLog << "#Error while reading message:" << e.what() << std::endl;
01084         return false;
01085     }
01086     return true;
01087 }
01088 
01089 
01090 bool
01091 TraCITestClient::validateSubscription(tcpip::Storage& inMsg) {
01092     try {
01093         int respStart = inMsg.position();
01094         int length = inMsg.readUnsignedByte();
01095         if (length == 0) {
01096             length = inMsg.readInt();
01097         }
01098         int cmdId = inMsg.readUnsignedByte();
01099         if (cmdId < 0xe0 || cmdId > 0xef) {
01100             answerLog << "#Error: received response with command id: " << cmdId << " but expected a subscription response (0xe0-0xef)" << std::endl;
01101             return false;
01102         }
01103         answerLog << "  CommandID=" << cmdId;
01104         answerLog << "  ObjectID=" << inMsg.readString();
01105         unsigned int varNo = inMsg.readUnsignedByte();
01106         answerLog << "  #variables=" << varNo << std::endl;
01107         for (unsigned int i = 0; i < varNo; ++i) {
01108             answerLog << "      VariableID=" << inMsg.readUnsignedByte();
01109             bool ok = inMsg.readUnsignedByte() == RTYPE_OK;
01110             answerLog << "      ok=" << ok;
01111             int valueDataType = inMsg.readUnsignedByte();
01112             answerLog << " valueDataType=" << valueDataType;
01113             readAndReportTypeDependent(inMsg, valueDataType);
01114         }
01115     } catch (std::invalid_argument& e) {
01116         answerLog << "#Error while reading message:" << e.what() << std::endl;
01117         return false;
01118     }
01119     return true;
01120 }
01121 
01122 
01123 bool
01124 TraCITestClient::validatePositionConversion(tcpip::Storage& inMsg) {
01125     int cmdId;
01126     int cmdLength;
01127     int posType;
01128     int reqPosType;
01129     int cmdStart;
01130     testclient::PositionRoadMap roadPos;
01131     testclient::Position pos2D;
01132     testclient::Position3D pos3D;
01133 
01134     try {
01135         cmdStart = inMsg.position();
01136         cmdLength = inMsg.readUnsignedByte();
01137         // read command id
01138         cmdId = inMsg.readUnsignedByte();
01139         if (cmdId != CMD_POSITIONCONVERSION) {
01140             answerLog << "#Error: received response with command id: " << cmdId
01141                       << "but expected: " << (int)CMD_POSITIONCONVERSION << std::endl;
01142             return false;
01143         }
01144         answerLog << ".. Received Response <PositionConversion>:" << std::endl;
01145         // read converted position
01146         posType = inMsg.readUnsignedByte();
01147         switch (posType) {
01148             case POSITION_2D:
01149                 pos2D.x = inMsg.readDouble();
01150                 pos2D.y = inMsg.readDouble();
01151                 answerLog << "2D-Position: x=" << pos2D.x << " y=" << pos2D.y << std::endl;
01152                 break;
01153             case POSITION_3D:
01154                 answerLog << "3D-Position: ";
01155                 pos3D.x = inMsg.readDouble();
01156                 pos3D.y = inMsg.readDouble();
01157                 pos3D.z = inMsg.readDouble();
01158                 answerLog << "x=" << pos3D.x << " y=" << pos3D.y << " z=" << pos3D.z << std::endl;
01159                 break;
01160             case POSITION_ROADMAP:
01161                 roadPos.roadId = inMsg.readString();
01162                 roadPos.pos = inMsg.readDouble();
01163                 roadPos.laneId = inMsg.readUnsignedByte();
01164                 answerLog << "RoadMap-Position: roadId=" << roadPos.roadId << " pos=" << roadPos.pos
01165                           << " laneId=" << (int)roadPos.laneId << std::endl;
01166                 break;
01167             default:
01168                 answerLog << "#Error: received unknown position format" << std::endl;
01169                 return false;
01170         }
01171         // read requested position type
01172         reqPosType = inMsg.readUnsignedByte();
01173         if (reqPosType != posType) {
01174             answerLog << "#Warning: requested position type (" << reqPosType
01175                       << ") and received position type (" << posType << ") do not match" << std::endl;
01176         }
01177         // check command length
01178         if ((cmdStart + cmdLength) != inMsg.position()) {
01179             answerLog << "#Error: command at position " << cmdStart << " has wrong length" << std::endl;
01180             return false;
01181         }
01182     } catch (std::invalid_argument& e) {
01183         answerLog << "#Error while reading message:" << e.what() << std::endl;
01184         return false;
01185     }
01186 
01187     return true;
01188 }
01189 
01190 
01191 bool
01192 TraCITestClient::validateDistanceRequest(tcpip::Storage& inMsg) {
01193     int cmdId;
01194     int cmdLength;
01195     int flag;
01196     int cmdStart;
01197     SUMOReal distance;
01198     /*testclient::PositionRoadMap roadPos;
01199     testclient::Position pos2D;
01200     testclient::Position3D pos3D;*/
01201 
01202     try {
01203         cmdStart = inMsg.position();
01204         cmdLength = inMsg.readUnsignedByte();
01205         // read command id
01206         cmdId = inMsg.readUnsignedByte();
01207         if (cmdId != CMD_DISTANCEREQUEST) {
01208             answerLog << "#Error: received response with command id: " << cmdId
01209                       << "but expected: " << (int)CMD_DISTANCEREQUEST << std::endl;
01210             return false;
01211         }
01212         answerLog << ".. Received Response <DistanceRequest>:" << std::endl;
01213         // read flag
01214         flag = inMsg.readUnsignedByte();
01215         answerLog << " flag=" << flag;
01216         // read computed distance
01217         distance = inMsg.readDouble();
01218         answerLog << " distance=" << distance << std::endl;
01220         //posType = inMsg.readUnsignedByte();
01221         //switch (posType) {
01222         //case POSITION_2D:
01223         //  pos2D.x = inMsg.readDouble();
01224         //  pos2D.y = inMsg.readDouble();
01225         //  answerLog << "2D-Position: x=" << pos2D.x << " y=" << pos2D.y;
01226         //  break;
01227         //case POSITION_3D:
01228         //  answerLog << "3D-Position: ";
01229         //  pos3D.x = inMsg.readDouble();
01230         //  pos3D.y = inMsg.readDouble();
01231         //  pos3D.z = inMsg.readDouble();
01232         //  answerLog << "x=" << pos3D.x << " y=" << pos3D.y << " z=" << pos3D.z;
01233         //  break;
01234         //case POSITION_ROADMAP:
01235         //  roadPos.roadId = inMsg.readString();
01236         //  roadPos.pos = inMsg.readDouble();
01237         //  roadPos.laneId = inMsg.readUnsignedByte();
01238         //  answerLog << "RoadMap-Position: roadId=" << roadPos.roadId << " pos=" << roadPos.pos
01239         //      << " laneId=" << (int)roadPos.laneId;
01240         //  break;
01241         //default:
01242         //  answerLog << "#Error: received unknown position format: " << posType << std::endl;
01243         //  return false;
01244         //}
01245         // check command length
01246         if ((cmdStart + cmdLength) != inMsg.position()) {
01247             answerLog << "#Error: command at position " << cmdStart << " has wrong length" << std::endl;
01248             return false;
01249         }
01250     } catch (std::invalid_argument& e) {
01251         answerLog << "#Error while reading message:" << e.what() << std::endl;
01252         return false;
01253     }
01254 
01255     return true;
01256 }
01257 
01258 
01259 bool
01260 TraCITestClient::readAndReportTypeDependent(tcpip::Storage& inMsg, int valueDataType) {
01261     if (valueDataType == TYPE_UBYTE) {
01262         int ubyte = inMsg.readUnsignedByte();
01263         answerLog << " Unsigned Byte Value: " << ubyte << std::endl;
01264     } else if (valueDataType == TYPE_BYTE) {
01265         int byte = inMsg.readByte();
01266         answerLog << " Byte value: " << byte << std::endl;
01267     } else if (valueDataType == TYPE_INTEGER) {
01268         int integer = inMsg.readInt();
01269         answerLog << " Int value: " << integer << std::endl;
01270     } else if (valueDataType == TYPE_FLOAT) {
01271         float floatv = inMsg.readFloat();
01272         if (floatv < 0.1 && floatv > 0) {
01273             answerLog.setf(std::ios::scientific, std::ios::floatfield);
01274         }
01275         answerLog << " float value: " << floatv << std::endl;
01276         answerLog.setf(std::ios::fixed , std::ios::floatfield); // use decimal format
01277         answerLog.setf(std::ios::showpoint); // print decimal point
01278         answerLog << std::setprecision(2);
01279     } else if (valueDataType == TYPE_DOUBLE) {
01280         double doublev = inMsg.readDouble();
01281         answerLog << " Double value: " << doublev << std::endl;
01282     } else if (valueDataType == TYPE_BOUNDINGBOX) {
01283         testclient::BoundingBox box;
01284         box.lowerLeft.x = inMsg.readDouble();
01285         box.lowerLeft.y = inMsg.readDouble();
01286         box.upperRight.x = inMsg.readDouble();
01287         box.upperRight.y = inMsg.readDouble();
01288         answerLog << " BoundaryBoxValue: lowerLeft x=" << box.lowerLeft.x
01289                   << " y=" << box.lowerLeft.y << " upperRight x=" << box.upperRight.x
01290                   << " y=" << box.upperRight.y << std::endl;
01291     } else if (valueDataType == TYPE_POLYGON) {
01292         int length = inMsg.readUnsignedByte();
01293         answerLog << " PolygonValue: ";
01294         for (int i = 0; i < length; i++) {
01295             SUMOReal x = inMsg.readDouble();
01296             SUMOReal y = inMsg.readDouble();
01297             answerLog << "(" << x << "," << y << ") ";
01298         }
01299         answerLog << std::endl;
01300     } else if (valueDataType == POSITION_3D) {
01301         SUMOReal x = inMsg.readDouble();
01302         SUMOReal y = inMsg.readDouble();
01303         SUMOReal z = inMsg.readDouble();
01304         answerLog << " Position3DValue: " << std::endl;
01305         answerLog << " x: " << x << " y: " << y
01306                   << " z: " << z << std::endl;
01307     } else if (valueDataType == POSITION_ROADMAP) {
01308         std::string roadId = inMsg.readString();
01309         SUMOReal pos = inMsg.readDouble();
01310         int laneId = inMsg.readUnsignedByte();
01311         answerLog << " RoadMapPositionValue: roadId=" << roadId
01312                   << " pos=" << pos
01313                   << " laneId=" << laneId << std::endl;
01314     } else if (valueDataType == TYPE_TLPHASELIST) {
01315         int length = inMsg.readUnsignedByte();
01316         answerLog << " TLPhaseListValue: length=" << length << std::endl;
01317         for (int i = 0; i < length; i++) {
01318             std::string pred = inMsg.readString();
01319             std::string succ = inMsg.readString();
01320             int phase = inMsg.readUnsignedByte();
01321             answerLog << " precRoad=" << pred << " succRoad=" << succ
01322                       << " phase=";
01323             switch (phase) {
01324                 case TLPHASE_RED:
01325                     answerLog << "red" << std::endl;
01326                     break;
01327                 case TLPHASE_YELLOW:
01328                     answerLog << "yellow" << std::endl;
01329                     break;
01330                 case TLPHASE_GREEN:
01331                     answerLog << "green" << std::endl;
01332                     break;
01333                 default:
01334                     answerLog << "#Error: unknown phase value" << (int)phase << std::endl;
01335                     return false;
01336             }
01337         }
01338     } else if (valueDataType == TYPE_STRING) {
01339         std::string s = inMsg.readString();
01340         answerLog << " string value: " << s << std::endl;
01341     } else if (valueDataType == TYPE_STRINGLIST) {
01342         std::vector<std::string> s = inMsg.readStringList();
01343         answerLog << " string list value: [ " << std::endl;
01344         for (std::vector<std::string>::iterator i = s.begin(); i != s.end(); ++i) {
01345             if (i != s.begin()) {
01346                 answerLog << ", ";
01347             }
01348             answerLog << '"' << *i << '"';
01349         }
01350         answerLog << " ]" << std::endl;
01351     } else if (valueDataType == TYPE_COMPOUND) {
01352         int no = inMsg.readInt();
01353         answerLog << " compound value with " << no << " members: [ " << std::endl;
01354         for (int i = 0; i < no; ++i) {
01355             int currentValueDataType = inMsg.readUnsignedByte();
01356             answerLog << " valueDataType=" << currentValueDataType;
01357             readAndReportTypeDependent(inMsg, currentValueDataType);
01358         }
01359         answerLog << " ]" << std::endl;
01360     } else if (valueDataType == POSITION_2D) {
01361         SUMOReal xv = inMsg.readDouble();
01362         SUMOReal yv = inMsg.readDouble();
01363         answerLog << " position value: (" << xv << "," << yv << ")" << std::endl;
01364     } else if (valueDataType == TYPE_COLOR) {
01365         int r = inMsg.readUnsignedByte();
01366         int g = inMsg.readUnsignedByte();
01367         int b = inMsg.readUnsignedByte();
01368         int a = inMsg.readUnsignedByte();
01369         answerLog << " color value: (" << r << "," << g << "," << b << "," << a << ")" << std::endl;
01370     } else {
01371         answerLog << "#Error: unknown valueDataType!" << std::endl;
01372         return false;
01373     }
01374     return true;
01375 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines