I use OMNeT++-5.3 and Veins-4.7.1.
this is how I implement my code to send a message in counter mode (I do the same with flooding)
void Counter::sendMessage(std::string blockedRoadId)
{
t_channel channel = dataOnSch ? type_SCH : type_CCH;
WaveShortMessage* wsm = prepareWSM("data", dataLengthBits, channel, dataPriority, -1,2);
wsm->setWsmData(blockedRoadId.c_str());
sendWSM(wsm);
sentMessage = true;
}
void Counter::handleSelfMsg(cMessage *msg)
{
// for "data" and "beacon" self messages
if ((!strcmp(msg->getName(), "data")) || (!strcmp(msg->getName(), "beacon"))) {
BaseWaveApplLayer::handleSelfMsg(msg);
return;
}
else { // for "rebroadcast" self messages
// if the number of times a warning message is received exceeds the counterThreshold
// configuration variable, do not rebroadcast.
if (receivedMessages[atol(msg->getName())].size() >= (unsigned)counterThreshold)
return;
// if greater than threshold.. rebroadcast.
sendWSM(receivedMessages[atol(msg->getName())][0]->dup());
}
}
these are the errors I find:
'dataPriority’ was not declared in this scope
‘sendWSM’ was not declared in this scope
could you help me?
this is the code Counter.h
typedef std::vector<WaveShortMessage*> WaveShortMessages;
class Counter : public BaseWaveApplLayer
{
public:
virtual void initialize(int stage);
virtual void receiveSignal(cComponent *source, simsignal_t signalID, cObject *obj);
protected:
TraCIMobility* traci;
vector<WaveShortMessage*> warningMessages;
map<long,WaveShortMessages> receivedMessages; // treeId, WSM vector
protected:
virtual void onBeacon(WaveShortMessage *wsm);
virtual void onData(WaveShortMessage *wsm);
virtual void handlePositionUpdate(cObject *obj);
virtual void sendMessage(std::string blockedRoadId);
virtual void handleSelfMsg(cMessage *msg)
Related
I'm asking about a ring topology network, I'm looking to send a message from the node to hub and then to another node then back to the hub but when it simulates there is an error that pops up. I'm not sure what is the issue.
send()/sendDelayed(): No gate index specified when accessing vector gate 'out' -- in module (node) Startop.node[0] (id=2), during network initialization
Here is my .ned file:
package startop;
simple node
{
parameters:
#display("i=device/pc2_s");
gates:
input in[];
output out[];
}
simple hub
{
parameters:
#display("i=device/switch");
gates:
input in[];
output out[];
}
network Startop
{
parameters:
int n #prompt("Number of stations") = default(2);
submodules:
node[n]: node;
hub: hub {
#display("p=222,170");
}
connections allowunconnected:
for i=0..n-1 {
node[i].out++ --> hub.in++;
hub.out++ --> node[i].in++;
}
}
This is the .cc file:
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
class node : public cSimpleModule
{
private:
simtime_t timeout; // timeout
cMessage *timeoutEvent; // holds pointer to the timeout self-message
public:
node();
virtual ~node();
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(node);
node::node()
{
timeoutEvent = nullptr;
}
node::~node()
{
cancelAndDelete(timeoutEvent);
}
void node::initialize()
{
// Initialize variables.
timeout = 1.0;
timeoutEvent = new cMessage("timeoutEvent");
// Generate and send initial message.
EV << "Sending initial message\n";
cMessage *msg = new cMessage("StarMsg");
send(msg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);
}
void node::handleMessage(cMessage *msg)
{
if (msg == timeoutEvent) {
// If we receive the timeout event, that means the packet hasn't
// arrived in time and we have to re-send it.
EV << "Timeout expired, resending message and restarting timer\n";
cMessage *newMsg = new cMessage("StarMsg");
send(newMsg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);
}
else { // message arrived
// Acknowledgement received -- delete the received message and cancel
// the timeout event.
EV << "Timer cancelled.\n";
cancelEvent(timeoutEvent);
delete msg;
// Ready to send another one.
cMessage *newMsg = new cMessage("starMsg");
send(newMsg, "out");
scheduleAt(simTime()+timeout, timeoutEvent);
}
}
class hub : public cSimpleModule
{
protected:
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(hub);
void hub::handleMessage(cMessage *msg)
{
if (uniform(0, 1) < 0.1) {
EV << "\"Losing\" message.\n";
bubble("message lost"); // making animation more informative...
delete msg;
}
else {
EV << "Sending back same message as acknowledgement.\n";
send(msg, "out");
}
}
May I know how to solve this problem?
The issue is exactly what the error message said. The NED file defines the out gate a vector both in node and hub:
output out[];
However your c++ code always uses the send method send(msg, "out") without specifying which out gate should be used. i.e. it never specifies the index. You must use the send(msg, "out", getIndex) for this.
I'm making a randomly generated network where the node will send an update massage after asking if the other node already know the update. Currently the update status is still predefined. I'm getting this error message when running the simulation:
send()/sendDelayed(): Gate index 1048576 out of range when accessing vector gate 'out[]' with size 1 -- in module (Sg1) Simplegossip1.node[2] (id=4), at t=0s event #1
Here's my code:
simplegossip1.ned
simple Sg1
{
parameters:
#display("i=block/routing");
bool updated;
gates:
input in[]; // declare in[] and out[] to be vector gates
output out[];
}
network Simplegossip1
{
parameters:
int count;
double connectedness; // 0.0<x<1.0
#display("bgb=640,444");
submodules:
node[count]: Sg1 {
gates:
in[]; // removed the size of gate
out[];
}
connections allowunconnected:
for i=0..count-2, for j=i+1..count-1, if uniform(0,1)<connectedness {
node[i].out++ --> node[j].in++;
node[i].in++ <-- node[j].out++;
}
}
Here's the cc file.
sg1.cc
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* First attempt for gossip protocol
*/
class Sg1 : public cSimpleModule
{
protected:
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(Sg1);
void Sg1::initialize()
{
if (getIndex() == 0) {
cMessage *askupdated = new cMessage("Ask Update");
int m = gateSize("out");
int l = intuniform(0, m-1);
send(askupdated, "out",l);
}
}
void Sg1::handleMessage(cMessage *msg)
{
//gate randomizer
int n = gateSize("out");
int k = intuniform(0, n-1);
int sid = msg->getArrivalGateId();
bool updatestatus = par("updated");
EV << "Received message `" << msg->getName() << "', sending it out again\n";
if (strncmp (msg->getName(),"Ask Update",2) == 0) {
if (updatestatus == true){
delete msg;
cMessage *updated = new cMessage("Updated");
send(updated, "out", sid);
}
else {
delete msg;
cMessage *unupdated = new cMessage("Unupdated");
send(unupdated, "out", sid);
}
}
else if (strncmp (msg->getName(),"Unupdated",2) == 0) {
delete msg;
cMessage *update = new cMessage("Here is the update");
send(update, "out", sid);
}
else {
delete msg;
cMessage *askupdated = new cMessage("Ask Update");
send(askupdated, "out", sid);
}
}
And an omnet.ini file that only calling the Simplegossip1 network.
How do I solve this? Thanks in advance.
In the line:
int sid = msg->getArrivalGateId();
you read the gate ID. Then you use this value as a gate index:
send(updated, "out", sid);
However, a gate ID is not the same as gate index. Therefore there is an error during send().
In the simulation every object (e.g. module, gate, message) has a unique number (i.e. ID). It is clearly mentioned in
OMNeT++ Simulation Library.
You should check the current size of the gate and be sure that you do not try to send via index out of scope.
I'm making a randomly generated network where the node will send an update massage after asking if the other node already know the update. Currently the update status is still predefined. I'm getting this error message when running the simulation:
"(omnetpp::cModule)Simplegossip1: Unknown parameter 'updated' -- in module (Sg1) Simplegossip1.node[0] (id=2), at t=0s, event #1"
Here's my code:
simplegossip1.ned (I'm using code from here How to create a randomly connected graph in OMNeT++?)
simple Sg1
{
parameters:
#display("i=block/routing");
bool updated;
gates:
input in[]; // declare in[] and out[] to be vector gates
output out[];
}
network Simplegossip1
{
parameters:
int count;
double connectedness; // 0.0<x<1.0
submodules:
node[count]: Sg1 {
gates:
in[]; // removed the size of gate
out[];
}
connections allowunconnected:
for i=0..count-2, for j=i+1..count-1, if uniform(0,1)<connectedness {
node[i].out++ --> node[j].in++;
node[i].in++ <-- node[j].out++;
}
}
sg1.cc
#include <stdio.h>
#include <string.h>
#include <omnetpp.h>
using namespace omnetpp;
/**
* First attempt for gossip protocol
*/
class Sg1 : public cSimpleModule
{
public:
cMessage *askupdated = new cMessage("Ask Update");
cMessage *updated = new cMessage("Updated");
cMessage *unupdated = new cMessage("Unupdated");
cMessage *update = new cMessage("Here is the update");
protected:
virtual void forwardMessage(cMessage *msg, int dest);
virtual void initialize() override;
virtual void handleMessage(cMessage *msg) override;
};
Define_Module(Sg1);
void Sg1::initialize()
{
if (getIndex() == 0) {
// Boot the process scheduling the initial message as a self-message.
char msgname[20];
sprintf(msgname, "tic-%d", getIndex());
cMessage *msg = new cMessage(msgname);
scheduleAt(0.0, msg);
}
}
void Sg1::handleMessage(cMessage *msg)
{
int n = gateSize("out");
int k = intuniform(0, n-1);
int sid = msg->getArrivalGateId();
bool updatestatus = getParentModule()->par("updated");
if (msg == askupdated) {
if (updatestatus == true){
forwardMessage(updated,sid);
}
else {
forwardMessage(unupdated,sid);
}
}
else if (msg == unupdated) {
forwardMessage(update,sid);
}
else {
forwardMessage(askupdated,k);
}
}
void Sg1::forwardMessage(cMessage *msg, int dest)
{
// In this example, we just pick a random gate to send it on.
// We draw a random number between 0 and the size of gate `out[]'.
EV << "Forwarding message " << msg << " on port out[" << dest << "]\n";
send(msg, "out", dest);
}
And an omnet.ini file that only calling the Simplegossip1 network.
How do I solve this? Thanks in advance.
You have to change the line
bool updatestatus = getParentModule()->par("updated");
into
bool updatestatus = par("updated");
because updated is the parameter of Sg1 not of the parent of Sg1.
I have an assignment of creating a Circuit Sim and I'm having issues with NotGate class when I try to use it.
Components is an abstract class.
class Component
{
public:
virtual bool getOutput() = 0;
virtual void prettyPrint(string padding) = 0;
virtual void linearPrint() = 0;
};
Then I have Pin and NotGate, they inherit through dependency of Components.
class Pin {
private:
bool value;
string label;
public:
Pin::Pin(string theLabel) {
label = theLabel;
}
bool Pin::getOutput() {
return value;
}
void Pin::setValue(bool newVal) {
this->value = newVal;
}
};
class NotGate {
private:
shared_ptr<Component> input;
public:
NotGate::NotGate() {
input = make_shared<Component>();
}
bool NotGate::getOutput() {
if (input == 0) {
return true;
} else {
return false;
}
}
void NotGate::setInput(shared_ptr<Component> in) {
this->input = in;
}
};
I created a Pin "c" and a notGate "n1", I want to have "c" as the input for "n1". When I try to do it with the command:
n1->setInput(c);
It tells me that: No viable conversion from 'shared_ptr<Pin>' to 'shared_ptr<Component>s'
I tried creating a new shated_ptr of Components and a bunch of different things that didn't work.
The error message from the compiler is clear. If you want to be able to use a shared_ptr<Pin> when a shared_ptr<Component> is expected, you should make Pin a sub-class of Component. From an abstraction standpoint, it makes sense to me that Pin be a sub-class of Component.
class Pin : public Component
{
...
};
I thought I had found the answer in the following example, but not quite.
boost::asio::ip::udp::socket socket(io_service);
...
boost::asio::ip::address_v4 local_interface =
boost::asio::ip::address_v4::from_string("1.2.3.4");
boost::asio::ip::multicast::outbound_interface option(local_interface);
socket.set_option(option);
How do I map eth0 to the appropriate outbound_interface option?
The following code works fine on Windows and Mac OS X:
const ip::udp::resolver::query queryIF( ip::udp::v4(),
_description->getInterface(), "0" );
const ip::udp::resolver::iterator interfaceIP =
resolver.resolve( queryIF );
if( interfaceIP == end )
return false;
const ip::address ifAddr( ip::udp::endpoint( *interfaceIP ).address( ));
_read->set_option( ip::multicast::join_group( mcAddr.to_v4(),
ifAddr.to_v4( )));
_write->set_option( ip::multicast::outbound_interface( ifAddr.to_v4()));
EDIT: I had some issues on Linux, but did not look into it yet. My guess is the socket option is ignored in favor of the routing table.
I think the reason why your example and eile's example don't work is because you didn't set the SO_BINDTODEVICE socket option.
See this to know why it doesn't work: http://codingrelic.geekhold.com/2009/10/code-snippet-sobindtodevice.html
See this to know how to do it with boost::asio: http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/2724
/**************************************************************************//**
\brief
\details
*******************************************************************************/
class UDPClient : public BoostSocketClient
{
public:
UDPClient ();
virtual ~UDPClient();
virtual ARLErrorCode_e open(int port_num, const char* network_type="ipv4", const char* ip_address="", uint32_t listen_interface=0);
virtual ARLErrorCode_e send(u8* message, u32 size);
virtual ARLErrorCode_e close();
virtual bool isOpen();
//virtual void onReceived(u8*, u32);
private:
void startReceive();
void handleReceive(const boost::system::error_code&, std::size_t);
void handleSend(const boost::system::error_code& error, std::size_t bytes_transferred);
private:
boost::asio::io_service send_ios_;
std::unique_ptr<boost::asio::io_service::work> send_worker_;
boost::asio::io_service receive_ios_;
std::unique_ptr<boost::asio::io_service::work> receive_worker_;
boost::thread send_thread_;
boost::thread receive_thread_;
boost::array<u8, 1024> _buffer;
boost::asio::ip::udp::endpoint send_endpoint_;
boost::asio::ip::udp::endpoint sender_endpoint_;
boost::asio::ip::udp::endpoint listen_endpoint_;
std::unique_ptr<boost::asio::ip::udp::socket> send_udp_socket_;
std::unique_ptr<boost::asio::ip::udp::socket> receive_udp_socket_;
};
#include <ACCompLib/Include/Typedefs.h>
#include <ACCompLib/Include/ARLErrorCodes.h>
#include <NetLib/Platform/Boost/cpp/UDPClient.h>
#include "Ws2tcpip.h"
#include "Iphlpapi.h"
using namespace std;
using namespace boost;
using namespace asio;
using namespace ip;
using namespace NetLib;
/***************************************************************************//**
\brief Constructor
\details
*******************************************************************************/
UDPClient::UDPClient()
{
receive_worker_.reset(new boost::asio::io_service::work(receive_ios_));
}
/***************************************************************************//**
\brief ctor
\details
*******************************************************************************/
UDPClient::~UDPClient()
{
try
{
receive_worker_.reset();
//send_worker_.reset();
if (send_thread_.joinable()) {
send_thread_.join();
}
if (receive_thread_.joinable()) {
receive_thread_.join();
}
}
catch (std::exception& e)
{
std::string str = e.what();
}
}
/***************************************************************************//**
\brief
\details
\note
\param[in]
*******************************************************************************/
ARLErrorCode_e UDPClient::open(int port_num, const char* network_type, const char* multicastAddress, uint32_t listen_interface)
{
try
{
struct in_addr in;
in.S_un.S_addr = listen_interface;
char* address_listen = inet_ntoa(in);
//const char* address_listen = "0.0.0.0";
std::string address_mcast = multicastAddress;
unsigned short address_port = port_num;
boost::system::error_code ec;
boost::asio::ip::address listen_addr = boost::asio::ip::address::from_string(address_listen, ec);
boost::asio::ip::address mcast_addr = boost::asio::ip::address::from_string(address_mcast, ec);
if (strcmp(network_type, "ipv4") == 0)
{
listen_endpoint_ = udp::endpoint(listen_addr, port_num);
send_endpoint_ = udp::endpoint(mcast_addr, port_num);
}
else if (strcmp(network_type, "ipv6") == 0)
{
}
else
return ES35_INVALID_SOCKET_CONNECTION;
send_udp_socket_.reset(new boost::asio::ip::udp::socket(send_ios_));
receive_udp_socket_.reset(new boost::asio::ip::udp::socket(receive_ios_));
send_udp_socket_->open(boost::asio::ip::udp::v4());
receive_udp_socket_->open(listen_endpoint_.protocol());
send_udp_socket_->set_option(boost::asio::ip::udp::socket::reuse_address(true));
receive_udp_socket_->set_option(boost::asio::ip::udp::socket::reuse_address(true));
boost::asio::ip::address_v4 local_interface =
boost::asio::ip::address_v4::from_string(address_listen);
boost::asio::ip::multicast::outbound_interface option(local_interface);
// Join the multicast group.
receive_udp_socket_->set_option(
boost::asio::ip::multicast::join_group(mcast_addr));
send_udp_socket_->set_option(option);
receive_udp_socket_->set_option(option);
boost::asio::ip::multicast::hops hops_option(3);
//send_udp_socket_->set_option(hops_option);
receive_udp_socket_->set_option(hops_option);
receive_udp_socket_->bind(listen_endpoint_);
startReceive();
receive_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &receive_ios_));
send_thread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &send_ios_));
return ES_NoError;
}
catch (std::exception& exp)
{
std::string str = exp.what();
return ES35_INVALID_SOCKET_CONNECTION;
}
}
/***************************************************************************//**
\brief
\details
*******************************************************************************/
ARLErrorCode_e UDPClient::close(void)
{
try {
boost::system::error_code ec;
//udp_socket_->cancel();
//udp_socket_.shutdown(socket_base::shutdown_both, ec);
if (ec)
{
return ES35_INVALID_SOCKET_CONNECTION;
}
if (send_udp_socket_->is_open())
{
send_udp_socket_->close();
}
if (receive_udp_socket_->is_open())
{
receive_udp_socket_->close();
}
receive_udp_socket_.reset();
send_udp_socket_.reset();
}
catch (std::exception& e)
{
std::string str = e.what();
return ES35_INVALID_SOCKET_CONNECTION;
}
return ES_NoError;
}
/***************************************************************************//**
\brief
\details
*******************************************************************************/
bool UDPClient::isOpen()
{
return send_udp_socket_->is_open() && receive_udp_socket_->is_open();
}
/***************************************************************************//**
\brief Send a message.
\details The message is sent asynchronously.
\param message
\param message size
*******************************************************************************/
ARLErrorCode_e UDPClient::send(u8* message, u32 size)
{
if (!isOpen()) {
return ES35_INVALID_SOCKET_CONNECTION;
}
std::string send_to_address = send_endpoint_.address().to_string();
send_udp_socket_->set_option(asio::ip::multicast::enable_loopback(false));
send_udp_socket_->async_send_to(
buffer(message, size),
send_endpoint_,
bind(
&UDPClient::handleSend,
this,
asio::placeholders::error,
asio::placeholders::bytes_transferred));
return ES_NoError;
}
/***************************************************************************//**
\brief Do nothing.
\details This function has the required signature to be used as an
asynchronous send completion handler.
\param not used
\param not used
*******************************************************************************/
void UDPClient::handleSend(const system::error_code& error, size_t)
{
if (error)
{
BoostSocketClient::onError(ES35_UDP_SEND_ERROR, (u8*)error.message().c_str(), error.message().size());
}
else
{
send_udp_socket_->set_option(asio::ip::multicast::enable_loopback(true));
}
}
/***************************************************************************//**
\brief Start an asynchronous receiver.
*******************************************************************************/
void NetLib::UDPClient::startReceive()
{
receive_udp_socket_->async_receive_from(
buffer(_buffer),
sender_endpoint_,
bind(
&UDPClient::handleReceive,
this,
asio::placeholders::error,
asio::placeholders::bytes_transferred));
std::string sender_address = sender_endpoint_.address().to_string();
}
/***************************************************************************//**
\brief Pass received data to the base class.
\details A new receiver is started.
\param error code
\param data size
*******************************************************************************/
void NetLib::UDPClient::handleReceive(const system::error_code& error, size_t size)
{
if (!error || error == error::message_size)
{
BoostSocketClient::onReceived(_buffer.data(), size);
startReceive();
}
else
{
BoostSocketClient::onError(ES35_UDP_RECEIVE_ERROR, (u8*)error.message().c_str(), error.message().size());
}
}
This code is not receiving response.please check
http://permalink.gmane.org/gmane.comp.lib.boost.asio.user/2724 is invalid.
The following code seems to be invalid:
boost::asio::ip::address_v4 local_interface =
boost::asio::ip::address_v4::from_string(ip);
boost::asio::ip::multicast::outbound_interface option(local_interface);
sock.set_option(option);