A Discrete-Event Network Simulator
API
bsm-application.cc
Go to the documentation of this file.
1/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014 North Carolina State University
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Scott E. Carpenter <scarpen@ncsu.edu>
19 *
20 */
21
22#include "ns3/bsm-application.h"
23#include "ns3/log.h"
24#include "ns3/wave-net-device.h"
25#include "ns3/wave-mac-helper.h"
26#include "ns3/wave-helper.h"
27#include "ns3/mobility-model.h"
28#include "ns3/mobility-helper.h"
29
30NS_LOG_COMPONENT_DEFINE ("BsmApplication");
31
32namespace ns3 {
33
34// (Arbitrary) port for establishing socket to transmit WAVE BSMs
36
37NS_OBJECT_ENSURE_REGISTERED (BsmApplication);
38
39TypeId
41{
42 static TypeId tid = TypeId ("ns3::BsmApplication")
44 .SetGroupName ("Wave")
45 .AddConstructor<BsmApplication> ()
46 ;
47 return tid;
48}
49
51 : m_waveBsmStats (0),
52 m_txSafetyRangesSq (),
53 m_TotalSimTime (Seconds (10)),
54 m_wavePacketSize (200),
55 m_numWavePackets (1),
56 m_waveInterval (MilliSeconds (100)),
57 m_gpsAccuracyNs (10000),
58 m_adhocTxInterfaces (0),
59 m_nodesMoving (0),
60 m_unirv (0),
61 m_nodeId (0),
62 m_chAccessMode (0),
63 m_txMaxDelay (MilliSeconds (10)),
64 m_prevTxDelay (MilliSeconds (0))
65{
66 NS_LOG_FUNCTION (this);
67}
68
70{
71 NS_LOG_FUNCTION (this);
72}
73
74void
76{
77 NS_LOG_FUNCTION (this);
78
79 // chain up
81}
82
83// Application Methods
84void BsmApplication::StartApplication () // Called at time specified by Start
85{
86 NS_LOG_FUNCTION (this);
87
88 // setup generation of WAVE BSM messages
89 Time waveInterPacketInterval = m_waveInterval;
90
91 // BSMs are not transmitted for the first second
92 Time startTime = Seconds (1.0);
93 // total length of time transmitting WAVE packets
94 Time totalTxTime = m_TotalSimTime - startTime;
95 // total WAVE packets needing to be sent
97
98 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
99
100 // every node broadcasts WAVE BSM to potentially all other nodes
105 recvSink->Bind (local);
106 recvSink->SetAllowBroadcast (true);
107
108 // dest is broadcast address
109 InetSocketAddress remote = InetSocketAddress (Ipv4Address ("255.255.255.255"), wavePort);
110 recvSink->Connect (remote);
111
112 // Transmission start time for each BSM:
113 // We assume that the start transmission time
114 // for the first packet will be on a ns-3 time
115 // "Second" boundary - e.g., 1.0 s.
116 // However, the actual transmit time must reflect
117 // additional effects of 1) clock drift and
118 // 2) transmit delay requirements.
119 // 1) Clock drift - clocks are not perfectly
120 // synchronized across all nodes. In a VANET
121 // we assume all nodes sync to GPS time, which
122 // itself is assumed accurate to, say, 40-100 ns.
123 // Thus, the start transmission time must be adjusted
124 // by some value, t_drift.
125 // 2) Transmit delay requirements - The US
126 // minimum performance requirements for V2V
127 // BSM transmission expect a random delay of
128 // +/- 5 ms, to avoid simultaneous transmissions
129 // by all vehicles congesting the channel. Thus,
130 // we need to adjust the start transmission time by
131 // some value, t_tx_delay.
132 // Therefore, the actual transmit time should be:
133 // t_start = t_time + t_drift + t_tx_delay
134 // t_drift is always added to t_time.
135 // t_tx_delay is supposed to be +/- 5ms, but if we
136 // allow negative numbers the time could drift to a value
137 // BEFORE the interval start time (i.e., at 100 ms
138 // boundaries, we do not want to drift into the
139 // previous interval, such as at 95 ms. Instead,
140 // we always want to be at the 100 ms interval boundary,
141 // plus [0..10] ms tx delay.
142 // Thus, the average t_tx_delay will be
143 // within the desired range of [0..10] ms of
144 // (t_time + t_drift)
145
146 // WAVE devices sync to GPS time
147 // and all devices would like to begin broadcasting
148 // their safety messages immediately at the start of
149 // the CCH interval. However, if all do so, then
150 // significant collisions occur. Thus, we assume there
151 // is some GPS sync accuracy on GPS devices,
152 // typically 40-100 ns.
153 // Get a uniformly random number for GPS sync accuracy, in ns.
155
156 // When transmitting at a default rate of 10 Hz,
157 // the subsystem shall transmit every 100 ms +/-
158 // a random value between 0 and 5 ms. [MPR-BSMTX-TXTIM-002]
159 // Source: CAMP Vehicle Safety Communications 4 Consortium
160 // On-board Minimum Performance Requirements
161 // for V2V Safety Systems Version 1.0, December 17, 2014
162 // max transmit delay (default 10ms)
163 // get value for transmit delay, as number of ns
164 uint32_t d_ns = static_cast<uint32_t> (m_txMaxDelay.GetInteger ());
165 // convert random tx delay to ns-3 time
166 // see note above regarding centering tx delay
167 // offset by 5ms + a random value.
168 Time txDelay = NanoSeconds (m_unirv->GetInteger (0, d_ns));
169 m_prevTxDelay = txDelay;
170
171 Time txTime = startTime + tDrift + txDelay;
172 // schedule transmission of first packet
175 recvSink, m_wavePacketSize, m_numWavePackets, waveInterPacketInterval, m_nodeId);
176}
177
178void BsmApplication::StopApplication () // Called at time specified by Stop
179{
180 NS_LOG_FUNCTION (this);
181}
182
183void
185 int nodeId,
186 Time totalTime,
187 uint32_t wavePacketSize, // bytes
188 Time waveInterval,
189 double gpsAccuracyNs,
190 std::vector <double> rangesSq, // m ^2
191 Ptr<WaveBsmStats> waveBsmStats,
192 std::vector<int> * nodesMoving,
193 int chAccessMode,
194 Time txMaxDelay)
195{
196 NS_LOG_FUNCTION (this);
197
198 m_unirv = CreateObject<UniformRandomVariable> ();
199
200 m_TotalSimTime = totalTime;
201 m_wavePacketSize = wavePacketSize;
202 m_waveInterval = waveInterval;
203 m_gpsAccuracyNs = gpsAccuracyNs;
204 int size = rangesSq.size ();
205 m_waveBsmStats = waveBsmStats;
206 m_nodesMoving = nodesMoving;
207 m_chAccessMode = chAccessMode;
208 m_txSafetyRangesSq.clear ();
209 m_txSafetyRangesSq.resize (size, 0);
210
211 for (int index = 0; index < size; index++)
212 {
213 // stored as square of value, for optimization
214 m_txSafetyRangesSq[index] = rangesSq[index];
215 }
216
218 m_nodeId = nodeId;
219 m_txMaxDelay = txMaxDelay;
220}
221
222void
224 uint32_t pktCount, Time pktInterval,
225 uint32_t sendingNodeId)
226{
227 NS_LOG_FUNCTION (this);
228
229 // more packets to send?
230 if (pktCount > 0)
231 {
232 // for now, we cannot tell if each node has
233 // started mobility. so, as an optimization
234 // only send if this node is moving
235 // if not, then skip
236 int txNodeId = sendingNodeId;
237 Ptr<Node> txNode = GetNode (txNodeId);
238 Ptr<MobilityModel> txPosition = txNode->GetObject<MobilityModel> ();
239 NS_ASSERT (txPosition != 0);
240
241 int senderMoving = m_nodesMoving->at (txNodeId);
242 if (senderMoving != 0)
243 {
244 // send it!
245 socket->Send (Create<Packet> (pktSize));
246 // count it
247 m_waveBsmStats->IncTxPktCount ();
248 m_waveBsmStats->IncTxByteCount (pktSize);
249 int wavePktsSent = m_waveBsmStats->GetTxPktCount ();
250 if ((m_waveBsmStats->GetLogging () != 0) && ((wavePktsSent % 1000) == 0))
251 {
252 NS_LOG_UNCOND ("Sending WAVE pkt # " << wavePktsSent );
253 }
254
255 // find other nodes within range that would be
256 // expected to receive this broadbast
257 int nRxNodes = m_adhocTxInterfaces->GetN ();
258 for (int i = 0; i < nRxNodes; i++)
259 {
260 Ptr<Node> rxNode = GetNode (i);
261 int rxNodeId = rxNode->GetId ();
262
263 if (rxNodeId != txNodeId)
264 {
265 Ptr<MobilityModel> rxPosition = rxNode->GetObject<MobilityModel> ();
266 NS_ASSERT (rxPosition != 0);
267 // confirm that the receiving node
268 // has also started moving in the scenario
269 // if it has not started moving, then
270 // it is not a candidate to receive a packet
271 int receiverMoving = m_nodesMoving->at (rxNodeId);
272 if (receiverMoving == 1)
273 {
274 double distSq = MobilityHelper::GetDistanceSquaredBetween (txNode, rxNode);
275 if (distSq > 0.0)
276 {
277 // dest node within range?
278 int rangeCount = m_txSafetyRangesSq.size ();
279 for (int index = 1; index <= rangeCount; index++)
280 {
281 if (distSq <= m_txSafetyRangesSq[index - 1])
282 {
283 // we should expect dest node to receive broadcast pkt
284 m_waveBsmStats->IncExpectedRxPktCount (index);
285 }
286 }
287 }
288 }
289 }
290 }
291 }
292
293 // every BSM must be scheduled with a tx time delay
294 // of +/- (5) ms. See comments in StartApplication().
295 // we handle this as a tx delay of [0..10] ms
296 // from the start of the pktInterval boundary
297 uint32_t d_ns = static_cast<uint32_t> (m_txMaxDelay.GetInteger ());
298 Time txDelay = NanoSeconds (m_unirv->GetInteger (0, d_ns));
299
300 // do not want the tx delay to be cumulative, so
301 // deduct the previous delay value. thus we adjust
302 // to schedule the next event at the next pktInterval,
303 // plus some new [0..10] ms tx delay
304 Time txTime = pktInterval - m_prevTxDelay + txDelay;
305 m_prevTxDelay = txDelay;
306
309 socket, pktSize, pktCount - 1, pktInterval, socket->GetNode ()->GetId ());
310 }
311 else
312 {
313 socket->Close ();
314 }
315}
316
318{
319 NS_LOG_FUNCTION (this);
320
321 Ptr<Packet> packet;
322 Address senderAddr;
323 while ((packet = socket->RecvFrom (senderAddr)))
324 {
325 Ptr<Node> rxNode = socket->GetNode ();
326
327 if (InetSocketAddress::IsMatchingType (senderAddr))
328 {
331 for (int i = 0; i < nodes; i++)
332 {
333 if (addr.GetIpv4 () == m_adhocTxInterfaces->GetAddress (i) )
334 {
335 Ptr<Node> txNode = GetNode (i);
336 HandleReceivedBsmPacket (txNode, rxNode);
337 }
338 }
339 }
340 }
341}
342
344 Ptr<Node> rxNode)
345{
346 NS_LOG_FUNCTION (this);
347
348 m_waveBsmStats->IncRxPktCount ();
349
350 Ptr<MobilityModel> rxPosition = rxNode->GetObject<MobilityModel> ();
351 NS_ASSERT (rxPosition != 0);
352 // confirm that the receiving node
353 // has also started moving in the scenario
354 // if it has not started moving, then
355 // it is not a candidate to receive a packet
356 int rxNodeId = rxNode->GetId ();
357 int receiverMoving = m_nodesMoving->at (rxNodeId);
358 if (receiverMoving == 1)
359 {
360 double rxDistSq = MobilityHelper::GetDistanceSquaredBetween (rxNode, txNode);
361 if (rxDistSq > 0.0)
362 {
363 int rangeCount = m_txSafetyRangesSq.size ();
364 for (int index = 1; index <= rangeCount; index++)
365 {
366 if (rxDistSq <= m_txSafetyRangesSq[index - 1])
367 {
368 m_waveBsmStats->IncRxPktInRangeCount (index);
369 }
370 }
371 }
372 }
373}
374
375int64_t
376BsmApplication::AssignStreams (int64_t streamIndex)
377{
378 NS_LOG_FUNCTION (this);
379
380 NS_ASSERT (m_unirv); // should be set by Setup() prevoiusly
381 m_unirv->SetStream (streamIndex);
382
383 return 1;
384}
385
388{
389 NS_LOG_FUNCTION (this);
390
391 std::pair<Ptr<Ipv4>, uint32_t> interface = m_adhocTxInterfaces->Get (id);
392 Ptr<Ipv4> pp = interface.first;
393 Ptr<Node> node = pp->GetObject<Node> ();
394
395 return node;
396}
397
400{
401 NS_LOG_FUNCTION (this);
402
403 std::pair<Ptr<Ipv4>, uint32_t> interface = m_adhocTxInterfaces->Get (id);
404 Ptr<Ipv4> pp = interface.first;
405 Ptr<NetDevice> device = pp->GetObject<NetDevice> ();
406
407 return device;
408}
409
410} // namespace ns3
a polymophic address class
Definition: address.h:91
The base class for all ns3 applications.
Definition: application.h:61
virtual void DoDispose(void)
Destructor implementation.
Definition: application.cc:83
Ptr< Node > GetNode() const
Definition: application.cc:104
The BsmApplication class sends and receives the IEEE 1609 WAVE (Wireless Access in Vehicular Environm...
uint32_t m_wavePacketSize
bytes
Ptr< NetDevice > GetNetDevice(int id)
Get the net device for the desired id.
Ipv4InterfaceContainer * m_adhocTxInterfaces
transmit interfaces
Time m_TotalSimTime
total sim time
int64_t AssignStreams(int64_t streamIndex)
Assign a fixed random variable stream number to the random variables used by this model.
void GenerateWaveTraffic(Ptr< Socket > socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval, uint32_t sendingNodeId)
Creates and transmits a WAVE BSM packet.
virtual void StartApplication(void)
Called at time specified by Start.
std::vector< double > m_txSafetyRangesSq
tx safety range squared, for optimization
Time m_txMaxDelay
When transmitting at a default rate of 10 Hz, the subsystem shall transmit every 100 ms +/- a random ...
uint32_t m_numWavePackets
number of wave packets
double m_gpsAccuracyNs
GPS accuracy.
void ReceiveWavePacket(Ptr< Socket > socket)
Receive a WAVE BSM packet.
std::vector< int > * m_nodesMoving
nodes moving
static TypeId GetTypeId(void)
Get the type ID.
virtual void StopApplication(void)
Called at time specified by Stop.
int m_chAccessMode
WAVE channel access mode. 0=continuous PHY; 1=channel-switching.
Ptr< UniformRandomVariable > m_unirv
random variable
static int wavePort
(Arbitrary) port number that is used to create a socket for transmitting WAVE BSMs.
Time m_waveInterval
wave interval
void Setup(Ipv4InterfaceContainer &i, int nodeId, Time totalTime, uint32_t wavePacketSize, Time waveInterval, double gpsAccuracyNs, std::vector< double > rangesSq, Ptr< WaveBsmStats > waveBsmStats, std::vector< int > *nodesMoving, int mode, Time txDelay)
Setup BSM generation parameters for a node.
Time m_prevTxDelay
previous transmit delay
BsmApplication()
Constructor.
virtual void DoDispose(void)
Destructor implementation.
void HandleReceivedBsmPacket(Ptr< Node > txNode, Ptr< Node > rxNode)
Handle the receipt of a WAVE BSM packet from sender to receiver.
Ptr< WaveBsmStats > m_waveBsmStats
BSM stats.
an Inet address class
Ipv4Address GetIpv4(void) const
static bool IsMatchingType(const Address &address)
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Ipv4Address GetAny(void)
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
static double GetDistanceSquaredBetween(Ptr< Node > n1, Ptr< Node > n2)
Keep track of the current position and velocity of an object.
Network layer to device interface.
Definition: net-device.h:96
A network Node.
Definition: node.h:57
uint32_t GetId(void) const
Definition: node.cc:109
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static void ScheduleWithContext(uint32_t context, Time const &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:571
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
virtual Ptr< Node > GetNode(void) const =0
Return the node this socket is associated with.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
virtual int Close(void)=0
Close a socket.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetDouble(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:419
int64_t GetInteger(void) const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:423
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:829
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionally.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
nodes
Definition: first.py:32
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:89