ns-3 PLC model
|
00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 00002 /* 00003 * Copyright (c) 2012 University of British Columbia, Vancouver 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation; 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 * 00018 * Author: Alexander Schloegl <alexander.schloegl@gmx.de> 00019 */ 00020 00021 #ifndef PLC_CHANNEL_H_ 00022 #define PLC_CHANNEL_H_ 00023 00024 #include <math.h> 00025 #include <complex> 00026 #include <vector> 00027 #include <set> 00028 00029 #include <ns3/assert.h> 00030 #include <ns3/object.h> 00031 #include <ns3/type-id.h> 00032 00033 #include <ns3/system-thread.h> 00034 #include <ns3/packet.h> 00035 #include <ns3/channel.h> 00036 #include <ns3/nstime.h> 00037 #include <ns3/packet.h> 00038 #include <ns3/spectrum-value.h> 00039 #include <ns3/net-device.h> 00040 #include <ns3/bridge-net-device.h> 00041 #include <ns3/traced-value.h> 00042 #include <ns3/trace-source-accessor.h> 00043 00044 #include "plc-interface.h" 00045 00046 namespace ns3 { 00047 00048 class PLC_Graph; 00049 class PLC_Phy; 00050 class PLC_TxInterface; 00051 class PLC_RxInterface;; 00052 00053 class PLC_TrxMetaInfo : public Object 00054 { 00055 public: 00056 static TypeId GetTypeId (void); 00057 00058 PLC_TrxMetaInfo (void); 00059 00060 void SetUncodedPacket (Ptr<const Packet> p) { m_uncoded_packet = p; } 00061 Ptr<const Packet> GetUncodedPacket (void) const { return m_uncoded_packet; } 00062 void SetHeaderMcs (ModulationAndCodingType mcs) { m_header_mcs = mcs; } 00063 ModulationAndCodingType GetHeaderMcs (void) const { return m_header_mcs; } 00064 void SetPayloadMcs (ModulationAndCodingType mcs) { m_payload_mcs = mcs; } 00065 ModulationAndCodingType GetPayloadMcs (void) const { return m_payload_mcs; } 00066 void SetHeaderDuration (Time duration) { m_header_duration = duration; } 00067 Time GetHeaderDuration (void) const { return m_header_duration; } 00068 void SetPayloadDuration (Time duration) { m_payload_duration = duration; } 00069 Time GetPayloadDuration (void) const { return m_payload_duration; } 00070 00071 private: 00072 Ptr<const Packet> m_uncoded_packet; 00073 ModulationAndCodingType m_header_mcs; 00074 ModulationAndCodingType m_payload_mcs; 00075 Time m_header_duration; 00076 Time m_payload_duration; 00077 }; 00078 00084 class PLC_EdgeTransferUnit : public Object 00085 { 00086 friend class PLC_Outlet; 00087 00088 public: 00089 static TypeId GetTypeId(void); 00090 00098 PLC_EdgeTransferUnit(PLC_Edge *edge, PLC_Node *dst_node, Ptr<const SpectrumModel> sm, bool time_variant = false); 00099 00103 ~PLC_EdgeTransferUnit(void) {} 00104 00109 PLC_Edge *GetEdge(void) const { return m_edge; } 00110 00115 PLC_Node *GetDstNode(void) const { return m_dst_node; } 00116 00121 void SetEdgeTransferVector(Ptr<PLC_TransferBase> ctv); 00122 00127 Ptr<PLC_TransferBase> GetEdgeTransferVector(void); 00128 00133 PLC_TransferBase *GetEdgeTransferVectorPtr(void) { return PeekPointer(m_edge_transfer_vector); } 00134 00139 bool IsUp2Date(void) const { return m_is_up_2_date; } 00140 00144 void SetOutOfDate(void) { m_is_up_2_date = false; } 00145 00150 bool IsTimeVariant(void); 00151 00155 void Lock(void) const { m_edge_transfer_unit_mutex.Lock(); } 00156 void Unlock(void) const { m_edge_transfer_unit_mutex.Unlock(); } 00157 00158 private: 00159 void DoDispose(void); 00160 00161 Ptr<const SpectrumModel> m_spectrum_model; 00162 mutable PLC_Mutex m_edge_transfer_unit_mutex; 00163 PLC_Edge *m_edge; // non ns3::Ptr<>, because object system 00164 PLC_Node *m_dst_node; // gets screwed up with parallel processing 00165 Ptr<PLC_TransferBase> m_edge_transfer_vector; // Channel Transfer Function data for the m_edge heading to m_dst_node 00166 00167 bool m_is_up_2_date; 00168 }; 00169 00176 class PLC_ChannelTransferImpl : public Object 00177 { 00178 friend class PLC_TxInterface; 00179 00180 public: 00181 static TypeId GetTypeId(void); 00182 00190 PLC_ChannelTransferImpl(PLC_TxInterface *txInterface, PLC_RxInterface *rxInterface, Ptr<const SpectrumModel> sm, bool create_backbone_path = true); 00191 ~PLC_ChannelTransferImpl() {} 00192 00197 Ptr<PLC_Graph> GetGraph(void); 00198 00203 bool IsTimeVariant(void); 00204 00209 void SetTimeVariant(void); 00210 00217 void UpdateImmediately(bool value) { m_update_immediately = value; } 00218 00223 bool IsUp2Date(void) { return m_is_up_2_date; } 00224 00228 Time GetDirectPathPropagationDelay(void); 00229 00235 std::list<PLC_BackboneBranch *> GetBackbonePath(void); 00236 00241 PLC_BackbonePath::iterator BackbonePathBegin(void); 00242 00247 PLC_BackbonePath::iterator BackbonePathEnd(void); 00248 00252 void CreateBackbonePath(void); 00253 00263 void DiscoverBackboneBranches(void); 00264 00269 void InitializeChannelTransferVector(bool set_time_variant = false); 00270 00274 void CalculateChannelTransferVector(void); 00275 00279 Ptr<PLC_TransferBase> GetChannelTransferVector(void); 00280 00287 Ptr<SpectrumValue> GetAbsSqrCtf(unsigned int timeslot = 0); 00288 00292 void GenerateAbsSqrCtf(void); 00293 00303 Ptr<SpectrumValue> CalculateRxPowerSpectralDensity(Ptr<const SpectrumValue> txPsd, Timeslot timeslot = 0); 00304 00308 void Lock(void) const { m_mutex.Lock(); } 00309 void Unlock(void) const { m_mutex.Unlock(); } 00310 00311 private: 00312 void DoDispose(void); 00313 00314 void AddBackboneBranch(Ptr<PLC_Node> branch, Ptr<PLC_Node> node_before, Ptr<PLC_Node> node_next); 00315 Ptr<PLC_TransferBase> MultiplyChannelTransferVector(Ptr<PLC_TransferBase> result, PLC_TransferBase *ctv); 00316 void SetOutOfDate(void); 00317 void CalculateDirectPathPropagationDelay(void); 00318 00319 Ptr<const SpectrumModel> m_spectrum_model; 00320 mutable PLC_Mutex m_mutex; 00321 PLC_TxInterface *m_txInterface; 00322 PLC_RxInterface *m_rxInterface; 00323 PLC_BackbonePath m_backbone_path; 00324 Ptr<PLC_TransferBase> m_channel_transfer_vector; 00325 std::vector<Ptr<SpectrumValue> > m_abs_sqr_ctf; 00326 00327 uint64_t m_impedance_hash_sum; 00328 00329 Time m_delay; 00330 bool m_is_time_variant; 00331 bool m_ctv_is_up_2_date; 00332 bool m_is_up_2_date; 00333 00334 bool m_update_immediately; 00335 bool m_update_scheduled; 00336 TracedCallback<Time, Ptr<PLC_TransferBase> > m_channelDataTracer; 00337 }; 00338 00346 class PLC_Channel : public Channel 00347 { 00348 friend class PLC_Outlet; 00349 00350 public: 00351 static TypeId GetTypeId(void); 00352 00356 PLC_Channel(); 00357 00362 PLC_Channel(Ptr<PLC_Graph> graph); 00363 ~PLC_Channel(void); 00364 00370 void SetGraph(Ptr<PLC_Graph> graph); 00371 00375 Ptr<PLC_Graph> GetGraph(void) { return this->m_graph; } 00376 00380 uint32_t AddTxInterface(Ptr<PLC_TxInterface> txInterface); 00381 00385 uint32_t GetNTxInterfaces(void) const; 00386 00391 Ptr<PLC_TxInterface> GetTxInterface(uint32_t i) const; 00392 00396 uint32_t AddRxInterface(Ptr<PLC_RxInterface> rxInterface); 00397 00401 uint32_t GetNRxInterfaces(void) const; 00402 00409 Ptr<PLC_RxInterface> GetRxInterface(uint32_t i) const; 00410 00419 uint32_t AddDevice(Ptr<NetDevice>); 00420 00426 uint32_t GetNDevices (void) const; 00427 00432 Ptr<NetDevice> GetDevice (uint32_t i) const; 00433 00437 void InitTransmissionChannels(void); 00438 00443 void CalcTransmissionChannels(void); 00444 00448 Ptr<PLC_TransferBase> GetChannelTransferData(uint32_t txId, uint32_t rxId); 00449 00463 void TransmissionStart(Ptr<const Packet> p, uint32_t txId, Ptr<const SpectrumValue> txPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00464 00478 bool TransmissionEnd(uint32_t txId, Time propagation_delay); 00479 00487 void PropagationCompleteEvent(uint32_t txId); 00488 00492 Timeslot GetCurrentTimeslot(void); 00493 00497 Time GetRemainingSlotTime(Time t); 00498 00504 void ProcessTimeslotTasks(Timeslot timeslot); 00505 00510 void ScheduleNextTimeslotTasks(void); 00511 00516 void UpdateReceivePSDs(Timeslot timeslot, bool channel_changed = false); 00517 00523 void DeleteOutOfDatePSDs(Ptr<PLC_TxInterface> tx, Ptr<PLC_RxInterface> rx); 00524 00528 void Lock(void) const { m_mutex.Lock(); } 00529 void Unlock(void) const { m_mutex.Unlock(); } 00530 00531 private: 00532 void DoStart(void); 00533 void DoDispose(void); 00534 00538 void MakeRxPsdMapEntries(Timeslot cur_timeslot, Timeslot end_timeslot, PLC_RxPsdMap& rxPsdMap, PLC_ChannelTransferImpl *ch_impl, Ptr<const SpectrumValue> txPsd); 00539 00540 mutable PLC_Mutex m_mutex; 00541 mutable PLC_Mutex m_schedule_mutex; 00542 Ptr<PLC_Graph> m_graph; 00543 00544 std::set<Ptr<PLC_Phy> > m_phys; 00545 std::vector<Ptr<PLC_TxInterface> > m_txInterfaces; 00546 std::vector<Ptr<PLC_RxInterface> > m_rxInterfaces; 00547 std::vector<Ptr<NetDevice> > m_devices; 00548 00549 std::set<uint32_t> m_transmitting; 00550 std::set<uint32_t> m_propagating; 00551 PLC_TransmissionDescriptorMap m_transmission_descriptors; 00552 00553 bool m_timeslot_tasks_scheduled; 00554 00555 TracedCallback<Time, uint32_t, bool> m_occupancyLogger; 00556 TracedCallback<Time, std::set<uint32_t> > m_activeTxIfLogger; 00557 }; 00558 00559 } 00560 00561 #endif /* PLC_CHANNEL_H_ */