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_PHY_H_ 00022 #define PLC_PHY_H_ 00023 00024 #include <cmath> 00025 #include <vector> 00026 #include <ns3/object.h> 00027 #include <ns3/nstime.h> 00028 #include <ns3/traced-value.h> 00029 #include <ns3/trace-source-accessor.h> 00030 #include "plc-interface.h" 00031 #include "plc-header.h" 00032 #include "plc-outlet.h" 00033 #include "plc-link-performance-model.h" 00034 #include "plc-channel.h" 00035 00036 namespace ns3 { 00037 00038 // Forward declarations 00039 class PLC_TrxMetaInfo; 00040 class PLC_Channel; 00041 class PLC_ChannelTransferImpl; 00042 class PLC_LinkPerformanceModel; 00043 00047 typedef enum 00048 { 00049 CHANNEL_CLEAR, 00050 CHANNEL_OCCUPIED 00051 } PLC_PhyCcaResult; 00052 00053 // Callback definitions 00054 typedef Callback<void, Ptr<const Packet> > PhyRxEndOkCallback; 00055 typedef Callback< void > PhyRxEndErrorCallback; 00056 typedef Callback< void, PLC_PhyCcaResult > PLC_PhyCcaConfirmCallback; 00057 typedef Callback<void> PLC_PhyDataFrameSentCallback; 00058 typedef std::vector<std::pair<Time, Ptr<const SpectrumValue> > > PLC_SinrTrace; 00059 00060 // Helper functions 00061 size_t RequiredSymbols (size_t encoded_bits, ModulationAndCodingType mcs, size_t subbands); 00062 Time CalculateTransmissionDuration(size_t encoded_bits, ModulationAndCodingType mcs, size_t subbands); 00063 00064 00065 size_t RawBitsPerOfdmSymbol (ModulationAndCodingType mcs, size_t numSubcarriers); 00066 size_t RawBytesInOfdmSymbols (ModulationAndCodingType mcs, size_t numSubCarriers, size_t num_bytes); 00067 00072 class PLC_Phy : public Object 00073 { 00074 public: 00075 00076 virtual ~PLC_Phy (); 00077 00078 static TypeId GetTypeId (void); 00079 00087 bool StartTx (Ptr<Packet> p); 00088 00097 void StartRx (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00098 00105 void RxPsdChanged (uint32_t txId, Ptr<SpectrumValue> newRxPsd); 00106 00117 static void SetSymbolDuration (Time tSymbol); 00118 00122 static Time GetSymbolDuration (void); 00123 00127 Ptr<PLC_Node> GetNode (void) { return m_node; } 00128 00133 void SetDataFrameSentCallback (PLC_PhyDataFrameSentCallback c); 00134 00139 void SetReceiveSuccessCallback (PhyRxEndOkCallback c); 00140 00145 void SetReceiveErrorCallback (PhyRxEndErrorCallback c); 00146 00150 PLC_ChannelTransferImpl *GetChannelTransferImpl (Ptr<PLC_Phy> rxPhy); 00151 00155 Ptr<PLC_TransferBase> GetChannelTransferVector(Ptr<PLC_Phy> rxPhy); 00156 00157 00161 void NotifyDataFrameSent (void); 00162 00163 protected: 00164 static Time symbol_duration; 00165 00166 virtual void DoStart (void); 00167 virtual void DoDispose (void); 00168 00169 virtual bool DoStartTx (Ptr<Packet> p) = 0; 00170 virtual void DoStartRx (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo) = 0; 00171 virtual void DoUpdateRxPsd (uint32_t txId, Ptr<SpectrumValue> newRxPsd) = 0; 00172 virtual PLC_ChannelTransferImpl *DoGetChannelTransferImpl (Ptr<PLC_Phy> rxPhy) = 0; 00173 00174 Ptr<PLC_Node> m_node; 00175 00176 PLC_PhyDataFrameSentCallback m_data_frame_sent_callback; 00177 PhyRxEndOkCallback m_receive_success_cb; 00178 PhyRxEndErrorCallback m_receive_error_cb; 00179 }; 00180 00197 class PLC_HalfDuplexOfdmPhy : public PLC_Phy 00198 { 00199 public: 00200 00204 enum State 00205 { 00206 IDLE, 00207 TX, 00208 RX, 00209 }; 00210 00211 static TypeId GetTypeId (void); 00212 00216 PLC_HalfDuplexOfdmPhy (); 00217 virtual ~PLC_HalfDuplexOfdmPhy () = 0; 00218 00219 static void SetGuardIntervalDuration (Time duration);; 00220 static Time GetGuardIntervalDuration (void); 00221 00232 void CreateInterfaces (Ptr<PLC_Outlet> outlet, Ptr<SpectrumValue> txPsd, Ptr<PLC_Impedance> rxImpedance = 0, Ptr<PLC_Impedance> txImpedance = 0); 00233 00237 Ptr<PLC_Outlet> GetOutlet (void) { return m_outlet; } 00238 00243 void SetTxPowerSpectralDensity (Ptr<SpectrumValue> txPsd); 00244 00248 Ptr<const SpectrumValue> GetTxPowerSpectralDensity (void) { return m_txPsd; } 00249 00253 Ptr<PLC_TxInterface> GetTxInterface (void); 00254 00258 Ptr<PLC_RxInterface> GetRxInterface (void); 00259 00264 void SetShuntImpedance (Ptr<PLC_Impedance> shuntImpedance); 00265 00270 void SetRxImpedance (Ptr<PLC_Impedance> rxImpedance); 00271 00276 void SetTxImpedance (Ptr<PLC_Impedance> txImpedance); 00277 00281 Ptr<PLC_Impedance> GetShuntImpedance (void) { return m_shuntImpedance; } 00282 00286 Ptr<PLC_Impedance> GetRxImpedance (void) { return m_rxImpedance; } 00287 00291 Ptr<PLC_Impedance> GetTxImpedance (void) { return m_txImpedance; } 00292 00293 void SetNoiseFloor (Ptr<const SpectrumValue> noiseFloor); 00294 00299 void CcaRequest (void); 00300 00304 void CancelCca (void); 00305 00309 void EndCca (void); 00310 00316 void SetCcaConfirmCallback (PLC_PhyCcaConfirmCallback c); 00317 00322 void ChangeState (State newState); 00323 00328 State GetState (void); 00329 00333 bool IsBusy(void) { return m_state != IDLE; } 00334 00335 protected: 00336 virtual void DoStart (void); 00337 virtual void DoDispose (void); 00338 virtual void DoSetNoiseFloor (Ptr<const SpectrumValue> noiseFloor) = 0; 00339 virtual PLC_ChannelTransferImpl *DoGetChannelTransferImpl (Ptr<PLC_Phy> rxPhy); 00340 00341 static Time guard_interval_duration; 00342 00343 void ComputeEquivalentImpedances (void); 00344 virtual PLC_PhyCcaResult ClearChannelAssessment (void) = 0; 00345 00346 Time CalculateTxDuration (size_t nSymbols); 00347 00354 void SwitchImpedance (State state); 00355 00356 Ptr<PLC_Outlet> m_outlet; 00357 Ptr<SpectrumValue> m_txPsd; 00358 Ptr<PLC_TxInterface> m_txInterface; 00359 Ptr<PLC_RxInterface> m_rxInterface; 00360 Ptr<PLC_Impedance> m_shuntImpedance; 00361 Ptr<PLC_Impedance> m_txImpedance; 00362 Ptr<PLC_Impedance> m_rxImpedance; 00363 Ptr<PLC_Impedance> m_eqRxImpedance; 00364 Ptr<PLC_Impedance> m_eqTxImpedance; 00365 00366 size_t m_numSubcarriers; 00367 00368 uint32_t m_locked_txId; 00369 Ptr<Packet> m_incoming_packet; 00370 00371 // The PHY has to be aware of all receive PSDs to 00372 // update the interference model when a signal changes 00373 std::map<uint32_t, Ptr<const SpectrumValue> > m_rxNoisePsdMap; 00374 00375 EventId m_ccaEndEvent; 00376 PLC_PhyCcaConfirmCallback m_ccaConfirmCallback; 00377 00378 State m_state; 00379 TracedCallback<Time, State> m_PhyStateLogger; 00380 }; 00381 00387 class PLC_ErrorRatePhy : public PLC_HalfDuplexOfdmPhy 00388 { 00389 public: 00390 static TypeId GetTypeId (void); 00391 00392 PLC_ErrorRatePhy(); 00393 00398 virtual void SetModulationAndCodingScheme(ModulationAndCodingType mcs); 00399 ModulationAndCodingType GetModulationAndCodingScheme(void) { return m_mcs; } 00400 00401 virtual void PreambleDetectionSuccessful (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00402 virtual void EndRx(uint32_t txId); 00403 00404 private: 00405 virtual void DoStart (void); 00406 virtual void DoDispose (void); 00407 virtual void DoSetNoiseFloor (Ptr<const SpectrumValue> noiseFloor); 00408 virtual bool DoStartTx (Ptr<Packet> p); 00409 virtual void DoStartRx (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00410 virtual void DoUpdateRxPsd (uint32_t txId, Ptr<SpectrumValue> newRxPsd); 00411 00412 PLC_PhyCcaResult ClearChannelAssessment (void); 00413 Time CalculateTxDuration(Ptr<const Packet> p); 00414 00415 ModulationAndCodingType m_mcs; 00416 Ptr<const Packet> m_rxPacket; 00417 Ptr<PLC_ErrorRateModel> m_error_rate_model; 00418 }; 00419 00425 class PLC_InformationRatePhy : public PLC_HalfDuplexOfdmPhy 00426 { 00427 public: 00428 static TypeId GetTypeId (void); 00429 00430 PLC_InformationRatePhy (void); 00431 00439 void SetHeaderModulationAndCodingScheme(ModulationAndCodingType mcs); 00440 ModulationAndCodingType GetHeaderModulationAndCodingScheme(void); 00441 00442 void SetPayloadModulationAndCodingScheme(ModulationAndCodingType mcs); 00443 ModulationAndCodingType GetPayloadModulationAndCodingScheme(void); 00444 00449 static void SetOfdmSymbolsPerCodeBlock (size_t spb); 00450 00454 size_t GetOfdmSymbolsPerCodeBlock (void); 00455 00465 static void SetRatelessCodingOverhead (double overhead); 00466 static double GetRatelessCodingOverhead (void) { return rateless_coding_overhead; } 00467 00468 void EndRxHeader(Ptr<SpectrumValue>& rxPsd, Ptr<const PLC_TrxMetaInfo> metaInfo); 00469 void EndRxPayload(Ptr<const PLC_TrxMetaInfo> metaInfo); 00470 void ReceptionFailure(void); 00471 00472 void SendFrame (Ptr<Packet> p, Ptr<PLC_TrxMetaInfo> metaInfo); 00473 00474 virtual void PreambleDetectionSuccessful (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00475 00476 protected: 00477 static size_t modulation_symbols_per_code_block; 00478 static double rateless_coding_overhead; 00479 00480 virtual void DoStart (void); 00481 virtual void DoDispose (void); 00482 virtual void DoSetNoiseFloor (Ptr<const SpectrumValue> noiseFloor); 00483 virtual bool DoStartTx (Ptr<Packet> p); 00484 virtual void DoStartRx (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00485 virtual void DoUpdateRxPsd (uint32_t txId, Ptr<SpectrumValue> newRxPsd); 00486 00487 virtual void StartReception (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00488 virtual void NotifySuccessfulReception (void); 00489 00490 Ptr<Packet> CreateEncodedPacket (Ptr<PLC_TrxMetaInfo> metaInfo); 00491 Ptr<Packet> CreateFixedRateEncodedPacket (Ptr<PLC_TrxMetaInfo> metaInfo); 00492 Ptr<Packet> CreateRatelessEncodedPacket (Ptr<PLC_TrxMetaInfo> metaInfo); 00493 00494 PLC_PhyCcaResult ClearChannelAssessment (void); 00495 00496 size_t RequiredChunks (size_t num_blocks); 00497 size_t ChunksInByte (size_t num_chunks, size_t raw_bits_per_symbol); 00498 00499 Ptr<PLC_InformationRateModel> m_information_rate_model; 00500 00501 ModulationAndCodingType m_header_mcs; 00502 ModulationAndCodingType m_payload_mcs; 00503 }; 00504 00508 class PLC_ChaseCombiningPhy : public PLC_InformationRatePhy 00509 { 00510 public: 00511 static TypeId GetTypeId (void); 00512 00513 PLC_ChaseCombiningPhy(void); 00514 00515 void UpdateSinrBase (Ptr<const SpectrumValue> newSinrBase); 00516 void TraceSinr(Time t, Ptr<const SpectrumValue> sinr); 00517 00518 protected: 00519 virtual void DoStart (void); 00520 virtual void DoDispose (void); 00521 00522 virtual void StartReception (Ptr<const Packet> p, uint32_t txId, Ptr<SpectrumValue>& rxPsd, Time duration, Ptr<const PLC_TrxMetaInfo> metaInfo); 00523 virtual void NotifySuccessfulReception (void); 00524 00525 private: 00526 Time m_rxStartTime; 00527 Ptr<const Packet> m_rxPacketRef; 00528 PLC_SinrTrace m_sinrBaseTrace; 00529 }; 00530 00531 // TODO: PLC_IncrementalRedundancyPhy 00532 00533 } 00534 00535 #endif /* PLC_PHY_H_ */