Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(433)

Unified Diff: src/rns/model/rns-specialization.cc

Issue 7304093: SMECN protocol and RNS algorithm
Patch Set: Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/rns/model/rns-neighbors-table.h ('k') | src/rns/test/rns-algorithm-tests.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/rns/model/rns-specialization.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/rns/model/rns-specialization.cc
@@ -0,0 +1,488 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2012 Michal Paszta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Michal Paszta
+ */
+#include <ns3/rns-helper.h>
+#include "rns.h"
+#include "rns-header.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/yans-wifi-channel.h"
+#include "ns3/pointer.h"
+#include "ns3/integer.h"
+#include "ns3/double.h"
+
+namespace ns3 {
+namespace rns {
+
+
+/* Ipv4 specialization */
+
+template <> TypeId Rns<Ipv4Address>::GetTypeId(void)
+{
+ static TypeId tid = TypeId ("ns3::rns::RnsIpv4AddressImpl")
+ .SetParent<Object> ()
+ .AddConstructor<Rns<Ipv4Address> > ()
+ .AddAttribute("Test","Set to true for testing.",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<Ipv4Address>::IsTest),
+ MakeBooleanChecker())
+ .AddAttribute("ConnectivityMaintenanceMode","Use automatic radio range estimation and maintain network's connectivity.",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<Ipv4Address>::ConnectivityMaintenanceMode),
+ MakeBooleanChecker())
+ .AddAttribute("EventTriggerredBroadcast","Whether Rns broadcast should be triggerred by events or by timer",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<Ipv4Address>::EventTrigerredBroadcast),
+ MakeBooleanChecker())
+ .AddAttribute("UpdateInterval","Interval between automatic Rns updates; Rns message is sent only if EventTriggerBroadcast is set to false.",
+ TimeValue(Seconds(1.0)),
+ MakeTimeAccessor(&Rns<Ipv4Address>::UpdateInterval),
+ MakeTimeChecker())
+ .AddAttribute("MaxEntryAge","The age at which a node's position, range and status are regarded out of date.",
+ TimeValue(Seconds(100)),
+ MakeTimeAccessor(&Rns<Ipv4Address>::MaxEntryAge),
+ MakeTimeChecker())
+ .AddAttribute("UpdateIntervalTimeScatter","Time scatter of Update Interval to avoid collision [ms].",
+ DoubleValue(100),
+ MakeDoubleAccessor(&Rns<Ipv4Address>::UpdateIntervalTimeScatter),
+ MakeDoubleChecker<double>())
+ .AddAttribute("AllowedStatusChanges","How often is the status allowed to change per update period.",
+ IntegerValue(5),
+ MakeIntegerAccessor(&Rns<Ipv4Address>::AllowedStatusChanges),
+ MakeIntegerChecker<uint32_t>())
+ .AddAttribute ("RangeEstimationAccuracy","How accurate should the range estimation be [m].",
+ DoubleValue (0.01),
+ MakeDoubleAccessor (&Rns<Ipv4Address>::RangeEstimationAccuracy),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("ProtocolPeriodicUpdate","Whether the protocol will provide a periodic update on neighbors situation.",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<Ipv4Address>::ProtocolPeriodicUpdate),
+ MakeBooleanChecker())
+ .AddAttribute ("PositionInRnsHeader","Whether position information has to be passed in RNS header.",
+ BooleanValue(true),
+ MakeBooleanAccessor(&Rns<Ipv4Address>::PositionInRnsHeader),
+ MakeBooleanChecker())
+ ;
+ return tid;
+}
+
+template <>
+void Rns<Ipv4Address>::Ipv4Receive (Ptr<Socket> socket)
+{
+ while (m_socket->GetRxAvailable () > 0)
+ {
+ Address from;
+ Ptr<Packet> p = m_socket->RecvFrom (0xffffffff, 0, from);
+ Ipv4Header ipv4;
+ p->RemoveHeader (ipv4);
+ Ipv4Address sender = ipv4.GetSource();
+
+ RnsHeader<Ipv4Address> rnsMsg;
+ if (PositionInRnsHeader) rnsMsg.SetPositionInRnsHeader(true);
+ p->RemoveHeader (rnsMsg);
+ ReceiveRnsMessage(rnsMsg,sender);
+ }
+}
+
+template <>
+void Rns<Ipv4Address>::Ipv4Send (RnsHeader<Ipv4Address> h)
+{
+ Ptr<Packet> p = Create<Packet>();
+ p->AddHeader(h);
+
+ //Set power level.
+ uint8_t txPowerLevelBuffer = m_yansWifiPhy->GetTxPowerLevel();
+ m_yansWifiPhy->SetTxPowerLevel(m_broadcastPowerLevel);
+
+ Ipv4Address destination = Ipv4Address ("255.255.255.255");
+ m_socket->SendTo(p,0,InetSocketAddress(destination));
+
+ //Reset original power level.
+ m_yansWifiPhy->SetTxPowerLevel(txPowerLevelBuffer);
+}
+
+template <>
+void Rns<Ipv4Address>::Start(Ptr<Node> node)
+{
+ if (IsTest)
+ {
+ PositionInRnsHeader = false;
+ m_protocolUpdate = MakeNullCallback<void, Neighbor<Ipv4Address> > ();
+ return;
+ }
+ m_node = node;
+ m_redundantRelatedNodes.clear();
+
+ m_broadcastTimer.SetFunction(&Rns<Ipv4Address>::UpdateTimerExpire,this);
+ m_broadcastTimer.Schedule(UpdateInterval
+ - Time (MilliSeconds (UniformVariable().GetValue(0.0, UpdateIntervalTimeScatter))));
+
+ m_agingTimer.SetFunction(&Rns<Ipv4Address>::AgingTimerExpire,this);
+ m_agingTimer.Schedule(Seconds (1));
+ m_neighbors.SetMaxAge(MaxEntryAge);
+
+ Ptr<NetDevice> netDev = m_node->GetDevice(0);
+ Ptr<WifiNetDevice> wifiNetDev = DynamicCast<WifiNetDevice>(netDev);
+
+ //Phy detection
+ Ptr<WifiPhy> wifiPhy = wifiNetDev->GetPhy();
+ Ptr<YansWifiPhy> yansWifiPhy = DynamicCast<YansWifiPhy>(wifiPhy);
+ if (yansWifiPhy != NULL)
+ {
+ m_yansWifiPhy = yansWifiPhy;
+ }
+
+ //Mobility Detection
+ Ptr<MobilityModel> AggregatedMobilityModel = m_node->GetObject<MobilityModel>();
+ NS_ASSERT(AggregatedMobilityModel != NULL);
+ this->SetMobility(AggregatedMobilityModel);
+
+ //PropagationLossModel detection
+ Ptr<Channel> wifiCh = wifiNetDev->GetChannel();
+ Ptr<YansWifiChannel> yansWifiCh = DynamicCast<YansWifiChannel>(wifiCh);
+ PointerValue pval;
+ wifiCh->GetAttribute("PropagationLossModel",pval);
+ Ptr<PropagationLossModel> prop = pval.Get<PropagationLossModel> ();
+ if (prop != NULL)
+ {
+ m_propagationModel = prop;
+ }
+
+ SetRanges();
+ RangeUpdate();
+
+ //Ipv4 stack detection
+ Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+ // The assertion should be altered or removed when other stacks are supported.
+ NS_ASSERT_MSG(ipv4 != NULL, "No Ipv4 stack detected.\n");
+ if (ipv4 != NULL)
+ {
+ //Obtain this nodes own address.
+ m_id = ipv4->GetAddress(1,0).GetLocal();
+
+ m_socket = Socket::CreateSocket (m_node,
+ TypeId::LookupByName ("ns3::Ipv4RawSocketFactory"));
+ NS_ASSERT_MSG (m_socket != 0,"Socket not created.");
+ m_socket->SetAttribute ("Protocol", UintegerValue (4)); // ip
+ m_socket->SetRecvCallback (MakeCallback (&Rns::Ipv4Receive, this));
+ InetSocketAddress src = InetSocketAddress (Ipv4Address::GetAny (), 0);
+ int status;
+ status = m_socket->Bind (src);
+ NS_ASSERT (status != -1);
+ m_socket->SetAllowBroadcast(true);
+
+ return;
+ }
+}
+
+template <>
+uint32_t NeighborsTable<Ipv4Address>::Ipv4ToNodeNumber(Ipv4Address addr) const
+{
+ uint32_t n = addr.Get();
+ n = n & 0x000000FF;
+ return n-1;
+}
+
+template <>
+uint32_t Neighbor<Ipv4Address>::Ipv4ToNodeNumber(Ipv4Address addr) const
+{
+ uint32_t n = addr.Get();
+ n = n & 0x000000FF;
+ return n-1;
+}
+
+template <>
+uint32_t Rns<Ipv4Address>::Ipv4ToNodeNumber(Ipv4Address addr) const
+{
+ uint32_t n = addr.Get();
+ n = n & 0x000000FF;
+ return n-1;
+}
+
+template <>
+TypeId RnsHeader<Ipv4Address>::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::rns::RnsHeaderIpv4Address")
+ .SetParent<Header> ()
+ .AddConstructor<RnsHeader>();
+ return tid;
+}
+
+template <>
+uint32_t RnsHeader<Ipv4Address>::GetSerializedSize () const
+{
+ uint32_t size = 1 + sizeof(Ipv4Address) + 4; //status + id + range
+ if (PositionInRnsHeader)
+ {
+ size += 8; // + position
+ }
+ size += sizeof(uint32_t); //entries_number
+ size += m_entriesNumber*sizeof(Ipv4Address);
+ return size;
+}
+
+template <>
+void RnsHeader<Ipv4Address>::Serialize (Buffer::Iterator start) const
+{
+ WriteTo (start,m_id);
+ start.WriteU8(m_status);
+ start.WriteHtonU32(m_range);
+ if (PositionInRnsHeader)
+ {
+ start.WriteHtonU32(m_x);
+ start.WriteHtonU32(m_y);
+ }
+ start.WriteHtonU32(m_entriesNumber);
+ for (std::vector<Ipv4Address>::const_iterator i = m_rrns.begin();
+ i != m_rrns.end(); i++)
+ {
+ WriteTo(start,*i);
+ }
+}
+
+template <>
+uint32_t RnsHeader<Ipv4Address>::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i= start;
+
+ ReadFrom (i,m_id);
+ m_status = i.ReadU8();
+ m_range = i.ReadNtohU32();
+ if (PositionInRnsHeader)
+ {
+ m_x = i.ReadNtohU32();
+ m_y = i.ReadNtohU32();
+ }
+ m_entriesNumber = i.ReadNtohU32();
+ for (uint32_t k = 0; k < m_entriesNumber; k++)
+ {
+ Ipv4Address addr;
+ ReadFrom(i,addr);
+ m_rrns.push_back(addr);
+ }
+
+
+ uint32_t dist = i.GetDistanceFrom(start);
+ NS_ASSERT(dist == GetSerializedSize());
+ return dist;
+}
+
+#ifndef IPV4_REGISTERED
+#define IPV4_REGISTERED
+typedef class RnsHeader<Ipv4Address> RnsHeaderIpv4AddressImpl;
+NS_OBJECT_ENSURE_REGISTERED (RnsHeaderIpv4AddressImpl);
+typedef class Rns<Ipv4Address> RnsIpv4AddressImpl;
+NS_OBJECT_ENSURE_REGISTERED(RnsIpv4AddressImpl);
+#endif
+
+
+
+/* uint32_t specialization */
+
+template <> TypeId Rns<uint32_t>::GetTypeId(void)
+{
+ static TypeId tid = TypeId ("ns3::rns::RnsUint32Impl")
+ .SetParent<Object> ()
+ .AddConstructor<Rns<uint32_t> > ()
+ .AddAttribute("Test","Set to true for testing.",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<uint32_t>::IsTest),
+ MakeBooleanChecker())
+ .AddAttribute("ConnectivityMaintenanceMode","Use automatic radio range estimation and maintain network's connectivity.",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<uint32_t>::ConnectivityMaintenanceMode),
+ MakeBooleanChecker())
+ .AddAttribute("EventTriggerredBroadcast","Whether Rns broadcast should be triggerred by events or by timer",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<uint32_t>::EventTrigerredBroadcast),
+ MakeBooleanChecker())
+ .AddAttribute("UpdateInterval","Interval between automatic Rns updates; Rns message is sent only if EventTriggerBroadcast is set to false.",
+ TimeValue(Seconds(1.0)),
+ MakeTimeAccessor(&Rns<uint32_t>::UpdateInterval),
+ MakeTimeChecker())
+ .AddAttribute("MaxEntryAge","The age at which a node's position, range and status are regarded out of date.",
+ TimeValue(Seconds(100)),
+ MakeTimeAccessor(&Rns<uint32_t>::MaxEntryAge),
+ MakeTimeChecker())
+ .AddAttribute("UpdateIntervalTimeScatter","Time scatter of Update Interval to avoid collision.",
+ DoubleValue(100),
+ MakeDoubleAccessor(&Rns<uint32_t>::UpdateIntervalTimeScatter),
+ MakeDoubleChecker<double>())
+ .AddAttribute ("RangeEstimationAccuracy","How accurate should the range estimation be [m].",
+ DoubleValue (0.01),
+ MakeDoubleAccessor (&Rns<uint32_t>::RangeEstimationAccuracy),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("ProtocolPeriodicUpdate","Whether the protocol will provide a periodic update on neighbors situation.",
+ BooleanValue(false),
+ MakeBooleanAccessor(&Rns<uint32_t>::ProtocolPeriodicUpdate),
+ MakeBooleanChecker())
+ .AddAttribute ("PositionInRnsHeader","Whether position information has to be passed in RNS header.",
+ BooleanValue(true),
+ MakeBooleanAccessor(&Rns<uint32_t>::PositionInRnsHeader),
+ MakeBooleanChecker())
+ ;
+ return tid;
+}
+
+template <>
+void Rns<uint32_t>::Start(Ptr<Node> node)
+{
+ m_node = node;
+
+ if (IsTest)
+ {
+ PositionInRnsHeader = false;
+ m_protocolUpdate = MakeNullCallback<void, Neighbor<uint32_t> > ();
+ return;
+ }
+
+ m_broadcastTimer.SetFunction(&Rns<uint32_t>::UpdateTimerExpire,this);
+ m_broadcastTimer.Schedule(UpdateInterval -
+ Time (MilliSeconds (UniformVariable ().GetInteger (0, 10))/100.0));
+
+ m_agingTimer.SetFunction(&Rns<uint32_t>::AgingTimerExpire,this);
+ m_agingTimer.Schedule(Seconds (1));
+ m_neighbors.SetMaxAge(MaxEntryAge);
+
+ SetRanges();
+}
+
+template <>
+void Rns<uint32_t>::Ipv4Receive (Ptr<Socket> socket)
+{
+ NS_FATAL_ERROR("Ipv4Receive message used with uint32_t IdType.");
+}
+
+template <>
+void Rns<uint32_t>::Ipv4Send (RnsHeader<uint32_t> h)
+{
+ NS_FATAL_ERROR("Ipv4Send message used with uint32_t IdType.");
+}
+
+template <>
+uint32_t Rns<uint32_t>::Ipv4ToNodeNumber(uint32_t addr) const
+{
+ return 0;
+}
+
+template <>
+uint32_t NeighborsTable<uint32_t>::Ipv4ToNodeNumber(uint32_t addr) const
+{
+ return addr;
+}
+
+template <>
+uint32_t Neighbor<uint32_t>::Ipv4ToNodeNumber(uint32_t addr) const
+{
+ return addr;
+}
+
+template <>
+TypeId RnsHeader<uint32_t>::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::rns::RnsHeaderU32")
+ .SetParent<Header> ()
+ .AddConstructor<RnsHeader>();
+ return tid;
+}
+
+template <>
+uint32_t RnsHeader<uint32_t>::GetSerializedSize () const
+{
+ uint32_t size = 1 + sizeof(uint32_t) + 4; //status + id + range
+ if (PositionInRnsHeader)
+ {
+ size += 8; // + position
+ }
+ size += sizeof(uint32_t); //entries_number
+ size += m_entriesNumber*sizeof(uint32_t);
+ return size;
+}
+
+template <>
+void RnsHeader<uint32_t>::Serialize (Buffer::Iterator start) const
+{
+ start.WriteHtonU32(m_id);
+ start.WriteU8(m_status);
+ start.WriteHtonU32(m_range);
+ if (PositionInRnsHeader)
+ {
+ start.WriteHtonU32(m_x);
+ start.WriteHtonU32(m_y);
+ }
+ start.WriteHtonU32(m_entriesNumber);
+ for (std::vector<uint32_t>::const_iterator i = m_rrns.begin();
+ i != m_rrns.end(); i++)
+ {
+ start.WriteHtonU32(*i);
+ }
+}
+
+template <>
+uint32_t RnsHeader<uint32_t>::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i= start;
+
+ m_id = i.ReadNtohU32();
+ m_status = i.ReadU8();
+ m_range = i.ReadNtohU32();
+ if (PositionInRnsHeader)
+ {
+ m_x = i.ReadNtohU32();
+ m_y = i.ReadNtohU32();
+ }
+ m_entriesNumber = i.ReadNtohU32();
+ for (uint32_t k = 0; k < m_entriesNumber; k++)
+ {
+ uint32_t addr;
+ addr = i.ReadNtohU32();
+ m_rrns.push_back(addr);
+ }
+
+ uint32_t dist = i.GetDistanceFrom(start);
+ NS_ASSERT(dist == GetSerializedSize());
+ return dist;
+}
+
+
+
+
+#ifndef UINT32_REGISTERED
+#define UINT32_REGISTERED
+typedef class RnsHeader<uint32_t> RnsHeaderUint32Impl;
+NS_OBJECT_ENSURE_REGISTERED (RnsHeaderUint32Impl);
+typedef class Rns<uint32_t> RnsUint32Impl;
+NS_OBJECT_ENSURE_REGISTERED(RnsUint32Impl);
+#endif
+
+} // namespace rns
+/* Helper constructor specializations */
+
+template <> RnsHelper<Ipv4Address>::RnsHelper ()
+{
+ m_agentFactory.SetTypeId ("ns3::rns::RnsIpv4AddressImpl");
+}
+
+template <> RnsHelper<uint32_t>::RnsHelper ()
+{
+ m_agentFactory.SetTypeId ("ns3::rns::RnsUint32Impl");
+}
+
+
+
+} // namespace ns3
« no previous file with comments | « src/rns/model/rns-neighbors-table.h ('k') | src/rns/test/rns-algorithm-tests.cc » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b