View | Details | Raw Unified | Return to bug 2324
Collapse All | Expand All

(-)a/src/wave/doc/wave.rst (+80 lines)
 Lines 58-63    Link Here 
58
The source code for the WAVE MAC models lives in the directory
58
The source code for the WAVE MAC models lives in the directory
59
``src/wave``.
59
``src/wave``.
60
60
61
Moveover, the part of IEEE 1609.3 [ieee1609dot3]_, called (WAVE Short Message Protocol, WSMP) 
62
is implemented. This is a simple high layer protocol, which will add a WSMP header before 
63
the user's data is transmit over WAVE devices.
64
61
For better modeling WAVE and VANET, the WAVE models for high layers 
65
For better modeling WAVE and VANET, the WAVE models for high layers 
62
(mainly [ieee1609dot3]_ ) are planned for a later patch.
66
(mainly [ieee1609dot3]_ ) are planned for a later patch.
63
67
 Lines 335-340    Link Here 
335
attributes "TxPowerStart", 
339
attributes "TxPowerStart", 
336
"TxPowerEnd" and "TxPowerLevels" of the YansWifiPhy class by themselves.
340
"TxPowerEnd" and "TxPowerLevels" of the YansWifiPhy class by themselves.
337
341
342
High layer
343
##########
344
345
When users create WaveNetDevice objects by using ``ns3::WaveHelper``, the ``ns3::WsmpProtocol`` will be 
346
added into each Node object automatically. Then, users can use ``ns3::WsmpSocket`` to send and receive data 
347
packet over WSMP header. Here ``ns3::WsmpSocket`` makes references to the UDP design in Internet module.
348
338
Scope and Limitations
349
Scope and Limitations
339
=====================
350
=====================
340
351
 Lines 785-790    Link Here 
785
the request will be discarded by devices and the method will return false to
796
the request will be discarded by devices and the method will return false to
786
indicate failure.
797
indicate failure.
787
798
799
High layer
800
##########
801
802
The APIs of ``ns3::WsmpSocket`` are very similar to that of ``ns3::Socket``, but 
803
``ns3::WsmpSocket`` is not the subclass of ``ns3::Socket``, so users should keep 
804
in mind that "Do Not use Socket when transmiting WSMP packets".
805
806
1. create some Node objects and WaveNetDevice objects by helpers, e.g. one sender and one receiver.
807
808
2. create WsmpSocket objects.
809
810
  ::
811
812
    TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory");
813
    Ptr<WsmpSocket> socket = WsmpSocket::CreateSocket (node, tid);
814
815
3. receiver binds the intertesed WSMP packets by Psid.
816
817
  ::
818
 
819
    Psid psid = Psid(0x80, 0x01);
820
    socket->Bind (psid);
821
822
or binds any coming WSMP packets.
823
824
  ::
825
826
    socket->Bind ();
827
828
4. receiver registers a RecvCallback, then this will be notified when packets come.
829
830
  ::
831
 
832
    socket->SetRecvCallback (MakeCallback (&ReceivePacket));
833
834
5. receiver uses Recv or RecvFrom to read WSMP packets when callback is notified.
835
836
  ::
837
838
    void ReceivePacket (Ptr<WsmpSocket> socket)
839
      {
840
        while (socket->Recv ())
841
          {
842
            NS_LOG_UNCOND ("Received one packet!");
843
          }
844
      }
845
846
6. sender uses Connect to associate with peer host.
847
848
  ::
849
850
    source->Connect (Mac48Address::GetBroadcast(), psid, WsmpInfo());
851
852
Note: Although it is named "Connect", the WSMP protocol is only a connectionless service, 
853
thus this method is just a convenient and helpful function for Send method.
854
Therefor this method is optional if users use SendTo method.
855
856
7. sender uses Send or SendTo to transmit WSMP packets.
857
858
  ::
859
860
    Simulator::Schedule(Seconds (1.0), &WsmpSocket::Send, socket, Create<Packet>(100));
861
862
8. finally sender and receiver close these sockets.
863
864
  ::
865
866
    Simulator::Schedule(Seconds (1.0), &WsmpSocket::Close, socket);
867
788
Attributes
868
Attributes
789
==========
869
==========
790
870
(-)f6eaede3f93d (+148 lines)
Added Link Here 
1
/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2005,2006,2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 *
21
 */
22
23
#include "ns3/vector.h"
24
#include "ns3/string.h"
25
#include "ns3/socket.h"
26
#include "ns3/double.h"
27
#include "ns3/config.h"
28
#include "ns3/log.h"
29
#include "ns3/command-line.h"
30
#include "ns3/mobility-model.h"
31
#include "ns3/yans-wifi-helper.h"
32
#include "ns3/position-allocator.h"
33
#include "ns3/mobility-helper.h"
34
#include <iostream>
35
36
#include "ns3/ocb-wifi-mac.h"
37
#include "ns3/wave-mac-helper.h"
38
#include "ns3/wave-helper.h"
39
#include "ns3/wsmp-socket.h"
40
#include "ns3/wsmp-header.h"
41
#include "ns3/wsmp-protocol.h"
42
43
using namespace ns3;
44
45
NS_LOG_COMPONENT_DEFINE ("WaveWsmp");
46
47
void ReceivePacket (Ptr<WsmpSocket> socket)
48
{
49
  while (socket->Recv ())
50
    {
51
      NS_LOG_UNCOND ("Received one packet!");
52
    }
53
}
54
55
static void GenerateTraffic (Ptr<WsmpSocket> socket, uint32_t pktSize,
56
                             uint32_t pktCount, Time pktInterval )
57
{
58
  if (pktCount > 0)
59
    {
60
      socket->Send (Create<Packet> (pktSize));
61
      Simulator::Schedule (pktInterval, &GenerateTraffic,
62
                           socket, pktSize,pktCount - 1, pktInterval);
63
    }
64
  else
65
    {
66
      socket->Close ();
67
    }
68
}
69
70
int main (int argc, char *argv[])
71
{
72
  std::string phyMode ("OfdmRate6MbpsBW10MHz");
73
  uint32_t packetSize = 1000; // bytes
74
  uint32_t numPackets = 1;
75
  double interval = 1.0; // seconds
76
  bool verbose = false;
77
78
  CommandLine cmd;
79
80
  cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
81
  cmd.AddValue ("packetSize", "size of application packet sent", packetSize);
82
  cmd.AddValue ("numPackets", "number of packets generated", numPackets);
83
  cmd.AddValue ("interval", "interval (seconds) between packets", interval);
84
  cmd.AddValue ("verbose", "turn on all WifiNetDevice log components", verbose);
85
  cmd.Parse (argc, argv);
86
  // Convert to time object
87
  Time interPacketInterval = Seconds (interval);
88
89
  NodeContainer c;
90
  c.Create (2);
91
92
  YansWifiChannelHelper waveChannel = YansWifiChannelHelper::Default ();
93
  YansWavePhyHelper wavePhy =  YansWavePhyHelper::Default ();
94
  wavePhy.SetChannel (waveChannel.Create ());
95
  wavePhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11);
96
  QosWaveMacHelper waveMac = QosWaveMacHelper::Default ();
97
  WaveHelper waveHelper = WaveHelper::Default ();
98
  waveHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
99
                                      "DataMode",StringValue (phyMode),
100
                                      "ControlMode",StringValue (phyMode));
101
  if (verbose)
102
    {
103
	  waveHelper.EnableLogComponents ();      // Turn on all WAVE logging
104
    }
105
  NetDeviceContainer devices = waveHelper.Install (wavePhy, waveMac, c);
106
107
  // If we do not assign channel access here, the WAVE devices will be assigned
108
  // continuous CCH access by default.
109
  for (uint32_t i = 0; i != devices.GetN(); i++)
110
    {
111
      Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice> (devices.Get(i));
112
	  // Alternating access without immediate channel switch
113
      const SchInfo schInfo = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
114
      // An important point is that the receiver should also be assigned channel
115
       // access for the same channel to receive packets.
116
       Simulator::Schedule (Seconds (0.0), &WaveNetDevice::StartSch, device, schInfo);
117
    }
118
119
  // Tracing
120
  wavePhy.EnablePcap ("wave-simple-wsmp", devices);
121
122
  MobilityHelper mobility;
123
  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
124
  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
125
  positionAlloc->Add (Vector (5.0, 0.0, 0.0));
126
  mobility.SetPositionAllocator (positionAlloc);
127
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
128
  mobility.Install (c);
129
130
  TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory");
131
  Ptr<WsmpSocket> recvSink = WsmpSocket::CreateSocket (c.Get (0), tid);
132
  Psid psid = Psid(0x80, 0x01);
133
  recvSink->Bind (psid);
134
  recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
135
136
  Ptr<WsmpSocket> source = WsmpSocket::CreateSocket (c.Get (1), tid);
137
  source->Connect (Mac48Address::GetBroadcast(), psid);
138
139
  Simulator::ScheduleWithContext (c.Get(1)->GetId (),
140
                                  Seconds (1.0), &GenerateTraffic,
141
                                  source, packetSize, numPackets, interPacketInterval);
142
143
  Simulator::Stop (Seconds (10.0));
144
  Simulator::Run ();
145
  Simulator::Destroy ();
146
147
  return 0;
148
}
(-)a/src/wave/examples/wscript (+4 lines)
 Lines 9-14    Link Here 
9
        ['core', 'applications', 'mobility', 'network', 'wifi','wave'])
9
        ['core', 'applications', 'mobility', 'network', 'wifi','wave'])
10
    obj.source = 'wave-simple-device.cc'
10
    obj.source = 'wave-simple-device.cc'
11
11
12
    obj = bld.create_ns3_program('wave-simple-wsmp',
13
        ['core', 'applications', 'mobility', 'network', 'wifi','wave'])
14
    obj.source = 'wave-simple-wsmp.cc'
15
12
    obj = bld.create_ns3_program('vanet-routing-compare',
16
    obj = bld.create_ns3_program('vanet-routing-compare',
13
        ['core', 'aodv', 'applications', 'dsr', 'dsdv', 'flow-monitor', 'mobility', 'network', 'olsr', 'propagation', 'wifi', 'wave'])
17
        ['core', 'aodv', 'applications', 'dsr', 'dsdv', 'flow-monitor', 'mobility', 'network', 'olsr', 'propagation', 'wifi', 'wave'])
14
    obj.source = 'vanet-routing-compare.cc'
18
    obj.source = 'vanet-routing-compare.cc'
(-)a/src/wave/helper/wave-helper.cc (+11 lines)
 Lines 763-768    Link Here 
763
      node->AddDevice (device);
763
      node->AddDevice (device);
764
      devices.Add (device);
764
      devices.Add (device);
765
    }
765
    }
766
767
  // Moreover, ns3::WsmpProtocol class which implements IEEE 1609.3 WSMP protocol will be added into ns3::Node.
768
  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
769
  {
770
	  Ptr<Node> node = (*i);
771
	  ObjectFactory factory;
772
	  factory.SetTypeId ("ns3::WsmpProtocol");
773
	  Ptr<Object> protocol = factory.Create <Object> ();
774
	  node->AggregateObject (protocol);
775
   }
776
766
  return devices;
777
  return devices;
767
}
778
}
768
779
(-)f6eaede3f93d (+312 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2005 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 */
21
22
#include "wsmp-header.h"
23
24
namespace ns3 {
25
26
NS_OBJECT_ENSURE_REGISTERED (WsmpHeader);
27
28
#define WSMP_VERSION_MASK            0x0f
29
30
#define ELEMENT_ID_CHANNEL_NUMBER    0x0f
31
#define ELEMENT_ID_DATARATE          0x10
32
#define ELEMENT_ID_TX_POWER          0x04
33
#define ELEMENT_ID_WSMP_N            0x80
34
#define ELEMENT_ID_WSMP_S            0x81
35
#define ELEMENT_ID_WSMP_I            0x82
36
37
// The length field of channel number, txpower, datarate is 1.
38
#define ELEMENT_LENGTH_ONE           0x01
39
40
const uint16_t WsmpHeader::MAX_HEADER_SIZE = 17;
41
const uint16_t WsmpHeader::MIN_HEADER_SIZE = 8;
42
43
WsmpHeader::WsmpHeader ()
44
  : m_version (0),
45
    m_channel (0),
46
    m_datarate(0),
47
    m_power(0),
48
    m_id(ELEMENT_ID_WSMP_N),
49
    m_length(0)
50
{
51
}
52
53
WsmpHeader::~WsmpHeader ()
54
{
55
}
56
57
void
58
WsmpHeader::SetVersion (uint8_t version)
59
{
60
  m_version = version;
61
}
62
63
uint8_t
64
WsmpHeader::GetVersion (void)
65
{
66
  return m_version;
67
}
68
69
void
70
WsmpHeader::SetPsid (Psid psid)
71
{
72
   m_psid= psid;
73
}
74
75
Psid
76
WsmpHeader::GetPsid (void)
77
{
78
  return m_psid;
79
}
80
81
void
82
WsmpHeader::SetExtensionChannelNumber (uint8_t channelNumber)
83
{
84
  m_channel = channelNumber;
85
}
86
87
uint8_t
88
WsmpHeader::GetExtenstionChannelNumber (void)
89
{
90
  return m_channel;
91
}
92
93
void
94
WsmpHeader::SetExtensionDataRate (uint8_t dataRate)
95
{
96
  m_datarate = dataRate;
97
}
98
99
uint8_t
100
WsmpHeader::GetExtensionDataRate (void)
101
{
102
  return m_datarate;
103
}
104
105
void
106
WsmpHeader::SetExtensionTxPower (int8_t txPowerUsed)
107
{
108
  m_power = txPowerUsed;
109
}
110
111
int8_t
112
WsmpHeader::GetExtensionTxPower (void)
113
{
114
  return m_power;
115
}
116
117
void
118
WsmpHeader::SetElementId (WsmpElementId id)
119
{
120
  switch (id)
121
    {
122
      case WSMP_N:
123
        m_id = ELEMENT_ID_WSMP_N;
124
        break;
125
      case WSMP_S:
126
        m_id = ELEMENT_ID_WSMP_S;
127
        break;
128
      case WSMP_I:
129
        m_id = ELEMENT_ID_WSMP_I;
130
        break;
131
      default:
132
        NS_FATAL_ERROR("Element ID " << id << " cannot be identified");
133
        break;
134
    }
135
}
136
137
WsmpElementId
138
WsmpHeader::GetElementId (void)
139
{
140
  switch (m_id)
141
    {
142
      case ELEMENT_ID_WSMP_N:
143
        return WSMP_N;
144
      case ELEMENT_ID_WSMP_S:
145
        return WSMP_S;
146
      case ELEMENT_ID_WSMP_I:
147
        return WSMP_I;
148
      default:
149
        return WSMP_UNKNOW;
150
    }
151
}
152
153
void
154
WsmpHeader::SetLength(uint16_t length)
155
{
156
  m_length = length;
157
}
158
159
uint16_t
160
WsmpHeader::GetLength (void)
161
{
162
  return m_length;
163
}
164
165
void
166
WsmpHeader::Reset (void)
167
{
168
  m_version = 0;
169
  m_psid = Psid ();
170
  m_channel = 0;
171
  m_datarate = 0;
172
  m_power = 0;
173
  m_id = ELEMENT_ID_WSMP_N;
174
  m_length = 0;
175
}
176
177
TypeId
178
WsmpHeader::GetTypeId (void)
179
{
180
  static TypeId tid = TypeId ("ns3::WsmpHeader")
181
    .SetParent<Header> ()
182
    .SetGroupName ("Wave")
183
    .AddConstructor<WsmpHeader> ()
184
  ;
185
  return tid;
186
}
187
188
TypeId
189
WsmpHeader::GetInstanceTypeId (void) const
190
{
191
  return GetTypeId ();
192
}
193
194
void
195
WsmpHeader::Print (std::ostream &os) const
196
{
197
  os << "m_version=" << m_version << ", ";
198
199
  if (m_channel != 0)
200
    os << "m_channel=" << m_channel << ", ";
201
  if (m_datarate != 0)
202
    os << "m_datarate=" << m_datarate << ", ";
203
  if (m_power != 0)
204
    os << "m_power=" << m_power << ", ";
205
206
  os  << "m_id=" << m_id << ", ";
207
  os  << "m_length" << m_length;
208
}
209
210
uint32_t
211
WsmpHeader::GetSerializedSize (void) const
212
{
213
  return    1
214
            + m_psid.GetLength()
215
            + (m_channel == 0 ? 0 : 3)
216
            + (m_datarate== 0 ? 0 : 3)
217
            + (m_power == 0 ? 0 : 3)
218
            + 1
219
            + 2;
220
}
221
222
void
223
WsmpHeader::Serialize (Buffer::Iterator start) const
224
{
225
  start.WriteU8(m_version & WSMP_VERSION_MASK);
226
227
  const uint8_t * data = m_psid.GetData();
228
  for (uint8_t i = 0; i != m_psid.GetLength(); i++)
229
    start.WriteU8(data[i]);
230
231
  if (m_channel)
232
    {
233
      start.WriteU8(ELEMENT_ID_CHANNEL_NUMBER);
234
      start.WriteU8(ELEMENT_LENGTH_ONE);
235
      start.WriteU8(m_channel);
236
    }
237
  if(m_datarate)
238
    {
239
      start.WriteU8(ELEMENT_ID_DATARATE);
240
      start.WriteU8(ELEMENT_LENGTH_ONE);
241
      start.WriteU8(m_datarate);
242
    }
243
  if (m_power)
244
    {
245
      start.WriteU8(ELEMENT_ID_TX_POWER);
246
      start.WriteU8(ELEMENT_LENGTH_ONE);
247
      start.WriteU8((uint8_t)m_power);
248
    }
249
250
  start.WriteU8(m_id);
251
  start.WriteHtonU16(m_length);
252
}
253
254
uint32_t
255
WsmpHeader::Deserialize (Buffer::Iterator start)
256
{
257
//  Reset();
258
  m_version = start.ReadU8() & WSMP_VERSION_MASK;
259
260
  int length = start.PeekU8();
261
  if (length <= PSID_LENGTH_MASK_ONE)
262
    length = 1;
263
  else if (length <= PSID_LENGTH_MASK_TWO)
264
    length= 2;
265
  else if (length <= PSID_LENGTH_MASK_THREE)
266
    length= 3;
267
  else if (length <= PSID_LENGTH_MASK_FOUR)
268
    length= 4;
269
  else
270
    length = 0;
271
  uint8_t * data = new uint8_t[length];
272
  for (uint8_t i = 0; i != length; i++)
273
    data[i] = start.ReadU8();
274
  m_psid = Psid (data, length);
275
  delete[] data;
276
277
  for (int times = 0; times < 3; times++)
278
    {
279
      uint8_t extension = start.PeekU8();
280
      if (extension == ELEMENT_ID_CHANNEL_NUMBER)
281
        {
282
          start.ReadU8();    // discard the extension id
283
          if (start.ReadU8() != ELEMENT_LENGTH_ONE)
284
            NS_FATAL_ERROR("The length field of Channel Number shall be 1");
285
          m_channel = start.ReadU8();
286
        }
287
      else if (extension == ELEMENT_ID_DATARATE)
288
        {
289
          start.ReadU8();    // discard the extension id
290
          if (start.ReadU8() != ELEMENT_LENGTH_ONE)
291
            NS_FATAL_ERROR("The length field of DataRate shall be 1");
292
          m_datarate = start.ReadU8();
293
       }
294
      else if (extension == ELEMENT_ID_TX_POWER)
295
        {
296
          start.ReadU8();    // discard the extension id
297
          if (start.ReadU8() != ELEMENT_LENGTH_ONE)
298
            NS_FATAL_ERROR("The length field of Tx Power shall be 1");
299
          m_power = (int8_t)start.ReadU8();
300
        }
301
      else
302
        {
303
          break;
304
        }
305
    }
306
307
  m_id = start.ReadU8 ();
308
  m_length = start.ReadNtohU16 ();
309
  return GetSerializedSize ();
310
}
311
312
} // namespace ns3
(-)f6eaede3f93d (+103 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2005 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 */
21
22
#ifndef WSMP_HEADER_H
23
#define WSMP_HEADER_H
24
25
#include "ns3/header.h"
26
#include "wsmp-socket.h"
27
28
namespace ns3 {
29
30
/**
31
 * \ingroup wave
32
 * \brief Packet header for WSMP packets
33
 *
34
 * See IEEE 1609.3 Annex G.2 WSM example
35
 */
36
class WsmpHeader : public Header
37
{
38
public:
39
40
  /**
41
   * \brief Constructor
42
   *
43
   * Creates a null header
44
   */
45
  WsmpHeader ();
46
  virtual ~WsmpHeader ();
47
48
  /**
49
   * \brief The maximum header size for WSMP header.
50
   */
51
  static const uint16_t MAX_HEADER_SIZE;
52
  /**
53
   * \brief The minimum header size for WSMP header.
54
   */
55
  static const uint16_t MIN_HEADER_SIZE;
56
57
  void SetVersion(uint8_t version);
58
  uint8_t GetVersion (void);
59
60
  void SetPsid (Psid psid);
61
  Psid GetPsid (void);
62
63
  void SetExtensionChannelNumber (uint8_t channelNumber);
64
  uint8_t GetExtenstionChannelNumber (void);
65
66
  void SetExtensionDataRate (uint8_t dataRate);
67
  uint8_t GetExtensionDataRate (void);
68
69
  void SetExtensionTxPower (int8_t txPowerUsed);
70
  int8_t GetExtensionTxPower (void);
71
72
  void SetElementId (WsmpElementId id);
73
  WsmpElementId GetElementId (void);
74
75
  void SetLength(uint16_t length);
76
  uint16_t GetLength (void);
77
78
  void Reset (void);
79
80
  /**
81
   * \brief Get the type ID.
82
   * \return the object TypeId
83
   */
84
  static TypeId GetTypeId (void);
85
  virtual TypeId GetInstanceTypeId (void) const;
86
  virtual void Print (std::ostream &os) const;
87
  virtual uint32_t GetSerializedSize (void) const;
88
  virtual void Serialize (Buffer::Iterator start) const;
89
  virtual uint32_t Deserialize (Buffer::Iterator start);
90
91
private:
92
  uint8_t m_version;
93
  Psid m_psid;
94
  uint8_t m_channel;
95
  uint8_t m_datarate;
96
  int8_t m_power;
97
  uint8_t m_id;
98
  uint16_t m_length;
99
};
100
101
} // namespace ns3
102
103
#endif /* WSMP_HEADER */
(-)f6eaede3f93d (+475 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 *
16
 * Author: Junling Bu <linlinjavaer@gmail.com>
17
 */
18
19
#include "ns3/log.h"
20
#include "ns3/wsmp-header.h"
21
#include "ns3/object-vector.h"
22
#include "ns3/wsmp-socket-impl.h"
23
#include "ns3/wsmp-socket-factory-impl.h"
24
#include "wsmp-protocol.h"
25
26
namespace ns3 {
27
28
NS_LOG_COMPONENT_DEFINE ("WsmpProtocol");
29
30
NS_OBJECT_ENSURE_REGISTERED (WsmpProtocol);
31
32
// see 5.2 of IEEE 1609.3
33
const uint16_t WsmpProtocol::PROT_NUMBER = 0x88dc;
34
// see 8.3.2 of IEEE 1609.3
35
const uint8_t WsmpProtocol::VERSION = 0x02;
36
37
TypeId
38
WsmpProtocol::GetTypeId (void)
39
{
40
  static TypeId tid = TypeId ("ns3::WsmpProtocol")
41
    .SetParent<Object> ()
42
    .SetGroupName("Wave")
43
    .AddConstructor<WsmpProtocol> ()
44
    .AddAttribute ("SocketList", "The list of sockets associated to this protocol.",
45
                   ObjectVectorValue (),
46
                   MakeObjectVectorAccessor (&WsmpProtocol::m_sockets),
47
                   MakeObjectVectorChecker<WsmpSocketImpl> ())
48
  .AddAttribute ("WsmMaxLength", "The max length for WSMP header and WSM data.",
49
		  	  	  UintegerValue (1400),
50
		  	  	  MakeUintegerAccessor (&WsmpProtocol::m_wsmMaxLength),
51
		  	  	  MakeUintegerChecker<uint32_t> ());
52
  return tid;
53
}
54
55
WsmpProtocol::WsmpProtocol()
56
: m_node(0),
57
  m_wsmMaxLength(0)
58
{
59
  NS_LOG_FUNCTION_NOARGS ();
60
}
61
62
WsmpProtocol::~WsmpProtocol()
63
{
64
  NS_LOG_FUNCTION_NOARGS ();
65
}
66
67
void
68
WsmpProtocol::DoDispose (void)
69
{
70
  for (std::vector<Ptr<WsmpSocket> >::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
71
    {
72
      *i = 0;
73
    }
74
  m_sockets.clear ();
75
76
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end(); ++i)
77
    {
78
      delete (*i);
79
    }
80
  m_endpoints.clear();
81
82
  m_node = 0;
83
  m_downTarget.Nullify ();
84
  Object::DoDispose ();
85
}
86
87
void
88
WsmpProtocol::NotifyNewAggregate (void)
89
{
90
  NS_LOG_FUNCTION (this);
91
  if (m_node != 0)
92
    return;
93
94
  Ptr<Node> node = this->GetObject<Node> ();
95
  SetNode (node);
96
  Ptr<WsmpSocketFactoryImpl> wsmpFactory = CreateObject<WsmpSocketFactoryImpl> ();
97
  wsmpFactory->SetWsmp (this);
98
  node->AggregateObject (wsmpFactory);
99
100
  Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice>(node->GetDevice(0));
101
  if (device == 0)
102
    NS_FATAL_ERROR_NO_MSG();
103
  node->RegisterProtocolHandler (MakeCallback (&WsmpProtocol::Receive, this), WsmpProtocol::PROT_NUMBER, device);
104
  m_downTarget = MakeCallback (&WaveNetDevice::SendX, device);
105
106
  Object::NotifyNewAggregate ();
107
}
108
109
void
110
WsmpProtocol::SetNode (Ptr<Node> node)
111
{
112
  NS_LOG_FUNCTION (this << node);
113
  m_node = node;
114
}
115
116
Ptr<Node>
117
WsmpProtocol::GetNode (void)
118
{
119
  NS_LOG_FUNCTION (this);
120
  return m_node;
121
}
122
123
uint16_t
124
WsmpProtocol::GetProtocolNumber (void)
125
{
126
  NS_LOG_FUNCTION (this);
127
  return PROT_NUMBER;
128
}
129
130
uint8_t
131
WsmpProtocol::GetVersion (void)
132
{
133
  NS_LOG_FUNCTION (this);
134
  return VERSION;
135
}
136
137
uint32_t
138
WsmpProtocol::GetWsmMaxLength (void)
139
{
140
  NS_LOG_FUNCTION (this);
141
  return m_wsmMaxLength;
142
}
143
144
uint8_t
145
WsmpProtocol::GetPowerLevel (int8_t power)
146
{
147
  // Currently WsmpProtocol supposes that:
148
  // (1) The Node has only single WaveNetDevice
149
  // (2) and The WaveNetDevice only has single WifiPhy.
150
  Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice>(m_node->GetDevice(0));
151
  Ptr<WifiPhy> phy = device->GetPhy(0);
152
  double start = phy->GetTxPowerStart();
153
  double end = phy->GetTxPowerEnd();
154
  uint32_t levels = phy->GetNTxPower();
155
156
  for (uint32_t level = levels; level != 0; level--)
157
    {
158
      // This implementation refers to YansWifiPhy::GetPowerDbm
159
      double dbm = start + level * (end - start) / (levels - 1);
160
      if (dbm <= power)
161
        return level;
162
    }
163
164
    return 0;
165
}
166
167
WifiMode
168
WsmpProtocol::GetDataRate (uint8_t datarate)
169
{
170
  //Currently WsmpProtocol supposes that:
171
  // (1) The Node has only single WaveNetDevice
172
  // (2) and The WaveNetDevice only has single WifiPhy.
173
  Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice>(m_node->GetDevice(0));
174
  Ptr<WifiPhy> phy = device->GetPhy(0);
175
176
  if (datarate * 0.5 <= 3.0)
177
    return WifiPhy::GetOfdmRate3MbpsBW10MHz ();
178
  if (datarate * 0.5 <= 4.5)
179
    return WifiPhy::GetOfdmRate4_5MbpsBW10MHz ();
180
  if (datarate * 0.5 <= 6.0)
181
    return WifiPhy::GetOfdmRate6MbpsBW10MHz ();
182
  if (datarate * 0.5 <= 9.0)
183
    return WifiPhy::GetOfdmRate9MbpsBW10MHz ();
184
  if (datarate * 0.5 <= 12.0)
185
    return WifiPhy::GetOfdmRate12MbpsBW10MHz ();
186
  if (datarate * 0.5 <= 18.0)
187
    return WifiPhy::GetOfdmRate18MbpsBW10MHz ();
188
  if (datarate * 0.5 <= 24.0)
189
    return WifiPhy::GetOfdmRate24MbpsBW10MHz ();
190
  if (datarate * 0.5 <= 27.0)
191
    return WifiPhy::GetOfdmRate27MbpsBW10MHz ();
192
193
  return WifiMode ();
194
}
195
196
int
197
WsmpProtocol::Send (Ptr<Packet> packet, Address peer, Psid psid, WsmpInfo info)
198
{
199
  NS_LOG_FUNCTION (this << packet << peer << psid << &info);
200
  uint8_t channel = info.GetChannelNumber();
201
  uint8_t power = info.GetTxPower();
202
  uint8_t datarate = info.GetDataRate();
203
  uint8_t priority = info.GetUserPriority();
204
205
  // create a WSMP header
206
  WsmpHeader header;
207
  header.SetVersion(VERSION);
208
  header.SetPsid(psid);
209
  if (channel != 0 && info.IsChannelNumberExtension())
210
    {
211
      header.SetExtensionChannelNumber(channel);
212
    }
213
  if (power != 0 && info.IsTxPowerExtension())
214
    {
215
      header.SetExtensionTxPower(power);
216
    }
217
  if (datarate != 0 && info.IsDatatRateExtension())
218
    {
219
      header.SetExtensionDataRate(datarate);
220
    }
221
  header.SetElementId(info.GetElementId());
222
  header.SetLength(packet->GetSize());
223
  packet->AddHeader (header);
224
225
  if (packet->GetSize() > m_wsmMaxLength)
226
    {
227
      NS_LOG_WARN ("The packet size exceeds the allowable maximum size " << m_wsmMaxLength);
228
      return -1;
229
    }
230
231
  TxInfo txInfo;
232
  if (channel != 0)
233
    {
234
      txInfo.channelNumber = channel;
235
    }
236
  if (power != 0)
237
    {
238
      uint8_t level = GetPowerLevel (power);
239
240
      if (level == 0)
241
        {
242
          NS_LOG_WARN ("cannot find the appropriate TxPowerLevel for request power " << power);
243
          return -2;
244
        }
245
      txInfo.txPowerLevel = level;
246
    }
247
  if (datarate != 0)
248
    {
249
      WifiMode mode = GetDataRate (datarate);
250
      if (mode.GetUid () == 0)
251
        {
252
    	  NS_LOG_WARN("cannot determine the appropriate DataRate for request datarate " << datarate);
253
          return -3;
254
         }
255
      txInfo.dataRate = mode;
256
    }
257
  txInfo.priority = priority;
258
259
  bool result = m_downTarget (packet, peer, PROT_NUMBER, txInfo);
260
  if(!result)
261
    {
262
      NS_LOG_WARN("The WaveNetDevice fails to transmit the packet");
263
      return -4;
264
    }
265
266
  return 0;
267
}
268
269
Ptr<WsmpSocket>
270
WsmpProtocol::CreateSocket ()
271
{
272
  NS_LOG_FUNCTION_NOARGS ();
273
  Ptr<WsmpSocketImpl> socket = CreateObject<WsmpSocketImpl> ();
274
  socket->SetWsmp (this);
275
  m_sockets.push_back(socket);
276
  return socket;
277
}
278
279
bool
280
WsmpProtocol::AddIndicationCallback (IndicationCallback callback)
281
{
282
  NS_LOG_FUNCTION (this << &callback);
283
284
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end(); ++i)
285
    {
286
      if ((*i)->indication.IsEqual (callback))
287
        {
288
    	  NS_LOG_WARN ("The parameter callback is already registered");
289
          return false;
290
        }
291
    }
292
293
  /**
294
   * A special "null" PSID indicates that this is a willcard callback.
295
   * Any coming WSMP packets will notify this registered willcard callback.
296
   */
297
  Psid nullPsid = Psid ();
298
299
  EndPoint * endpoint = new EndPoint();
300
  endpoint->psid = nullPsid;
301
  endpoint->indication = callback;
302
  m_endpoints.push_back(endpoint);
303
  return true;
304
}
305
306
bool
307
WsmpProtocol::AddIndicationCallback (Psid psid, IndicationCallback callback)
308
{
309
  NS_LOG_FUNCTION (this << psid << &callback);
310
311
  if (psid.IsNull ())
312
    {
313
      NS_LOG_WARN ("The parameter psid is null");
314
      return false;
315
    }
316
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end(); ++i)
317
    {
318
      if ((*i)->psid == psid)
319
        {
320
    	  NS_LOG_WARN ("The parameter psid is already registered");
321
    	  return false;
322
        }
323
    }
324
325
	EndPoint * endpoint = new EndPoint();
326
	endpoint->psid = psid;
327
	endpoint->indication = callback;
328
	m_endpoints.push_back(endpoint);
329
	return true;
330
}
331
332
bool
333
WsmpProtocol::RemoveIndicationCallback (Psid psid)
334
{
335
  NS_LOG_FUNCTION (this << psid);
336
337
  if (psid.IsNull ())
338
    {
339
      NS_LOG_WARN ("The parameter psid is null");
340
      return false;
341
    }
342
343
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end(); i++)
344
    {
345
      if ((*i)->psid == psid)
346
        {
347
          delete (*i);
348
          m_endpoints.erase(i);
349
          return true;
350
        }
351
    }
352
353
  return false;
354
}
355
356
bool
357
WsmpProtocol::RemoveIndicationCallback (IndicationCallback callback)
358
{
359
  NS_LOG_FUNCTION (this << &callback);
360
361
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end(); i++)
362
    {
363
      if ((*i)->indication.IsEqual (callback))
364
        {
365
          delete (*i);
366
          m_endpoints.erase(i);
367
          return true;
368
        }
369
    }
370
371
  return false;
372
}
373
374
void
375
WsmpProtocol::RemoveWillcardCallbacks (void)
376
{
377
  NS_LOG_FUNCTION (this);
378
379
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end();)
380
    {
381
      if ((*i)->psid.IsNull ())
382
        {
383
          delete (*i);
384
          i = m_endpoints.erase (i);
385
        }
386
      else
387
        {
388
    	  i++;
389
        }
390
    }
391
}
392
393
void
394
WsmpProtocol::RemoveAllCallbacks (void)
395
{
396
  NS_LOG_FUNCTION (this);
397
398
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin (); i != m_endpoints.end (); ++i)
399
    {
400
	  delete (*i);
401
    }
402
  m_endpoints.clear ();
403
}
404
405
void
406
WsmpProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
407
                          const Address &to, NetDevice::PacketType packetType)
408
{
409
  NS_LOG_FUNCTION (this << device << p << protocol << from << to << packetType);
410
411
  Ptr<Packet> pkt = p->Copy (); // need to pass a non-const packet up
412
413
  WsmpHeader header;
414
  pkt->RemoveHeader (header);
415
416
  if (header.GetVersion() > VERSION)
417
    {
418
      NS_LOG_WARN ("The version in the WMSP header is not the supported version");
419
      return;
420
    }
421
422
  Psid psid = header.GetPsid ();
423
  if (!psid.IsValid ())
424
    {
425
      NS_LOG_WARN ("The PSID in the WSMP header is invalid");
426
      return;
427
    }
428
429
  WsmpInfo info;
430
  if (header.GetExtenstionChannelNumber() != 0)
431
    {
432
      info.SetChannelNumber(header.GetExtenstionChannelNumber(), true);
433
    }
434
  if (header.GetExtensionTxPower() != 0)
435
    {
436
      info.SetTxPower(header.GetExtensionTxPower(), true);
437
    }
438
  if (header.GetExtensionDataRate() != 0)
439
    {
440
      info.SetDataRate(header.GetExtensionDataRate(), true);
441
    }
442
443
  WsmpElementId id = header.GetElementId();
444
  if (id != WSMP_N)
445
    {
446
      NS_LOG_WARN ("The WAVE Element ID in the WSMP header is not supported");
447
      return;
448
    }
449
450
  uint16_t length = header.GetLength();
451
  if (length != pkt->GetSize())
452
    {
453
      NS_LOG_WARN ("The length in the WSMP header is same with the received data length");
454
      return;
455
    }
456
457
  for (std::vector<EndPoint *>::iterator i = m_endpoints.begin(); i != m_endpoints.end(); ++i)
458
    {
459
      if ((*i)->psid == psid)
460
        {
461
          IndicationCallback indication = (*i)->indication;
462
          indication(pkt->Copy(), from, psid,  info);
463
          return;
464
        }
465
466
      if ((*i)->psid.IsNull ())
467
        {
468
          IndicationCallback indication = (*i)->indication;
469
          indication(pkt->Copy(), from, psid,  info);
470
          continue;
471
        }
472
    }
473
}
474
475
} // namespace ns3
(-)f6eaede3f93d (+208 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 *
16
 * Author: Junling Bu <linlinjavaer@gmail.com>
17
 */
18
19
#ifndef WSMP_PROTOCOL_H
20
#define WSMP_PROTOCOL_H
21
22
#include "ns3/address.h"
23
#include "ns3/wsmp-socket.h"
24
#include "ns3/wave-net-device.h"
25
#include "ns3/wifi-mode.h"
26
#include <vector>
27
28
namespace ns3 {
29
30
class WsmpSocket;
31
32
/**
33
 * \brief Implementation of the WSMP protocol
34
 * \ingroup wave
35
 *
36
* A few things to keep in mind about this type protocol of WSMP:
37
* - WSMP is similar, but different from UDP.
38
* - WSMP uses PSID to identify service rather than port in UDP.
39
* - WSMP only use single PSID rather than source port and destination ports in UDP
40
* - WSMP can specify some tx parameters for transmit.
41
*
42
* Different from Ipv4L3Protocol class which will internally support add multiple
43
* NetDevice and UdpL4Protocol class which will bind these devices with IP address and Port,
44
* currently  WsmpProtocol class will only support add and bind the single device.
45
*
46
* About WsmpSocket API, IEEE 1609.3 only defines three service primitives:
47
* - WSM-WaveShortMessage.request
48
* - WSM-WaveShortMessage.confirm
49
* - WSM-WaveShortMessage.indication
50
* Therefore, WsmpProtocol class here provides two methods to support service primitives:
51
* Send
52
* IndicationCallback
53
*/
54
class WsmpProtocol  : public Object {
55
public:
56
  /**
57
   * \brief Get the type ID.
58
   * \return the object TypeId
59
   */
60
  static TypeId GetTypeId (void);
61
  WsmpProtocol();
62
  virtual ~WsmpProtocol();
63
64
  /**
65
   * \brief The protocol number for WSMP (0x88DC).
66
   */
67
  static const uint16_t PROT_NUMBER;
68
  /**
69
   * \brief The protocol version for WSMP (2).
70
   */
71
  static const uint8_t VERSION;
72
73
  /**
74
   * Set node associated with this stack
75
   * \param node the node
76
   */
77
  void SetNode (Ptr<Node> node);
78
79
  /**
80
   * \return the associated node
81
   */
82
  Ptr<Node> GetNode (void);
83
84
  /**
85
   * \return the protocol number (or Ethertype)
86
   */
87
  uint16_t GetProtocolNumber (void);
88
89
  /**
90
   * \return which version of WSMP protocol
91
   */
92
  uint8_t GetVersion (void);
93
94
  /**
95
   * \return the allowable maximum length for WSMP header and WSM data.
96
   */
97
  uint32_t GetWsmMaxLength (void);
98
99
  /**
100
   * \return A smart Socket pointer to a WsmpSocket, allocated by this instance
101
   * of the WSMP protocol
102
   */
103
  Ptr<WsmpSocket> CreateSocket (void);
104
105
  /**
106
   * \param packet packet to send
107
   * \param peer peer address of packet
108
   * \param psid psid of packet
109
   * \param info tx information
110
   * \return
111
   */
112
  int Send (Ptr<Packet> packet, Address peer, Psid psid, WsmpInfo info);
113
114
  /**
115
   * IndicationCallback signature for packet receipt events.
116
   *
117
   * \param packet the packet.
118
   * \param address the peer adress
119
   * \param psid the psid of this packet
120
   * \param info the extension wsmp information of this packet
121
   * \return the callback result
122
   */
123
  typedef Callback< bool, Ptr<Packet>, const Address &, const Psid &,  const WsmpInfo & > IndicationCallback;
124
125
  /**
126
   * \brief Add a normal IndicationCallback
127
   * \param psid the psid specify which type WSMP packets will be delivered
128
   * \param callback the callback which will be notified
129
   * \return whether succeed or fail
130
   */
131
  bool AddIndicationCallback (Psid psid, IndicationCallback callback);
132
  /**
133
   * \brief Add a willcard IndicationCallback
134
   * \return whether succeed or fail
135
   *
136
   * Any coming WSMP packets will notify this callback.
137
   */
138
  bool AddIndicationCallback (IndicationCallback callback);
139
140
  /**
141
   * \brief Remove IndicationCallback indicated by PSID
142
   * \param psid the psid
143
   * \return whether succeed or fail
144
   */
145
  bool RemoveIndicationCallback (Psid psid);
146
  /**
147
   * \brief Remove IndicationCallback indicated by callback
148
   * \param callback the callback
149
   * \return whether succeed or fail
150
   */
151
  bool RemoveIndicationCallback (IndicationCallback callback);
152
  /**
153
   * \brief Remove all of wildcard IndicationCallback
154
   */
155
  void RemoveWillcardCallbacks (void);
156
  /**
157
   * \brief Remove all of IndicationCallback
158
   */
159
  void RemoveAllCallbacks (void);
160
161
protected:
162
  /**
163
   * \brief Allocate a local endpoint for this socket.
164
   * \param address the address to try to allocate
165
   */
166
  void Receive (Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
167
                            const Address &to, NetDevice::PacketType packetType);
168
169
  virtual void DoDispose (void);
170
  /*
171
   * This function will notify other components connected to the node that a new stack member is now connected
172
   */
173
  virtual void NotifyNewAggregate (void);
174
175
  /**
176
   * The IEEE 1609.3 specifies parameter "power", while IEEE 1609.4 specifies parameter "power level".
177
   * Here this function will do convert operation.
178
   */
179
  uint8_t GetPowerLevel (int8_t power);
180
  /**
181
   * Here this function will do convert operation.
182
   */
183
  WifiMode GetDataRate (uint8_t datarate);
184
185
private:
186
  Ptr<Node> m_node;
187
  uint32_t m_wsmMaxLength;
188
189
  /**
190
   * \brief callback to send packets over WaveNetDevice::SendX method
191
   */
192
  typedef Callback<bool, Ptr<Packet>, const Address &, uint32_t, const TxInfo & > SendXCallback;
193
  SendXCallback m_downTarget;
194
195
  std::vector<Ptr<WsmpSocket> > m_sockets;
196
197
  struct EndPoint
198
    {
199
      Psid psid;
200
      IndicationCallback indication;
201
    };
202
203
  std::vector<EndPoint *> m_endpoints;
204
};
205
206
} // namespace ns3
207
208
#endif /* WSMP_PROTOCOL_H */
(-)f6eaede3f93d (+55 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 */
21
22
#include "wsmp-socket-factory-impl.h"
23
24
namespace ns3 {
25
26
NS_OBJECT_ENSURE_REGISTERED (WsmpSocketFactoryImpl);
27
28
WsmpSocketFactoryImpl::WsmpSocketFactoryImpl ()
29
: m_wsmp (0)
30
{
31
}
32
WsmpSocketFactoryImpl::~WsmpSocketFactoryImpl ()
33
{
34
}
35
36
void
37
WsmpSocketFactoryImpl::SetWsmp (Ptr<WsmpProtocol> wsmp)
38
{
39
  m_wsmp = wsmp;
40
}
41
42
Ptr<WsmpSocket>
43
WsmpSocketFactoryImpl::CreateSocket (void)
44
{
45
  return m_wsmp->CreateSocket();
46
}
47
48
void
49
WsmpSocketFactoryImpl::DoDispose (void)
50
{
51
  m_wsmp = 0;
52
  WsmpSocketFactory::DoDispose ();
53
}
54
55
} // namespace ns3
(-)f6eaede3f93d (+66 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 */
21
#ifndef WSMP_SOCKET_FACTORY_IMPL_H
22
#define WSMP_SOCKET_FACTORY_IMPL_H
23
24
#include "wsmp-socket.h"
25
#include "wsmp-socket-factory.h"
26
#include "wsmp-protocol.h"
27
28
namespace ns3 {
29
30
/**
31
 * \ingroup wave
32
 * \brief Object to create WSMP socket instances
33
 *
34
 * This class implements the API for creating WSMP sockets.
35
 * It is a socket factory (deriving from class WsmpSocketFactory).
36
 */
37
class WsmpSocketFactoryImpl : public WsmpSocketFactory
38
{
39
public:
40
  WsmpSocketFactoryImpl ();
41
  virtual ~WsmpSocketFactoryImpl ();
42
43
  /**
44
   * \brief Set the associated WSMP protocol.
45
   * \param udp the WSMP protocol
46
   */
47
  void SetWsmp (Ptr<WsmpProtocol> wsmp);
48
49
  /**
50
   * \brief Implements a method to create a Wsmp-based socket and return
51
   * a base class smart pointer to the socket.
52
   *
53
   * \return smart pointer to Socket
54
   */
55
  virtual Ptr<WsmpSocket> CreateSocket (void);
56
57
protected:
58
  virtual void DoDispose (void);
59
60
private:
61
  Ptr<WsmpProtocol> m_wsmp;
62
};
63
64
} // namespace ns3
65
66
#endif /* WSMP_SOCKET_FACTORY_IMPL_H */
(-)f6eaede3f93d (+48 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 */
21
22
#include "wsmp-socket-factory.h"
23
24
namespace ns3 {
25
26
NS_OBJECT_ENSURE_REGISTERED (WsmpSocketFactory);
27
28
29
TypeId WsmpSocketFactory::GetTypeId (void)
30
{
31
  static TypeId tid = TypeId ("ns3::WsmpSocketFactory")
32
    .SetParent<Object> ()
33
    .SetGroupName ("Wave")
34
  ;
35
  return tid;
36
}
37
38
39
WsmpSocketFactory::WsmpSocketFactory ()
40
{
41
}
42
43
WsmpSocketFactory::~WsmpSocketFactory ()
44
{
45
}
46
47
} // namespace ns3
48
(-)f6eaede3f93d (+63 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19
 * Author: Junling Bu <linlinjavaer@gmail.com>
20
 */
21
22
#ifndef WSMP_SOCKET_FACTORY_H
23
#define WSMP_SOCKET_FACTORY_H
24
25
#include "ns3/wsmp-socket.h"
26
27
namespace ns3 {
28
29
class WsmpSocket;
30
31
/**
32
 * \ingroup wave
33
 *
34
 * \brief API to create WSMP socket instances
35
 *
36
 * This abstract class defines the API for WSMP socket factory.
37
 * All WSMP implementations must provide an implementation of CreateSocket
38
 * below.
39
 *
40
 * \see WsmpSocketFactoryImpl
41
 */
42
class WsmpSocketFactory  : public Object {
43
public:
44
  /**
45
   * \brief Get the type ID.
46
   * \return the object TypeId
47
   */
48
  static TypeId GetTypeId (void);
49
50
  WsmpSocketFactory ();
51
  virtual ~WsmpSocketFactory();
52
53
  /**
54
   * \return smart pointer to Socket
55
   *
56
   * Base class method for creating socket instances.
57
   */
58
  virtual Ptr<WsmpSocket> CreateSocket (void) = 0;
59
};
60
61
} // namespace ns3
62
63
#endif /* WSMP_SOCKET_FACTORY_H */
(-)f6eaede3f93d (+236 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 *
16
 * Author: Junling Bu <linlinjavaer@gmail.com>
17
 */
18
19
#include "ns3/log.h"
20
#include "ns3/wave-net-device.h"
21
#include "ns3/wsmp-header.h"
22
#include "wsmp-socket-impl.h"
23
24
namespace ns3 {
25
26
NS_LOG_COMPONENT_DEFINE ("WsmpSocketImpl");
27
28
NS_OBJECT_ENSURE_REGISTERED (WsmpSocketImpl);
29
30
TypeId
31
WsmpSocketImpl::GetTypeId (void)
32
{
33
  static TypeId tid = TypeId ("ns3::WsmpSocketImpl")
34
    .SetParent<WsmpSocket> ()
35
    .SetGroupName("Wave")
36
    .AddAttribute ("RcvBufSize",
37
                   "WsmpSocket maximum receive buffer size (bytes)",
38
                   UintegerValue (131072),
39
                   MakeUintegerAccessor (&WsmpSocketImpl::GetRcvBufSize,
40
                                         &WsmpSocketImpl::SetRcvBufSize),
41
                   MakeUintegerChecker<uint32_t> ());
42
  return tid;
43
}
44
45
WsmpSocketImpl::WsmpSocketImpl()
46
: m_node (0),
47
  m_wsmp (0),
48
  m_connected (false),
49
  m_binded (false),
50
  m_rcvBufSize (0),
51
  m_rxAvailable (0)
52
{
53
}
54
55
WsmpSocketImpl::~WsmpSocketImpl()
56
{
57
}
58
59
void
60
WsmpSocketImpl::SetWsmp(Ptr<WsmpProtocol> wsmp)
61
{
62
  NS_LOG_FUNCTION (this << wsmp);
63
  m_wsmp = wsmp;
64
}
65
66
void
67
WsmpSocketImpl::SetRcvBufSize (uint32_t size)
68
{
69
  NS_LOG_FUNCTION (this << size);
70
  m_rcvBufSize = size;
71
}
72
73
uint32_t
74
WsmpSocketImpl::GetRcvBufSize (void) const
75
{
76
  NS_LOG_FUNCTION (this);
77
  return m_rcvBufSize;
78
}
79
int
80
WsmpSocketImpl::Bind (const Psid &psid)
81
{
82
  NS_LOG_FUNCTION (this << psid);
83
84
  if (m_binded)
85
    return -1;
86
87
  m_callback = MakeCallback (&WsmpSocketImpl::ForwardUp, this);
88
  m_binded = m_wsmp->AddIndicationCallback(psid, m_callback);
89
  if (!m_binded)
90
    return -2;
91
92
  return 0;
93
}
94
95
int
96
WsmpSocketImpl::Bind (void)
97
{
98
  NS_LOG_FUNCTION (this);
99
100
  if (m_binded)
101
    return -1;
102
103
  m_callback = MakeCallback (&WsmpSocketImpl::ForwardUp, this);
104
  m_binded = m_wsmp->AddIndicationCallback(m_callback);
105
106
  if (!m_binded)
107
    return -2;
108
109
  return 0;
110
}
111
112
uint32_t
113
WsmpSocketImpl::GetTxAvailable (void) const
114
{
115
  NS_LOG_FUNCTION (this);
116
  // Since WSMP header is variable, here we choose a conservative way.
117
  return m_wsmp->GetWsmMaxLength () - WsmpHeader::MAX_HEADER_SIZE;
118
}
119
120
uint32_t
121
WsmpSocketImpl::GetRxAvailable (void) const
122
{
123
  NS_LOG_FUNCTION (this);
124
  // We separately maintain this state to avoid walking the queue
125
  // every time this might be called
126
  return m_rxAvailable;
127
}
128
129
Ptr<Packet>
130
WsmpSocketImpl::Recv ()
131
{
132
  NS_LOG_FUNCTION (this);
133
134
  if (m_deliveryQueue.empty ())
135
    return 0;
136
137
  RecvedPacket* p = m_deliveryQueue.front ();
138
  m_deliveryQueue.pop ();
139
  Ptr<Packet> pkt = p->packet;
140
  m_rxAvailable -= pkt->GetSize();
141
  delete p;
142
  return pkt;
143
}
144
145
Ptr<Packet>
146
WsmpSocketImpl::RecvFrom (Address & address, Psid & psid, WsmpInfo & wsmpInfo)
147
{
148
  NS_LOG_FUNCTION (this);
149
  if (m_deliveryQueue.empty ())
150
    return 0;
151
152
  RecvedPacket* p = m_deliveryQueue.front ();
153
  m_deliveryQueue.pop ();
154
  Ptr<Packet> pkt = p->packet;
155
  address = p->peer;
156
  psid = p->psid;
157
  m_rxAvailable -= pkt->GetSize ();
158
  delete p;
159
  return pkt;
160
}
161
162
int
163
WsmpSocketImpl::Connect (const Psid &psid)
164
{
165
  NS_LOG_FUNCTION (this);
166
  return Connect (Mac48Address::GetBroadcast(), psid);
167
}
168
int
169
WsmpSocketImpl::Connect (const Address &peer, const Psid &psid)
170
{
171
  NS_LOG_FUNCTION (this);
172
  return Connect (peer, psid, WsmpInfo ());
173
}
174
175
int
176
WsmpSocketImpl::Connect (const Address &peer, const Psid &psid, const WsmpInfo &wsmpInfo)
177
{
178
  NS_LOG_FUNCTION (this);
179
  m_defaultPeer = peer;
180
  m_defaultPsid = psid;
181
  m_defaultWsmpInfo = wsmpInfo;
182
  m_connected = true;
183
  return 0;
184
}
185
186
int
187
WsmpSocketImpl::Send (Ptr<Packet> packet)
188
{
189
  NS_LOG_FUNCTION (this << packet);
190
  if (!m_connected)
191
    {
192
      return -1;
193
    }
194
195
  return m_wsmp->Send(packet, m_defaultPeer, m_defaultPsid, m_defaultWsmpInfo);
196
}
197
198
int
199
WsmpSocketImpl::SendTo (Ptr<Packet> packet, const Address & peer, const Psid & psid, const WsmpInfo & wsmpInfo)
200
{
201
  NS_LOG_FUNCTION (this << packet << peer << psid << &wsmpInfo);
202
  return  m_wsmp->Send(packet, peer, psid, wsmpInfo);
203
}
204
205
bool
206
WsmpSocketImpl::ForwardUp (Ptr<Packet> pkt, const Address & sender, const Psid & psid, const WsmpInfo & wsmpInfo)
207
{
208
  if ((m_rxAvailable + pkt->GetSize ()) <= m_rcvBufSize)
209
    {
210
      RecvedPacket * recv = new RecvedPacket();
211
      recv->packet = pkt;
212
      recv->psid =psid;
213
      recv->peer = sender;
214
      m_deliveryQueue.push (recv);
215
      m_rxAvailable += pkt->GetSize ();
216
      NotifyDataRecv ();
217
      return true;
218
    }
219
220
  return false;
221
}
222
223
int
224
WsmpSocketImpl::Close (void)
225
{
226
  NS_LOG_FUNCTION (this);
227
  if (m_binded)
228
    {
229
      m_binded = false;
230
      m_wsmp->RemoveIndicationCallback(m_callback);
231
    }
232
  return 0;
233
}
234
235
236
} // namespace ns3
(-)f6eaede3f93d (+110 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 *
16
 * Author: Junling Bu <linlinjavaer@gmail.com>
17
 */
18
19
#ifndef WSMP_SOCKET_IMPL_H
20
#define WSMP_SOCKET_IMPL_H
21
22
#include "ns3/wsmp-socket.h"
23
#include "ns3/wsmp-protocol.h"
24
#include <queue>
25
26
namespace ns3 {
27
28
class WsmpProtocol;
29
30
/**
31
 * \ingroup wave
32
 * \brief A sockets interface to WSMP
33
 *
34
 * This class subclasses ns3::WsmpSocket, and provides a socket interface
35
 * to ns3's implementation of WSMP.
36
 * This class refers to the class UdpSocketImpl
37
*/
38
class WsmpSocketImpl  : public WsmpSocket {
39
public:
40
  /**
41
   * \brief Get the type ID.
42
   * \return the object TypeId
43
   */
44
  static TypeId GetTypeId (void);
45
  WsmpSocketImpl();
46
  virtual ~WsmpSocketImpl();
47
48
  /**
49
   * \brief Set the associated WSMP protocol.
50
   * \param wsmp the WSMP protocol
51
   */
52
  void SetWsmp (Ptr<WsmpProtocol> wsmp);
53
54
  /**
55
   * \brief Set the internal buffer size for Recv..
56
   * \param size the buffer size.
57
   */
58
  void SetRcvBufSize (uint32_t size);
59
  /**
60
   * \return the internal buffer size for Recv.
61
   */
62
  uint32_t GetRcvBufSize (void) const;
63
64
  virtual int Bind (void);
65
  virtual int Bind (const Psid &psid);
66
67
  virtual int Connect (const Psid &psid);
68
  virtual int Connect (const Address &peer, const Psid &psid);
69
  virtual int Connect (const Address &peer, const Psid &psid, const WsmpInfo &info);
70
71
  virtual int Send (Ptr<Packet> p);
72
  virtual int SendTo (Ptr<Packet> packet, const Address & peer, const Psid & psid, const WsmpInfo & wsmpInfo);
73
74
  virtual Ptr<Packet> Recv (void);
75
  virtual Ptr<Packet> RecvFrom (Address & address, Psid & psid, WsmpInfo & wsmpInfo);
76
77
  virtual uint32_t GetTxAvailable (void) const;
78
  virtual uint32_t GetRxAvailable (void) const;
79
80
  virtual int Close (void);
81
82
private:
83
  bool ForwardUp (Ptr<Packet> pkt, const Address & sender, const Psid & psid, const WsmpInfo & wsmpInfo);
84
85
  Ptr<Node> m_node;
86
  Ptr<WsmpProtocol> m_wsmp;
87
88
  bool  m_connected;
89
  Address 	 m_defaultPeer;
90
  Psid m_defaultPsid;
91
  WsmpInfo m_defaultWsmpInfo;
92
93
  bool m_binded;
94
  WsmpProtocol::IndicationCallback m_callback;
95
96
  uint32_t m_rcvBufSize;
97
  uint32_t m_rxAvailable;
98
99
  struct RecvedPacket
100
  {
101
	  Psid psid;
102
	  Address peer;
103
	  Ptr<Packet> packet;
104
  };
105
  std::queue<RecvedPacket *> m_deliveryQueue; //!< Queue for incoming packets
106
};
107
108
} // namespace ns3
109
110
#endif /* WSMP_SOCKET_IMPL_H */
(-)f6eaede3f93d (+216 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 *
16
 * Author: Junling Bu <linlinjavaer@gmail.com>
17
 */
18
19
#include "ns3/log.h"
20
#include "ns3/packet.h"
21
#include "wsmp-socket.h"
22
#include "wsmp-socket-factory.h"
23
24
namespace ns3 {
25
26
NS_LOG_COMPONENT_DEFINE ("WsmpSocket");
27
28
NS_OBJECT_ENSURE_REGISTERED (WsmpSocket);
29
30
Psid::Psid ()
31
  : m_length (0)
32
{
33
}
34
35
Psid::Psid (uint8_t data0)
36
  : m_length (1)
37
{
38
  m_data[0] = data0;
39
  Assert ();
40
}
41
42
Psid::Psid (uint8_t data0, uint8_t data1)
43
 : m_length (2)
44
{
45
  m_data[0] = data0;
46
  m_data[1] = data1;
47
  Assert ();
48
}
49
50
Psid::Psid (uint8_t data0, uint8_t data1, uint8_t data2)
51
 : m_length (3)
52
{
53
  m_data[0] = data0;
54
  m_data[1] = data1;
55
  m_data[2] = data2;
56
  Assert ();
57
}
58
59
Psid::Psid (uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3)
60
  : m_length (4)
61
{
62
  m_data[0] = data0;
63
  m_data[1] = data1;
64
  m_data[2] = data2;
65
  m_data[3] = data3;
66
  Assert ();
67
}
68
69
Psid::Psid (uint8_t * data, uint8_t length)
70
{
71
  if (data == 0 || length > 4)
72
    return;
73
  for (int i = 0; i != length; i++)
74
    m_data[i] = data[i];
75
  m_length = length;
76
  Assert();
77
}
78
79
80
void
81
Psid::Assert (void)
82
{
83
  if (!IsValid())
84
    NS_FATAL_ERROR("Invalid PSID");
85
}
86
87
bool
88
Psid::IsValid (void) const
89
{
90
  if (m_length == 0)
91
    return false;
92
93
  if (m_data[0] <= PSID_LENGTH_MASK_ONE)
94
    return m_length == 1;
95
  if (m_data[0] <= PSID_LENGTH_MASK_TWO)
96
    return m_length == 2;
97
  if (m_data[0] <= PSID_LENGTH_MASK_THREE)
98
    return m_length == 3;
99
  if (m_data[0] <= PSID_LENGTH_MASK_FOUR)
100
    return m_length == 4;
101
102
  return false;
103
}
104
105
bool
106
Psid::IsNull (void) const
107
{
108
  return m_length == 0;
109
}
110
111
bool
112
Psid::IsEqualTo (const Psid & psid) const
113
{
114
  if (m_length != psid.m_length)
115
    return false;
116
  for (uint8_t i = 0; i != m_length; i++)
117
    {
118
      if (m_data[i] != psid.m_data[i])
119
        return false;
120
    }
121
  return true;
122
}
123
124
const uint8_t *
125
Psid::GetData (void) const
126
{
127
  return m_data;
128
}
129
130
uint8_t
131
Psid::GetLength (void) const
132
{
133
  return m_length;
134
}
135
136
std::ostream& operator<< (std::ostream& os, const Psid & psid)
137
{
138
  for (uint8_t i = 0; i != psid.m_length; i++)
139
    {
140
      os << psid.m_data[i] << " ";
141
    }
142
  return os;
143
}
144
145
bool operator == (const Psid &a, const Psid &b)
146
{
147
  if (a.m_length != b.m_length)
148
    return false;
149
  for (uint8_t i = 0; i != a.m_length; i++)
150
    {
151
      if (a.m_data[i] != b.m_data[i])
152
        return false;
153
    }
154
  return true;
155
}
156
157
bool operator != (const Psid &a, const Psid &b)
158
{
159
  if (a.m_length != b.m_length)
160
    return true;
161
  for (uint8_t i = 0; i != a.m_length; i++)
162
    {
163
      if (a.m_data[i] != b.m_data[i])
164
        return true;
165
    }
166
  return false;
167
}
168
169
TypeId
170
WsmpSocket::GetTypeId (void)
171
{
172
  static TypeId tid = TypeId ("ns3::WsmpSocket")
173
    .SetParent<Object> ()
174
    .SetGroupName("Wave");
175
  return tid;
176
}
177
178
WsmpSocket::WsmpSocket()
179
{
180
}
181
182
WsmpSocket::~WsmpSocket()
183
{
184
}
185
186
Ptr<WsmpSocket>
187
WsmpSocket::CreateSocket (Ptr<Node> node, TypeId tid)
188
{
189
  NS_LOG_FUNCTION (node << tid);
190
  Ptr<WsmpSocket> s;
191
  NS_ASSERT (node != 0);
192
  Ptr<WsmpSocketFactory> socketFactory = node->GetObject<WsmpSocketFactory> (tid);
193
  NS_ASSERT (socketFactory != 0);
194
  s = socketFactory->CreateSocket ();
195
  NS_ASSERT (s != 0);
196
  return s;
197
}
198
199
void
200
WsmpSocket::SetRecvCallback (Callback<void, Ptr<WsmpSocket> > callback)
201
{
202
  NS_LOG_FUNCTION (this << &callback);
203
  m_receivedData = callback;
204
}
205
206
void
207
WsmpSocket::NotifyDataRecv (void)
208
{
209
  NS_LOG_FUNCTION (this);
210
  if (!m_receivedData.IsNull ())
211
    {
212
      m_receivedData (this);
213
    }
214
}
215
216
} // namespace ns3
(-)f6eaede3f93d (+371 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License version 2 as
5
 * published by the Free Software Foundation;
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15
 *
16
 * Author: Junling Bu <linlinjavaer@gmail.com>
17
 */
18
19
#ifndef WSMP_SOCKET_H
20
#define WSMP_SOCKET_H
21
22
#include "ns3/node.h"
23
24
namespace ns3 {
25
26
#define PSID_LENGTH_MASK_ONE       0x7f
27
#define PSID_LENGTH_MASK_TWO       0xbf
28
#define PSID_LENGTH_MASK_THREE     0xdf
29
#define PSID_LENGTH_MASK_FOUR      0xef
30
31
/**
32
 * The range of PSID is
33
 * 1. 0x00 ~ 0x7f
34
 * 2. 0x8000 ~ 0xbfff
35
 * 3. 0xc00000 ~ 0xdfffff
36
 * 4. 0xe0000000 ~ 0xefffffff
37
 * Other number will be taken as invalid.
38
 * See IEEE 1609.3 section 8.1.3 and Annex H "PSID examples"
39
 *
40
 * Usage:
41
 * Psid validPsid1 = Psid(0x01);
42
 * Psid validPsid2 = Psid(0x80, 0x01);
43
 * Psid validPsid3 = Psid(0xc0, 0x00, 0x01);
44
 * Psid validPsid4 = Psid(0xef, 0x00, 0x00, 0x01);
45
 * Psid invalidPsid1 = Psid();               // this is an invalid PSID which cannot be used for transmit.
46
 * Psid invalidPsid2 = Psid(0x81);     // this is an invalid PSID which cannot be used for transmit.
47
 *
48
 * A special "null" Psid is invalid, but here is used internally by class WsmpProtocol.
49
 * Users should not use the "null" Psid for transmit.
50
 */
51
52
class Psid {
53
public:
54
  Psid ();
55
  Psid (uint8_t data0);
56
  Psid (uint8_t data0, uint8_t data1);
57
  Psid (uint8_t data0, uint8_t data1, uint8_t data2);
58
  Psid (uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3);
59
  Psid (uint8_t * data, uint8_t length);
60
61
  bool IsValid (void) const;
62
63
  bool IsNull (void) const;
64
65
  bool IsEqualTo (const Psid & psid) const;
66
67
  const uint8_t * GetData (void) const;
68
  uint8_t GetLength (void) const;
69
70
private:
71
  void Assert (void);
72
73
  friend std::ostream& operator<< (std::ostream& os, const Psid & psid);
74
  friend bool operator == (const Psid &a, const Psid &b);
75
  friend bool operator != (const Psid &a, const Psid &b);
76
77
  uint8_t m_data[4];
78
  uint8_t m_length;
79
};
80
81
std::ostream& operator<< (std::ostream& os, const Psid & psid);
82
bool operator == (const Psid &a, const Psid &b);
83
bool operator != (const Psid &a, const Psid &b);
84
85
/**
86
 * WSMP Normal, see 5.5, 7.3.2
87
 * WSMP Safety supplement, see Annex F
88
 * WSMP Identify supplement, see IEEE 1609.1
89
 *
90
 */
91
enum WsmpElementId {
92
	  WSMP_N,
93
	  WSMP_S,
94
	  WSMP_I,
95
	  WSMP_UNKNOW,
96
};
97
98
class WsmpInfo {
99
public:
100
	WsmpInfo ()
101
	:  m_channel (0),
102
	   m_channelExtension (false),
103
	   m_datarate (0),
104
	   m_datarateExtension (false),
105
	   m_power (0),
106
	   m_powerExtension (false),
107
	   m_id (WSMP_N),
108
	   m_priority (7)
109
	  {
110
111
	  }
112
113
  void SetChannelNumber (uint8_t channel, bool extensonEnabled)
114
  {
115
    m_channel = channel;
116
    m_channelExtension = extensonEnabled;
117
  }
118
119
  uint8_t GetChannelNumber (void)
120
  {
121
    return m_channel;
122
  }
123
124
  bool IsChannelNumberExtension (void)
125
  {
126
    return m_channelExtension;
127
  }
128
129
  void SetDataRate (uint8_t datarate, bool extensionEnabled)
130
  {
131
    m_datarate = datarate;
132
    m_datarateExtension = extensionEnabled;
133
  }
134
135
  uint8_t GetDataRate (void)
136
  {
137
    return m_datarate;
138
  }
139
140
  bool IsDatatRateExtension (void)
141
  {
142
    return m_datarateExtension;
143
  }
144
145
  void SetTxPower (uint8_t power, bool extensionEnabled)
146
  {
147
    m_power = power;
148
    m_powerExtension = extensionEnabled;
149
  }
150
151
  uint8_t GetTxPower (void)
152
  {
153
    return m_power;
154
  }
155
156
  bool IsTxPowerExtension (void)
157
  {
158
    return m_powerExtension;
159
  }
160
161
  void SetElementId (WsmpElementId id)
162
  {
163
    m_id = id;
164
  }
165
166
  WsmpElementId GetElementId (void)
167
  {
168
    return m_id;
169
  }
170
171
  void SetUserPriority (uint8_t priority)
172
  {
173
    m_priority = priority;
174
  }
175
176
  uint8_t GetUserPriority (void)
177
  {
178
    return m_priority;
179
  }
180
181
private:
182
  uint8_t m_channel;
183
  bool m_channelExtension;
184
  uint8_t m_datarate;
185
  bool m_datarateExtension;
186
  uint8_t m_power;
187
  bool m_powerExtension;
188
  WsmpElementId m_id;
189
  uint8_t m_priority;
190
};
191
192
/**
193
 * \brief A low-level Socket API
194
 * \ingroup wave
195
 *
196
 * WsmpSocket API is similar with BSD Socket API, but still differs from BSD Socket API,
197
 * thus this class does not inherit directly from ns3::Socket class.
198
 *
199
* To satisfy users who are familiar with UDP, here also providers connectionless methods.
200
* - For transmit: Connect, Send, Close
201
* - For receipt: Bind, Recv, Close.
202
*
203
* Usage:
204
* TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory");
205
*
206
* Ptr<WsmpSocket> recv = WsmpSocket::CreateSocket (c.Get (0), tid);
207
* Psid psid = Psid(0x80, 0x01);
208
* recv->Bind (psid);
209
* recv->SetRecvCallback (MakeCallback (&ReceivePacket));
210
*
211
* Ptr<WsmpSocket> source = WsmpSocket::CreateSocket (c.Get (1), tid);
212
* source->Connect (Mac48Address::GetBroadcast(), psid);
213
* Simulator::Schedule(Seconds (1.0), &SendPacket, source);
214
*/
215
class WsmpSocket  : public Object {
216
public:
217
  /**
218
   * \brief Get the type ID.
219
   * \return the object TypeId
220
   */
221
  static TypeId GetTypeId (void);
222
  WsmpSocket();
223
  virtual ~WsmpSocket();
224
225
  /**
226
   * This method wraps the creation of sockets that is performed
227
   * on a given node by a WsmpSocketFactory specified by TypeId.
228
   *
229
   * \return A smart pointer to a newly created socket.
230
   *
231
   * \param node The node on which to create the socket
232
   * \param tid The TypeId of a WsmpSocketFactory class to use
233
   */
234
  static Ptr<WsmpSocket>  CreateSocket (Ptr<Node> node, TypeId tid);
235
236
  /**
237
   * \brief Notify application when new data is available to be read.
238
   * \param callback This callback is intended to notify a socket that would
239
   * have been blocked in a blocking socket model that data is available to be read.
240
   */
241
  void SetRecvCallback (Callback<void, Ptr<WsmpSocket> > callback);
242
243
  /**
244
   * \brief Allocate a local endpoint for this socket.
245
   * \returns 0 on success, -1 on failure.
246
   *
247
   * Note: This WsmpSocket::Bind() behavior is different from Socket::Bind().
248
   * Socket::Bind() will randomly select a unused Port for Recv,
249
   * while WsmpSocket::Bind() will only bind a special "null" Psid, so that
250
   * any incoming WSMP packet will notify the RecvCallback.
251
   */
252
  virtual int Bind (void) = 0;
253
  /**
254
   * \brief Allocate a local endpoint for this socket.
255
   * \param psid the psid to try to allocate
256
   * \returns 0 on success, -1 on failure.
257
   */
258
  virtual int Bind (const Psid &psid) = 0;
259
260
  /**
261
   * \brief Initiate a connection to all of remote hosts
262
   * \param psid Psid of remote.
263
   * \returns 0 on success, -1 on error (in which case errno is set).
264
   *
265
   * Note: Although it is named "connect", the WSMP protocol is only a
266
   * connectionless service, thus this method is just a convenient and
267
   * helpful function for Send (Packet) method.
268
   */
269
  virtual int Connect (const Psid &psid) = 0;
270
  /**
271
   * \brief Initiate a connection to a remote host
272
   * \param peer the peer address
273
   * \param psid the psid in the WSMP header of this packet
274
   * \returns 0 on success, -1 on error (in which case errno is set).
275
   *
276
   * Note: Although it is named "connect", the WSMP protocol is only a
277
   * connectionless service, thus this method is just a convenient and
278
   * helpful function for Send (Packet) method.
279
   */
280
  virtual int Connect (const Address &peer, const Psid &psid) = 0;
281
  /**
282
   * \brief Initiate a connection to a remote host
283
   * \param peer the peer address
284
   * \param psid the psid in the WSMP header of this packet
285
   * \param info the transmit and extension information of this packet
286
   * \returns 0 on success, -1 on error (in which case errno is set).
287
   *
288
   * Note: Although it is named "connect", the WSMP protocol is only a
289
   * connectionless service, thus this method is just a convenient and
290
   * helpful function for Send (Packet) method.
291
   */
292
  virtual int Connect (const Address &peer, const Psid &psid, const WsmpInfo &info) = 0;
293
294
  /**
295
   * \brief Send data (or dummy data) to the remote host
296
   *
297
   * \param packet ns3::Packet to send
298
   * \returns the number of bytes accepted for transmission if no error
299
   *          occurs, and negative otherwise.
300
   */
301
  virtual int Send (Ptr<Packet> packet) = 0;
302
  /**
303
   * \brief Send data (or dummy data) to the remote host
304
   *
305
   * \param packet ns3::Packet to send
306
   * \param peer the peer address
307
   * \param psid the psid in the WSMP header of this packet
308
   * \param info the transmit and extension information of this packet
309
   * \returns the number of bytes accepted for transmission if no error
310
   *          occurs, and negative otherwise.
311
   *
312
   *  Note: Although WsmpInfo parameter can determine the transmit channel number,
313
   *  Users should assign channel access for request channel by using WaveNetDevice::StartSch,
314
   *  otherwise the created WaveNetDevice only assigns default continuous CCH channel access.
315
   */
316
  virtual int SendTo (Ptr<Packet> packet, const Address & peer, const Psid & psid, const WsmpInfo & info) = 0;
317
318
  /**
319
   * \brief Read a single packet from the socket
320
   *
321
   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
322
   * 0 if the socket cannot return a next in-sequence packet.
323
   */
324
  virtual Ptr<Packet> Recv (void) = 0;
325
  /**
326
   * \brief Recv data from the remote host
327
   *
328
   * \param address the peer address
329
   * \param psid the psid in the WMSP header of coming packet
330
   * \param info the extension information in the WSMP header of coming packet
331
   * \returns Ptr<Packet> of the next in-sequence packet.  Returns
332
   * 0 if the socket cannot return a next in-sequence packet.
333
   */
334
  virtual Ptr<Packet> RecvFrom (Address & address, Psid & psid, WsmpInfo & info) = 0;
335
336
  /**
337
   * \returns The number of bytes which can be sent in a single Send call.
338
   */
339
  virtual uint32_t GetTxAvailable (void) const = 0;
340
  /**
341
   * Return number of bytes which can be returned from one or
342
   * multiple calls to Recv.
343
   * Must be possible to call this method from the Recv callback.
344
   *
345
   * \returns the number of bytes which can be returned from one or
346
   *          multiple Recv calls.
347
   */
348
  virtual uint32_t GetRxAvailable (void) const = 0;
349
350
  /**
351
   * \brief Close a socket.
352
   * \returns zero on success, -1 on failure.
353
   *
354
   * After the Close call, the socket is no longer valid, and cannot
355
   * safely be used for subsequent operations.
356
   */
357
  virtual int Close (void) = 0;
358
359
protected:
360
  /**
361
   * \brief Notify through the callback (if set) that some data have been received.
362
   */
363
  void NotifyDataRecv (void);
364
365
private:
366
  Callback<void, Ptr<WsmpSocket> > m_receivedData;
367
};
368
369
} // namespace ns3
370
371
#endif /* WSMP_SOCKET_H */
(-)a/src/wave/test/examples-to-run.py (+1 lines)
 Lines 10-15    Link Here 
10
cpp_examples = [
10
cpp_examples = [
11
    ("wave-simple-80211p", "True", "True"),
11
    ("wave-simple-80211p", "True", "True"),
12
    ("wave-simple-device", "True", "True"),
12
    ("wave-simple-device", "True", "True"),
13
    ("wave-simple-wsmp", "True", "True"),
13
]
14
]
14
15
15
# A list of Python examples to run in order to ensure that they remain
16
# A list of Python examples to run in order to ensure that they remain
(-)f6eaede3f93d (+94 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2016 Dalian University of Technology
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: Junling Bu <linlinjavaer@gmail.com>
19
 */
20
#include "ns3/test.h"
21
#include "ns3/vector.h"
22
#include "ns3/string.h"
23
#include "ns3/wsmp-protocol.h"
24
#include "ns3/wsmp-header.h"
25
#include <iostream>
26
27
using namespace ns3;
28
29
class WsmpHeaderTestCase : public TestCase
30
{
31
public:
32
	WsmpHeaderTestCase (void);
33
  virtual ~WsmpHeaderTestCase (void);
34
private:
35
  virtual void DoRun (void);
36
37
};
38
39
WsmpHeaderTestCase::WsmpHeaderTestCase (void)
40
  : TestCase ("WSMP Header")
41
{
42
}
43
44
WsmpHeaderTestCase::~WsmpHeaderTestCase (void)
45
{
46
}
47
48
void
49
WsmpHeaderTestCase::DoRun ()
50
{
51
  Ptr<Packet> packet = Create<Packet> (reinterpret_cast<const uint8_t*> ("Hello World!"), 13);
52
53
  WsmpHeader wsmpHeader = WsmpHeader ();
54
  wsmpHeader.SetVersion(WsmpProtocol::VERSION);
55
  wsmpHeader.SetPsid(Psid (0xc0, 0x03, 0x05));
56
  wsmpHeader.SetExtensionChannelNumber(172);
57
  wsmpHeader.SetExtensionDataRate(12);
58
  wsmpHeader.SetExtensionTxPower(30);
59
  wsmpHeader.SetElementId(WSMP_N);
60
  wsmpHeader.SetLength(packet->GetSize());
61
  packet->AddHeader(wsmpHeader);
62
63
  // the data of packet
64
  int dataSize = packet->GetSize();
65
  uint8_t *data = new uint8_t[dataSize];
66
  packet->CopyData (data, dataSize);
67
68
  // see Annex G.2 "WSM Example"
69
  uint8_t wsmp[] = {0x02, 0xC0, 0x03, 0x05, 0x0F, 0x01,
70
                    0xAC, 0x10, 0x01, 0x0C, 0x04, 0x01,
71
                    0x1E, 0x80, 0x00, 0x0D, 0x48, 0x65,
72
                    0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F,
73
                    0x72, 0x6C, 0x64, 0x21, 0x00};
74
  NS_TEST_EXPECT_MSG_EQ (dataSize, 29, "");
75
  for (int i = 0; i < 29; i++)
76
    NS_TEST_EXPECT_MSG_EQ (data[i], wsmp[i], "");
77
}
78
79
class WsmpHeaderTestSuite : public TestSuite
80
{
81
public:
82
	WsmpHeaderTestSuite ();
83
};
84
85
WsmpHeaderTestSuite::WsmpHeaderTestSuite ()
86
  : TestSuite ("wsmp-header", UNIT)
87
{
88
  // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
89
  AddTestCase (new WsmpHeaderTestCase, TestCase::QUICK);
90
}
91
92
// Do not forget to allocate an instance of this TestSuite
93
static WsmpHeaderTestSuite wsmpHeaderTestSuite;
94
(-)f6eaede3f93d (+203 lines)
Added Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2016 Dalian University of Technology
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: Junling Bu <linlinjavaer@gmail.com>
19
 */
20
#include "ns3/test.h"
21
#include "ns3/simulator.h"
22
#include "ns3/config.h"
23
#include "ns3/data-rate.h"
24
#include "ns3/vector.h"
25
#include "ns3/string.h"
26
#include "ns3/mobility-model.h"
27
#include "ns3/yans-wifi-helper.h"
28
#include "ns3/position-allocator.h"
29
#include "ns3/mobility-helper.h"
30
#include "ns3/mac48-address.h"
31
#include "ns3/wave-helper.h"
32
#include "ns3/wave-mac-helper.h"
33
#include "ns3/wsmp-socket.h"
34
35
using namespace ns3;
36
37
class WsmpSocketTestCase : public TestCase
38
{
39
public:
40
  WsmpSocketTestCase (void);
41
  virtual ~WsmpSocketTestCase (void);
42
  void CreateDevices (uint32_t num);
43
  void ReceivePacket (Ptr<WsmpSocket> socket);
44
  void SendPacket (Ptr<WsmpSocket> socket);
45
private:
46
  virtual void DoRun (void);
47
  void TestBroadcast (void);
48
  void TestUnicastSucceed (void);
49
  void TestUnicastFail (void);
50
51
  NodeContainer m_nodes;
52
53
  uint32_t m_send;
54
  uint32_t m_recv;
55
};
56
57
WsmpSocketTestCase::WsmpSocketTestCase (void)
58
  : TestCase ("WSMP Socket"),
59
    m_send (0),
60
    m_recv (0)
61
{
62
}
63
64
WsmpSocketTestCase::~WsmpSocketTestCase (void)
65
{
66
}
67
68
void
69
WsmpSocketTestCase::CreateDevices (uint32_t num)
70
{
71
  m_nodes = NodeContainer ();
72
  m_nodes.Create (num);
73
74
  YansWifiChannelHelper waveChannel = YansWifiChannelHelper::Default ();
75
  YansWavePhyHelper wavePhy =  YansWavePhyHelper::Default ();
76
  wavePhy.SetChannel (waveChannel.Create ());
77
  QosWaveMacHelper waveMac = QosWaveMacHelper::Default ();
78
  WaveHelper waveHelper = WaveHelper::Default ();
79
  NetDeviceContainer devices = waveHelper.Install (wavePhy, waveMac, m_nodes);
80
81
  MobilityHelper mobility;
82
  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
83
  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
84
  positionAlloc->Add (Vector (5.0, 0.0, 0.0));
85
  mobility.SetPositionAllocator (positionAlloc);
86
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
87
  mobility.Install (m_nodes);
88
}
89
90
void
91
WsmpSocketTestCase::TestBroadcast (void)
92
{
93
  m_recv = 0;
94
  m_send = 0;
95
  CreateDevices (2);
96
97
  TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory");
98
  // Create a Socket on Node 0 for recv all WSMP packets
99
  Ptr<WsmpSocket> destination = WsmpSocket::CreateSocket (m_nodes.Get (0), tid);
100
  destination->Bind ();
101
  destination->SetRecvCallback (MakeCallback (&WsmpSocketTestCase::ReceivePacket, this));
102
  // Create a Socket on Node 1 for send
103
  Psid psid = Psid(0x80, 0x01);
104
  Ptr<WsmpSocket> source = WsmpSocket::CreateSocket (m_nodes.Get (1), tid);
105
  source->Connect (Mac48Address::GetBroadcast(), psid);
106
  Simulator::Schedule(Seconds (1.0), &WsmpSocketTestCase::SendPacket, this, source);
107
  Simulator::Stop (Seconds (5.0));
108
  Simulator::Run ();
109
  Simulator::Destroy ();
110
111
  NS_TEST_EXPECT_MSG_EQ (m_send, m_recv, "send " << m_send << ", recv " << m_recv);
112
}
113
114
void
115
WsmpSocketTestCase::TestUnicastSucceed (void)
116
{
117
  m_recv = 0;
118
  m_send = 0;
119
  CreateDevices (2);
120
121
  TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory");
122
  // Create a Socket on Node 0 for recv all WSMP packets
123
  Ptr<WsmpSocket> destination = WsmpSocket::CreateSocket (m_nodes.Get (0), tid);
124
  Psid psid1 = Psid(0x80, 0x01);
125
  destination->Bind (psid1);
126
  destination->SetRecvCallback (MakeCallback (&WsmpSocketTestCase::ReceivePacket, this));
127
  // Create a Socket on Node 1 for send
128
  Psid psid2 = Psid(0x80, 0x01);
129
  Ptr<WsmpSocket> source = WsmpSocket::CreateSocket (m_nodes.Get (1), tid);
130
  source->Connect (Mac48Address::GetBroadcast(), psid2);
131
  Simulator::Schedule(Seconds (1.0), &WsmpSocketTestCase::SendPacket, this, source);
132
  Simulator::Stop (Seconds (5.0));
133
  Simulator::Run ();
134
  Simulator::Destroy ();
135
136
  NS_TEST_EXPECT_MSG_EQ (m_send, m_recv, "send " << m_send << ", recv " << m_recv);
137
}
138
139
void
140
WsmpSocketTestCase::TestUnicastFail (void)
141
{
142
  m_recv = 0;
143
  m_send = 0;
144
  CreateDevices (2);
145
146
  TypeId tid = TypeId::LookupByName ("ns3::WsmpSocketFactory");
147
  // Create a Socket on Node 0 for recv all WSMP packets
148
  Ptr<WsmpSocket> destination = WsmpSocket::CreateSocket (m_nodes.Get (0), tid);
149
  Psid psid1 = Psid(0x80, 0x01);
150
  destination->Bind (psid1);
151
  destination->SetRecvCallback (MakeCallback (&WsmpSocketTestCase::ReceivePacket, this));
152
  // Create a Socket on Node 1 for send
153
  Psid psid2 = Psid(0x80, 0x02);
154
  Ptr<WsmpSocket> source = WsmpSocket::CreateSocket (m_nodes.Get (1), tid);
155
  source->Connect (Mac48Address::GetBroadcast(), psid2);
156
  Simulator::Schedule(Seconds (1.0), &WsmpSocketTestCase::SendPacket, this, source);
157
  Simulator::Stop (Seconds (5.0));
158
  Simulator::Run ();
159
  Simulator::Destroy ();
160
161
  NS_TEST_EXPECT_MSG_NE (m_send, m_recv, "send " << m_send << ", recv " << m_recv);
162
}
163
164
void
165
WsmpSocketTestCase::ReceivePacket (Ptr<WsmpSocket> socket)
166
{
167
  while (socket->Recv ())
168
    {
169
      m_recv++;
170
    }
171
}
172
173
void
174
WsmpSocketTestCase::SendPacket (Ptr<WsmpSocket> socket)
175
{
176
  socket->Send (Create<Packet> (100));
177
  m_send++;
178
}
179
180
void
181
WsmpSocketTestCase::DoRun ()
182
{
183
  TestBroadcast();
184
  TestUnicastSucceed();
185
  TestUnicastFail();
186
}
187
188
class WsmpSocketTestSuite : public TestSuite
189
{
190
public:
191
	WsmpSocketTestSuite ();
192
};
193
194
WsmpSocketTestSuite::WsmpSocketTestSuite ()
195
  : TestSuite ("wsmp-socket", UNIT)
196
{
197
  // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
198
  AddTestCase (new WsmpSocketTestCase, TestCase::QUICK);
199
}
200
201
// Do not forget to allocate an instance of this TestSuite
202
static WsmpSocketTestSuite wsmpHeaderTestSuite;
203
(-)a/src/wave/wscript (+14 lines)
 Lines 20-25    Link Here 
20
        'model/bsm-application.cc',
20
        'model/bsm-application.cc',
21
        'model/higher-tx-tag.cc',
21
        'model/higher-tx-tag.cc',
22
        'model/wave-net-device.cc',
22
        'model/wave-net-device.cc',
23
        'model/wsmp-header.cc',
24
        'model/wsmp-socket.cc',
25
        'model/wsmp-socket-factory.cc',
26
        'model/wsmp-socket-factory-impl.cc',
27
        'model/wsmp-socket-impl.cc',
28
        'model/wsmp-protocol.cc',
23
        'helper/wave-bsm-stats.cc',
29
        'helper/wave-bsm-stats.cc',
24
        'helper/wave-mac-helper.cc',
30
        'helper/wave-mac-helper.cc',
25
        'helper/wave-helper.cc',
31
        'helper/wave-helper.cc',
 Lines 31-36    Link Here 
31
    module_test.source = [
37
    module_test.source = [
32
        'test/mac-extension-test-suite.cc',
38
        'test/mac-extension-test-suite.cc',
33
        'test/ocb-test-suite.cc',
39
        'test/ocb-test-suite.cc',
40
        'test/wsmp-header-test-suite.cc',
41
        'test/wsmp-socket-test-suite.cc',
34
        ]
42
        ]
35
43
36
    headers = bld(features='ns3header')
44
    headers = bld(features='ns3header')
 Lines 47-52    Link Here 
47
        'model/higher-tx-tag.h',
55
        'model/higher-tx-tag.h',
48
        'model/wave-net-device.h',
56
        'model/wave-net-device.h',
49
        'model/bsm-application.h',
57
        'model/bsm-application.h',
58
        'model/wsmp-header.h',
59
        'model/wsmp-socket.h',
60
        'model/wsmp-socket-factory.h',
61
        'model/wsmp-socket-factory-impl.h',
62
        'model/wsmp-socket-impl.h',
63
        'model/wsmp-protocol.h',
50
        'helper/wave-bsm-stats.h',
64
        'helper/wave-bsm-stats.h',
51
        'helper/wave-mac-helper.h',
65
        'helper/wave-mac-helper.h',
52
        'helper/wave-helper.h',
66
        'helper/wave-helper.h',

Return to bug 2324