With particular regards to Ieee80211 in INet library, I have a question about what happens when a cPacket/cMessage is sent across multiple stations.
It is possible that this is not strictly about INet, but a general behavior of OmNet++. Here's the question:
When sending a cPacket/cMessage and it is received by multiple stations/modules, is it copied or all receivers get a pointer to the same instance?
Real scenario
So, in such a network:
Station A is sending a cMessage which is received by all the other stations. Of course only one station is the receiver, everyone else will drop the packet. So if B is the receiver and C, D, E and F go:
void handleMessage(cMessage *msg) {
if (this->isNotForUs())
delete msg;
}
Will it cause B to have its frame destroyed?
In OMNeT++/INET sending a cMessage to multiple receivers is modelled by creating multiple copies of this message and sending one copy to one receiver. There is dup() method that creates an exact copy of the message. For example:
cMessage *msg2 = msg->dup();
As a consequence, every receiver will receive a new instance of cMessage object, and it can remove or process it in any way. Therefore, in your example deleting a message by C,D,E, and F does not affect the message received by B.
Related
I am working on a project where an RSU sends beacons to the cars in its range .When this beacon is received by the car it should send its id back to the RSU.I made a custom message file with just the vehicle id in it.This is how i am handling the beacons now.
void MyVeinsApp::onBSM(DemoSafetyMessage* bsm)
{
findHost()->getDisplayString().setTagArg("i", 1, "green");
if(sentMessage==false){
sendDown(bsm);
//scheduleAt(simTime() + 2 + uniform(0.01, 0.2), wsm->dup());
sentMessage=true;
}
}
This does not work for me at all.Is there any way I can send messages from cars to RSU?
I am not an expert but i recently started working on a similar project with yours. So your message includes a parameter like, let say, vehicle_id and upon receiving a beacon you have to send the message to the RSU with the id include. To do such thing you have to first of all fill the message with the vehicle id like
bsm->setVehicle_id(findHost()->getIndex());
When you create a new message file with variables inside it and then building it the program also creates the get() and set() functions in order to handle those parameters.
Now for the RSU to simply acquire the message variable you have sent it must call the get() function like:
RSU_vehicle_id=wsm->getVehicle_id();
So now you have a variable that includes the received vehicle node id.
I highly suggest you to offer a couple of day just to understand the principles behind the Veins tutorial and how it handles all its aspects.
I have a sensor network where nodes exchange messages and calculate some parameters on which we decide if a clone has been inserted into the network or not. If it is the case, I call the endSimulation() instruction in order to stop the simulation. But I noticed that some messages continue to be exchanged after the instruction endsimulation() and I got the message:
undisposed object: (omnetpp::cMessage) Drones.clone.app.event2 -- check module destructor"
Although I have a finish() method where I cancelAndDelete(event2). I want to know how to delete event after calling endSimulation().
I am working on a wireless routing protocol. I have created a Queue at every node. In this queue, every node kept packet which it already transmitted. If packet is not transmitted by nexthop then previous node will retransmit the packet after timeout. The problem is that when node is trying to retransmitt the packet by calling postRotingHook in handle function to retransmit then it is not doing anything. This postRoutingHook is created locally so it is not actually sending the packet. So how to connect this packet with network for retransmission?
Example: Suppose We have 3 nodes A, B and C. A is source, B is intermediate and C is destination. Node A sent a packet initially. Now node B will forward it to node C. At this time node A will overhear this packet and it will cancel the timer and delete this packet from its Queue. (in normal condition)
Suppose node B could not forward the packet because of some reason then node A should re-transmit the packet after time out. I am unable to achieve this functionality.
My programming scenario is:
I have modified GPSR protocol. Where header file have definition of these 5 INetfilterHooks methods. I didn't use any control packet e.g. request, response, beacon etc. I am directly dealing with data packet which contains some control information. I have implemented my logic in datagramPreRoutingHook() method (when data is received from lower layer) and datagramLocalOutHook() method (when data is received from upper layer).
Source node (at network layer) receives packet from upper layer at IPv4.cc using handlePacketFromHL() ->datagramLocalOutHook(datagram, destIE, nextHopAddr) == INetfilter::IHook::ACCEPT) when it calls datagramLocalOutHook(datagram, destIE, nextHopAddr) then control goes to my routing protocol. It makes necessary changes, Adds source, destination address, creates options and keeps the packet in Queue (for retransmission by scheduling timer) then return ACCEP. Then control again goes to IPv4.cc.
After this process, if time out occurs at my protocol then I am unable to send packet to IPv4.cc. I called postRoutingHook to retransmit the packet then it simly return ACCEPT (as defined in header file) and does nothing. I have tried to call some methods of IPv4.cc by making object of IPv4 in my protocol but these methods are protected so I couldn't access these methods.
I tried with making some public methods of IPv4.cc but it is giving error at further stage.
I have tried to make the object of INetfilter::IHook for calling its postRoutingHook() but is also providing error as object of abstract class can not be created.
TLDR: Can I register callback functions in golang to get notified if a struct member is changed?
I would like to create a simple two-way-binding between a go server and an angular client. The communication is done via websockets.
Example:
Go:
type SharedType struct {
A int
B string
}
sharedType := &SharedType{}
...
sharedType.A = 52
JavaScript:
var sharedType = {A: 0, B: ""};
...
sharedType.A = 52;
Idea:
In both cases, after modifying the values, I want to trigger a custom callback function, send a message via the websocket, and update the value on the client/server side accordingly.
The sent message should only state which value changed (the key / index) and what the new value is. It should also support nested types (structs, that contain other structs) without the need of transmitting everything.
On the client side (angular), I can detect changes of JavaScript objects by registering a callback function.
On the server side (golang), I could create my own map[] and slice[] implementations to trigger callbacks everytime a member is modified (see the Cabinet class in this example: https://appliedgo.net/generics/).
Within these callback-functions, I could then send the modified data to the other side, so two-way binding would be possible for maps and slices.
My Question:
I would like to avoid things like
sharedType.A = 52
sharedType.MemberChanged("A")
// or:
sharedType.Set("A", 52) //.. which is equivalent to map[], just with a predifined set of allowed keys
Is there any way in golang to get informed if a struct member is modified? Or is there any other, generic way for easy two-way binding without huge amounts of boiler-plate code?
No, it's not possible.
But the real question is: how do you suppose to wield all such magic in your Go program?
Consider what you'd like to have would be indeed possible.
Now an innocent assignment
v.A = 42
would—among other things—trigger sending stuff
over a websocket connection to the client.
Now what happens if the connection is closed (client disconnected),
and the sending fails?
What happens if sending fails to complete before a deadline is reached?
OK, suppose you get it at least partially right and actual modification of the local field happens only if sending succeeds.
Still, how should sending errors be handled?
Say, what should happen if the third assignment in
v.A = 42
v.B = "foo"
v.C = 1e10-23
fails?
you could try using server sent events (SSE) to send realtime data to the frontend, while sending a single post request with ur changes. That way you can monitor in the back and send data every second.
I noticed that in the Veins demo scenario a node broadcasts the data message it creates to each and every other node in the simulation.
I tried to modify that a bit. I modified the sendMessage() function in TraCIDemo11p.cc file by initializing the address of the recipient in the WSMusing the setRecipientAddress() function. But while running the simulation in Veins 3.0, I find that this message is still being broadcast to all the nodes apart from the target node.
How do I implement this p2p connection?
How do I generalize by adding an RSU to the scenario to implement a heterogeneous communication framework?
In its basis the 802.11p standard, which is the main communication standard for Vehicular Communication (and also the one used in Veins), does broadcast.
So basically, whatever you send via a 802.11p network interface, it will always be broadcasted, however you can make-up some type of p2p by doing "source-destination checking" from the frames.
You can extend the WaveShortMessage to contain Source and Destination fields specific for your application, and then perform checks if the destination is receiving from the intended sender.
Lets say we have two nodes nodeSender and nodeReceiver who want to communicate.
nodeSender would need to include its own identifier (name, ID etc) in the message:
msgToSend->setSourceAddress("nodeSender")
nodeReceiver would need to check if the message it "hears" is from the intended sender. Because in reality it will be hearing from multiple senders due to the broadcast nature of 80211p
if(receivedMsg->getSourceAddress() == 'nodeSender')
{
/* this is the message which I need */
else
{
/* do nothing with the message from other senders */
}
You can use vehicles SUMO id as their unique identifier for the addresses. You can obtain that by querying the TraCIMobility module:
cModule *tmpMobility = getParentModule()->getSubmodule("veinsmobility");
mobility = dynamic_cast<Veins::TraCIMobility*>(tmpMobility);
ASSERT(mobility);
mySumoID = mobility->getExternalId();