0

I'm using Veins 4.4 and I need to store some results in an outer server, so I would like to open a UDP connection toward it.

I've read several posts about using a TCP connection for the mobility in Veins,and I understood I should resort to the Inet module to open a connection. Although I don't need it for the mobility, but to send data to an external server.

Is there any suggestion?

I was trying to use the method processCommandFromApp method from inet/src/transport/UDP.cc class:

    void UDP::processCommandFromApp(cMessage *msg)
{
    switch (msg->getKind())
    {
        case UDP_C_BIND: {
            UDPBindCommand *ctrl = check_and_cast<UDPBindCommand*>(msg->getControlInfo());
            bind(ctrl->getSockId(), msg->getArrivalGate()->getIndex(), ctrl->getLocalAddr(), ctrl->getLocalPort());
            break;
        }
        case UDP_C_CONNECT: {
            UDPConnectCommand *ctrl = check_and_cast<UDPConnectCommand*>(msg->getControlInfo());
            connect(ctrl->getSockId(), msg->getArrivalGate()->getIndex(), ctrl->getRemoteAddr(), ctrl->getRemotePort());
            break;
        }
        case UDP_C_CLOSE: {
            UDPCloseCommand *ctrl = check_and_cast<UDPCloseCommand*>(msg->getControlInfo());
            close(ctrl->getSockId());
            break;
        }
        case UDP_C_SETOPTION: {
            UDPSetOptionCommand *ctrl = check_and_cast<UDPSetOptionCommand *>(msg->getControlInfo());
            SockDesc *sd = getOrCreateSocket(ctrl->getSockId(), msg->getArrivalGate()->getIndex());

            if (dynamic_cast<UDPSetTimeToLiveCommand*>(ctrl))
                setTimeToLive(sd, ((UDPSetTimeToLiveCommand*)ctrl)->getTtl());
            else if (dynamic_cast<UDPSetTypeOfServiceCommand*>(ctrl))
                setTypeOfService(sd, ((UDPSetTypeOfServiceCommand*)ctrl)->getTos());
            else if (dynamic_cast<UDPSetBroadcastCommand*>(ctrl))
                setBroadcast(sd, ((UDPSetBroadcastCommand*)ctrl)->getBroadcast());
            else if (dynamic_cast<UDPSetMulticastInterfaceCommand*>(ctrl))
                setMulticastOutputInterface(sd, ((UDPSetMulticastInterfaceCommand*)ctrl)->getInterfaceId());
            else if (dynamic_cast<UDPSetMulticastLoopCommand*>(ctrl))
                setMulticastLoop(sd, ((UDPSetMulticastLoopCommand*)ctrl)->getLoop());
            else if (dynamic_cast<UDPSetReuseAddressCommand*>(ctrl))
                setReuseAddress(sd, ((UDPSetReuseAddressCommand*)ctrl)->getReuseAddress());
            else if (dynamic_cast<UDPJoinMulticastGroupsCommand*>(ctrl))
            {
                UDPJoinMulticastGroupsCommand *cmd = (UDPJoinMulticastGroupsCommand*)ctrl;
                std::vector<IPvXAddress> addresses;
                std::vector<int> interfaceIds;
                for (int i = 0; i < (int)cmd->getMulticastAddrArraySize(); i++)
                    addresses.push_back(cmd->getMulticastAddr(i));
                for (int i = 0; i < (int)cmd->getInterfaceIdArraySize(); i++)
                    interfaceIds.push_back(cmd->getInterfaceId(i));
                joinMulticastGroups(sd, addresses, interfaceIds);
            }
            else if (dynamic_cast<UDPLeaveMulticastGroupsCommand*>(ctrl))
            {
                UDPLeaveMulticastGroupsCommand *cmd = (UDPLeaveMulticastGroupsCommand*)ctrl;
                std::vector<IPvXAddress> addresses;
                for (int i = 0; i < (int)cmd->getMulticastAddrArraySize(); i++)
                    addresses.push_back(cmd->getMulticastAddr(i));
                leaveMulticastGroups(sd, addresses);
            }
            else
                throw cRuntimeError("Unknown subclass of UDPSetOptionCommand received from app: %s", ctrl->getClassName());
            break;
        }
        default: {
            throw cRuntimeError("Unknown command code (message kind) %d received from app", msg->getKind());
        }
    }

    delete msg; // also deletes control info in it
}

I included the inet path as follows:

#include <inet/src/transport/udp/UDP.h>

and I call it as follows, by passing as input UDP_C_CONNECT message.:

cMessage *UDP_C_CONNECT;
void Inet::UDP::processCommandFromApp(UDP_C_CONNECT);

But when I run the simulation, it crashes, returning this error:

Errors occurred during the build.
Errors running builder 'OMNeT++ Makefile Builder' on project 'veins'.
java.lang.NullPointerException

1) Is there the correct way to set up the required connection?

2) Why I'm getting this error as soon as I include the inet path?

UPDATE I also tried another way to establish the connection:

std::string host;
host = "16777343";
int port = 5144;
Veins::TraCIConnection* connection;
connection = TraCIConnection::connect(host.c_str(), port);

but as soon as it load the plugin, then it's like it is waiting for something at time 0.0 without starting the generation of the nodes. Thanks for helping

moi
  • 13
  • 5
  • Do you aim to *simulate* a connection to a server or to physically contact a computer on your network? Your question is not very clear on this and you seem to have attempted a mix of both. – Christoph Sommer Feb 14 '17 at 23:33
  • @ChristophSommer I need to transfer the collected data from Veins, to a server on my computer. – moi Feb 16 '17 at 08:41

1 Answers1

1

Simulations using OMNeT++ are C++ programs, so you can use the full range of libraries and system calls available to any C++ program. If you want to open a UDP connection to some other computer on your network, just create a UDP socket as you would in any C++ program, then send the data whenever needed.

Maybe the easiest way to go about writing this is to

  • start with a plain C++ program that has nothing to do with OMNeT++
  • move the part of the program that has to run before everything else into the initialize method of a module in your simulation, the rest to a handleMessage method.
Christoph Sommer
  • 6,893
  • 1
  • 17
  • 35