Files
openairinterface5g/openair2/UTIL/OMG/client_traci_OMG.c
T
Navid Nikaein b264c0b9ee update license for OMG
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5581 818b1a75-f10b-46b9-bf7c-635c3b92a50f
2014-07-22 20:00:26 +00:00

426 lines
13 KiB
C

/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
*******************************************************************************/
/*! \file client_traci_OMG.c
* \brief The OMG TraCI to send/receive commands from/to SUMO via socket interfaces.
* \author S. Uppoor, J. Harri
* \date 2012
* \version 0.1
* \company INRIA, Eurecom
* \email: sandesh.uppor@inria.fr, haerri@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include "client_traci_OMG.h"
#include "TraCIConstants.h"
#define UNUSED_VARIABLE(vARIABLE) (void)(vARIABLE)
int handshake(char *hoststr,int portno){
check_endianness(); // check endianness
int i;
for(i = 0; i< 10; i++) {
if ( connection_(hoststr,portno) <0 ) {
#ifdef STANDALONE
printf("connection error...trying again in 3 seconds\n");
#else
LOG_E(OMG, " Could not connect to TraCIServer - sleeping before trying again...\n");
#endif
sleep(5);
}
else {
#ifdef STANDALONE
printf(" SUMO now connected to OMG on host address\n");
#else
LOG_N(OMG, " SUMO now connected to OMG on host address %s and port %i .\n", hoststr, portno);
#endif
return 0;
}
}
#ifdef STANDALONE
printf(" SUMO unreachable...giving up...\n");
#else
LOG_E(OMG, " SUMO unreachable...giving up...\n");
#endif
return -1;
}
void init(int max_sim_time) {
#ifdef STANDALONE
printf(" Initializing TraCI...\n");
#else
LOG_N(OMG, " Initializing TraCI...\n");
#endif
char *objID = " ";
// size_t size = strlen(objID);
int noSubscribedVars = 2;
writeUnsignedByte(0);
writeInt(1 + 4 + 1 + 4 + 4 + 4 + (int) strlen(objID) + 1 + noSubscribedVars);
writeUnsignedByte(CMD_SUBSCRIBE_SIM_VARIABLE); // command id
writeInt(0); // begin time
writeInt(max_sim_time*1000); // end time
writeString(objID); // object id
writeUnsignedByte(noSubscribedVars); // variable number
writeUnsignedByte(VAR_DEPARTED_VEHICLES_IDS);
writeUnsignedByte(VAR_ARRIVED_VEHICLES_IDS);
// send request message
sendExact(storageLength(storageStart));
extractCommandStatus(receiveExact(), CMD_SUBSCRIBE_SIM_VARIABLE, description);
if (departed == NULL) {
departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
departed->string = NULL;
departed->next = NULL;
}
if (arrived == NULL) {
arrived = (string_list*) malloc(sizeof(string_list)); // arrived MUST point to HEAD
arrived->string = NULL;
arrived->next = NULL;
}
processSubscriptions();
reset();
}
void processSubscriptions() {
int noSubscriptions = readInt();
string_list* tmp_departed = departed;
string_list* tmp_arrived = arrived;
int s;
for (s = 0; s<noSubscriptions; ++s) {
int respStart = readInt();
int respLength = readUnsignedByte();
if (respLength == 0)
respLength = readInt();
int cmdId = readUnsignedByte();
if (cmdId<0xe0||cmdId>0xef) { // only responses to subscription to supported types (vehicles, TLC, polygones...) are accepted
//LOG_W(OMG, " Invalide Subscription response: %d\n",cmdId);
//printf(" Invalide Subscription response: %d\n",cmdId);
return;
}
char *objID = readString();
int varNo = readUnsignedByte();
UNUSED_VARIABLE(objID);
UNUSED_VARIABLE(respStart);
int i;
for (i=0; i<varNo; ++i) {
int varID = readUnsignedByte();
bool ok = readUnsignedByte()==RTYPE_OK;
int valueDataType = readUnsignedByte();
UNUSED_VARIABLE(valueDataType);
if (ok&&cmdId==CMD_SUBSCRIBE_SIM_VARIABLE+0x10&&varID==VAR_DEPARTED_VEHICLES_IDS) {
tmp_departed = readStringList(tmp_departed);
//printf(" OMG Got departed cars\n");
continue;
}
if (ok&&cmdId==CMD_SUBSCRIBE_SIM_VARIABLE+0x10&&varID==VAR_ARRIVED_VEHICLES_IDS) {
tmp_arrived = readStringList(tmp_arrived);
//printf(" OMG Got arrived cars\n");
continue;
}
}
}
}
int extractCommandStatus(storage *s, unsigned char commandId, char * description)
{
int success=0;
if(s == NULL) {
//LOG_E(OMG, " client_traci_OMG::extractCommandStatus(): Tracker is NULL \n");
//printf(" client_traci_OMG::extractCommandStatus(): Tracker is NULL \n");
return success=0;
}
// validate the the message response from SUMO
int storageLength_ = storageLength(s);
// tracker currently points to the begining of the recieved data in the linked list
tracker = s;
// storage *freeTracker = tracker; // save it for calling free
int commandLength = readUnsignedByte();
// CommandID needs to fit
int rcvdCommandId = readUnsignedByte();
if (rcvdCommandId == (int)commandId)
{
//printf("%d",rcvdCommandId);
//LOG_E(OMG, " Server answered to command\n");
//printf(" Server answered to command\n");
}
// Get result and description
unsigned char result = readUnsignedByte();
if (result != RTYPE_OK)
{
printf(" Server returned error\n");
return success=0;
}
if (result == RTYPE_OK) {
// printf(" Server returned success\n");
success=1;
}
description = readString();
// print description if needed
//free actual message content
//depends on the message which is handled
/* if (commandId != CMD_GET_VEHICLE_VARIABLE)
freeStorage(freeTracker);*/
UNUSED_VARIABLE(commandLength);
UNUSED_VARIABLE(storageLength_);
return success;
}
void commandSimulationStep(double time)
{ // progress the simulation in SUMO
// reset is used to initalize the global parameters
reset();
// Send command
writeUnsignedByte(1 + 1 + 4); // command length
writeUnsignedByte(CMD_SIMSTEP2); // look up TraCIConstants.h
// writeInt((int)(time*1000)); // TraCI accepts time in milli seconds
writeInt((int)(time)); // TraCI accepts time in milli seconds
sendExact(storageLength(storageStart));
extractCommandStatus(receiveExact(), CMD_SIMSTEP2, description);
if (departed == NULL) {
departed = (string_list*) malloc(sizeof(string_list)); // departed MUST point to HEAD
departed->string = NULL;
departed->next = NULL;
}
if (arrived == NULL) {
arrived = (string_list*) malloc(sizeof(string_list)); // arrived MUST point to HEAD
arrived->string = NULL;
arrived->next = NULL;
}
/* if (departed == NULL)
departed = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
if (arrived == NULL)
arrived = (String_list)malloc(sizeof(String_list)); // departed MUST point to HEAD
*/
processSubscriptions();
}
void commandClose()
{ reset();
// command length
writeUnsignedByte(0x02);
// command id
writeUnsignedByte(CMD_CLOSE);
// send request message
#ifdef STANDALONE
printf("closing the socket... \n");
#else
LOG_N(OMG,"closing the socket... \n");
#endif
sendExact(storageLength(storageStart));
extractCommandStatus(receiveExact(), CMD_CLOSE, description);
}
void commandGetVehicleVariable(char *vehID, int varID)// malloc for vehID and varID depends on speed or position
{
reset();
int domID = CMD_GET_VEHICLE_VARIABLE;//0xa4 specific for get vehicle variable command
// command length
writeUnsignedByte(1 + 1 + 1 + 4 + (int)strlen(vehID));
// command id
writeUnsignedByte(CMD_GET_VEHICLE_VARIABLE);
// variable id
writeUnsignedByte(varID);
// object id
writeString(vehID);
// send request message
sendExact(storageLength(storageStart));
// receive answer message
//receiveExact();
if (extractCommandStatus(receiveExact(), CMD_GET_VEHICLE_VARIABLE, description)){//<---RESPONSE_GET_VEHICLE_VARIABLE
// validate result state
if(tracker == NULL) {
// LOG_E(OMG, " client_traci_OMG::commandGetVehicleVariable(): Tracker is NULL \n");
//printf(" client_traci_OMG::commandGetVehicleVariable(): Tracker is NULL \n");
return;
}
int length = readUnsignedByte();
if(length ==0)
length = readInt();
int cmdId =readUnsignedByte();
if (cmdId != (CMD_GET_VEHICLE_VARIABLE+0x10)) {
//LOG_E(OMG, " Wrong response recieved\n");
//printf(" Wrong response recieved\n");
return;
}
int VariableID = readUnsignedByte();
char* rs = readString();
int valueDataType = readUnsignedByte();
UNUSED_VARIABLE(VariableID);
UNUSED_VARIABLE(rs);
UNUSED_VARIABLE(valueDataType);
UNUSED_VARIABLE(domID);
}
}
// TODO not working for now..need to find a way to get the same info without using CMD_SCENARIO (as not implemented by SUMO)
int commandGetMaxSUMONodesVariable()
{
reset();
int max_car = 0;
// command length
writeUnsignedByte(1 + 1 + 1 + 1 + 4 + 1 + 1 + 4);
// command id
writeUnsignedByte(CMD_SCENARIO);
// flag
writeUnsignedByte(0x00); // GET command for the generic environment-related values
// command id
//writeUnsignedByte(CMD_SCENARIO);
// domain id
writeUnsignedByte(0x01); // vehicle
writeInt(0); // first vehicular domain
// variable id
writeUnsignedByte(DOMVAR_MAXCOUNT); // get maximum number of vehicles
writeUnsignedByte(TYPE_INTEGER); // get maximum number of vehicles
writeInt(max_car); // get maximum number of vehicles
// send request message
sendExact(storageLength(storageStart));
// receive answer message
if (extractCommandStatus(receiveExact(), CMD_SCENARIO, description)){//<---RESPONSE_GET_VEHICLE_VARIABLE
// validate result state
if(tracker == NULL) {
//LOG_E(OMG, " client_traci_OMG::commandGetMaxSUMONodesVariable(): Tracker is NULL \n");
return -1;
}
int res = readUnsignedByte();
int Length = readUnsignedByte(); // to check with Int
int cmdId =readUnsignedByte();
if (cmdId != (CMD_SCENARIO)) {
//LOG_E(OMG, " Wrong response recieved \n");
return -1;
}
int flag = readUnsignedByte();
int dom = readUnsignedByte(); // domain
int domID = readInt(); // domain ID
int VariableID = readUnsignedByte();
int valueDataType = readUnsignedByte();
if (valueDataType == TYPE_INTEGER) {
max_car = readInt();
//LOG_N(OMG, " max Number SUMO nodes is: %f \n", max_car);
}
else {
//LOG_W(OMG, " No Matching Data Type Value \n");
}
UNUSED_VARIABLE(res);
UNUSED_VARIABLE(Length);
UNUSED_VARIABLE(flag);
UNUSED_VARIABLE(dom);
UNUSED_VARIABLE(domID);
UNUSED_VARIABLE(VariableID);
}
return max_car;
}
void GetSpeed(node_struct* node, char * sumo_id)
{
commandGetVehicleVariable(sumo_id, VAR_SPEED);
double speed_double = readDouble();
node->mob->speed = speed_double;
}
void GetPosition(node_struct* node, char * sumo_id)
{
commandGetVehicleVariable(sumo_id, VAR_POSITION);
double x_double = readDouble();
if (x_double < 0.0)
x_double = 0.0;
double y_double = readDouble();
if (y_double < 0.0)
y_double = 0.0;
node->x_pos = x_double;
node->y_pos = y_double;
}