├── examples ├── wscript └── lora-example.cc ├── doc └── lora.rst ├── README.md ├── model ├── lora-mac.cc ├── lora-transducer.cc ├── lora-noise-model.cc ├── lora-noise-model.h ├── lora-noise-model-default.h ├── lora-prop-model-ideal.h ├── lora-prop-model-ideal.cc ├── lora-prop-model-thorp.h ├── lora-noise-model-default.cc ├── mac-lora-gw.h ├── lora-transducer-hd.h ├── lora-prop-model-thorp.cc ├── lora-address.cc ├── lora-header-common.cc ├── lora-mac.h ├── lora-header-common.h ├── mac-lora-gw.cc ├── lora-phy.cc ├── lora-address.h ├── lora-transducer.h ├── lora-transducer-hd.cc ├── lora-tx-mode.cc ├── lora-channel.cc ├── lora-channel.h ├── lora-tx-mode.h ├── lora-prop-model.cc ├── lora-prop-model.h ├── lora-net-device.h ├── lora-phy-gen.h ├── lora-net-device.cc └── lora-phy.h ├── wscript ├── test └── lora-test.cc └── LICENSE /examples/wscript: -------------------------------------------------------------------------------- 1 | ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- 2 | 3 | def build(bld): 4 | obj = bld.create_ns3_program('lora-example', ['internet', 'mobility', 'stats', 'applications', 'lora']) 5 | obj.source = 'lora-example.cc' 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /doc/lora.rst: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ## Overview 4 | 5 | 6 | The ns3 lora module is a simplistic model of a lora-like network. It 7 | supports LoraWAN Class A end devices and one gateway. 8 | 9 | ## Installing 10 | 11 | To install this module, you should do as follow: 12 | 1. Download ns-3 latest version (ns-3-27) at [ns-3 main page](https://www.nsnam.org/ns-3-27). 13 | 2. Extract ns-allinone-3.27.tar.bz2 file. 14 | 3. Download ns3 lora module, then copy it ./src folder inside ns-allinone-3.27 folder. 15 | 4. Run three next statements to build source code: 16 | ``` 17 | ~/ns-allinone-3.27/ns-3$ ./waf clean 18 | ~/ns-allinone-3.27/ns-3$ ./waf configure --enable-tests --enable-examples 19 | ~/ns-allinone-3.27/ns-3$ ./waf build 20 | ``` 21 | ## Running the tests and examples 22 | 23 | To test ns3 lora module, you run this statement: 24 | ``` 25 | ~/ns-allinone-3.27/ns-3$ ./test.py -s lora-node -m -t lora-node.txt 26 | ``` 27 | To run example of ns3 lora module, you run this statement: 28 | ``` 29 | ~/ns-allinone-3.27/ns-3$ ./waf --run lora-example 30 | ``` 31 | ## License 32 | 33 | This software is licensed under the terms of the GNU GPLv2 - see the [LICENSE](LICENSE) file for details. 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ## Overview 4 | 5 | 6 | The ns3 lora module is a simplistic model of a lora-like network. It 7 | supports LoraWAN Class A end devices and one gateway. 8 | 9 | ## Installing 10 | 11 | To install this module, you should do as follow: 12 | 1. Download ns-3 latest version (ns-3-27) at [ns-3 main page](https://www.nsnam.org/ns-3-27). 13 | 2. Extract ns-allinone-3.27.tar.bz2 file. 14 | 3. Download ns3 lora module, then copy it ./src folder inside ns-allinone-3.27 folder. 15 | 4. Run three next statements to build source code: 16 | ``` 17 | ~/ns-allinone-3.27/ns-3$ ./waf clean 18 | ~/ns-allinone-3.27/ns-3$ ./waf configure --enable-tests --enable-examples 19 | ~/ns-allinone-3.27/ns-3$ ./waf build 20 | ``` 21 | 22 | ## Running the tests and examples 23 | 24 | To test ns3 lora module, you run this statement: 25 | ``` 26 | ~/ns-allinone-3.27/ns-3$ ./test.py -s lora-node -m -t lora-node.txt 27 | ``` 28 | To run example of ns3 lora module, you run this statement: 29 | ``` 30 | ~/ns-allinone-3.27/ns-3$ ./waf --run lora-example 31 | ``` 32 | ## License 33 | 34 | This software is licensed under the terms of the GNU GPLv2 - see the [LICENSE](LICENSE) file for details. 35 | 36 | -------------------------------------------------------------------------------- /model/lora-mac.cc: -------------------------------------------------------------------------------- 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: Mitch Watrous 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-mac.h" 21 | 22 | namespace ns3 { 23 | 24 | NS_OBJECT_ENSURE_REGISTERED (LoraMac); 25 | 26 | TypeId LoraMac::GetTypeId (void) 27 | { 28 | static TypeId tid = TypeId ("ns3::LoraMac") 29 | .SetParent () 30 | .SetGroupName ("Lora") 31 | ; 32 | return tid; 33 | } 34 | 35 | } // namespace ns3 36 | -------------------------------------------------------------------------------- /model/lora-transducer.cc: -------------------------------------------------------------------------------- 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: Mitch Watrous 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-transducer.h" 21 | 22 | namespace ns3 { 23 | 24 | NS_OBJECT_ENSURE_REGISTERED (LoraTransducer); 25 | 26 | TypeId LoraTransducer::GetTypeId (void) 27 | { 28 | static TypeId tid = TypeId ("ns3::LoraTransducer") 29 | .SetParent () 30 | .SetGroupName ("Lora") 31 | ; 32 | return tid; 33 | } 34 | 35 | } // namespace ns3 36 | -------------------------------------------------------------------------------- /model/lora-noise-model.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-noise-model.h" 21 | 22 | namespace ns3 { 23 | 24 | NS_OBJECT_ENSURE_REGISTERED (LoraNoiseModel); 25 | 26 | TypeId LoraNoiseModel::GetTypeId (void) 27 | { 28 | static TypeId tid = TypeId ("ns3::LoraNoiseModel") 29 | .SetParent () 30 | .SetGroupName ("Lora") 31 | ; 32 | return tid; 33 | } 34 | 35 | void 36 | LoraNoiseModel::Clear (void) 37 | { 38 | } 39 | 40 | void 41 | LoraNoiseModel::DoDispose (void) 42 | { 43 | Clear (); 44 | Object::DoDispose (); 45 | } 46 | 47 | 48 | 49 | } // namespace ns3 50 | -------------------------------------------------------------------------------- /model/lora-noise-model.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_NOISE_MODEL_H 21 | #define LORA_NOISE_MODEL_H 22 | 23 | #include "ns3/object.h" 24 | 25 | namespace ns3 { 26 | 27 | /** 28 | * 29 | * LORA Noise Model base class. 30 | */ 31 | class LoraNoiseModel : public Object 32 | { 33 | public: 34 | /** 35 | * Register this type. 36 | * \return The TypeId. 37 | */ 38 | static TypeId GetTypeId (void); 39 | 40 | /** 41 | * Compute the noise power at a given frequency. 42 | * 43 | * \param fKhz Frequency in kHz. 44 | * \return Noise power in dB re 1uPa/Hz. 45 | */ 46 | virtual double GetNoiseDbHz (double fKhz) const = 0; 47 | 48 | /** Clear all pointer references. */ 49 | virtual void Clear (void); 50 | 51 | virtual void DoDispose (void); 52 | 53 | }; // class LoraNoiseModel 54 | 55 | } // namespace ns3 56 | 57 | #endif /* LORA_NOISE_MODEL_H */ 58 | -------------------------------------------------------------------------------- /model/lora-noise-model-default.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_NOISE_MODEL_DEFAULT_H 21 | #define LORA_NOISE_MODEL_DEFAULT_H 22 | 23 | #include "ns3/lora-noise-model.h" 24 | #include "ns3/attribute.h" 25 | #include "ns3/object.h" 26 | 27 | namespace ns3 { 28 | 29 | /** 30 | * 31 | * Standard ambient acoustic noise model. 32 | * 33 | */ 34 | class LoraNoiseModelDefault : public LoraNoiseModel 35 | { 36 | public: 37 | LoraNoiseModelDefault (); //!< Default constructor. 38 | virtual ~LoraNoiseModelDefault (); //!< Dummy destructor, DoDispose. 39 | 40 | /** 41 | * Register this type. 42 | * \return The TypeId. 43 | */ 44 | static TypeId GetTypeId (void); 45 | 46 | // Inherited methods 47 | virtual double GetNoiseDbHz (double fKhz) const; 48 | 49 | private: 50 | double m_wind; //!< Wind speed in m/s. 51 | double m_shipping; //!< Shipping contribution to noise between 0 and 1. 52 | 53 | }; // class LoraNoiseModelDefault 54 | 55 | } // namespace ns3 56 | 57 | #endif /* LORA_NOISE_MODEL_DEFAULT_H */ 58 | -------------------------------------------------------------------------------- /model/lora-prop-model-ideal.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_PROP_MODEL_IDEAL_H 21 | #define LORA_PROP_MODEL_IDEAL_H 22 | 23 | #include "lora-prop-model.h" 24 | #include "ns3/mobility-model.h" 25 | #include "ns3/nstime.h" 26 | 27 | namespace ns3 { 28 | 29 | /** 30 | * 31 | * Ideal propagation model (no pathloss, impulse PDP). 32 | */ 33 | class LoraPropModelIdeal : public LoraPropModel 34 | { 35 | public: 36 | /** Default constructor. */ 37 | LoraPropModelIdeal (); 38 | /** Destructor */ 39 | virtual ~LoraPropModelIdeal (); 40 | 41 | /** 42 | * Register this type. 43 | * \return The object TypeId. 44 | */ 45 | static TypeId GetTypeId (void); 46 | 47 | // Inherited methods 48 | virtual double GetPathLossDb (Ptr a, Ptr b, LoraTxMode mode); 49 | virtual LoraPdp GetPdp (Ptr a, Ptr b, LoraTxMode mode); 50 | virtual Time GetDelay (Ptr a, Ptr b, LoraTxMode mode); 51 | 52 | }; // class LoraPropModelIdeal 53 | 54 | } // namespace ns3 55 | 56 | #endif /* LORA_PROP_MODEL_IDEAL_H */ 57 | -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | 2 | ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- 3 | 4 | def build(bld): 5 | module = bld.create_ns3_module('lora', ['network','mobility', 'energy']) 6 | module.source = [ 7 | 'model/lora-channel.cc', 8 | 'model/lora-phy-gen.cc', 9 | 'model/lora-mac.cc', 10 | 'model/lora-transducer.cc', 11 | 'model/lora-transducer-hd.cc', 12 | 'model/lora-address.cc', 13 | 'model/lora-net-device.cc', 14 | 'model/lora-tx-mode.cc', 15 | 'model/lora-prop-model.cc', 16 | 'model/lora-prop-model-ideal.cc', 17 | 'model/mac-lora-gw.cc', 18 | 'model/lora-phy-dual.cc', 19 | 'model/lora-header-common.cc', 20 | 'model/lora-noise-model-default.cc', 21 | 'model/lora-prop-model-thorp.cc', 22 | 'model/lora-phy.cc', 23 | 'model/lora-noise-model.cc', 24 | ] 25 | 26 | module_test = bld.create_ns3_module_test_library('lora') 27 | module_test.source = [ 28 | 'test/lora-test.cc', 29 | ] 30 | 31 | headers = bld(features='ns3header') 32 | headers.module = 'lora' 33 | headers.source = [ 34 | 'model/lora-channel.h', 35 | 'model/lora-phy.h', 36 | 'model/lora-mac.h', 37 | 'model/lora-net-device.h', 38 | 'model/lora-prop-model.h', 39 | 'model/lora-tx-mode.h', 40 | 'model/lora-transducer.h', 41 | 'model/lora-phy-gen.h', 42 | 'model/lora-transducer-hd.h', 43 | 'model/lora-address.h', 44 | 'model/lora-prop-model-ideal.h', 45 | 'model/mac-lora-gw.h', 46 | 'model/lora-phy-dual.h', 47 | 'model/lora-header-common.h', 48 | 'model/lora-noise-model.h', 49 | 'model/lora-noise-model-default.h', 50 | 'model/lora-prop-model-thorp.h', 51 | ] 52 | 53 | 54 | if (bld.env['ENABLE_EXAMPLES']): 55 | bld.recurse('examples') 56 | 57 | # bld.ns3_python_bindings() 58 | -------------------------------------------------------------------------------- /model/lora-prop-model-ideal.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-prop-model-ideal.h" 21 | #include "lora-tx-mode.h" 22 | #include "ns3/mobility-model.h" 23 | 24 | namespace ns3 { 25 | 26 | NS_OBJECT_ENSURE_REGISTERED (LoraPropModelIdeal); 27 | 28 | LoraPropModelIdeal::LoraPropModelIdeal () 29 | { 30 | } 31 | 32 | LoraPropModelIdeal::~LoraPropModelIdeal () 33 | { 34 | } 35 | 36 | TypeId 37 | LoraPropModelIdeal::GetTypeId (void) 38 | { 39 | static TypeId tid = TypeId ("ns3::LoraPropModelIdeal") 40 | .SetParent () 41 | .SetGroupName ("Lora") 42 | .AddConstructor () 43 | ; 44 | return tid; 45 | } 46 | 47 | 48 | double 49 | LoraPropModelIdeal::GetPathLossDb (Ptr a, Ptr b, LoraTxMode mode) 50 | { 51 | 52 | return 0; 53 | } 54 | LoraPdp 55 | LoraPropModelIdeal::GetPdp (Ptr a, Ptr b, LoraTxMode mode) 56 | { 57 | return LoraPdp::CreateImpulsePdp (); 58 | } 59 | 60 | Time 61 | LoraPropModelIdeal::GetDelay (Ptr a, Ptr b, LoraTxMode mode) 62 | { 63 | return Seconds (a->GetDistanceFrom (b) / 1500.0); 64 | } 65 | 66 | 67 | } // namespace ns3 68 | -------------------------------------------------------------------------------- /model/lora-prop-model-thorp.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_PROP_MODEL_THORP_H 21 | #define LORA_PROP_MODEL_THORP_H 22 | 23 | #include "lora-prop-model.h" 24 | 25 | namespace ns3 { 26 | 27 | class LoraTxMode; 28 | 29 | /** 30 | * 31 | * Uses Thorp's approximation to compute pathloss. Assumes implulse PDP. 32 | */ 33 | class LoraPropModelThorp : public LoraPropModel 34 | { 35 | public: 36 | /** Default constructor. */ 37 | LoraPropModelThorp (); 38 | /** Destructor */ 39 | virtual ~LoraPropModelThorp (); 40 | 41 | /** 42 | * Register this type. 43 | * \return The object TypeId. 44 | */ 45 | static TypeId GetTypeId (void); 46 | 47 | // Inherited methods 48 | virtual double GetPathLossDb (Ptr a, Ptr b, LoraTxMode mode); 49 | virtual LoraPdp GetPdp (Ptr a, Ptr b, LoraTxMode mode); 50 | virtual Time GetDelay (Ptr a, Ptr b, LoraTxMode mode); 51 | 52 | private: 53 | /** 54 | * Get the attenuation in dB / 1000 yards. 55 | * \param freqKhz The channel center frequency, in kHz. 56 | * \return The attenuation, in dB / 1000 yards. 57 | */ 58 | double GetAttenDbKyd (double freqKhz); 59 | /** 60 | * Get the attenuation in dB / km. 61 | * \param freqKhz The channel center frequency, in kHz. 62 | * \return The attenuation, in dB/km. 63 | */ 64 | double GetAttenDbKm (double freqKhz); 65 | 66 | double m_SpreadCoef; //!< Spreading coefficient used in calculation of Thorp's approximation. 67 | 68 | }; // class LoraPropModelThorp 69 | 70 | } // namespace ns3 71 | 72 | #endif /* LORA_PROP_MODEL_THORP_H */ 73 | -------------------------------------------------------------------------------- /model/lora-noise-model-default.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-noise-model-default.h" 21 | #include "ns3/double.h" 22 | 23 | #include 24 | 25 | namespace ns3 { 26 | 27 | NS_OBJECT_ENSURE_REGISTERED (LoraNoiseModelDefault); 28 | 29 | LoraNoiseModelDefault::LoraNoiseModelDefault () 30 | { 31 | 32 | } 33 | 34 | LoraNoiseModelDefault::~LoraNoiseModelDefault () 35 | { 36 | } 37 | 38 | TypeId 39 | LoraNoiseModelDefault::GetTypeId (void) 40 | { 41 | static TypeId tid = TypeId ("ns3::LoraNoiseModelDefault") 42 | .SetParent () 43 | .SetGroupName ("Lora") 44 | .AddConstructor () 45 | .AddAttribute ("Wind", "Wind speed in m/s.", 46 | DoubleValue (1), 47 | MakeDoubleAccessor (&LoraNoiseModelDefault::m_wind), 48 | MakeDoubleChecker (0)) 49 | .AddAttribute ("Shipping", "Shipping contribution to noise between 0 and 1.", 50 | DoubleValue (0), 51 | MakeDoubleAccessor (&LoraNoiseModelDefault::m_shipping), 52 | MakeDoubleChecker (0,1)) 53 | ; 54 | return tid; 55 | } 56 | 57 | double 58 | LoraNoiseModelDefault::GetNoiseDbHz (double fKhz) const 59 | { 60 | double turb, wind, ship, thermal; 61 | double turbDb, windDb, shipDb, thermalDb, noiseDb; 62 | 63 | turbDb = 17.0 - 30.0 * std::log10 (fKhz); 64 | turb = std::pow (10.0, turbDb * 0.1); 65 | 66 | shipDb = 40.0 + 20.0 * (m_shipping - 0.5) + 26.0 * std::log10 (fKhz) - 60.0 * std::log10 (fKhz + 0.03); 67 | ship = std::pow (10.0, (shipDb * 0.1)); 68 | 69 | windDb = 50.0 + 7.5 * std::pow (m_wind, 0.5) + 20.0 * std::log10 (fKhz) - 40.0 * std::log10 (fKhz + 0.4); 70 | wind = std::pow (10.0, windDb * 0.1); 71 | 72 | thermalDb = -15 + 20 * std::log10 (fKhz); 73 | thermal = std::pow (10, thermalDb * 0.1); 74 | 75 | noiseDb = 10 * std::log10 (turb + ship + wind + thermal); 76 | 77 | return noiseDb; 78 | } 79 | 80 | } // namespace ns3 81 | -------------------------------------------------------------------------------- /model/mac-lora-gw.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef MAC_LORA_H 21 | #define MAC_LORA_H 22 | 23 | #include "lora-mac.h" 24 | #include "lora-address.h" 25 | 26 | namespace ns3 27 | { 28 | 29 | 30 | class LoraPhy; 31 | class LoraTxMode; 32 | 33 | /** 34 | * 35 | * Packets received on multiple channels and multiple spreading factors. 36 | */ 37 | class MacLoraAca : public LoraMac 38 | { 39 | public: 40 | /** Default constructor */ 41 | MacLoraAca (); 42 | /** Dummy destructor, see DoDispose. */ 43 | virtual ~MacLoraAca (); 44 | /** 45 | * Register this type. 46 | * \return The TypeId. 47 | */ 48 | static TypeId GetTypeId (void); 49 | 50 | 51 | // Inherited methods 52 | Address GetAddress (void); 53 | virtual void SetAddress (LoraAddress addr); 54 | virtual bool Enqueue (Ptr pkt, const Address &dest, uint16_t protocolNumber); 55 | virtual void SetForwardUpCb (Callback, const LoraAddress& > cb); 56 | virtual void AttachPhy (Ptr phy); 57 | virtual Address GetBroadcast (void) const; 58 | virtual void Clear (void); 59 | int64_t AssignStreams (int64_t stream); 60 | 61 | private: 62 | /** The MAC address. */ 63 | LoraAddress m_address; 64 | /** PHY layer attached to this MAC. */ 65 | Ptr m_phy; 66 | /** Forwarding up callback. */ 67 | Callback, const LoraAddress& > m_forUpCb; 68 | /** Flag when we've been cleared. */ 69 | bool m_cleared; 70 | 71 | /** 72 | * Receive packet from lower layer (passed to PHY as callback). 73 | * 74 | * \param pkt Packet being received. 75 | * \param sinr SINR of received packet. 76 | * \param txMode Mode of received packet. 77 | */ 78 | void RxPacketGood (Ptr pkt, double sinr, LoraTxMode txMode); 79 | 80 | /** 81 | * Packet received at lower layer in error. 82 | * 83 | * \param pkt Packet received in error. 84 | * \param sinr SINR of received packet. 85 | */ 86 | void RxPacketError (Ptr pkt, double sinr); 87 | protected: 88 | virtual void DoDispose (); 89 | 90 | }; // class MacLoraAca 91 | 92 | } // namespace ns3 93 | 94 | #endif /* MAC_LORA_H */ 95 | -------------------------------------------------------------------------------- /model/lora-transducer-hd.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_TRANSDUCER_HD_H 21 | #define LORA_TRANSDUCER_HD_H 22 | 23 | #include "lora-transducer.h" 24 | #include "ns3/simulator.h" 25 | namespace ns3 { 26 | 27 | /** 28 | * 29 | * Half duplex implementation of transducer object 30 | * 31 | * This class will only allow attached Phy's to receive packets 32 | * if not in TX mode. 33 | */ 34 | class LoraTransducerHd : public LoraTransducer 35 | { 36 | public: 37 | /** Constructor */ 38 | LoraTransducerHd (); 39 | /** Dummy destructor, see DoDispose */ 40 | virtual ~LoraTransducerHd (); 41 | 42 | /** 43 | * Register this type. 44 | * \return The object TypeId. 45 | */ 46 | static TypeId GetTypeId (void); 47 | 48 | // inherited methods 49 | virtual State GetState (void) const; 50 | virtual bool IsRx (void) const; 51 | virtual bool IsTx (void) const; 52 | virtual const ArrivalList &GetArrivalList (void) const; 53 | virtual void Receive (Ptr packet, double rxPowerDb, LoraTxMode txMode, LoraPdp pdp); 54 | virtual void Transmit (Ptr src, Ptr packet, double txPowerDb, LoraTxMode txMode); 55 | virtual void SetChannel (Ptr chan); 56 | virtual Ptr GetChannel (void) const; 57 | virtual void AddPhy (Ptr); 58 | virtual const LoraPhyList &GetPhyList (void) const; 59 | virtual void Clear (void); 60 | 61 | private: 62 | State m_state; //!< Transducer state. 63 | ArrivalList m_arrivalList; //!< List of arriving packets which overlap in time. 64 | LoraPhyList m_phyList; //!< List of physical layers attached above this tranducer. 65 | Ptr m_channel; //!< The attached channel. 66 | EventId m_endTxEvent; //!< Event scheduled for end of transmission. 67 | Time m_endTxTime; //!< Time at which transmission will be completed. 68 | bool m_cleared; //!< Flab when we've been cleared. 69 | 70 | /** 71 | * Remove an entry from the arrival list. 72 | * 73 | * \param arrival The packet arrival to remove. 74 | */ 75 | void RemoveArrival (LoraPacketArrival arrival); 76 | /** Handle end of transmission event. */ 77 | void EndTx (void); 78 | protected: 79 | virtual void DoDispose (); 80 | 81 | }; // class LoraTransducerHd 82 | 83 | } // namespace ns3 84 | 85 | #endif /* LORA_TRANSDUCER_HD_H */ 86 | -------------------------------------------------------------------------------- /model/lora-prop-model-thorp.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | #include "lora-prop-model-thorp.h" 20 | #include "lora-tx-mode.h" 21 | #include "ns3/double.h" 22 | #include "ns3/log.h" 23 | 24 | namespace ns3 { 25 | 26 | NS_LOG_COMPONENT_DEFINE ("LoraPropModelThorp"); 27 | 28 | NS_OBJECT_ENSURE_REGISTERED (LoraPropModelThorp); 29 | 30 | LoraPropModelThorp::LoraPropModelThorp () 31 | { 32 | } 33 | 34 | LoraPropModelThorp::~LoraPropModelThorp () 35 | { 36 | } 37 | 38 | TypeId 39 | LoraPropModelThorp::GetTypeId (void) 40 | { 41 | static TypeId tid = TypeId ("ns3::LoraPropModelThorp") 42 | .SetParent () 43 | .SetGroupName ("Lora") 44 | .AddConstructor () 45 | .AddAttribute ("SpreadCoef", 46 | "Spreading coefficient used in calculation of Thorp's approximation.", 47 | DoubleValue (1.5), 48 | MakeDoubleAccessor (&LoraPropModelThorp::m_SpreadCoef), 49 | MakeDoubleChecker ()) 50 | ; 51 | return tid; 52 | } 53 | 54 | double 55 | LoraPropModelThorp::GetPathLossDb (Ptr a, Ptr b, LoraTxMode mode) 56 | { 57 | double dist = a->GetDistanceFrom (b); 58 | 59 | return m_SpreadCoef * 10.0 * std::log10 (dist) 60 | + (dist / 1000.0) * GetAttenDbKm (mode.GetCenterFreqHz () / 1000.0); 61 | } 62 | 63 | LoraPdp 64 | LoraPropModelThorp::GetPdp (Ptr a, Ptr b, LoraTxMode mode) 65 | { 66 | return LoraPdp::CreateImpulsePdp (); 67 | } 68 | 69 | Time 70 | LoraPropModelThorp::GetDelay (Ptr a, Ptr b, LoraTxMode mode) 71 | { 72 | return Seconds (a->GetDistanceFrom (b) / 1500.0); 73 | } 74 | 75 | double 76 | LoraPropModelThorp::GetAttenDbKyd (double freqKhz) 77 | { 78 | 79 | return GetAttenDbKm (freqKhz) / 1.093613298; 80 | } 81 | 82 | double 83 | LoraPropModelThorp::GetAttenDbKm (double freqKhz) 84 | { 85 | 86 | double fsq = freqKhz * freqKhz; 87 | double atten; 88 | 89 | if (freqKhz >= 0.4) 90 | { 91 | atten = 0.11 * fsq / (1 + fsq) + 44 * fsq / (4100 + fsq) 92 | + 2.75 * 0.0001 * fsq + 0.003; 93 | } 94 | else 95 | { 96 | atten = 0.002 + 0.11 * (freqKhz / (1 + freqKhz)) + 0.011 * freqKhz; 97 | } 98 | 99 | return atten; 100 | } 101 | 102 | } // namespace ns3 103 | -------------------------------------------------------------------------------- /model/lora-address.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-address.h" 21 | #include "ns3/address.h" 22 | 23 | namespace ns3 { 24 | 25 | LoraAddress::LoraAddress () 26 | { 27 | m_address = 255; 28 | } 29 | 30 | LoraAddress::LoraAddress (uint8_t addr) 31 | : m_address (addr) 32 | { 33 | } 34 | 35 | LoraAddress::~LoraAddress () 36 | { 37 | } 38 | 39 | uint8_t 40 | LoraAddress::GetType (void) 41 | { 42 | static uint8_t type = Address::Register (); 43 | return type; 44 | } 45 | 46 | Address 47 | LoraAddress::ConvertTo (void) const 48 | { 49 | return Address (GetType (), &m_address, 1); 50 | } 51 | 52 | LoraAddress 53 | LoraAddress::ConvertFrom (const Address &address) 54 | { 55 | NS_ASSERT (IsMatchingType (address)); 56 | LoraAddress uAddr; 57 | address.CopyTo (&uAddr.m_address); 58 | return uAddr; 59 | } 60 | 61 | uint8_t 62 | LoraAddress::GetAsInt (void) const 63 | { 64 | return m_address; 65 | } 66 | bool 67 | LoraAddress::IsMatchingType (const Address &address) 68 | { 69 | return address.CheckCompatible (GetType (), 1); 70 | } 71 | 72 | LoraAddress::operator Address () const 73 | { 74 | return ConvertTo (); 75 | } 76 | 77 | void 78 | LoraAddress::CopyFrom (const uint8_t *pBuffer) 79 | { 80 | m_address = *pBuffer; 81 | } 82 | 83 | void 84 | LoraAddress::CopyTo (uint8_t *pBuffer) 85 | { 86 | *pBuffer = m_address; 87 | 88 | } 89 | 90 | LoraAddress 91 | LoraAddress::GetBroadcast () 92 | { 93 | return LoraAddress (255); 94 | } 95 | LoraAddress 96 | LoraAddress::Allocate () 97 | { 98 | static uint8_t nextAllocated = 0; 99 | 100 | uint32_t address = nextAllocated++; 101 | if (nextAllocated == 255) 102 | { 103 | nextAllocated = 0; 104 | } 105 | 106 | return LoraAddress (address); 107 | } 108 | 109 | bool 110 | operator < (const LoraAddress &a, const LoraAddress &b) 111 | { 112 | return a.m_address < b.m_address; 113 | } 114 | 115 | bool 116 | operator == (const LoraAddress &a, const LoraAddress &b) 117 | { 118 | return a.m_address == b.m_address; 119 | } 120 | 121 | bool 122 | operator != (const LoraAddress &a, const LoraAddress &b) 123 | { 124 | return !(a == b); 125 | } 126 | 127 | std::ostream& 128 | operator<< (std::ostream& os, const LoraAddress & address) 129 | { 130 | os << (int) address.m_address; 131 | return os; 132 | } 133 | std::istream& 134 | operator>> (std::istream& is, LoraAddress & address) 135 | { 136 | int x; 137 | is >> x; 138 | NS_ASSERT (0 <= x); 139 | NS_ASSERT (x <= 255); 140 | address.m_address = x; 141 | return is; 142 | } 143 | 144 | } // namespace ns3 145 | -------------------------------------------------------------------------------- /model/lora-header-common.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-header-common.h" 21 | #include "lora-address.h" 22 | 23 | namespace ns3 { 24 | 25 | NS_OBJECT_ENSURE_REGISTERED (LoraHeaderCommon); 26 | 27 | LoraHeaderCommon::LoraHeaderCommon () 28 | { 29 | } 30 | 31 | LoraHeaderCommon::LoraHeaderCommon (const LoraAddress src, const LoraAddress dest, uint8_t type) 32 | : Header (), 33 | m_dest (dest), 34 | m_src (src), 35 | m_type (type) 36 | { 37 | 38 | } 39 | 40 | TypeId 41 | LoraHeaderCommon::GetTypeId (void) 42 | { 43 | static TypeId tid = TypeId ("ns3::LoraHeaderCommon") 44 | .SetParent
() 45 | .SetGroupName ("Lora") 46 | .AddConstructor () 47 | ; 48 | return tid; 49 | } 50 | 51 | TypeId 52 | LoraHeaderCommon::GetInstanceTypeId (void) const 53 | { 54 | return GetTypeId (); 55 | } 56 | LoraHeaderCommon::~LoraHeaderCommon () 57 | { 58 | } 59 | 60 | 61 | void 62 | LoraHeaderCommon::SetDest (LoraAddress dest) 63 | { 64 | m_dest = dest; 65 | } 66 | void 67 | LoraHeaderCommon::SetSrc (LoraAddress src) 68 | { 69 | m_src = src; 70 | } 71 | 72 | void 73 | LoraHeaderCommon::SetType (uint8_t type) 74 | { 75 | m_type = type; 76 | } 77 | 78 | void 79 | LoraHeaderCommon::SetPayload (uint16_t payload) 80 | { 81 | m_payload = payload; 82 | } 83 | 84 | void 85 | LoraHeaderCommon::SetPreamble (uint16_t preamble) 86 | { 87 | m_preamble = preamble; 88 | } 89 | 90 | 91 | LoraAddress 92 | LoraHeaderCommon::GetDest (void) const 93 | { 94 | return m_dest; 95 | } 96 | LoraAddress 97 | LoraHeaderCommon::GetSrc (void) const 98 | { 99 | return m_src; 100 | } 101 | uint8_t 102 | LoraHeaderCommon::GetType (void) const 103 | { 104 | return m_type; 105 | } 106 | 107 | // Inherrited methods 108 | 109 | uint32_t 110 | LoraHeaderCommon::GetSerializedSize (void) const 111 | { 112 | return 1 + 1 + 1; 113 | } 114 | 115 | void 116 | LoraHeaderCommon::Serialize (Buffer::Iterator start) const 117 | { 118 | start.WriteU8 (m_src.GetAsInt ()); 119 | start.WriteU8 (m_dest.GetAsInt ()); 120 | start.WriteU8 (m_type); 121 | } 122 | 123 | uint32_t 124 | LoraHeaderCommon::Deserialize (Buffer::Iterator start) 125 | { 126 | Buffer::Iterator rbuf = start; 127 | 128 | m_src = LoraAddress (rbuf.ReadU8 ()); 129 | m_dest = LoraAddress (rbuf.ReadU8 ()); 130 | m_type = rbuf.ReadU8 (); 131 | 132 | return rbuf.GetDistanceFrom (start); 133 | } 134 | 135 | void 136 | LoraHeaderCommon::Print (std::ostream &os) const 137 | { 138 | os << "LORA src=" << m_src << " dest=" << m_dest << " type=" << (uint32_t) m_type; 139 | } 140 | 141 | 142 | 143 | 144 | } // namespace ns3 145 | -------------------------------------------------------------------------------- /model/lora-mac.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_MAC_H 21 | #define LORA_MAC_H 22 | 23 | #include "ns3/address.h" 24 | #include "ns3/object.h" 25 | #include "ns3/packet.h" 26 | 27 | #include "ns3/address.h" 28 | #include "ns3/nstime.h" 29 | #include "ns3/ptr.h" 30 | 31 | namespace ns3 { 32 | 33 | class LoraPhy; 34 | class LoraChannel; 35 | class LoraNetDevice; 36 | class LoraTransducer; 37 | class LoraTxMode; 38 | class LoraAddress; 39 | 40 | 41 | /** 42 | * 43 | * Virtual base class for all LORA MAC protocols. 44 | */ 45 | class LoraMac : public Object 46 | { 47 | public: 48 | /** 49 | * Register this type. 50 | * \return The TypeId. 51 | */ 52 | static TypeId GetTypeId (void); 53 | 54 | /** 55 | * Get the MAC Address. 56 | * 57 | * \return MAC Address. 58 | */ 59 | virtual Address GetAddress (void) = 0; 60 | 61 | /** 62 | * Set the address. 63 | * 64 | * \param addr LoraAddress for this MAC. 65 | */ 66 | virtual void SetAddress (LoraAddress addr) = 0; 67 | 68 | /** 69 | * Enqueue packet to be transmitted. 70 | * 71 | * \param pkt Packet to be transmitted. 72 | * \param dest Destination address. 73 | * \param protocolNumber Protocol number. Usage varies by MAC. 74 | * \return True if packet was successfully enqueued. 75 | */ 76 | virtual bool Enqueue (Ptr pkt, const Address &dest, uint16_t protocolNumber) = 0; 77 | /** 78 | * Set the callback to forward packets up to higher layers. 79 | * 80 | * \param cb The callback. 81 | * \pname{packet} The packet. 82 | * \pname{address} The source address. 83 | */ 84 | virtual void SetForwardUpCb (Callback, const LoraAddress&> cb) = 0; 85 | 86 | /** 87 | * Attach PHY layer to this MAC. 88 | * 89 | * Some MACs may be designed to work with multiple PHY 90 | * layers. Others may only work with one. 91 | * 92 | * \param phy Phy layer to attach to this MAC. 93 | */ 94 | virtual void AttachPhy (Ptr phy) = 0; 95 | 96 | /** 97 | * Get the broadcast address. 98 | * 99 | * \return The broadcast address. 100 | */ 101 | virtual Address GetBroadcast (void) const = 0; 102 | 103 | /** Clears all pointer references. */ 104 | virtual void Clear (void) = 0; 105 | 106 | /** 107 | * Assign a fixed random variable stream number to the random variables 108 | * used by this model. Return the number of streams (possibly zero) that 109 | * have been assigned. 110 | * 111 | * \param stream First stream index to use. 112 | * \return The number of stream indices assigned by this model. 113 | */ 114 | virtual int64_t AssignStreams (int64_t stream) = 0; 115 | 116 | /** 117 | * TracedCallback signature for packet reception/enqueue/dequeue events. 118 | * 119 | * \param [in] packet The Packet. 120 | * \param [in] mode The LoraTxMode. 121 | */ 122 | typedef void (* PacketModeTracedCallback) 123 | (const Ptr packet, const LoraTxMode & mode); 124 | 125 | }; // class LoraMac 126 | 127 | } // namespace ns3 128 | 129 | #endif /* LORA_MAC_H */ 130 | -------------------------------------------------------------------------------- /model/lora-header-common.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_HEADER_COMMON_H 21 | #define LORA_HEADER_COMMON_H 22 | 23 | #include "ns3/header.h" 24 | #include "ns3/nstime.h" 25 | #include "ns3/simulator.h" 26 | #include "lora-address.h" 27 | 28 | namespace ns3 { 29 | 30 | /** 31 | * 32 | * Common packet header fields. 33 | * 34 | * Includes 1 byte src address, 1 byte dest address, 35 | * and a 1 byte type field. 36 | * 37 | * The type field is protocol specific; see the relevant MAC protocol. 38 | */ 39 | class LoraHeaderCommon : public Header 40 | { 41 | public: 42 | /** Default constructor */ 43 | LoraHeaderCommon (); 44 | /** 45 | * Create LoraHeaderCommon object with given source and destination 46 | * address and header type 47 | * 48 | * \param src Source address defined in header. 49 | * \param dest Destination address defined in header. 50 | * \param type Header type. 51 | */ 52 | LoraHeaderCommon (const LoraAddress src, const LoraAddress dest, uint8_t type); 53 | /** Destructor */ 54 | virtual ~LoraHeaderCommon (); 55 | 56 | /** 57 | * Register this type. 58 | * \return The TypeId. 59 | */ 60 | static TypeId GetTypeId (void); 61 | 62 | /** 63 | * Set the destination address. 64 | * 65 | * \param dest Address of destination node. 66 | */ 67 | void SetDest (LoraAddress dest); 68 | /** 69 | * Set the source address. 70 | * 71 | * \param src Address of packet source node. 72 | */ 73 | void SetSrc (LoraAddress src); 74 | /** 75 | * Set the header type. 76 | * 77 | * Use of this value is protocol specific. 78 | * \param type The type value. 79 | */ 80 | void SetType (uint8_t type); 81 | 82 | /** 83 | * Set the payload. 84 | * 85 | * Use of this value is protocol specific. 86 | * \param type The type value. 87 | */ 88 | void SetPayload (uint16_t payload); 89 | 90 | /** 91 | * Set the preamble. 92 | * 93 | * Use of this value is protocol specific. 94 | * \param type The type value. 95 | */ 96 | void SetPreamble (uint16_t preamble); 97 | 98 | 99 | /** 100 | * Get the destination address. 101 | * 102 | * \return LoraAddress in destination field. 103 | */ 104 | LoraAddress GetDest (void) const; 105 | /** 106 | * Get the source address 107 | * 108 | * \return LoraAddress in source field. 109 | */ 110 | LoraAddress GetSrc (void) const; 111 | /** 112 | * Get the header type value. 113 | * 114 | * \return value of type field. 115 | */ 116 | uint8_t GetType (void) const; 117 | 118 | 119 | // Inherited methods 120 | virtual uint32_t GetSerializedSize (void) const; 121 | virtual void Serialize (Buffer::Iterator start) const; 122 | virtual uint32_t Deserialize (Buffer::Iterator start); 123 | virtual void Print (std::ostream &os) const; 124 | virtual TypeId GetInstanceTypeId (void) const; 125 | private: 126 | LoraAddress m_dest; //!< The destination address. 127 | LoraAddress m_src; //!< The source address. 128 | uint8_t m_type; //!< The type field. 129 | uint16_t m_payload; //!< The payload field. 130 | uint16_t m_preamble; //!< The preamble field. 131 | 132 | 133 | }; // class LoraHeaderCommon 134 | 135 | } // namespace ns3 136 | 137 | #endif /* LORA_HEADER_COMMON_H */ 138 | -------------------------------------------------------------------------------- /model/mac-lora-gw.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "mac-lora-gw.h" 21 | #include "lora-tx-mode.h" 22 | #include "lora-address.h" 23 | #include "ns3/log.h" 24 | #include "lora-phy.h" 25 | #include "lora-header-common.h" 26 | 27 | #include 28 | 29 | namespace ns3 30 | { 31 | 32 | NS_LOG_COMPONENT_DEFINE ("MacLoraAca"); 33 | 34 | NS_OBJECT_ENSURE_REGISTERED (MacLoraAca); 35 | 36 | MacLoraAca::MacLoraAca () 37 | : LoraMac (), 38 | m_cleared (false) 39 | { 40 | } 41 | 42 | 43 | 44 | MacLoraAca::~MacLoraAca () 45 | { 46 | } 47 | 48 | void 49 | MacLoraAca::Clear () 50 | { 51 | if (m_cleared) 52 | { 53 | return; 54 | } 55 | m_cleared = true; 56 | if (m_phy) 57 | { 58 | m_phy->Clear (); 59 | m_phy = 0; 60 | } 61 | } 62 | 63 | void 64 | MacLoraAca::DoDispose () 65 | { 66 | Clear (); 67 | LoraMac::DoDispose (); 68 | } 69 | 70 | TypeId 71 | MacLoraAca::GetTypeId (void) 72 | { 73 | static TypeId tid = TypeId ("ns3::MacLoraAca") 74 | .SetParent () 75 | .SetGroupName ("LoraAca") 76 | .AddConstructor () 77 | ; 78 | return tid; 79 | } 80 | 81 | Address 82 | MacLoraAca::GetAddress (void) 83 | { 84 | return m_address; 85 | } 86 | 87 | void 88 | MacLoraAca::SetAddress (LoraAddress addr) 89 | { 90 | m_address=addr; 91 | } 92 | bool 93 | MacLoraAca::Enqueue (Ptr packet, const Address &dest, uint16_t protocolNumber) 94 | { 95 | NS_LOG_DEBUG ("" << Simulator::Now ().GetSeconds () << " MAC " << LoraAddress::ConvertFrom (GetAddress ()) << " Queueing packet for " << LoraAddress::ConvertFrom (dest)); 96 | 97 | if (!m_phy->IsStateTx ()) 98 | { 99 | LoraAddress src = LoraAddress::ConvertFrom (GetAddress ()); 100 | LoraAddress udest = LoraAddress::ConvertFrom (dest); 101 | 102 | LoraHeaderCommon header; 103 | header.SetSrc (src); 104 | header.SetDest (udest); 105 | header.SetType (0); 106 | header.SetPayload(10); 107 | header.SetPreamble(12); 108 | 109 | packet->AddHeader (header); 110 | m_phy->SendPacket (packet, protocolNumber); 111 | return true; 112 | } 113 | else 114 | return false; 115 | } 116 | 117 | void 118 | MacLoraAca::SetForwardUpCb (Callback, const LoraAddress& > cb) 119 | { 120 | m_forUpCb = cb; 121 | } 122 | void 123 | MacLoraAca::AttachPhy (Ptr phy) 124 | { 125 | m_phy = phy; 126 | m_phy->SetReceiveOkCallback (MakeCallback (&MacLoraAca::RxPacketGood, this)); 127 | m_phy->SetReceiveErrorCallback (MakeCallback (&MacLoraAca::RxPacketError, this)); 128 | 129 | } 130 | void 131 | MacLoraAca::RxPacketGood (Ptr pkt, double sinr, LoraTxMode txMode) 132 | { 133 | LoraHeaderCommon header; 134 | pkt->RemoveHeader (header); 135 | NS_LOG_DEBUG ("Receiving packet from " << header.GetSrc () << " For " << header.GetDest ()); 136 | 137 | if (header.GetDest () == GetAddress () || header.GetDest () == LoraAddress::GetBroadcast ()) 138 | { 139 | m_forUpCb (pkt, header.GetSrc ()); 140 | } 141 | 142 | } 143 | 144 | void 145 | MacLoraAca::RxPacketError (Ptr pkt, double sinr) 146 | { 147 | NS_LOG_DEBUG ("" << Simulator::Now () << " MAC " << LoraAddress::ConvertFrom (GetAddress ()) << " Received packet in error with sinr " << sinr); 148 | } 149 | 150 | Address 151 | MacLoraAca::GetBroadcast (void) const 152 | { 153 | LoraAddress broadcast (255); 154 | return broadcast; 155 | } 156 | 157 | int64_t 158 | MacLoraAca::AssignStreams (int64_t stream) 159 | { 160 | NS_LOG_FUNCTION (this << stream); 161 | return 0; 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /model/lora-phy.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-phy.h" 21 | 22 | namespace ns3 { 23 | 24 | NS_OBJECT_ENSURE_REGISTERED (LoraPhyCalcSinr); 25 | 26 | TypeId LoraPhyCalcSinr::GetTypeId (void) 27 | { 28 | static TypeId tid = TypeId ("ns3::LoraPhyCalcSinr") 29 | .SetParent () 30 | .SetGroupName ("Lora") 31 | ; 32 | return tid; 33 | } 34 | 35 | void 36 | LoraPhyCalcSinr::Clear () 37 | { 38 | } 39 | 40 | void 41 | LoraPhyCalcSinr::DoDispose () 42 | { 43 | Clear (); 44 | Object::DoDispose (); 45 | } 46 | 47 | NS_OBJECT_ENSURE_REGISTERED (LoraPhyPer); 48 | 49 | TypeId LoraPhyPer::GetTypeId (void) 50 | { 51 | static TypeId tid = TypeId ("ns3::LoraPhyPer") 52 | .SetParent () 53 | .SetGroupName ("Lora") 54 | ; 55 | return tid; 56 | } 57 | 58 | void 59 | LoraPhyPer::Clear () 60 | { 61 | } 62 | 63 | void 64 | LoraPhyPer::DoDispose () 65 | { 66 | Clear (); 67 | Object::DoDispose (); 68 | } 69 | 70 | NS_OBJECT_ENSURE_REGISTERED (LoraPhy); 71 | 72 | TypeId LoraPhy::GetTypeId (void) 73 | { 74 | static TypeId tid = TypeId ("ns3::LoraPhy") 75 | .SetParent () 76 | .SetGroupName ("Lora") 77 | .AddTraceSource ("PhyTxBegin", 78 | "Trace source indicating a packet has " 79 | "begun transmitting over the channel medium.", 80 | MakeTraceSourceAccessor (&LoraPhy::m_phyTxBeginTrace), 81 | "ns3::Packet::TracedCallback") 82 | .AddTraceSource ("PhyTxEnd", 83 | "Trace source indicating a packet has " 84 | "been completely transmitted over the channel.", 85 | MakeTraceSourceAccessor (&LoraPhy::m_phyTxEndTrace), 86 | "ns3::Packet::TracedCallback") 87 | .AddTraceSource ("PhyTxDrop", 88 | "Trace source indicating a packet has " 89 | "been dropped by the device during transmission.", 90 | MakeTraceSourceAccessor (&LoraPhy::m_phyTxDropTrace), 91 | "ns3::Packet::TracedCallback") 92 | .AddTraceSource ("PhyRxBegin", 93 | "Trace source indicating a packet has " 94 | "begun being received from the channel medium by the device.", 95 | MakeTraceSourceAccessor (&LoraPhy::m_phyRxBeginTrace), 96 | "ns3::Packet::TracedCallback") 97 | .AddTraceSource ("PhyRxEnd", 98 | "Trace source indicating a packet has " 99 | "been completely received from the channel medium by the device.", 100 | MakeTraceSourceAccessor (&LoraPhy::m_phyRxEndTrace), 101 | "ns3::Packet::TracedCallback") 102 | .AddTraceSource ("PhyRxDrop", 103 | "Trace source indicating a packet has " 104 | "been dropped by the device during reception.", 105 | MakeTraceSourceAccessor (&LoraPhy::m_phyRxDropTrace), 106 | "ns3::Packet::TracedCallback") 107 | ; 108 | return tid; 109 | } 110 | 111 | 112 | void 113 | LoraPhy::NotifyTxBegin (Ptr packet) 114 | { 115 | m_phyTxBeginTrace (packet); 116 | } 117 | 118 | void 119 | LoraPhy::NotifyTxEnd (Ptr packet) 120 | { 121 | m_phyTxEndTrace (packet); 122 | } 123 | 124 | void 125 | LoraPhy::NotifyTxDrop (Ptr packet) 126 | { 127 | m_phyTxDropTrace (packet); 128 | } 129 | 130 | void 131 | LoraPhy::NotifyRxBegin (Ptr packet) 132 | { 133 | m_phyRxBeginTrace (packet); 134 | } 135 | 136 | void 137 | LoraPhy::NotifyRxEnd (Ptr packet) 138 | { 139 | m_phyRxEndTrace (packet); 140 | } 141 | 142 | void 143 | LoraPhy::NotifyRxDrop (Ptr packet) 144 | { 145 | m_phyRxDropTrace (packet); 146 | } 147 | 148 | } // namespace ns3 149 | -------------------------------------------------------------------------------- /model/lora-address.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_ADDRESS_H 21 | #define LORA_ADDRESS_H 22 | 23 | #include "ns3/address.h" 24 | #include 25 | 26 | namespace ns3 { 27 | 28 | /** 29 | * 30 | * A class used for addressing LORA MAC's. 31 | * 32 | */ 33 | class LoraAddress 34 | { 35 | public: 36 | /** Constructor */ 37 | LoraAddress (); 38 | /** 39 | * Create LoraAddress object with address addr. 40 | * 41 | * \param addr Byte address to assign to this address. 42 | */ 43 | LoraAddress (uint8_t addr); 44 | /** Destructor */ 45 | virtual ~LoraAddress (); 46 | 47 | /** 48 | * Convert a generic address to a LoraAddress. 49 | * 50 | */ 51 | static LoraAddress ConvertFrom (const Address &address); 52 | 53 | /** 54 | * Check that a generic Address is compatible with LoraAddress. 55 | * 56 | * \param address Address to test. 57 | * \return True if address given is consistant with LoraAddress. 58 | */ 59 | static bool IsMatchingType (const Address &address); 60 | 61 | /** 62 | * Create a generic Address. 63 | * 64 | * \return The Address. 65 | */ 66 | operator Address () const; 67 | 68 | /** 69 | * Sets address to address stored in parameter. 70 | * 71 | * \param pBuffer Buffer to extract address from. 72 | */ 73 | void CopyFrom (const uint8_t *pBuffer); 74 | 75 | /** 76 | * Writes address to buffer parameter. 77 | * 78 | * \param pBuffer 79 | */ 80 | void CopyTo (uint8_t *pBuffer); 81 | 82 | /** 83 | * Convert to integer. 84 | * 85 | * \return 8 bit integer version of address. 86 | */ 87 | uint8_t GetAsInt (void) const; 88 | 89 | /** 90 | * Get the broadcast address (255). 91 | * 92 | * \return Broadcast address. 93 | */ 94 | static LoraAddress GetBroadcast (void); 95 | 96 | /** 97 | * Allocates LoraAddress from 0-254 98 | * 99 | * Will wrap back to 0 if more than 254 are allocated. 100 | * Excludes the broadcast address. 101 | * 102 | * \return The next sequential LoraAddress. 103 | */ 104 | static LoraAddress Allocate (); 105 | 106 | 107 | private: 108 | uint8_t m_address; //!< The address. 109 | 110 | /** 111 | * Get the LoraAddress type. 112 | * 113 | * \return The type value. 114 | */ 115 | static uint8_t GetType (void); 116 | /** 117 | * Convert to a generic Address. 118 | * 119 | * \return The Address value. 120 | */ 121 | Address ConvertTo (void) const; 122 | 123 | friend bool operator < (const LoraAddress &a, const LoraAddress &b); 124 | friend bool operator == (const LoraAddress &a, const LoraAddress &b); 125 | friend bool operator != (const LoraAddress &a, const LoraAddress &b); 126 | friend std::ostream& operator<< (std::ostream& os, const LoraAddress & address); 127 | friend std::istream& operator>> (std::istream& is, LoraAddress & address); 128 | 129 | }; // class LoraAddress 130 | 131 | 132 | /** 133 | * Address comparison, less than. 134 | * 135 | * \param a First address to compare. 136 | * \param b Second address to compare. 137 | * \return True if a < b. 138 | */ 139 | bool operator < (const LoraAddress &a, const LoraAddress &b); 140 | 141 | /** 142 | * Address comparison, equalit. 143 | * 144 | * \param a First address to compare. 145 | * \param b Second address to compare. 146 | * \return True if a == b. 147 | */ 148 | bool operator == (const LoraAddress &a, const LoraAddress &b); 149 | 150 | /** 151 | * Address comparison, unequal. 152 | * 153 | * \param a First address to compare. 154 | * \param b Second address to compare. 155 | * \return True if a != b. 156 | */ 157 | bool operator != (const LoraAddress &a, const LoraAddress &b); 158 | 159 | /** 160 | * Write \pname{address} to stream \pname{os} as 8 bit integer. 161 | * 162 | * \param os The output stream. 163 | * \param address The address 164 | * \return The output stream. 165 | */ 166 | std::ostream& operator<< (std::ostream& os, const LoraAddress & address); 167 | 168 | /** 169 | * Read \pname{address} from stream \pname{is} as 8 bit integer. 170 | * 171 | * \param is The input stream. 172 | * \param address The address variable to set. 173 | * \return The input stream. 174 | */ 175 | std::istream& operator>> (std::istream& is, LoraAddress & address); 176 | 177 | } // namespace ns3 178 | 179 | #endif /* LORA_ADDRESS_H */ 180 | -------------------------------------------------------------------------------- /model/lora-transducer.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_TRANSDUCER_H 21 | #define LORA_TRANSDUCER_H 22 | 23 | #include "ns3/object.h" 24 | #include "ns3/packet.h" 25 | #include "lora-tx-mode.h" 26 | #include "ns3/lora-prop-model.h" 27 | 28 | #include 29 | 30 | namespace ns3 { 31 | 32 | class LoraPhy; 33 | class LoraChannel; 34 | 35 | 36 | /** 37 | * 38 | * Class consisting of packet arrival information (Time, RxPower, mode, PDP). 39 | */ 40 | class LoraPacketArrival 41 | { 42 | public: 43 | 44 | /** Default constructor. */ 45 | LoraPacketArrival () 46 | { 47 | } 48 | 49 | /** 50 | * Constructor. 51 | * 52 | * \param packet Packet arriving. 53 | * \param rxPowerDb RX signal power in dB of arriving packet. 54 | * \param txMode TX mode of arriving packet. 55 | * \param pdp Power delay profile of arriving packet. 56 | * \param arrTime Arrival time of packet. 57 | */ 58 | LoraPacketArrival (Ptr packet, double rxPowerDb, LoraTxMode txMode, LoraPdp pdp, Time arrTime) 59 | : m_packet (packet), 60 | m_rxPowerDb (rxPowerDb), 61 | m_txMode (txMode), 62 | m_pdp (pdp), 63 | m_arrTime (arrTime) 64 | { 65 | } 66 | 67 | /** Destructor */ 68 | ~LoraPacketArrival() 69 | { 70 | m_packet = 0; 71 | } 72 | 73 | /** 74 | * Get the arriving packet. 75 | * 76 | * \return Pointer to packet. 77 | */ 78 | inline Ptr GetPacket (void) const 79 | { 80 | return m_packet; 81 | } 82 | /** 83 | * Get the received signal strength. 84 | * 85 | * \return Received signal strength in dB re 1uPa 86 | */ 87 | inline double GetRxPowerDb (void) const 88 | { 89 | return m_rxPowerDb; 90 | } 91 | /** 92 | * Get the transmission mode of the packet. 93 | * 94 | * \return LoraTxMode. 95 | */ 96 | inline const LoraTxMode &GetTxMode (void) const 97 | { 98 | return m_txMode; 99 | } 100 | /** 101 | * Get the packet arrival time. 102 | * 103 | * \return Arrival time. 104 | */ 105 | inline Time GetArrivalTime (void) const 106 | { 107 | return m_arrTime; 108 | } 109 | /** 110 | * Get the propagation delay profile. 111 | * 112 | * \return PDP of arriving signal. 113 | */ 114 | inline LoraPdp GetPdp (void) const 115 | { 116 | return m_pdp; 117 | } 118 | private: 119 | Ptr m_packet; //!< The arrived packet. 120 | double m_rxPowerDb; //!< The received power, in dB. 121 | LoraTxMode m_txMode; //!< The transmission mode. 122 | LoraPdp m_pdp; //!< The propagation delay profile. 123 | Time m_arrTime; //!< The arrival time. 124 | 125 | }; // class LoraPacketArrival 126 | 127 | /** 128 | * 129 | * Virtual base for Transducer objects. 130 | * 131 | */ 132 | class LoraTransducer : public Object 133 | { 134 | public: 135 | /** 136 | * Register this type. 137 | * \return The object TypeId. 138 | */ 139 | static TypeId GetTypeId (void); 140 | 141 | /** Transducer state. */ 142 | enum State { 143 | TX, //!< Transmitting. 144 | RX //!< Receiving. 145 | }; 146 | 147 | /** List of arriving packets overlapping in time. */ 148 | typedef std::list ArrivalList; 149 | /** List of LoraPhy objects. */ 150 | typedef std::list > LoraPhyList; 151 | 152 | /** 153 | * Get the transducer state. 154 | * 155 | * \return State (TX or RX) of this transducer. 156 | */ 157 | virtual State GetState (void) const = 0; 158 | 159 | /** 160 | * Is the state receiving (or available for reception)? 161 | * 162 | * \return True if this transducer is available for receiving 163 | * an incoming packet. 164 | */ 165 | virtual bool IsRx (void) const = 0; 166 | /** 167 | * Is the state transmitting? 168 | * 169 | * \return True if there is a packet being transmitted from this transducer. 170 | */ 171 | virtual bool IsTx (void) const = 0; 172 | /** 173 | * Get the list of overlapped (in time) packets at this transducer. 174 | * 175 | * \return List of all packets currently crossing this node in the water. 176 | */ 177 | virtual const ArrivalList &GetArrivalList (void) const = 0; 178 | /** 179 | * Notify this object that a new packet has arrived at this nodes location 180 | * 181 | * \param packet Packet arriving. 182 | * \param rxPowerDb Signal power in dB of arriving packet. 183 | * \param txMode Mode arriving packet is using. 184 | * \param pdp PDP of arriving signal. 185 | */ 186 | virtual void Receive (Ptr packet, double rxPowerDb, LoraTxMode txMode, LoraPdp pdp) = 0; 187 | /** 188 | * Transmit a packet from this transducer. 189 | * 190 | * \param src Source PHY. 191 | * \param packet Packet to transmit. 192 | * \param txPowerDb Outgoing Tx power of packet. 193 | * \param txMode Mode to transmit packet with. 194 | */ 195 | virtual void Transmit (Ptr src, Ptr packet, double txPowerDb, LoraTxMode txMode) = 0; 196 | /** 197 | * Attach this transducer to a channel. 198 | * 199 | * \param chan The channel 200 | */ 201 | virtual void SetChannel (Ptr chan) = 0; 202 | /** 203 | * Get the attached channel. 204 | * 205 | * \return The channel. 206 | */ 207 | virtual Ptr GetChannel (void) const = 0; 208 | /** 209 | * Attach a physical network layer above this transducer. 210 | * 211 | * More than one physical layer may be attached. 212 | * 213 | * \param phy The physical layer. 214 | */ 215 | virtual void AddPhy (Ptr phy) = 0; 216 | /** 217 | * Get the list of physical layer above this transducer. 218 | * 219 | * \return List of attached physical layers. 220 | */ 221 | virtual const LoraPhyList &GetPhyList (void) const = 0; 222 | /** 223 | * Clears all pointer references. 224 | */ 225 | virtual void Clear (void) = 0; 226 | 227 | }; // class LoraTransducer 228 | 229 | } // namespace ns3 230 | 231 | #endif /* LORA_TRANSDUCER_H */ 232 | -------------------------------------------------------------------------------- /model/lora-transducer-hd.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-transducer-hd.h" 21 | #include "ns3/simulator.h" 22 | #include "ns3/lora-prop-model.h" 23 | #include "lora-phy.h" 24 | #include "lora-channel.h" 25 | #include "ns3/log.h" 26 | #include "ns3/pointer.h" 27 | 28 | 29 | namespace ns3 { 30 | 31 | NS_LOG_COMPONENT_DEFINE ("LoraTransducerHd"); 32 | 33 | NS_OBJECT_ENSURE_REGISTERED (LoraTransducerHd); 34 | 35 | LoraTransducerHd::LoraTransducerHd () 36 | : LoraTransducer (), 37 | m_state (RX), 38 | m_endTxTime (Seconds (0)), 39 | m_cleared (false) 40 | { 41 | } 42 | 43 | LoraTransducerHd::~LoraTransducerHd () 44 | { 45 | } 46 | 47 | void 48 | LoraTransducerHd::Clear () 49 | { 50 | if (m_cleared) 51 | { 52 | return; 53 | } 54 | m_cleared = true; 55 | if (m_channel) 56 | { 57 | m_channel->Clear (); 58 | m_channel = 0; 59 | } 60 | 61 | LoraPhyList::iterator it = m_phyList.begin (); 62 | for (; it != m_phyList.end (); it++) 63 | { 64 | if (*it) 65 | { 66 | (*it)->Clear (); 67 | *it = 0; 68 | } 69 | } 70 | ArrivalList::iterator ait = m_arrivalList.begin (); 71 | for (; ait != m_arrivalList.end (); ait++) 72 | { 73 | ait->GetPacket () = 0; 74 | } 75 | m_phyList.clear (); 76 | m_arrivalList.clear (); 77 | m_endTxEvent.Cancel (); 78 | } 79 | 80 | void 81 | LoraTransducerHd::DoDispose () 82 | { 83 | Clear (); 84 | LoraTransducer::DoDispose (); 85 | } 86 | TypeId 87 | LoraTransducerHd::GetTypeId () 88 | { 89 | static TypeId tid = TypeId ("ns3::LoraTransducerHd") 90 | .SetParent () 91 | .SetGroupName ("Lora") 92 | .AddConstructor () 93 | ; 94 | return tid; 95 | } 96 | 97 | LoraTransducer::State 98 | LoraTransducerHd::GetState () const 99 | { 100 | return m_state; 101 | } 102 | 103 | 104 | bool 105 | LoraTransducerHd::IsRx (void) const 106 | { 107 | return m_state == RX; 108 | } 109 | 110 | bool 111 | LoraTransducerHd::IsTx (void) const 112 | { 113 | return m_state == TX; 114 | 115 | } 116 | 117 | const LoraTransducer::ArrivalList & 118 | LoraTransducerHd::GetArrivalList (void) const 119 | { 120 | return m_arrivalList; 121 | } 122 | 123 | void 124 | LoraTransducerHd::Receive (Ptr packet, 125 | double rxPowerDb, 126 | LoraTxMode txMode, 127 | LoraPdp pdp) 128 | { 129 | LoraPacketArrival arrival (packet, 130 | rxPowerDb, 131 | txMode, 132 | pdp, 133 | Simulator::Now ()); 134 | 135 | m_arrivalList.push_back (arrival); 136 | Time txDelay = Seconds (packet->GetSize () * 8.0 / txMode.GetDataRateBps ()); 137 | Simulator::Schedule (txDelay, &LoraTransducerHd::RemoveArrival, this, arrival); 138 | NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Transducer in receive"); 139 | if (m_state == RX) 140 | { 141 | NS_LOG_DEBUG ("Transducer state = RX"); 142 | LoraPhyList::const_iterator it = m_phyList.begin (); 143 | for (; it != m_phyList.end (); it++) 144 | { 145 | NS_LOG_DEBUG ("Calling StartRx"); 146 | (*it)->StartRxPacket (packet, rxPowerDb, txMode, pdp); 147 | } 148 | } 149 | } 150 | 151 | void 152 | LoraTransducerHd::Transmit (Ptr src, 153 | Ptr packet, 154 | double txPowerDb, 155 | LoraTxMode txMode) 156 | { 157 | if (m_state == TX) 158 | { 159 | Simulator::Remove (m_endTxEvent); 160 | src->NotifyTxDrop(packet); // traced source netanim 161 | } 162 | else 163 | { 164 | m_state = TX; 165 | src->NotifyTxBegin(packet); // traced source netanim 166 | } 167 | 168 | 169 | Time delay = Seconds (packet->GetSize () * 8.0 / txMode.GetDataRateBps ()); 170 | NS_LOG_DEBUG ("Transducer transmitting: TX delay = " 171 | << delay << " seconds for packet size " 172 | << packet->GetSize () << " bytes and rate = " 173 | << txMode.GetDataRateBps () << " bps"); 174 | LoraPhyList::const_iterator it = m_phyList.begin (); 175 | for (; it != m_phyList.end (); it++) 176 | { 177 | if (src != (*it)) 178 | { 179 | (*it)->NotifyTransStartTx (packet, txPowerDb, txMode); 180 | } 181 | } 182 | m_channel->TxPacket (Ptr (this), packet, txPowerDb, txMode); 183 | 184 | 185 | delay = std::max (delay, m_endTxTime - Simulator::Now ()); 186 | 187 | m_endTxEvent = Simulator::Schedule (delay, &LoraTransducerHd::EndTx, this); 188 | m_endTxTime = Simulator::Now () + delay; 189 | Simulator::Schedule(delay, &LoraPhy::NotifyTxEnd, src, packet); // traced source netanim 190 | } 191 | 192 | void 193 | LoraTransducerHd::EndTx (void) 194 | { 195 | NS_ASSERT (m_state == TX); 196 | m_state = RX; 197 | m_endTxTime = Seconds (0); 198 | } 199 | void 200 | LoraTransducerHd::SetChannel (Ptr chan) 201 | { 202 | NS_LOG_DEBUG ("Transducer setting channel"); 203 | m_channel = chan; 204 | 205 | } 206 | Ptr 207 | LoraTransducerHd::GetChannel (void) const 208 | { 209 | return m_channel; 210 | } 211 | void 212 | LoraTransducerHd::AddPhy (Ptr phy) 213 | { 214 | m_phyList.push_back (phy); 215 | } 216 | 217 | const LoraTransducer::LoraPhyList & 218 | LoraTransducerHd::GetPhyList (void) const 219 | { 220 | return m_phyList; 221 | } 222 | 223 | void 224 | LoraTransducerHd::RemoveArrival (LoraPacketArrival arrival) 225 | { 226 | 227 | // Remove entry from arrival list 228 | ArrivalList::iterator it = m_arrivalList.begin (); 229 | for (; it != m_arrivalList.end (); it++) 230 | { 231 | if (it->GetPacket () == arrival.GetPacket ()) 232 | { 233 | m_arrivalList.erase (it); 234 | break; 235 | } 236 | } 237 | LoraPhyList::const_iterator ait = m_phyList.begin (); 238 | for (; ait != m_phyList.end (); ait++) 239 | { 240 | (*ait)->NotifyIntChange (); 241 | } 242 | 243 | } 244 | 245 | } // namespace ns3 246 | -------------------------------------------------------------------------------- /model/lora-tx-mode.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | #include "lora-tx-mode.h" 20 | #include "ns3/log.h" 21 | #include 22 | #include 23 | 24 | namespace ns3 { 25 | 26 | NS_LOG_COMPONENT_DEFINE ("LoraTxMode"); 27 | 28 | LoraTxMode::LoraTxMode () 29 | { 30 | } 31 | 32 | LoraTxMode::~LoraTxMode () 33 | { 34 | } 35 | 36 | 37 | LoraTxMode::ModulationType 38 | LoraTxMode::GetModType (void) const 39 | { 40 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_type; 41 | } 42 | 43 | uint32_t 44 | LoraTxMode::GetDataRateBps (void) const 45 | { 46 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_dataRateBps; 47 | } 48 | 49 | uint32_t 50 | LoraTxMode::GetPhyRateSps (void) const 51 | { 52 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_phyRateSps; 53 | } 54 | 55 | uint32_t 56 | LoraTxMode::GetCenterFreqHz (void) const 57 | { 58 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_cfHz; 59 | } 60 | 61 | uint32_t 62 | LoraTxMode::GetBandwidthHz (void) const 63 | { 64 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_bwHz; 65 | } 66 | 67 | uint32_t 68 | LoraTxMode::GetConstellationSize (void) const 69 | { 70 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_constSize; 71 | } 72 | 73 | std::string 74 | LoraTxMode::GetName (void) const 75 | { 76 | return LoraTxModeFactory::GetFactory ().GetModeItem (m_uid).m_name; 77 | } 78 | 79 | uint32_t 80 | LoraTxMode::GetUid (void) const 81 | { 82 | return m_uid; 83 | } 84 | 85 | std::ostream & 86 | operator<< (std::ostream & os, const LoraTxMode &mode) 87 | { 88 | os << mode.m_uid; 89 | return os; 90 | } 91 | 92 | std::istream & 93 | operator>> (std::istream & is, LoraTxMode &mode) 94 | { 95 | std::string name; 96 | uint32_t duh; 97 | 98 | is >> duh; 99 | 100 | mode.m_uid = duh; 101 | return is; 102 | } 103 | 104 | 105 | 106 | LoraTxModeFactory::LoraTxModeFactory () 107 | : m_nextUid (0) 108 | { 109 | 110 | } 111 | LoraTxModeFactory::~LoraTxModeFactory () 112 | { 113 | m_modes.clear (); 114 | } 115 | bool 116 | LoraTxModeFactory::NameUsed (std::string name) 117 | { 118 | std::map::iterator it = m_modes.begin (); 119 | 120 | for (; it != m_modes.end (); it++) 121 | { 122 | if ((*it).second.m_name == name) 123 | { 124 | return true; 125 | } 126 | } 127 | return false; 128 | } 129 | 130 | LoraTxMode 131 | LoraTxModeFactory::CreateMode (LoraTxMode::ModulationType type, 132 | uint32_t dataRateBps, 133 | uint32_t phyRateSps, 134 | uint32_t cfHz, 135 | uint32_t bwHz, 136 | uint32_t constSize, 137 | std::string name) 138 | { 139 | LoraTxModeFactory &factory = LoraTxModeFactory::GetFactory (); 140 | 141 | 142 | LoraTxModeItem *item; 143 | 144 | if (factory.NameUsed (name)) 145 | { 146 | NS_LOG_WARN ("Redefining LoraTxMode with name \"" << name << "\""); 147 | item = &factory.GetModeItem (name); 148 | } 149 | else 150 | { 151 | item = &factory.m_modes[factory.m_nextUid]; 152 | item->m_uid = factory.m_nextUid++; 153 | } 154 | 155 | item->m_type = type; 156 | item->m_dataRateBps = dataRateBps; 157 | item->m_phyRateSps = phyRateSps; 158 | item->m_cfHz = cfHz; 159 | item->m_bwHz = bwHz; 160 | item->m_constSize = constSize; 161 | item->m_name = name; 162 | return factory.MakeModeFromItem (*item); 163 | } 164 | 165 | LoraTxModeFactory::LoraTxModeItem & 166 | LoraTxModeFactory::GetModeItem (uint32_t uid) 167 | { 168 | if (uid >= m_nextUid) 169 | { 170 | NS_FATAL_ERROR ("Attempting to retrieve LoraTxMode with uid, " 171 | << uid << ", >= m_nextUid"); 172 | } 173 | 174 | return m_modes[uid]; 175 | } 176 | 177 | LoraTxModeFactory::LoraTxModeItem & 178 | LoraTxModeFactory::GetModeItem (std::string name) 179 | { 180 | std::map::iterator it = m_modes.begin (); 181 | for (; it != m_modes.end (); it++) 182 | { 183 | if ((*it).second.m_name == name) 184 | { 185 | return (*it).second; 186 | } 187 | } 188 | NS_FATAL_ERROR ("Unknown mode, \"" << name << "\", requested from mode factory"); 189 | return (*it).second; // dummy to get rid of warning 190 | } 191 | 192 | LoraTxMode 193 | LoraTxModeFactory::GetMode (std::string name) 194 | { 195 | LoraTxModeFactory &factory = LoraTxModeFactory::GetFactory (); 196 | return factory.MakeModeFromItem (factory.GetModeItem (name)); 197 | } 198 | 199 | LoraTxMode 200 | LoraTxModeFactory::GetMode (uint32_t uid) 201 | { 202 | LoraTxModeFactory &factory = LoraTxModeFactory::GetFactory (); 203 | return factory.MakeModeFromItem (factory.GetModeItem (uid)); 204 | } 205 | 206 | LoraTxMode 207 | LoraTxModeFactory::MakeModeFromItem (const LoraTxModeItem &item) 208 | { 209 | LoraTxMode mode; 210 | mode.m_uid = item.m_uid; 211 | return mode; 212 | } 213 | 214 | LoraTxModeFactory & 215 | LoraTxModeFactory::GetFactory (void) 216 | { 217 | static LoraTxModeFactory factory; 218 | return factory; 219 | } 220 | 221 | LoraModesList::LoraModesList (void) 222 | { 223 | } 224 | 225 | LoraModesList::~LoraModesList (void) 226 | { 227 | m_modes.clear (); 228 | } 229 | 230 | void 231 | LoraModesList::AppendMode (LoraTxMode newMode) 232 | { 233 | m_modes.push_back (newMode); 234 | } 235 | 236 | void 237 | LoraModesList::DeleteMode (uint32_t modeNum) 238 | { 239 | NS_ASSERT (modeNum < m_modes.size ()); 240 | 241 | 242 | std::vector::iterator it = m_modes.begin (); 243 | for (uint32_t i = 0; i < modeNum; i++) 244 | { 245 | it++; 246 | } 247 | it = m_modes.erase (it); 248 | } 249 | 250 | LoraTxMode 251 | LoraModesList::operator[] (uint32_t i) const 252 | { 253 | NS_ASSERT (i < m_modes.size ()); 254 | return m_modes[i]; 255 | } 256 | 257 | uint32_t 258 | LoraModesList::GetNModes (void) const 259 | { 260 | return m_modes.size (); 261 | } 262 | 263 | std::ostream & 264 | operator << (std::ostream &os, const LoraModesList &ml) 265 | { 266 | 267 | os << ml.GetNModes () << "|"; 268 | 269 | for (uint32_t i = 0; i < ml.m_modes.size (); i++) 270 | { 271 | os << ml[i] << "|"; 272 | } 273 | return os; 274 | } 275 | std::istream & 276 | operator >> (std::istream &is, LoraModesList &ml) 277 | { 278 | char c; 279 | 280 | int numModes; 281 | 282 | is >> numModes >> c; 283 | if (c != '|') 284 | { 285 | is.setstate (std::ios_base::failbit); 286 | } 287 | ml.m_modes.clear (); 288 | ml.m_modes.resize (numModes); 289 | 290 | for (int i = 0; i < numModes && !is.eof (); i++) 291 | { 292 | is >> ml.m_modes[i] >> c; 293 | if (c != '|') 294 | { 295 | is.setstate (std::ios_base::failbit); 296 | } 297 | } 298 | 299 | return is; 300 | } 301 | 302 | ATTRIBUTE_HELPER_CPP (LoraModesList); 303 | 304 | } // namespace ns3 305 | -------------------------------------------------------------------------------- /model/lora-channel.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "ns3/object.h" 21 | #include "ns3/packet.h" 22 | #include "ns3/simulator.h" 23 | #include "ns3/mobility-model.h" 24 | #include "ns3/net-device.h" 25 | #include "ns3/node.h" 26 | #include "ns3/log.h" 27 | #include "ns3/pointer.h" 28 | #include "ns3/string.h" 29 | #include "ns3/log.h" 30 | 31 | #include "lora-channel.h" 32 | #include "lora-phy.h" 33 | #include "lora-prop-model.h" 34 | #include "lora-tx-mode.h" 35 | #include "lora-net-device.h" 36 | #include "lora-transducer.h" 37 | #include "lora-noise-model-default.h" 38 | #include "lora-prop-model-ideal.h" 39 | 40 | namespace ns3 { 41 | 42 | NS_LOG_COMPONENT_DEFINE ("LoraChannel"); 43 | 44 | NS_OBJECT_ENSURE_REGISTERED (LoraChannel); 45 | 46 | TypeId 47 | LoraChannel::GetTypeId () 48 | { 49 | static TypeId tid = TypeId ("ns3::LoraChannel") 50 | .SetParent () 51 | .SetGroupName ("Lora") 52 | .AddConstructor () 53 | .AddAttribute ("PropagationModel", 54 | "A pointer to the propagation model.", 55 | StringValue ("ns3::LoraPropModelIdeal"), 56 | MakePointerAccessor (&LoraChannel::m_prop), 57 | MakePointerChecker ()) 58 | .AddAttribute ("NoiseModel", 59 | "A pointer to the model of the channel ambient noise.", 60 | StringValue ("ns3::LoraNoiseModelDefault"), 61 | MakePointerAccessor (&LoraChannel::m_noise), 62 | MakePointerChecker ()) 63 | ; 64 | 65 | return tid; 66 | } 67 | 68 | LoraChannel::LoraChannel () 69 | : Channel (), 70 | m_prop (0), 71 | m_cleared (false) 72 | { 73 | } 74 | 75 | LoraChannel::~LoraChannel () 76 | { 77 | } 78 | 79 | void 80 | LoraChannel::Clear () 81 | { 82 | if (m_cleared) 83 | { 84 | return; 85 | } 86 | m_cleared = true; 87 | LoraDeviceList::iterator it = m_devList.begin (); 88 | for (; it != m_devList.end (); it++) 89 | { 90 | if (it->first) 91 | { 92 | it->first->Clear (); 93 | it->first = 0; 94 | } 95 | if (it->second) 96 | { 97 | it->second->Clear (); 98 | it->second = 0; 99 | } 100 | } 101 | m_devList.clear (); 102 | if (m_prop) 103 | { 104 | m_prop->Clear (); 105 | m_prop = 0; 106 | } 107 | if (m_noise) 108 | { 109 | m_noise->Clear (); 110 | m_noise = 0; 111 | } 112 | 113 | } 114 | 115 | void 116 | LoraChannel::DoDispose () 117 | { 118 | Clear (); 119 | Channel::DoDispose (); 120 | } 121 | void 122 | LoraChannel::SetPropagationModel (Ptr prop) 123 | { 124 | NS_LOG_DEBUG ("Set Prop Model " << this); 125 | m_prop = prop; 126 | } 127 | 128 | std::size_t 129 | LoraChannel::GetNDevices () const 130 | { 131 | return m_devList.size (); 132 | } 133 | 134 | Ptr 135 | LoraChannel::GetDevice (std::size_t i) const 136 | { 137 | return m_devList[i].first; 138 | } 139 | 140 | void 141 | LoraChannel::AddDevice (Ptr dev, Ptr trans) 142 | { 143 | NS_LOG_DEBUG ("Adding dev/trans pair number " << m_devList.size ()); 144 | m_devList.push_back (std::make_pair (dev, trans)); 145 | } 146 | 147 | void 148 | LoraChannel::TxPacket (Ptr src, Ptr packet, 149 | double txPowerDb, LoraTxMode txMode) 150 | { 151 | Ptr senderMobility = 0; 152 | 153 | NS_LOG_DEBUG ("Channel scheduling"); 154 | for (LoraDeviceList::const_iterator i = m_devList.begin (); i 155 | != m_devList.end (); i++) 156 | { 157 | 158 | if (src == i->second) 159 | { 160 | senderMobility = i->first->GetNode ()->GetObject (); 161 | break; 162 | } 163 | } 164 | NS_ASSERT (senderMobility != 0); 165 | uint32_t j = 0; 166 | LoraDeviceList::const_iterator i = m_devList.begin (); 167 | for (; i != m_devList.end (); i++) 168 | { 169 | if (src != i->second) 170 | { 171 | NS_LOG_DEBUG ("Scheduling " << i->first->GetMac ()->GetAddress ()); 172 | Ptr rcvrMobility = i->first->GetNode ()->GetObject (); 173 | Time delay = m_prop->GetDelay (senderMobility, rcvrMobility, txMode); 174 | LoraPdp pdp = m_prop->GetPdp (senderMobility, rcvrMobility, txMode); 175 | double rxPowerDb = txPowerDb - m_prop->GetPathLossDb (senderMobility, 176 | rcvrMobility, 177 | txMode); 178 | 179 | NS_LOG_DEBUG ("txPowerDb=" << txPowerDb << "dB, rxPowerDb=" 180 | << rxPowerDb << "dB, distance=" 181 | << senderMobility->GetDistanceFrom (rcvrMobility) 182 | << "m, delay=" << delay); 183 | 184 | uint32_t dstNodeId = i->first->GetNode ()->GetId (); 185 | Ptr copy = packet->Copy (); 186 | Simulator::ScheduleWithContext (dstNodeId, delay, 187 | &LoraChannel::SendUp, 188 | this, 189 | j, 190 | copy, 191 | rxPowerDb, 192 | txMode, 193 | pdp); 194 | } 195 | j++; 196 | } 197 | } 198 | 199 | void 200 | LoraChannel::SetNoiseModel (Ptr noise) 201 | { 202 | NS_ASSERT (noise); 203 | m_noise = noise; 204 | } 205 | void 206 | LoraChannel::SendUp (uint32_t i, Ptr packet, double rxPowerDb, 207 | LoraTxMode txMode, LoraPdp pdp) 208 | { 209 | NS_LOG_DEBUG ("Channel: In sendup"); 210 | m_devList[i].second->Receive (packet, rxPowerDb, txMode, pdp); 211 | } 212 | 213 | double 214 | LoraChannel::GetNoiseDbHz (double fKhz) 215 | { 216 | NS_ASSERT (m_noise); 217 | double noise = m_noise->GetNoiseDbHz (fKhz); 218 | return noise; 219 | } 220 | 221 | 222 | 223 | /** 224 | * \param srcId The device Id of the net device that wants to 225 | * transmit on the channel. 226 | * \return True if the channel is not busy and the transmitting net 227 | * device is currently active. 228 | */ 229 | bool 230 | 231 | LoraChannel::TransmitStart (Ptr p, uint16_t protocolNumber) 232 | { 233 | 234 | NS_LOG_INFO ("UID is " << p->GetUid () << ")"); 235 | 236 | if (m_state[protocolNumber] != IDLE) 237 | { 238 | NS_LOG_WARN ("LoraChannel::TransmitStart(): State is not IDLE"); 239 | return false; 240 | } 241 | 242 | NS_LOG_LOGIC ("switch to TRANSMITTING"); 243 | m_currentPkt = p; 244 | m_state[protocolNumber] = TRANSMITTING; 245 | return true; 246 | } 247 | 248 | 249 | bool 250 | LoraChannel::TransmitEnd (uint16_t protocolNumber) 251 | { 252 | 253 | NS_LOG_FUNCTION (this << m_currentPkt << m_currentSrc); 254 | NS_LOG_INFO ("UID is " << m_currentPkt->GetUid () << ")"); 255 | 256 | NS_ASSERT (m_state[protocolNumber] == TRANSMITTING); 257 | m_state[protocolNumber] = IDLE; 258 | 259 | bool retVal = true; 260 | 261 | return retVal; 262 | } 263 | 264 | bool 265 | LoraChannel::IsBusy (uint16_t protocolNumber) 266 | { 267 | if (m_state[protocolNumber] == IDLE) 268 | { 269 | return false; 270 | } 271 | else 272 | { 273 | return true; 274 | } 275 | } 276 | 277 | 278 | DataRate 279 | LoraChannel::GetDataRate (void) 280 | { 281 | return m_bps; 282 | } 283 | 284 | Time 285 | LoraChannel::GetDelay (void) 286 | { 287 | return m_delay; 288 | } 289 | 290 | WireState 291 | LoraChannel::GetState (uint16_t protocolNumber) 292 | { 293 | return m_state[protocolNumber]; 294 | } 295 | 296 | 297 | 298 | } // namespace ns3 299 | -------------------------------------------------------------------------------- /model/lora-channel.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_CHANNEL_H 21 | #define LORA_CHANNEL_H 22 | 23 | #include "ns3/net-device.h" 24 | #include "ns3/channel.h" 25 | #include "ns3/packet.h" 26 | #include "ns3/lora-prop-model.h" 27 | #include "ns3/lora-noise-model.h" 28 | #include "ns3/nstime.h" 29 | #include "ns3/data-rate.h" 30 | #include "ns3/ptr.h" 31 | 32 | #include 33 | #include 34 | 35 | namespace ns3 { 36 | 37 | class LoraNetDevice; 38 | class LoraPhy; 39 | class LoraTransducer; 40 | class LoraTxMode; 41 | 42 | 43 | /** 44 | * Current state of the channel 45 | */ 46 | enum WireState 47 | { 48 | IDLE, /**< Channel is IDLE, no packet is being transmitted */ 49 | TRANSMITTING, /**< Channel is BUSY, a packet is being written by a net device */ 50 | PROPAGATING /**< Channel is BUSY, packet is propagating to all attached net devices */ 51 | }; 52 | 53 | 54 | 55 | /** 56 | * 57 | * Channel class used by LORA devices. 58 | */ 59 | class LoraChannel : public Channel 60 | { 61 | public: 62 | /** 63 | * LoraDeviceList is a standard template vector of pairs 64 | * (LoraNetDevice, LoraTransducer) 65 | */ 66 | typedef std::vector, Ptr > > LoraDeviceList; 67 | 68 | LoraChannel (); //!< Constructor 69 | virtual ~LoraChannel (); //!< Dummy destructor, see DoDispose. 70 | 71 | /** 72 | * Register this type. 73 | * \return The object TypeId. 74 | */ 75 | static TypeId GetTypeId (void); 76 | 77 | // Inherited methods 78 | virtual std::size_t GetNDevices (void) const; 79 | virtual Ptr GetDevice (std::size_t i) const; 80 | 81 | /** 82 | * Send a packet out on the channel. 83 | * 84 | * \param src Transducer transmitting packet. 85 | * \param packet Packet to be transmitted. 86 | * \param txPowerDb Transmission power in dB. 87 | * \param txmode LoraTxMode defining modulation of transmitted packet. 88 | */ 89 | void TxPacket (Ptr src, Ptr packet, double txPowerDb, 90 | LoraTxMode txmode); 91 | 92 | /** 93 | * Adds device to receiver list for this channel. 94 | * 95 | * \param dev Net Device of node. 96 | * \param trans Transducer of net device attached to this channel. 97 | */ 98 | void AddDevice (Ptr dev, Ptr trans); 99 | 100 | /** 101 | * Set the propagation model this channel will use 102 | * for path loss/propagation delay. 103 | * 104 | * \param prop The propagation model. 105 | */ 106 | void SetPropagationModel (Ptr prop); 107 | 108 | /** 109 | * Set the noise model this channel will use 110 | * to determine ambient channel noise. 111 | * 112 | * \param noise The noise model. 113 | */ 114 | void SetNoiseModel (Ptr noise); 115 | 116 | /** 117 | * Get the noise level on the channel. 118 | * 119 | * \param fKhz Frequency in kHz. 120 | * \return Ambient noise in dB/Hz on channel at a frequency. 121 | */ 122 | double GetNoiseDbHz (double fKhz); 123 | 124 | /** 125 | * Clear all pointer references. */ 126 | void Clear (void); 127 | 128 | 129 | 130 | /** 131 | * \brief Start transmitting a packet over the channel 132 | * 133 | * If the srcId belongs to a net device that is connected to the 134 | * channel, packet transmission begins, and the channel becomes busy 135 | * until the packet has completely reached all destinations. 136 | * 137 | * \param p A reference to the packet that will be transmitted over 138 | * the channel 139 | * \param srcId The device Id of the net device that wants to 140 | * transmit on the channel. 141 | * \return True if the channel is not busy and the transmitting net 142 | * device is currently active. 143 | * bool TransmitStart (Ptr p, uint32_t srcId); 144 | */ 145 | 146 | bool TransmitStart (Ptr p, uint16_t protocolNumber); 147 | 148 | /** 149 | * \brief Indicates that the net device has finished transmitting 150 | * the packet over the channel 151 | * 152 | * The channel will stay busy until the packet has completely 153 | * propagated to all net devices attached to the channel. The 154 | * TransmitEnd function schedules the PropagationCompleteEvent which 155 | * will free the channel for further transmissions. Stores the 156 | * packet p as the m_currentPkt, the packet being currently 157 | * transmitting. 158 | * 159 | * \return Returns true unless the source was detached before it 160 | * completed its transmission. 161 | * bool TransmitEnd (Ptr src, Ptr packet, 162 | * double txPowerDb, LoraTxMode txMode); 163 | */ 164 | bool TransmitEnd (uint16_t protocolNumber); 165 | 166 | /** 167 | * \brief Indicates that the channel has finished propagating the 168 | * current packet. The channel is released and becomes free. 169 | * 170 | * Calls the receive function of every active net device that is 171 | * attached to the channel. 172 | */ 173 | 174 | /** 175 | * \return Returns the state of the channel (IDLE -- free, 176 | * TRANSMITTING -- busy, PROPAGATING - busy ) 177 | */ 178 | WireState GetState (uint16_t protocolNumber); 179 | 180 | /** 181 | * \brief Indicates if the channel is busy. The channel will only 182 | * accept new packets for transmission if it is not busy. 183 | * 184 | * \return Returns true if the channel is busy and false if it is 185 | * free. 186 | */ 187 | bool IsBusy (uint16_t protocolNumber); 188 | 189 | /** 190 | * \brief Indicates if a net device is currently attached or 191 | * detached from the channel. 192 | * 193 | * \param deviceId The ID that was assigned to the net device when 194 | * it was attached to the channel. 195 | * \return Returns true if the net device is attached to the 196 | * channel, false otherwise. 197 | */ 198 | 199 | /** 200 | * Get the assigned data rate of the channel 201 | * 202 | * \return Returns the DataRate to be used by device transmitters. 203 | * with deviceId i. 204 | */ 205 | DataRate GetDataRate (void); 206 | 207 | /** 208 | * Get the assigned speed-of-light delay of the channel 209 | * 210 | * \return Returns the delay used by the channel. 211 | */ 212 | Time GetDelay (void); 213 | 214 | 215 | private: 216 | LoraDeviceList m_devList; //!< The list of devices on this channel. 217 | Ptr m_prop; //!< The propagation model. 218 | Ptr m_noise; //!< The noise model. 219 | /** Has Clear ever been called on the channel. */ 220 | bool m_cleared; 221 | 222 | /** 223 | * Send a packet up to the receiving LoraTransducer. 224 | * 225 | * \param i Device number. 226 | * \param packet The received packet. 227 | * \param rxPowerDb Signal power in dB of arriving packet. 228 | * \param txMode Mode arriving packet is using. 229 | * \param pdp PDP of arriving signal. 230 | */ 231 | void SendUp (uint32_t i, Ptr packet, double rxPowerDb, LoraTxMode txMode, LoraPdp pdp); 232 | 233 | 234 | 235 | /** 236 | * The assigned data rate of the channel 237 | */ 238 | DataRate m_bps; 239 | 240 | /** 241 | * The assigned speed-of-light delay of the channel 242 | */ 243 | Time m_delay; 244 | 245 | /** 246 | * The Packet that is currently being transmitted on the channel (or last 247 | * packet to have been transmitted on the channel if the channel is 248 | * free.) 249 | */ 250 | Ptr m_currentPkt; 251 | 252 | /** 253 | * Device Id of the source that is currently transmitting on the 254 | * channel. Or last source to have transmitted a packet on the 255 | * channel, if the channel is currently not busy. 256 | */ 257 | uint32_t m_currentSrc; 258 | 259 | /** 260 | * Current state of the channel 261 | */ 262 | WireState m_state[3]; 263 | 264 | 265 | protected: 266 | virtual void DoDispose (void); 267 | 268 | }; // class LoraChannel 269 | 270 | } // namespace ns3 271 | 272 | #endif /* LORA_CHANNEL_H */ 273 | -------------------------------------------------------------------------------- /model/lora-tx-mode.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_TX_MODE_H 21 | #define LORA_TX_MODE_H 22 | 23 | #include "ns3/object.h" 24 | #include 25 | 26 | namespace ns3 { 27 | 28 | class LoraTxModeFactory; 29 | class LoraTxMode; 30 | 31 | /** 32 | * 33 | * Abstraction of packet modulation information. 34 | * 35 | */ 36 | class LoraTxMode 37 | { 38 | public: 39 | LoraTxMode (); //!< Constructor. 40 | ~LoraTxMode (); //!< Destructor. 41 | 42 | /** 43 | * Modulation type. 44 | */ 45 | typedef enum { 46 | PSK, //!< Phase shift keying. 47 | QAM, //!< Quadrature amplitude modulation. 48 | FSK, //!< Frequency shift keying. 49 | LORA, //!< LORA Modulation. 50 | OTHER //!< Unspecified/undefined. 51 | } ModulationType; 52 | /** 53 | * Get the modulation type of the mode. 54 | * 55 | * \return The modulation type. 56 | */ 57 | ModulationType GetModType (void) const; 58 | /** 59 | * Get the data rate of the transmit mode. 60 | * 61 | * \return Data rate of the TX mode, in bits per second. 62 | */ 63 | uint32_t GetDataRateBps (void) const; 64 | /** 65 | * Get the physical signaling rate. 66 | * 67 | * \return PHY rate in symbols per second. 68 | */ 69 | uint32_t GetPhyRateSps (void) const; 70 | /** 71 | * Get the transmission center frequency. 72 | * 73 | * \return Center frequency, in Hz. 74 | */ 75 | uint32_t GetCenterFreqHz (void) const; 76 | /** 77 | * Get the transmission signal bandwidth. 78 | * 79 | * \return Bandwidth in Hz. 80 | */ 81 | uint32_t GetBandwidthHz (void) const; 82 | /** 83 | * Get the number of constellation points in the modulation scheme. 84 | * 85 | * \return Number of constellation points. 86 | */ 87 | uint32_t GetConstellationSize (void) const; 88 | /** 89 | * Get the mode name. 90 | * 91 | * \return Name 92 | */ 93 | std::string GetName (void) const; 94 | /** 95 | * Get a unique id for the mode. 96 | * 97 | * \return Unique ID. 98 | */ 99 | uint32_t GetUid (void) const; 100 | 101 | private: 102 | friend class LoraTxModeFactory; 103 | friend std::ostream &operator<< (std::ostream & os, const LoraTxMode &mode); 104 | friend std::istream &operator>> (std::istream & is, LoraTxMode &mode); 105 | 106 | 107 | uint32_t m_uid; //!< Mode id 108 | 109 | }; // class LoraTxMode 110 | 111 | 112 | /** 113 | * Writes tx mode entry to stream os. 114 | * 115 | * \param os The output stream. 116 | * \param mode The mode. 117 | * \return The stream. 118 | */ 119 | std::ostream & operator << (std::ostream & os, const LoraTxMode &mode); 120 | /** 121 | * Reads tx mode entry from stream is 122 | * 123 | * \param is The input stream. 124 | * \param mode The mode. 125 | * \return The stream. 126 | */ 127 | std::istream & operator >> (std::istream & is, LoraTxMode &mode); 128 | 129 | /** 130 | * 131 | * Global database of LoraTxMode objects, retrievable by id or name. 132 | */ 133 | class LoraTxModeFactory 134 | { 135 | public: 136 | LoraTxModeFactory (); //!< Constructor. 137 | ~LoraTxModeFactory (); //!< Destructor. 138 | 139 | /** 140 | * 141 | * \param type Modulation type. 142 | * \param dataRateBps Data rate in BPS. 143 | * \param phyRateSps Symbol rate in symbols per second. 144 | * \param cfHz Center frequency in Hz. 145 | * \param bwHz Bandwidth in Hz. 146 | * \param constSize Modulation constellation size (2 for BPSK, 4 for QPSK). 147 | * \param name Unique string name for this transmission mode. 148 | * 149 | * \return the transmit mode object 150 | */ 151 | static LoraTxMode CreateMode (LoraTxMode::ModulationType type, 152 | uint32_t dataRateBps, 153 | uint32_t phyRateSps, 154 | uint32_t cfHz, 155 | uint32_t bwHz, 156 | uint32_t constSize, 157 | std::string name); 158 | 159 | /** 160 | * Get a mode by name. 161 | * 162 | * \param name String name of mode. 163 | * \return Mode with given name. 164 | */ 165 | static LoraTxMode GetMode (std::string name); 166 | /** 167 | * Get a mode by id. 168 | * 169 | * \param uid Unique ID of mode. 170 | * \return The mode with given uid. 171 | */ 172 | static LoraTxMode GetMode (uint32_t uid); 173 | 174 | private: 175 | friend class LoraTxMode; 176 | uint32_t m_nextUid; //!< next id number 177 | 178 | /** 179 | * 180 | * Container for the LoraTxMode properties. 181 | */ 182 | struct LoraTxModeItem 183 | { 184 | LoraTxMode::ModulationType m_type; //!< Modulation type. 185 | uint32_t m_cfHz; //!< Center frequency in Hz. 186 | uint32_t m_bwHz; //!< Bandwidth in Hz. 187 | uint32_t m_dataRateBps; //!< Data rate in BPS. 188 | uint32_t m_phyRateSps; //!< Symbol rate in symbols per second. 189 | uint32_t m_constSize; //!< Modulation constellation size (2 for BPSK, 4 for QPSK). 190 | uint32_t m_uid; //!< Unique id. 191 | std::string m_name; //!< Unique string name for this transmission mode. 192 | }; 193 | 194 | /** 195 | * Container for modes 196 | * 197 | */ 198 | std::map m_modes; 199 | 200 | /** 201 | * Check if the mode \pname{name} already exists. 202 | * 203 | * \param name The mode name to test. 204 | * \return True if \pname{name} exists. 205 | */ 206 | bool NameUsed (std::string name); 207 | 208 | /** 209 | * Construct and get the static global factory instance. 210 | * 211 | * \return The global instance. 212 | */ 213 | static LoraTxModeFactory &GetFactory (void); 214 | 215 | /** 216 | * Get a mode by id. 217 | * 218 | * \param uid The unique id to find. 219 | * \return The corresponding mode. 220 | */ 221 | LoraTxModeItem &GetModeItem (uint32_t uid); 222 | 223 | /** 224 | * Get a mode by name. 225 | * \param name The mode name to find. 226 | * \return The corresponding mode. 227 | */ 228 | LoraTxModeItem &GetModeItem (std::string name); 229 | 230 | /** 231 | * Create a public LoraTxMode from an internal LoraTxModeItem. 232 | * 233 | * \param item The LoraTxModeItem to reference. 234 | * \return A public LoraTxMode. 235 | */ 236 | LoraTxMode MakeModeFromItem (const LoraTxModeItem &item); 237 | 238 | }; // class LoraTxModeFactory 239 | 240 | /** 241 | * 242 | * Container for LoraTxModes. 243 | * 244 | * \see attribute_LoraModesList 245 | */ 246 | class LoraModesList 247 | { 248 | public: 249 | LoraModesList (); //!< Constructor 250 | virtual ~LoraModesList (); //!< Destructor 251 | 252 | /** 253 | * Add mode to this list. 254 | * \param mode The mode to add. 255 | */ 256 | void AppendMode (LoraTxMode mode); 257 | /** 258 | * Delete the mode at given index. 259 | * \param num Index of mode to delete. 260 | */ 261 | void DeleteMode (uint32_t num); 262 | /** 263 | * Retrieve a mode by index. 264 | * 265 | * \param index Mode index. 266 | * \return Mode at given index. 267 | */ 268 | LoraTxMode operator[] (uint32_t index) const; 269 | /** 270 | * Get the number of modes in this list. 271 | * 272 | * \return Number of modes. 273 | */ 274 | uint32_t GetNModes (void) const; 275 | 276 | 277 | private: 278 | /** The vector of modes in this list. */ 279 | std::vector m_modes; 280 | 281 | friend std::ostream &operator << (std::ostream &os, const LoraModesList &ml); 282 | friend std::istream &operator >> (std::istream &is, LoraModesList &ml); 283 | 284 | }; // class LoraModesList 285 | 286 | /** 287 | * Write LoraModesList to stream os 288 | * 289 | * \param os The output stream. 290 | * \param ml The mode list. 291 | * \return The stream. 292 | */ 293 | std::ostream &operator << (std::ostream &os, const LoraModesList &ml); 294 | /** 295 | * Read LoraModesList from stream is. 296 | * 297 | * \param is The input stream. 298 | * \param ml The mode list to fill. 299 | * \return The stream. 300 | */ 301 | std::istream &operator >> (std::istream &is, LoraModesList &ml); 302 | 303 | ATTRIBUTE_HELPER_HEADER (LoraModesList); 304 | 305 | } // namespace ns3 306 | 307 | #endif /* LORA_TX_MODE_H */ 308 | -------------------------------------------------------------------------------- /model/lora-prop-model.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "lora-prop-model.h" 21 | #include "ns3/nstime.h" 22 | #include 23 | #include 24 | 25 | 26 | namespace ns3 { 27 | 28 | std::ostream & 29 | operator<< (std::ostream &os, const LoraPdp &pdp) 30 | { 31 | os << pdp.GetNTaps () << '|'; 32 | os << pdp.GetResolution ().GetSeconds () << '|'; 33 | 34 | LoraPdp::Iterator it = pdp.m_taps.begin (); 35 | for (; it != pdp.m_taps.end (); it++) 36 | { 37 | os << (*it).GetAmp () << '|'; 38 | } 39 | return os; 40 | 41 | } 42 | std::istream & 43 | operator>> (std::istream &is, LoraPdp &pdp) 44 | { 45 | uint32_t ntaps; 46 | double resolution; 47 | char c1; 48 | 49 | is >> ntaps >> c1; 50 | if (c1 != '|') 51 | { 52 | NS_FATAL_ERROR ("LoraPdp data corrupted at # of taps"); 53 | return is; 54 | } 55 | is >> resolution >> c1; 56 | if (c1 != '|') 57 | { 58 | NS_FATAL_ERROR ("LoraPdp data corrupted at resolution"); 59 | return is; 60 | } 61 | pdp.m_resolution = Seconds (resolution); 62 | 63 | 64 | std::complex amp; 65 | pdp.m_taps = std::vector (ntaps); 66 | for (uint32_t i = 0; i < ntaps && !is.eof (); i++) 67 | { 68 | is >> amp >> c1; 69 | if (c1 != '|') 70 | { 71 | NS_FATAL_ERROR ("LoraPdp data corrupted at tap " << i); 72 | return is; 73 | } 74 | pdp.m_taps[i] = Tap (Seconds (resolution * i), amp); 75 | } 76 | return is; 77 | 78 | } 79 | 80 | Tap::Tap () 81 | : m_amplitude (0.0), 82 | m_delay (Seconds (0)) 83 | { 84 | 85 | } 86 | 87 | Tap::Tap (Time delay, std::complex amp) 88 | : m_amplitude (amp), 89 | m_delay (delay) 90 | { 91 | 92 | } 93 | 94 | std::complex 95 | Tap::GetAmp (void) const 96 | { 97 | return m_amplitude; 98 | } 99 | 100 | Time 101 | Tap::GetDelay (void) const 102 | { 103 | return m_delay; 104 | } 105 | 106 | 107 | LoraPdp::LoraPdp () 108 | { 109 | 110 | } 111 | 112 | LoraPdp::LoraPdp (std::vector taps, Time resolution) 113 | : m_taps (taps), 114 | m_resolution (resolution) 115 | { 116 | } 117 | 118 | LoraPdp::LoraPdp (std::vector > amps, Time resolution) 119 | : m_resolution (resolution) 120 | { 121 | m_taps.resize (amps.size ()); 122 | Time arrTime = Seconds (0); 123 | for (uint32_t index = 0; index < amps.size (); index++) 124 | { 125 | m_taps[index] = Tap (arrTime, amps[index]); 126 | arrTime = arrTime + m_resolution; 127 | } 128 | } 129 | 130 | LoraPdp::LoraPdp (std::vector amps, Time resolution) 131 | : m_resolution (resolution) 132 | { 133 | m_taps.resize (amps.size ()); 134 | Time arrTime = Seconds (0); 135 | for (uint32_t index = 0; index < amps.size (); index++) 136 | { 137 | m_taps[index] = Tap (arrTime, amps[index]); 138 | arrTime = arrTime + m_resolution; 139 | } 140 | } 141 | 142 | LoraPdp::~LoraPdp () 143 | { 144 | m_taps.clear (); 145 | } 146 | 147 | void 148 | LoraPdp::SetTap (std::complex amp, uint32_t index) 149 | { 150 | if (m_taps.size () <= index) 151 | { 152 | m_taps.resize (index + 1); 153 | } 154 | 155 | Time delay = Seconds (index * m_resolution.GetSeconds ()); 156 | m_taps[index] = Tap (delay, amp); 157 | } 158 | const Tap & 159 | LoraPdp::GetTap (uint32_t i) const 160 | { 161 | NS_ASSERT_MSG (i < GetNTaps (), "Call to LoraPdp::GetTap with requested tap out of range"); 162 | return m_taps[i]; 163 | } 164 | void 165 | LoraPdp::SetNTaps (uint32_t nTaps) 166 | { 167 | m_taps.resize (nTaps); 168 | } 169 | void 170 | LoraPdp::SetResolution (Time resolution) 171 | { 172 | m_resolution = resolution; 173 | } 174 | LoraPdp::Iterator 175 | LoraPdp::GetBegin (void) const 176 | { 177 | return m_taps.begin (); 178 | } 179 | 180 | LoraPdp::Iterator 181 | LoraPdp::GetEnd (void) const 182 | { 183 | return m_taps.end (); 184 | } 185 | 186 | uint32_t 187 | LoraPdp::GetNTaps (void) const 188 | { 189 | return m_taps.size (); 190 | } 191 | 192 | Time 193 | LoraPdp::GetResolution (void) const 194 | { 195 | return m_resolution; 196 | } 197 | 198 | std::complex 199 | LoraPdp::SumTapsFromMaxC (Time delay, Time duration) const 200 | { 201 | if (m_resolution <= Seconds (0)) 202 | { 203 | NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in " 204 | "LoraPdp with resolution 0 and multiple taps"); 205 | 206 | return m_taps[0].GetAmp (); 207 | } 208 | 209 | uint32_t numTaps = static_cast (duration.GetSeconds () / m_resolution.GetSeconds () + 0.5); 210 | double maxAmp = -1; 211 | uint32_t maxTapIndex = 0; 212 | 213 | for (uint32_t i = 0; i < GetNTaps (); i++) 214 | { 215 | if (std::abs (m_taps[i].GetAmp ()) > maxAmp) 216 | { 217 | maxAmp = std::abs (m_taps[i].GetAmp ()); 218 | maxTapIndex = i; 219 | } 220 | } 221 | uint32_t start = maxTapIndex + static_cast (delay.GetSeconds () / m_resolution.GetSeconds ()); 222 | uint32_t end = std::min (start + numTaps, GetNTaps ()); 223 | std::complex sum = 0; 224 | for (uint32_t i = start; i < end; i++) 225 | { 226 | sum += m_taps[i].GetAmp (); 227 | } 228 | return sum; 229 | } 230 | double 231 | LoraPdp::SumTapsFromMaxNc (Time delay, Time duration) const 232 | { 233 | if (m_resolution <= Seconds (0)) 234 | { 235 | NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in " 236 | "LoraPdp with resolution 0 and multiple taps"); 237 | 238 | return std::abs (m_taps[0].GetAmp ()); 239 | } 240 | 241 | uint32_t numTaps = static_cast (duration.GetSeconds () / m_resolution.GetSeconds () + 0.5); 242 | double maxAmp = -1; 243 | uint32_t maxTapIndex = 0; 244 | 245 | for (uint32_t i = 0; i < GetNTaps (); i++) 246 | { 247 | if (std::abs (m_taps[i].GetAmp ()) > maxAmp) 248 | { 249 | maxAmp = std::abs (m_taps[i].GetAmp ()); 250 | maxTapIndex = i; 251 | } 252 | } 253 | 254 | 255 | uint32_t start = maxTapIndex + static_cast (delay.GetSeconds () / m_resolution.GetSeconds ()); 256 | uint32_t end = std::min (start + numTaps, GetNTaps ()); 257 | double sum = 0; 258 | for (uint32_t i = start; i < end; i++) 259 | 260 | { 261 | sum += std::abs (m_taps[i].GetAmp ()); 262 | } 263 | return sum; 264 | } 265 | double 266 | LoraPdp::SumTapsNc (Time begin, Time end) const 267 | { 268 | if (m_resolution <= Seconds (0)) 269 | { 270 | NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in " 271 | "LoraPdp with resolution 0 and multiple taps"); 272 | 273 | if (begin <= Seconds (0.0) && end >= Seconds (0.0)) 274 | { 275 | return std::abs (m_taps[0].GetAmp ()); 276 | } 277 | else 278 | { 279 | return 0.0; 280 | } 281 | } 282 | 283 | uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5); 284 | uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5); 285 | 286 | endIndex = std::min (endIndex, GetNTaps ()); 287 | double sum = 0; 288 | for (uint32_t i = stIndex; i < endIndex; i++) 289 | { 290 | sum += std::abs (m_taps[i].GetAmp ()); 291 | } 292 | return sum; 293 | 294 | } 295 | 296 | 297 | 298 | std::complex 299 | LoraPdp::SumTapsC (Time begin, Time end) const 300 | { 301 | if (m_resolution <= Seconds (0)) 302 | { 303 | NS_ASSERT_MSG (GetNTaps () == 1, "Attempted to sum taps over time interval in " 304 | "LoraPdp with resolution 0 and multiple taps"); 305 | 306 | if (begin <= Seconds (0.0) && end >= Seconds (0.0)) 307 | { 308 | return m_taps[0].GetAmp (); 309 | } 310 | else 311 | { 312 | return std::complex (0.0); 313 | } 314 | } 315 | 316 | uint32_t stIndex = (uint32_t)(begin.GetSeconds () / m_resolution.GetSeconds () + 0.5); 317 | uint32_t endIndex = (uint32_t)(end.GetSeconds () / m_resolution.GetSeconds () + 0.5); 318 | 319 | endIndex = std::min (endIndex, GetNTaps ()); 320 | 321 | std::complex sum = 0; 322 | for (uint32_t i = stIndex; i < endIndex; i++) 323 | { 324 | sum += m_taps[i].GetAmp (); 325 | } 326 | return sum; 327 | } 328 | 329 | LoraPdp 330 | LoraPdp::CreateImpulsePdp (void) 331 | { 332 | LoraPdp pdp; 333 | pdp.SetResolution (Seconds (0)); 334 | pdp.SetTap (1.0,0); 335 | return pdp; 336 | } 337 | 338 | NS_OBJECT_ENSURE_REGISTERED (LoraPropModel); 339 | 340 | TypeId LoraPropModel::GetTypeId (void) 341 | { 342 | static TypeId tid = TypeId ("ns3::LoraPropModel") 343 | .SetParent () 344 | .SetGroupName ("Lora") 345 | ; 346 | return tid; 347 | } 348 | 349 | void 350 | LoraPropModel::Clear (void) 351 | { 352 | } 353 | 354 | void 355 | LoraPropModel::DoDispose (void) 356 | { 357 | Clear (); 358 | Object::DoDispose (); 359 | } 360 | 361 | } 362 | -------------------------------------------------------------------------------- /model/lora-prop-model.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_PROP_MODEL_H 21 | #define LORA_PROP_MODEL_H 22 | 23 | #include "ns3/object.h" 24 | #include "ns3/mobility-model.h" 25 | #include "ns3/nstime.h" 26 | 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace ns3 { 33 | 34 | class LoraTxMode; 35 | 36 | /** 37 | * 38 | * Holds PDP Tap information (amplitude and delay) 39 | */ 40 | class Tap 41 | { 42 | public: 43 | /** 44 | * Default constructor. Creates Tap with delay=0, amp=0 45 | */ 46 | Tap (); 47 | /** 48 | * Constructor 49 | * 50 | * \param delay Time delay (usually from first arrival) of signal 51 | * \param amp Complex amplitude of arrival 52 | */ 53 | Tap (Time delay, std::complex amp); 54 | /** 55 | * Get the complex amplitude of arrival. 56 | * 57 | * \return The amplitude. 58 | */ 59 | std::complex GetAmp (void) const; 60 | /** 61 | * Get the delay time, usually from first arrival of signal. 62 | * \return The time delay. 63 | */ 64 | Time GetDelay (void) const; 65 | 66 | private: 67 | std::complex m_amplitude; //!< The amplitude. 68 | Time m_delay; //!< The time delay. 69 | 70 | }; // class Tap 71 | 72 | 73 | /** 74 | * 75 | * The power delay profile returned by propagation models. 76 | * 77 | * Generally, the profile should be normalized, such that 78 | * the sum of all taps should equal 1. The received signal 79 | * power on any interval (t1, t2) can then be found from 80 | * summing the taps on the interval and multiplying by 81 | * the total received power at the receiver. 82 | */ 83 | class LoraPdp 84 | { 85 | public: 86 | /** 87 | * Convenience iterator typedef. 88 | */ 89 | typedef std::vector::const_iterator Iterator; 90 | /** 91 | * Create empty PDP object. 92 | */ 93 | LoraPdp (); 94 | /** 95 | * Create PDP object from a vector of Tap objects. 96 | * 97 | * \param taps Taps to include in this PDP. 98 | * \param resolution Resolution of PDP object. 99 | */ 100 | LoraPdp (std::vector taps, Time resolution); 101 | /** 102 | * Create PDP object from vector of arrival amplitudes. 103 | * 104 | * \param arrivals Vector of complex amplitude arrivals. 105 | * \param resolution Time duration between arrivals in vector. 106 | */ 107 | LoraPdp (std::vector > arrivals, Time resolution); 108 | /** 109 | * Create PDP object from real valued arrival amplitudes. 110 | * 111 | * \param arrivals Vector of real valued arrivals. 112 | * \param resolution Time duration between arrivals in vector. 113 | */ 114 | LoraPdp (std::vector arrivals, Time resolution); 115 | /** Dummy destructor, see DoDispose. */ 116 | ~LoraPdp (); 117 | 118 | /** 119 | * Set the arrival value for a tap. 120 | * 121 | * The delay time is the index multiplied by the resolution. 122 | * The tap vector will be expanded to accomadate the requested 123 | * index. 124 | * 125 | * \param arrival Complex arrival value. 126 | * \param index Index of arrival. 127 | */ 128 | void SetTap (std::complex arrival, uint32_t index); 129 | /** 130 | * Resize the tap vector. 131 | * 132 | * \param nTaps Number of taps in this PDP 133 | */ 134 | void SetNTaps (uint32_t nTaps); 135 | /** 136 | * Set the time duration (resolution) between arrivals. 137 | * 138 | * \param resolution The resolution. 139 | */ 140 | void SetResolution (Time resolution); 141 | /** 142 | * Get the beginning of the tap vector. 143 | * 144 | * \return Iterator positioned at first arrival. 145 | */ 146 | Iterator GetBegin (void) const; 147 | /** 148 | * Get the end of the tap list (one beyond the last entry). 149 | * 150 | * \return Iterator positioned after last arrival 151 | */ 152 | Iterator GetEnd (void) const; 153 | /** 154 | * Get the number of taps. 155 | * 156 | * \return Number of taps in PDP. 157 | */ 158 | uint32_t GetNTaps (void) const; 159 | /** 160 | * Get the Tap at the specified delay index. 161 | * 162 | * \param i Index number of tap to return (0 based). 163 | * \return Tap object at index i. 164 | */ 165 | const Tap &GetTap (uint32_t i) const; 166 | /** 167 | * Get the delay time resolution (time duration between arrivals). 168 | * 169 | * \return Resolution of PDP. 170 | */ 171 | Time GetResolution (void) const; 172 | /** 173 | * Compute the non-coherent sum of tap amplitudes 174 | * between a start and end time. 175 | * 176 | * Assuming that Tap at index 0 arrives at time 0, 177 | * this function sums non-coherently (sums amplitude of arrivals 178 | * ignoring phase difference) all arrivals between a start 179 | * and end time. 180 | * 181 | * \param begin Time value to begin summing arrivals. 182 | * \param end Time value to end summing arrivals. 183 | * \return Non-coherent sum of arrivals between two time values. 184 | */ 185 | double SumTapsNc (Time begin, Time end) const; 186 | /** 187 | * Compute the coherent sum of tap amplitudes 188 | * between a start and end time. 189 | * 190 | * Assuming that Tap at index 0 arrives at time 0, 191 | * this function sums coherently (sums amplitude of arrivals 192 | * considering phase difference) all arrivals between a start 193 | * and end time. 194 | * 195 | * \param begin Time value to begin summing arrivals. 196 | * \param end Time value to end summing arrivals. 197 | * \return Coherent sum of arrivals between two time values. 198 | */ 199 | std::complex SumTapsC (Time begin, Time end) const; 200 | /** 201 | * Compute the non-coherent sum of tap amplitudes 202 | * starting after a delay from the maximum amplitude 203 | * for a total time duration. 204 | * 205 | * This function sums non-coherently (sums amplitude of arrivals 206 | * ignoring phase difference) all arrivals in a given duration 207 | * starting the given time after the maximum amplitude arrival received. 208 | * 209 | * \param delay Time duratation after max to begin summing arrivals. 210 | * \param duration Time duration to sum arrivals for. 211 | * \return Non-coherent sum of arrivals after max in given window. 212 | */ 213 | double SumTapsFromMaxNc (Time delay, Time duration) const; 214 | /** 215 | * Compute the coherent sum of tap amplitudes 216 | * starting after a delay from the maximum amplitude 217 | * for a total duration. 218 | * 219 | * this function sums coherently (sums amplitude of arrivals 220 | * considering phase difference) all arrivals in a given duration 221 | * starting the given time after the maximum amplitude arrival received 222 | * 223 | * \param delay Time duratation after max to begin summing arrivals. 224 | * \param duration Time duration to sum arrivals for. 225 | * \return Coherent sum of arrivals after max in given window. 226 | */ 227 | std::complex SumTapsFromMaxC (Time delay, Time duration) const; 228 | 229 | /** 230 | * Get a unit impulse PDP at time 0. 231 | * 232 | * \return The unit impulse. 233 | */ 234 | static LoraPdp CreateImpulsePdp (void); 235 | 236 | private: 237 | friend std::ostream &operator<< (std::ostream &os, const LoraPdp &pdp); 238 | friend std::istream &operator>> (std::istream &is, LoraPdp &pdp); 239 | 240 | std::vector m_taps; //!< The vector of Taps. 241 | Time m_resolution; //!< The time resolution. 242 | 243 | }; // class LoraPdp 244 | 245 | 246 | /** 247 | * Writes PDP to stream as list of arrivals 248 | * 249 | * \param os The output stream. 250 | * \param pdp The PDP. 251 | * \return The output stream. 252 | */ 253 | std::ostream &operator<< (std::ostream &os, const LoraPdp &pdp); 254 | /** 255 | * 256 | * Reads in list of arrivals from stream is 257 | * 258 | * \param is The input stream. 259 | * \param pdp The PDP variable to set. 260 | * \return The input stream. 261 | */ 262 | std::istream &operator>> (std::istream &is, LoraPdp &pdp); 263 | 264 | 265 | /** 266 | * 267 | * Base class for implemented underwater propagation models 268 | */ 269 | class LoraPropModel : public Object 270 | { 271 | public: 272 | /** 273 | * Register this type. 274 | * \return The object TypeId. 275 | */ 276 | static TypeId GetTypeId (void); 277 | 278 | /** 279 | * Computes pathloss between nodes a and b. 280 | * 281 | * \param a Ptr to mobility model of node a 282 | * \param b Ptr to mobility model of node b 283 | * \param txMode TX mode of transmission between a and b 284 | * \return Pathloss in dB re 1 uPa 285 | */ 286 | virtual double GetPathLossDb (Ptr a, Ptr b, LoraTxMode txMode) = 0; 287 | 288 | /** 289 | * Get the PDP for the path between two nodes. 290 | * 291 | * \param a Ptr to mobility model of node a. 292 | * \param b Ptr to mobility model of node b. 293 | * \param mode TX mode of transmission from a to b. 294 | * \return PDP for link between nodes a and b. 295 | */ 296 | virtual LoraPdp GetPdp (Ptr a, Ptr b, LoraTxMode mode) = 0; 297 | /** 298 | * Finds propagation delay between nodes a and b. 299 | * 300 | * \param a Ptr to mobility model of node a. 301 | * \param b Ptr to mobility model of node b. 302 | * \param mode TX mode of transmission. 303 | * \return Propagation delay. 304 | */ 305 | virtual Time GetDelay (Ptr a, Ptr b, LoraTxMode mode) = 0; 306 | 307 | /** Clear all pointer references. */ 308 | virtual void Clear (void); 309 | 310 | virtual void DoDispose (void); 311 | 312 | }; // class LoraPropModel 313 | 314 | } // namespace ns3 315 | 316 | #endif /* LORA_PROP_MODEL_H */ 317 | -------------------------------------------------------------------------------- /test/lora-test.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "ns3/lora-net-device.h" 21 | #include "ns3/lora-channel.h" 22 | #include "ns3/lora-phy-gen.h" 23 | #include "ns3/lora-transducer-hd.h" 24 | #include "ns3/lora-prop-model-ideal.h" 25 | #include "ns3/constant-position-mobility-model.h" 26 | #include "ns3/simulator.h" 27 | #include "ns3/test.h" 28 | #include "ns3/node.h" 29 | #include "ns3/object-factory.h" 30 | #include "ns3/pointer.h" 31 | #include "ns3/callback.h" 32 | #include "ns3/nstime.h" 33 | #include "ns3/log.h" 34 | #include "ns3/mac-lora-gw.h" 35 | 36 | using namespace ns3; 37 | 38 | class LoraTestAca : public TestCase 39 | { 40 | public: 41 | LoraTestAca (); 42 | 43 | virtual void DoRun (void); 44 | private: 45 | Ptr CreateNode (Vector pos, Ptr chan); 46 | 47 | Ptr CreateGateway (Vector pos, Ptr chan); 48 | 49 | bool DoPhyTests (); 50 | uint32_t DoOnePhyTest (Time t1, Time t2, uint32_t r1, uint32_t r2, Ptr prop, uint32_t mode1 = 0, uint32_t mode2 = 0); 51 | 52 | uint32_t DoOnePhyTest3_nNodes (Ptr prop); 53 | 54 | bool RxPacket (Ptr dev, Ptr pkt, uint16_t mode, const Address &sender); 55 | void SendOnePacket (Ptr dev, uint32_t mode); 56 | void SendOnePacket2GW (Ptr dev, uint32_t mode, Address &sender); 57 | 58 | uint32_t RanTxTime(uint32_t fMin, uint32_t fMax); 59 | 60 | uint32_t random_number(uint32_t min_num, uint32_t max_num); 61 | 62 | ObjectFactory m_phyFac; 63 | uint32_t m_bytesRx; 64 | }; 65 | 66 | 67 | LoraTestAca::LoraTestAca () : TestCase ("LORA") 68 | { 69 | 70 | } 71 | 72 | bool 73 | LoraTestAca::RxPacket (Ptr dev, Ptr pkt, uint16_t mode, const Address &sender) 74 | { 75 | m_bytesRx += pkt->GetSize (); 76 | return true; 77 | } 78 | void 79 | LoraTestAca::SendOnePacket (Ptr dev, uint32_t mode) 80 | { 81 | Ptr pkt = Create (13); 82 | dev->Send (pkt, dev->GetBroadcast (), mode); 83 | } 84 | 85 | void 86 | LoraTestAca::SendOnePacket2GW (Ptr dev, uint32_t mode, Address &sender) 87 | { 88 | Ptr pkt = Create (13); 89 | dev->Send (pkt, sender, mode); 90 | 91 | } 92 | 93 | Ptr 94 | LoraTestAca::CreateNode (Vector pos, Ptr chan) 95 | { 96 | 97 | Ptr phy = m_phyFac.Create (); 98 | Ptr node = CreateObject (); 99 | Ptr dev = CreateObject (); 100 | Ptr mac = CreateObject (); 101 | Ptr mobility = CreateObject (); 102 | 103 | Ptr trans = CreateObject (); 104 | 105 | mobility->SetPosition (pos); 106 | node->AggregateObject (mobility); 107 | mac->SetAddress (LoraAddress::Allocate ()); 108 | 109 | dev->SetPhy (phy); 110 | dev->SetMac (mac); 111 | dev->SetChannel (chan); 112 | dev->SetTransducer (trans); 113 | node->AddDevice (dev); 114 | 115 | return dev; 116 | } 117 | 118 | Ptr 119 | LoraTestAca::CreateGateway (Vector pos, Ptr chan) 120 | { 121 | 122 | Ptr phy = m_phyFac.Create (); 123 | Ptr node = CreateObject (); 124 | Ptr dev = CreateObject (); 125 | 126 | Ptr mac = CreateObject (); 127 | 128 | Ptr mobility = CreateObject (); 129 | 130 | Ptr trans = CreateObject (); 131 | 132 | mobility->SetPosition (pos); 133 | node->AggregateObject (mobility); 134 | mac->SetAddress (LoraAddress::Allocate ()); 135 | 136 | dev->SetPhy (phy); 137 | dev->SetMac (mac); 138 | dev->SetChannel (chan); 139 | dev->SetTransducer (trans); 140 | node->AddDevice (dev); 141 | 142 | return dev; 143 | } 144 | 145 | uint32_t 146 | LoraTestAca::RanTxTime(uint32_t fMin, uint32_t fMax) 147 | { 148 | 149 | return random_number(fMin, fMax); 150 | } 151 | 152 | 153 | uint32_t 154 | LoraTestAca::random_number(uint32_t min_num, uint32_t max_num) 155 | { 156 | uint32_t result = 0, low_num = 0, hi_num = 0; 157 | 158 | if (min_num < max_num) 159 | { 160 | low_num = min_num; 161 | hi_num = max_num + 1; 162 | } else { 163 | low_num = max_num + 1; 164 | hi_num = min_num; 165 | } 166 | 167 | result = (rand() % (hi_num - low_num)) + low_num; 168 | return result; 169 | } 170 | 171 | 172 | uint32_t 173 | LoraTestAca::DoOnePhyTest (Time txTime1, 174 | Time txTime2, 175 | uint32_t r1, 176 | uint32_t r2, 177 | Ptr prop, 178 | uint32_t mode1, 179 | uint32_t mode2) 180 | { 181 | 182 | Ptr channel = CreateObject (); 183 | channel->SetAttribute ("PropagationModel", PointerValue (prop)); 184 | 185 | 186 | Ptr gw0 = CreateGateway (Vector (r1,50,50), channel); 187 | 188 | 189 | Ptr dev1 = CreateNode (Vector (0,50,50), channel); 190 | Ptr dev2 = CreateNode (Vector (r1 + r2, 50, 50), channel); 191 | 192 | 193 | gw0->SetReceiveCallback (MakeCallback (&LoraTestAca::RxPacket, this)); 194 | 195 | Simulator::Schedule (txTime1, &LoraTestAca::SendOnePacket, this, dev1, mode1); 196 | Simulator::Schedule (txTime2, &LoraTestAca::SendOnePacket, this, dev2, mode2); 197 | 198 | m_bytesRx = 0; 199 | Simulator::Stop (Seconds (20.0)); 200 | Simulator::Run (); 201 | Simulator::Destroy (); 202 | 203 | return m_bytesRx; 204 | } 205 | 206 | 207 | uint32_t 208 | LoraTestAca::DoOnePhyTest3_nNodes (Ptr prop) 209 | { 210 | Ptr channel = CreateObject (); 211 | channel->SetAttribute ("PropagationModel", PointerValue (prop)); 212 | 213 | Ptr gw0 = CreateGateway (Vector (50,50,50), channel); 214 | 215 | //Set positions to nodes 216 | uint32_t x = 50; uint32_t y = 50; uint32_t z = 50; 217 | uint32_t n = 10; 218 | 219 | Ptr PtrDevice[n]; 220 | for (uint32_t i = 0; i < n; i++) 221 | { 222 | PtrDevice[i] = CreateNode (Vector (x,y,z), channel); 223 | x += 50; y += 50; z += 50; 224 | 225 | if ((x == 10000) || (y == 10000) || (z == 10000)) 226 | { 227 | x = 50; y = 50; z = 50; 228 | } 229 | 230 | } 231 | 232 | //Set gateway to receive packets from end devices node. 233 | gw0->SetReceiveCallback (MakeCallback (&LoraTestAca::RxPacket, this)); 234 | 235 | //Looping in Simulation Type: 236 | double simTime = 100.0; 237 | uint32_t mode [3] = {0, 1, 2}; 238 | uint32_t m = 0; 239 | double s_transmitStartTime; 240 | 241 | uint32_t nTempStart = 0; 242 | uint32_t nTempEnd = 100; 243 | 244 | uint32_t numNodesStart = 0; 245 | uint32_t numNodesEnd = 10; 246 | 247 | do { 248 | for (uint32_t j = numNodesStart; j < numNodesEnd; j++) 249 | { 250 | s_transmitStartTime = RanTxTime(nTempStart,nTempEnd); 251 | PtrDevice[j]->SetChannelMode(mode[m]); 252 | PtrDevice[j]->SetTransmitStartTime(s_transmitStartTime); 253 | 254 | Simulator::Schedule (Seconds(s_transmitStartTime), &LoraTestAca::SendOnePacket, this, PtrDevice[j], mode[m]); 255 | 256 | m += 1; 257 | if (m > 2) { m = 0; } 258 | } 259 | nTempStart = nTempEnd; 260 | nTempEnd = nTempEnd + 100; 261 | 262 | } while (nTempEnd <= simTime); 263 | 264 | 265 | m_bytesRx = 0; 266 | Simulator::Stop (Seconds (120.0)); 267 | Simulator::Run (); 268 | Simulator::Destroy (); 269 | 270 | return m_bytesRx; 271 | } 272 | 273 | 274 | bool 275 | LoraTestAca::DoPhyTests () 276 | { 277 | 278 | LoraModesList mList; 279 | 280 | LoraTxMode mode = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 80, 80, 10000, 4000, 2, "TestMode"); 281 | 282 | mList.AppendMode (LoraTxMode (mode)); 283 | 284 | Ptr perDef = CreateObject (); 285 | Ptr sinrDef = CreateObject (); 286 | m_phyFac.SetTypeId ("ns3::LoraPhyGen"); 287 | m_phyFac.Set ("PerModel", PointerValue (perDef)); 288 | m_phyFac.Set ("SinrModel", PointerValue (sinrDef)); 289 | m_phyFac.Set ("SupportedModes", LoraModesListValue (mList)); 290 | 291 | Ptr prop = CreateObject (); 292 | 293 | LoraTxMode mode00 = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 300, 120, 10000, 125, 2, "TestMode00"); 294 | LoraTxMode mode01 = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 300, 120, 11000, 125, 2, "TestMode01"); 295 | LoraTxMode mode02 = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 300, 120, 12000, 125, 2, "TestMode02"); 296 | 297 | LoraModesList m0; // Mode 0 298 | m0.AppendMode (mode00); 299 | 300 | LoraModesList m1; // Mode 1 301 | m1.AppendMode (mode01); 302 | 303 | LoraModesList m2; // Mode 2 304 | m2.AppendMode (mode02); 305 | 306 | m_phyFac = ObjectFactory (); 307 | m_phyFac.SetTypeId ("ns3::LoraPhyDual"); 308 | 309 | m_phyFac.Set ("SupportedModesPhy1", LoraModesListValue (m0)); 310 | m_phyFac.Set ("SupportedModesPhy2", LoraModesListValue (m1)); 311 | m_phyFac.Set ("SupportedModesPhy3", LoraModesListValue (m2)); 312 | 313 | //Test n nodes 314 | NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (DoOnePhyTest3_nNodes(prop), 130, "Test for n nodes"); 315 | 316 | return false; 317 | } 318 | 319 | void 320 | LoraTestAca::DoRun (void) 321 | { 322 | DoPhyTests (); 323 | } 324 | 325 | 326 | class LoraTestAcaSuite : public TestSuite 327 | { 328 | public: 329 | LoraTestAcaSuite (); 330 | }; 331 | 332 | LoraTestAcaSuite::LoraTestAcaSuite () 333 | : TestSuite ("lora-node", UNIT) 334 | { 335 | AddTestCase (new LoraTestAca, TestCase::QUICK); 336 | } 337 | 338 | static LoraTestAcaSuite g_LoraTestAcaSuite; 339 | -------------------------------------------------------------------------------- /examples/lora-example.cc: -------------------------------------------------------------------------------- 1 | /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 | /* 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation; 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | * GNU General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 16 | * 17 | * This is an example script for lora protocol. 18 | * 19 | * Authors: Pavel Boyko 20 | * To Thanh Hai 21 | * 22 | */ 23 | 24 | #include "ns3/lora-module.h" 25 | #include "ns3/core-module.h" 26 | #include "ns3/network-module.h" 27 | #include "ns3/internet-module.h" 28 | #include "ns3/mobility-module.h" 29 | 30 | #include "ns3/lora-net-device.h" 31 | #include "ns3/lora-channel.h" 32 | #include "ns3/lora-phy-gen.h" 33 | #include "ns3/lora-transducer-hd.h" 34 | #include "ns3/lora-prop-model-ideal.h" 35 | #include "ns3/constant-position-mobility-model.h" 36 | #include "ns3/simulator.h" 37 | #include "ns3/test.h" 38 | #include "ns3/node.h" 39 | #include "ns3/object-factory.h" 40 | #include "ns3/pointer.h" 41 | #include "ns3/callback.h" 42 | #include "ns3/nstime.h" 43 | #include "ns3/log.h" 44 | #include "ns3/mac-lora-gw.h" 45 | 46 | #include 47 | #include 48 | 49 | using namespace ns3; 50 | 51 | /** 52 | * \brief Test script. 53 | * 54 | * This script 10 lora end-devices, one gateway. Lora end-devices send packets on three channels. 55 | * 56 | */ 57 | class LoraExample 58 | { 59 | public: 60 | LoraExample (); 61 | /** 62 | * \brief Configure script parameters 63 | * \param argc is the command line argument count 64 | * \param argv is the command line arguments 65 | * \return true on successful configuration 66 | */ 67 | bool Configure (int argc, char **argv); 68 | /// Run simulation 69 | void Run (); 70 | /** 71 | * Report results 72 | * \param os the output stream 73 | */ 74 | void Report (std::ostream & os); 75 | 76 | private: 77 | 78 | // parameters 79 | /// Number of nodes 80 | uint32_t size; 81 | /// Number of channels 82 | double totalChannel; 83 | /// Simulation time, seconds 84 | double totalTime; 85 | 86 | ObjectFactory m_phyFac; 87 | uint32_t m_bytesRx; 88 | 89 | uint32_t packetPerNode; 90 | 91 | private: 92 | /// Create the nodes 93 | Ptr CreateNode (Vector pos, Ptr chan); 94 | Ptr CreateGateway (Vector pos, Ptr chan); 95 | 96 | bool DoExamples (); 97 | 98 | uint32_t DoOneExample (Ptr prop); 99 | 100 | bool RxPacket (Ptr dev, Ptr pkt, uint16_t mode, const Address &sender); 101 | void SendOnePacket (Ptr dev, uint32_t mode); 102 | 103 | void SendOnePacket2GW (Ptr dev, uint32_t mode, Address &sender); 104 | 105 | uint32_t RanTxTime(uint32_t fMin, uint32_t fMax); 106 | uint32_t random_number(uint32_t min_num, uint32_t max_num); 107 | }; 108 | 109 | int main (int argc, char **argv) 110 | { 111 | LoraExample test; 112 | if (!test.Configure (argc, argv)) 113 | NS_FATAL_ERROR ("Configuration failed. Aborted."); 114 | 115 | test.Run (); 116 | test.Report (std::cout); 117 | return 0; 118 | } 119 | 120 | //----------------------------------------------------------------------------- 121 | LoraExample::LoraExample () : 122 | size (10), 123 | totalChannel(3), 124 | totalTime (100) 125 | { 126 | } 127 | 128 | bool 129 | LoraExample::Configure (int argc, char **argv) 130 | { 131 | CommandLine cmd; 132 | 133 | cmd.AddValue ("size", "Number of nodes.", size); 134 | cmd.AddValue ("size", "Number of nodes.", totalChannel); 135 | cmd.AddValue ("time", "Simulation time, s.", totalTime); 136 | 137 | cmd.Parse (argc, argv); 138 | return true; 139 | } 140 | 141 | void 142 | LoraExample::Run () 143 | { 144 | std::cout << "Starting simulation for " << totalTime << " s ...\n"; 145 | std::cout << "Creating " << size << " nodes ...\n"; 146 | std::cout << "Transmission on " << totalChannel << " channels ...\n"; 147 | 148 | DoExamples (); 149 | } 150 | 151 | void 152 | LoraExample::Report (std::ostream &) 153 | { 154 | } 155 | 156 | 157 | bool 158 | LoraExample::RxPacket (Ptr dev, Ptr pkt, uint16_t mode, const Address &sender) 159 | { 160 | m_bytesRx += pkt->GetSize (); 161 | return true; 162 | } 163 | void 164 | LoraExample::SendOnePacket (Ptr dev, uint32_t mode) 165 | { 166 | Ptr pkt = Create (13); 167 | dev->Send (pkt, dev->GetBroadcast (), mode); 168 | } 169 | 170 | 171 | void 172 | LoraExample::SendOnePacket2GW (Ptr dev, uint32_t mode, Address &sender) 173 | { 174 | Ptr pkt = Create (13); 175 | dev->Send (pkt, sender, mode); 176 | 177 | } 178 | 179 | 180 | Ptr 181 | LoraExample::CreateNode (Vector pos, Ptr chan) 182 | { 183 | 184 | Ptr phy = m_phyFac.Create (); 185 | Ptr node = CreateObject (); 186 | Ptr dev = CreateObject (); 187 | Ptr mac = CreateObject (); 188 | Ptr mobility = CreateObject (); 189 | 190 | Ptr trans = CreateObject (); 191 | 192 | mobility->SetPosition (pos); 193 | node->AggregateObject (mobility); 194 | mac->SetAddress (LoraAddress::Allocate ()); 195 | 196 | dev->SetPhy (phy); 197 | dev->SetMac (mac); 198 | dev->SetChannel (chan); 199 | dev->SetTransducer (trans); 200 | node->AddDevice (dev); 201 | 202 | return dev; 203 | } 204 | 205 | Ptr 206 | LoraExample::CreateGateway (Vector pos, Ptr chan) 207 | { 208 | 209 | Ptr phy = m_phyFac.Create (); 210 | Ptr node = CreateObject (); 211 | Ptr dev = CreateObject (); 212 | 213 | Ptr mac = CreateObject (); 214 | 215 | Ptr mobility = CreateObject (); 216 | 217 | Ptr trans = CreateObject (); 218 | 219 | mobility->SetPosition (pos); 220 | node->AggregateObject (mobility); 221 | mac->SetAddress (LoraAddress::Allocate ()); 222 | 223 | dev->SetPhy (phy); 224 | dev->SetMac (mac); 225 | dev->SetChannel (chan); 226 | dev->SetTransducer (trans); 227 | node->AddDevice (dev); 228 | 229 | return dev; 230 | } 231 | 232 | uint32_t 233 | LoraExample::RanTxTime(uint32_t fMin, uint32_t fMax) 234 | { 235 | return random_number(fMin, fMax); 236 | } 237 | 238 | 239 | uint32_t 240 | LoraExample::random_number(uint32_t min_num, uint32_t max_num) 241 | { 242 | uint32_t result = 0, low_num = 0, hi_num = 0; 243 | 244 | if (min_num < max_num) 245 | { 246 | low_num = min_num; 247 | hi_num = max_num + 1; 248 | } else { 249 | low_num = max_num + 1; 250 | hi_num = min_num; 251 | } 252 | 253 | result = (rand() % (hi_num - low_num)) + low_num; 254 | return result; 255 | } 256 | 257 | 258 | uint32_t 259 | LoraExample::DoOneExample (Ptr prop) 260 | { 261 | Ptr channel = CreateObject (); 262 | channel->SetAttribute ("PropagationModel", PointerValue (prop)); 263 | 264 | Ptr gw0 = CreateGateway (Vector (50,50,50), channel); 265 | 266 | //Set positions to nodes 267 | uint32_t x = 50; uint32_t y = 50; uint32_t z = 50; 268 | uint32_t n = 10; 269 | 270 | Ptr PtrDevice[n]; 271 | for (uint32_t i = 0; i < n; i++) 272 | { 273 | PtrDevice[i] = CreateNode (Vector (x,y,z), channel); 274 | x += 50; y += 50; z += 50; 275 | 276 | if ((x == 10000) || (y == 10000) || (z == 10000)) 277 | { 278 | x = 50; y = 50; z = 50; 279 | } 280 | PtrDevice[i]->SetGWAddress(gw0->GetAddress()); 281 | } 282 | 283 | //Set gateway to receive packets from end devices node. 284 | gw0->SetReceiveCallback (MakeCallback (&LoraExample::RxPacket, this)); 285 | 286 | double simTime = 100.0; 287 | uint32_t mode [3] = {0, 1, 2}; 288 | uint32_t m = 0; 289 | double s_transmitStartTime; 290 | uint32_t nTempStart = 0; 291 | uint32_t nTempEnd = 100; 292 | uint32_t numNodesStart = 0; 293 | uint32_t numNodesEnd = 10; 294 | packetPerNode = 0; 295 | 296 | do { 297 | for (uint32_t j = numNodesStart; j < numNodesEnd; j++) 298 | { 299 | s_transmitStartTime = RanTxTime(nTempStart,nTempEnd); 300 | PtrDevice[j]->SetChannelMode(mode[m]); 301 | PtrDevice[j]->SetTransmitStartTime(s_transmitStartTime); 302 | Simulator::Schedule (Seconds(s_transmitStartTime), &LoraExample::SendOnePacket2GW, this, PtrDevice[j], 303 | mode[m], PtrDevice[j]->GetGWAddress()); 304 | 305 | m += 1; 306 | if (m > 2) { m = 0; } 307 | } 308 | nTempStart = nTempEnd; 309 | nTempEnd = nTempEnd + 100; 310 | packetPerNode++; 311 | 312 | } while (nTempEnd <= simTime); 313 | 314 | 315 | m_bytesRx = 0; 316 | Simulator::Stop (Seconds (120.0)); 317 | Simulator::Run (); 318 | Simulator::Destroy (); 319 | 320 | return m_bytesRx; 321 | } 322 | 323 | bool 324 | LoraExample::DoExamples () 325 | { 326 | 327 | LoraModesList mList; 328 | LoraTxMode mode = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 80, 80, 10000, 4000, 2, "TestMode"); 329 | mList.AppendMode (LoraTxMode (mode)); 330 | 331 | Ptr perDef = CreateObject (); 332 | Ptr sinrDef = CreateObject (); 333 | m_phyFac.SetTypeId ("ns3::LoraPhyGen"); 334 | m_phyFac.Set ("PerModel", PointerValue (perDef)); 335 | m_phyFac.Set ("SinrModel", PointerValue (sinrDef)); 336 | m_phyFac.Set ("SupportedModes", LoraModesListValue (mList)); 337 | 338 | Ptr prop = CreateObject (); 339 | 340 | LoraTxMode mode00 = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 300, 120, 10000, 125, 2, "TestMode00"); 341 | LoraTxMode mode01 = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 300, 120, 11000, 125, 2, "TestMode01"); 342 | LoraTxMode mode02 = LoraTxModeFactory::CreateMode (LoraTxMode::LORA, 300, 120, 12000, 125, 2, "TestMode02"); 343 | 344 | LoraModesList m0; 345 | m0.AppendMode (mode00); 346 | LoraModesList m1; 347 | m1.AppendMode (mode01); 348 | LoraModesList m2; 349 | m2.AppendMode (mode02); 350 | 351 | m_phyFac = ObjectFactory (); 352 | m_phyFac.SetTypeId ("ns3::LoraPhyDual"); 353 | 354 | m_phyFac.Set ("SupportedModesPhy1", LoraModesListValue (m0)); 355 | m_phyFac.Set ("SupportedModesPhy2", LoraModesListValue (m1)); 356 | m_phyFac.Set ("SupportedModesPhy3", LoraModesListValue (m2)); 357 | 358 | uint32_t n_ReceivedPacket = DoOneExample(prop); 359 | 360 | std::cout << size*packetPerNode << " packets transmitted, " << n_ReceivedPacket/13 << " packets received, " 361 | << (1 - (n_ReceivedPacket/13)/(size*packetPerNode))*100 << "\% packets loss.\n"; 362 | 363 | return false; 364 | } 365 | 366 | -------------------------------------------------------------------------------- /model/lora-net-device.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #ifndef LORA_NET_DEVICE_H 21 | #define LORA_NET_DEVICE_H 22 | 23 | #include "ns3/net-device.h" 24 | #include "ns3/pointer.h" 25 | #include "ns3/traced-callback.h" 26 | #include "lora-address.h" 27 | #include 28 | 29 | #include 30 | #include "ns3/node.h" 31 | #include "ns3/address.h" 32 | #include "ns3/net-device.h" 33 | #include "ns3/callback.h" 34 | #include "ns3/packet.h" 35 | #include "ns3/nstime.h" 36 | #include "ns3/data-rate.h" 37 | #include "ns3/ptr.h" 38 | #include "ns3/mac48-address.h" 39 | 40 | #include "lora-phy.h" 41 | 42 | namespace ns3 { 43 | 44 | class LoraChannel; 45 | class LoraPhy; 46 | class LoraMac; 47 | class LoraTransducer; 48 | 49 | /** 50 | * Net device for LORA models. 51 | */ 52 | class LoraNetDevice : public NetDevice 53 | { 54 | public: 55 | /** List of LoraPhy objects. */ 56 | typedef std::list > LoraPhyList; 57 | /** List of LoraTransducer objects. */ 58 | typedef std::list > LoraTransducerList; 59 | 60 | /** 61 | * Register this type. 62 | * \return The TypeId. 63 | */ 64 | static TypeId GetTypeId (void); 65 | 66 | /** Default constructor */ 67 | LoraNetDevice (); 68 | /** Dummy destructor, DoDispose. */ 69 | virtual ~LoraNetDevice (); 70 | 71 | /** 72 | * Set the MAC layer for this device. 73 | * 74 | * \param mac The MAC layer. 75 | */ 76 | void SetMac (Ptr mac); 77 | 78 | /** 79 | * Set the Phy layer for this device. 80 | * 81 | * \param phy The PHY layer. 82 | */ 83 | void SetPhy (Ptr phy); 84 | 85 | /** 86 | * Attach a channel. 87 | * 88 | * \param channel The channel. 89 | */ 90 | void SetChannel (Ptr channel); 91 | 92 | /** 93 | * Get the MAC used by this device. 94 | * 95 | * \return The MAC. 96 | */ 97 | Ptr GetMac (void) const; 98 | 99 | /** 100 | * Get the Phy used by this device. 101 | * 102 | * \return The Phy. 103 | */ 104 | Ptr GetPhy (void) const; 105 | 106 | /** 107 | * Get the transducer associated with this device. 108 | * 109 | * \return The transducer. 110 | */ 111 | Ptr GetTransducer (void) const; 112 | /** 113 | * Set the transdcuer used by this device. 114 | * 115 | * \param trans The transducer. 116 | */ 117 | void SetTransducer (Ptr trans); 118 | 119 | /** Clear all pointer references. */ 120 | void Clear (void); 121 | 122 | /** 123 | * Set the Phy SLEEP mode. 124 | * 125 | * \param sleep SLEEP on or off. 126 | */ 127 | void SetSleepMode (bool sleep); 128 | 129 | 130 | void SetChannelMode (uint32_t mode); 131 | uint32_t GetChannelMode (void); 132 | 133 | void SetTransmitStartTime (uint32_t transmitStartTime); 134 | double GetTransmitStartTime (void); 135 | 136 | bool SendCsma (Ptr packet, const Address& dest, uint16_t protocolNumber); 137 | bool SendFromCsma (Ptr packet, const Address& dest, uint16_t protocolNumber); 138 | 139 | virtual Address GetGWAddress (void) const; 140 | virtual void SetGWAddress (Address gwAddress); 141 | 142 | 143 | virtual void SetIfIndex (const uint32_t index); 144 | virtual uint32_t GetIfIndex (void) const; 145 | virtual Ptr GetChannel (void) const; 146 | virtual Address GetAddress (void) const; 147 | virtual bool SetMtu (const uint16_t mtu); 148 | virtual uint16_t GetMtu (void) const; 149 | virtual bool IsLinkUp (void) const; 150 | virtual bool IsBroadcast (void) const; 151 | virtual Address GetBroadcast (void) const; 152 | virtual bool IsMulticast (void) const; 153 | virtual Address GetMulticast (Ipv4Address multicastGroup) const; 154 | virtual Address GetMulticast (Ipv6Address addr) const; 155 | virtual bool IsBridge (void) const; 156 | virtual bool IsPointToPoint (void) const; 157 | virtual bool Send (Ptr packet, const Address& dest, uint16_t protocolNumber); 158 | virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); 159 | virtual Ptr GetNode (void) const; 160 | virtual void SetNode (Ptr node); 161 | virtual bool NeedsArp (void) const; 162 | virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb); 163 | virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb); 164 | virtual bool SupportsSendFrom (void) const; 165 | virtual void AddLinkChangeCallback (Callback callback); 166 | virtual void SetAddress (Address address); 167 | 168 | /** 169 | * TracedCallback signature for MAC send/receive events. 170 | * 171 | * \param [in] packet The Packet. 172 | * \param [in] address The source address. 173 | */ 174 | typedef void (* RxTxTracedCallback) 175 | (const Ptr packet, const LoraAddress address); 176 | 177 | private: 178 | /** 179 | * Forward the packet to a higher level, set with SetReceiveCallback. 180 | * 181 | * \param pkt The packet. 182 | * \param src The source address. 183 | */ 184 | virtual void ForwardUp (Ptr pkt, const LoraAddress &src); 185 | 186 | /** \return The channel attached to this device. */ 187 | Ptr DoGetChannel (void) const; 188 | 189 | Ptr m_trans; //!< The Transducer attached to this device. 190 | Ptr m_node; //!< The node hosting this device. 191 | Ptr m_channel; //!< The channel attached to this device. 192 | Ptr m_mac; //!< The MAC layer attached to this device. 193 | Ptr m_phy; //!< The PHY layer attached to this device. 194 | 195 | LoraTxMode m_txMode; 196 | 197 | uint32_t m_ifIndex; //!< The interface index of this device. 198 | uint16_t m_mtu; //!< The device MTU value, in bytes. 199 | bool m_linkup; //!< The link state, true if up. 200 | TracedCallback<> m_linkChanges; //!< Callback to invoke when the link state changes to UP. 201 | ReceiveCallback m_forwardUp; //!< The receive callback. 202 | 203 | 204 | uint32_t v_mode; 205 | double v_transmitStartTime; 206 | 207 | /** Trace source triggered when forwarding up received payload from the MAC layer. */ 208 | TracedCallback, LoraAddress> m_rxLogger; 209 | /** Trace source triggered when sending to the MAC layer */ 210 | TracedCallback, LoraAddress> m_txLogger; 211 | 212 | /** Flag when we've been cleared. */ 213 | bool m_cleared; 214 | 215 | 216 | /** 217 | * Start Sending a Packet Down the Wire. 218 | * 219 | * The TransmitStart method is the method that is used internally in 220 | * the CsmaNetDevice to begin the process of sending a packet 221 | * out on the channel. A corresponding method is called on the 222 | * channel to let it know that the physical device this class 223 | * represents has actually started sending signals, this causes the 224 | * channel to enter the BUSY state. An event is scheduled for the time at 225 | * which the bits have been completely transmitted. 226 | * 227 | * If the channel is found to be BUSY, this method reschedules itself for 228 | * execution at a later time (within the backoff period). 229 | * 230 | */ 231 | void TransmitStart (); 232 | 233 | 234 | /** 235 | * Stop Sending a Packet Down the Wire and Begin the Interframe Gap. 236 | * 237 | * The TransmitCompleteEvent method is used internally to finish the process 238 | * of sending a packet out on the channel. During execution of this method 239 | * the TransmitEnd method is called on the channel to let it know that the 240 | * physical device this class represents has finished sending simulated 241 | * signals. The channel uses this event to begin its speed of light delay 242 | * timer after which it notifies the Net Device(s) at the other end of the 243 | * link that new bits have arrived (it delivers the Packet). During this 244 | * method, the net device also schedules the TransmitReadyEvent at which 245 | * time the transmitter becomes ready to send the next packet. 246 | * 247 | * \see CsmaChannel::TransmitEnd () 248 | * \see TransmitReadyEvent () 249 | */ 250 | void TransmitCompleteEvent (void); 251 | 252 | /** 253 | * Cause the Transmitter to Become Ready to Send Another Packet. 254 | * 255 | * The TransmitReadyEvent method is used internally to re-enable the 256 | * transmit machine of the net device. It is scheduled after a suitable 257 | * interframe gap after the completion of the previous transmission. 258 | * The queue is checked at this time, and if there is a packet waiting on 259 | * the queue, the transmission process is begun. 260 | * 261 | * If a packet is in the queue, it is extracted for the queue as the 262 | * next packet to be transmitted by the net device. 263 | * 264 | * \see TransmitStart () 265 | */ 266 | void TransmitReadyEvent (void); 267 | 268 | /** 269 | * Aborts the transmission of the current packet 270 | * 271 | * If the net device has tried to transmit a packet for more times 272 | * than the maximum allowed number of retries (channel always busy) 273 | * then the packet is dropped. 274 | */ 275 | void TransmitAbort (void); 276 | 277 | 278 | /** 279 | * Enumeration of the states of the transmit machine of the net device. 280 | */ 281 | enum TxMachineState 282 | { 283 | READY, /**< The transmitter is ready to begin transmission of a packet */ 284 | BUSY, /**< The transmitter is busy transmitting a packet */ 285 | GAP, /**< The transmitter is in the interframe gap time */ 286 | // BACKOFF /**< The transmitter is waiting for the channel to be free */ 287 | }; 288 | 289 | /** 290 | * The state of the Net Device transmit state machine. 291 | * \see TxMachineState 292 | */ 293 | TxMachineState m_txMachineState; 294 | 295 | /** 296 | * The data rate that the Net Device uses to simulate packet transmission 297 | * timing. 298 | * \see class DataRate 299 | */ 300 | DataRate m_bps; 301 | 302 | /** 303 | * The interframe gap that the Net Device uses insert time between packet 304 | * transmission 305 | * \see class Time 306 | */ 307 | Time m_tInterframeGap; 308 | 309 | /** 310 | * Holds the backoff parameters and is used to calculate the next 311 | * backoff time to use when the channel is busy and the net device 312 | * is ready to transmit 313 | */ 314 | // Backoff m_backoff; 315 | 316 | /** 317 | * Next packet that will be transmitted (if transmitter is not 318 | * currently transmitting) or packet that is currently being 319 | * transmitted. 320 | */ 321 | Ptr m_currentPkt; 322 | 323 | /** 324 | * Save destination and protocolNumber for TransmitStart 325 | */ 326 | 327 | Address m_dest; 328 | Address m_gwAddress; 329 | uint16_t m_protocolNumber; 330 | 331 | protected: 332 | virtual void DoDispose (); 333 | 334 | }; // class LoraNetDevice 335 | 336 | } // namespace ns3 337 | 338 | #endif /* LORA_NET_DEVICE_H */ 339 | -------------------------------------------------------------------------------- /model/lora-phy-gen.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * Andrea Sacco 18 | * To Thanh Hai 19 | */ 20 | 21 | #ifndef LORA_PHY_GEN_H 22 | #define LORA_PHY_GEN_H 23 | 24 | 25 | #include "lora-phy.h" 26 | #include "ns3/traced-callback.h" 27 | #include "ns3/nstime.h" 28 | #include "ns3/device-energy-model.h" 29 | #include "ns3/random-variable-stream.h" 30 | #include 31 | 32 | namespace ns3 { 33 | 34 | /** 35 | * 36 | * Default Packet Error Rate calculator for LoraPhyGen 37 | * 38 | */ 39 | class LoraPhyPerGenDefault : public LoraPhyPer 40 | { 41 | public: 42 | /** Constructor */ 43 | LoraPhyPerGenDefault (); 44 | /** Destructor */ 45 | virtual ~LoraPhyPerGenDefault (); 46 | 47 | /** 48 | * Register this type. 49 | * \return The TypeId. 50 | */ 51 | static TypeId GetTypeId (void); 52 | 53 | virtual double CalcPer (Ptr pkt, double sinrDb, LoraTxMode mode); 54 | private: 55 | 56 | double m_thresh; //!< SINR threshold. 57 | 58 | }; // class LoraPhyPerGenDefault 59 | 60 | 61 | /** 62 | * 63 | * Packet error rate calculation assuming WHOI Micromodem-like PHY. 64 | * 65 | */ 66 | class LoraPhyPerUmodem : public LoraPhyPer 67 | { 68 | public: 69 | /** Constructor */ 70 | LoraPhyPerUmodem (); 71 | /** Destructor */ 72 | virtual ~LoraPhyPerUmodem (); 73 | 74 | /** 75 | * Register this type. 76 | * \return The TypeId. 77 | */ 78 | static TypeId GetTypeId (void); 79 | 80 | /** 81 | * Calculate the packet error probability based on 82 | * SINR at the receiver and a tx mode. 83 | * 84 | * \param pkt Packet which is under consideration. 85 | * \param sinrDb SINR at receiver. 86 | * \param mode TX mode used to transmit packet. 87 | * \return Probability of packet error. 88 | */ 89 | virtual double CalcPer (Ptr pkt, double sinrDb, LoraTxMode mode); 90 | 91 | private: 92 | /** 93 | * Binomial coefficient 94 | * 95 | * \param n Pool size. 96 | * \param k Number of draws. 97 | * \return Binomial coefficient n choose k. 98 | */ 99 | double NChooseK (uint32_t n, uint32_t k); 100 | 101 | }; // class LoraPhyPerUmodem 102 | 103 | 104 | /** 105 | * 106 | * Default SINR calculator for LoraPhyGen. 107 | * 108 | */ 109 | class LoraPhyCalcSinrDefault : public LoraPhyCalcSinr 110 | { 111 | 112 | public: 113 | /** Constructor */ 114 | LoraPhyCalcSinrDefault (); 115 | /** Destructor */ 116 | virtual ~LoraPhyCalcSinrDefault (); 117 | 118 | /** 119 | * Register this type. 120 | * \return The TypeId. 121 | */ 122 | static TypeId GetTypeId (void); 123 | 124 | /** 125 | * Calculate the SINR value for a packet. 126 | * 127 | * This implementation simply adds all arriving signal power 128 | * and assumes it acts identically to additional noise. 129 | * 130 | * \param pkt Packet to calculate SINR for. 131 | * \param arrTime Arrival time of pkt. 132 | * \param rxPowerDb The received signal strength of the packet in dB re 1 uPa. 133 | * \param ambNoiseDb Ambient channel noise in dB re 1 uPa. 134 | * \param mode TX Mode of pkt. 135 | * \param pdp Power delay profile of pkt. 136 | * \param arrivalList List of interfering arrivals given from Transducer. 137 | * \return The SINR in dB re 1 uPa. 138 | */ 139 | virtual double CalcSinrDb (Ptr pkt, 140 | Time arrTime, 141 | double rxPowerDb, 142 | double ambNoiseDb, 143 | LoraTxMode mode, 144 | LoraPdp pdp, 145 | const LoraTransducer::ArrivalList &arrivalList 146 | ) const; 147 | 148 | }; // class LoraPhyCalcSinrDefault 149 | 150 | 151 | class LoraPhyCalcSinrFhFsk : public LoraPhyCalcSinr 152 | { 153 | 154 | public: 155 | /** Constructor */ 156 | LoraPhyCalcSinrFhFsk (); 157 | /** Destructor */ 158 | virtual ~LoraPhyCalcSinrFhFsk (); 159 | 160 | /** 161 | * Register this type. 162 | * \return The TypeId. 163 | */ 164 | static TypeId GetTypeId (void); 165 | 166 | virtual double CalcSinrDb (Ptr pkt, 167 | Time arrTime, 168 | double rxPowerDb, 169 | double ambNoiseDb, 170 | LoraTxMode mode, 171 | LoraPdp pdp, 172 | const LoraTransducer::ArrivalList &arrivalList 173 | ) const; 174 | private: 175 | uint32_t m_hops; //!< Number of hops. 176 | 177 | }; // class LoraPhyCalcSinrFhFsk 178 | 179 | 180 | /** 181 | * 182 | * Generic PHY model. 183 | * 184 | */ 185 | class LoraPhyGen : public LoraPhy 186 | { 187 | public: 188 | /** Constructor */ 189 | LoraPhyGen (); 190 | /** Dummy destructor, see DoDispose */ 191 | virtual ~LoraPhyGen (); 192 | /** 193 | * Get the default transmission modes. 194 | * 195 | * \return The default mode list. 196 | */ 197 | static LoraModesList GetDefaultModes (void); 198 | 199 | 200 | /** 201 | * Register this type. 202 | * \return The TypeId. 203 | */ 204 | static TypeId GetTypeId (void); 205 | 206 | // Inherited methods 207 | virtual void SetEnergyModelCallback (DeviceEnergyModel::ChangeStateCallback cb); 208 | virtual void EnergyDepletionHandler (void); 209 | virtual void SendPacket (Ptr pkt, uint32_t modeNum); 210 | virtual void RegisterListener (LoraPhyListener *listener); 211 | virtual void StartRxPacket (Ptr pkt, double rxPowerDb, LoraTxMode txMode, LoraPdp pdp); 212 | virtual void SetReceiveOkCallback (RxOkCallback cb); 213 | virtual void SetReceiveErrorCallback (RxErrCallback cb); 214 | virtual bool IsStateSleep (void); 215 | virtual bool IsStateIdle (void); 216 | virtual bool IsStateBusy (void); 217 | virtual bool IsStateRx (void); 218 | virtual bool IsStateTx (void); 219 | virtual bool IsStateCcaBusy (void); 220 | virtual void SetRxGainDb (double gain); 221 | virtual void SetTxPowerDb (double txpwr); 222 | virtual void SetRxThresholdDb (double thresh); 223 | virtual void SetCcaThresholdDb (double thresh); 224 | virtual double GetRxGainDb (void); 225 | virtual double GetTxPowerDb (void); 226 | virtual double GetRxThresholdDb (void); 227 | virtual double GetCcaThresholdDb (void); 228 | virtual Ptr GetChannel (void) const; 229 | virtual Ptr GetDevice (void); 230 | virtual Ptr GetTransducer (void); 231 | virtual void SetChannel (Ptr channel); 232 | virtual void SetDevice (Ptr device); 233 | virtual void SetMac (Ptr mac); 234 | virtual void SetTransducer (Ptr trans); 235 | virtual void NotifyTransStartTx (Ptr packet, double txPowerDb, LoraTxMode txMode); 236 | virtual void NotifyIntChange (void); 237 | virtual uint32_t GetNModes (void); 238 | virtual LoraTxMode GetMode (uint32_t n); 239 | virtual Ptr GetPacketRx (void) const; 240 | virtual void Clear (void); 241 | virtual void SetSleepMode (bool sleep); 242 | int64_t AssignStreams (int64_t stream); 243 | 244 | private: 245 | /** List of Phy Listeners. */ 246 | typedef std::list ListenerList; 247 | 248 | LoraModesList m_modes; //!< List of modes supported by this PHY. 249 | 250 | State m_state; //!< Phy state. 251 | ListenerList m_listeners; //!< List of listeners. 252 | RxOkCallback m_recOkCb; //!< Callback for packets received without error. 253 | RxErrCallback m_recErrCb; //!< Callback for packets received with errors. 254 | Ptr m_channel; //!< Attached channel. 255 | Ptr m_transducer; //!< Associated transducer. 256 | Ptr m_device; //!< Device hosting this Phy. 257 | Ptr m_mac; //!< MAC layer. 258 | Ptr m_per; //!< Error model. 259 | Ptr m_sinr; //!< SINR calculator. 260 | 261 | double m_rxGainDb; //!< Receive gain. 262 | double m_txPwrDb; //!< Transmit power. 263 | double m_rxThreshDb; //!< Receive SINR threshold. 264 | double m_ccaThreshDb; //!< CCA busy threshold. 265 | 266 | Ptr m_pktRx; //!< Received packet. 267 | double m_minRxSinrDb; //!< Minimum receive SINR during packet reception. 268 | double m_rxRecvPwrDb; //!< Receiver power. 269 | Time m_pktRxArrTime; //!< Packet arrival time. 270 | LoraPdp m_pktRxPdp; //!< Power delay profile of pakket. 271 | LoraTxMode m_pktRxMode; //!< Packet transmission mode at receiver. 272 | 273 | bool m_cleared; //!< Flag when we've been cleared. 274 | bool m_disabled; //!< Energy depleted. 275 | 276 | /** Provides uniform random variables. */ 277 | Ptr m_pg; 278 | 279 | /** Energy model callback. */ 280 | DeviceEnergyModel::ChangeStateCallback m_energyCallback; 281 | /** A packet destined for this Phy was received without error. */ 282 | ns3::TracedCallback, double, LoraTxMode > m_rxOkLogger; 283 | /** A packet destined for this Phy was received with error. */ 284 | ns3::TracedCallback, double, LoraTxMode > m_rxErrLogger; 285 | /** A packet was sent from this Phy. */ 286 | ns3::TracedCallback, double, LoraTxMode > m_txLogger; 287 | 288 | /** 289 | * Calculate the SINR value for a packet. 290 | * 291 | * \param pkt Packet to calculate SINR for. 292 | * \param arrTime Arrival time of pkt. 293 | * \param rxPowerDb The received signal strength of the packet in dB re 1 uPa. 294 | * \param mode TX Mode of pkt. 295 | * \param pdp Power delay profile of pkt. 296 | * \return The SINR in dB re 1 uPa. 297 | */ 298 | double CalculateSinrDb (Ptr pkt, Time arrTime, double rxPowerDb, 299 | LoraTxMode mode, LoraPdp pdp); 300 | 301 | /** 302 | * Calculate interference power from overlapping packet arrivals, in dB. 303 | * 304 | * The "signal" packet power is excluded. Use 305 | * GetInterferenceDb ( (Ptr) 0) to treat all signals as 306 | * interference, for instance in calculating the CCA busy. 307 | * 308 | * \param pkt The arriving (signal) packet. 309 | * \return The total interference power, in dB. 310 | */ 311 | double GetInterferenceDb (Ptr pkt); 312 | /** 313 | * Convert dB to kilopascals. 314 | * 315 | * \f[{\rm{kPa}} = {10^{\frac{{{\rm{dB}}}}{{10}}}}\f] 316 | * 317 | * \param db Signal level in dB. 318 | * \return Sound pressure in kPa. 319 | */ 320 | double DbToKp (double db); 321 | /** 322 | * Convert kilopascals to dB. 323 | * 324 | * \f[{\rm{dB}} = 10{\log _{10}}{\rm{kPa}}\f] 325 | * 326 | * \param kp Sound pressure in kPa. 327 | * \return Signal level in dB. 328 | */ 329 | double KpToDb (double kp); 330 | /** 331 | * Event to process end of packet reception. 332 | * 333 | * \param pkt The packet. 334 | * \param rxPowerDb Received signal power. 335 | * \param txMode Transmission mode. 336 | */ 337 | void RxEndEvent (Ptr pkt, double rxPowerDb, LoraTxMode txMode); 338 | /** Event to process end of packet transmission. */ 339 | void TxEndEvent (); 340 | /** 341 | * Update energy source with new state. 342 | * 343 | * \param state The new Phy state. 344 | */ 345 | void UpdatePowerConsumption (const State state); 346 | 347 | 348 | /** Call LoraListener::NotifyRxStart on all listeners. */ 349 | void NotifyListenersRxStart (void); 350 | /** Call LoraListener::NotifyRxEndOk on all listeners. */ 351 | void NotifyListenersRxGood (void); 352 | /** Call LoraListener::NotifyRxEndError on all listeners. */ 353 | void NotifyListenersRxBad (void); 354 | /** Call LoraListener::NotifyCcaStart on all listeners. */ 355 | void NotifyListenersCcaStart (void); 356 | /** Call LoraListener::NotifyCcaEnd on all listeners. */ 357 | void NotifyListenersCcaEnd (void); 358 | /** 359 | * Call LoraListener::NotifyTxStart on all listeners. 360 | * 361 | * \param duration Duration of transmission. 362 | */ 363 | void NotifyListenersTxStart (Time duration); 364 | 365 | protected: 366 | virtual void DoDispose (); 367 | 368 | }; // class LoraPhyGen 369 | 370 | } // namespace ns3 371 | 372 | #endif /* LORA_PHY_GEN_H */ 373 | -------------------------------------------------------------------------------- /model/lora-net-device.cc: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * To Thanh Hai 18 | */ 19 | 20 | #include "ns3/trace-source-accessor.h" 21 | #include "ns3/traced-callback.h" 22 | #include "ns3/pointer.h" 23 | #include "ns3/node.h" 24 | #include "ns3/assert.h" 25 | #include "lora-net-device.h" 26 | #include "lora-phy.h" 27 | #include "lora-mac.h" 28 | #include "lora-channel.h" 29 | #include "lora-transducer.h" 30 | #include "ns3/log.h" 31 | 32 | #include "ns3/simulator.h" 33 | #include "ns3/ethernet-header.h" 34 | #include "ns3/ethernet-trailer.h" 35 | #include "ns3/llc-snap-header.h" 36 | #include "ns3/error-model.h" 37 | #include "ns3/enum.h" 38 | #include "ns3/boolean.h" 39 | #include "ns3/uinteger.h" 40 | #include "ns3/lora-tx-mode.h" 41 | 42 | namespace ns3 { 43 | 44 | NS_LOG_COMPONENT_DEFINE ("LoraNetDevice"); 45 | 46 | NS_OBJECT_ENSURE_REGISTERED (LoraNetDevice); 47 | 48 | LoraNetDevice::LoraNetDevice () 49 | : NetDevice (), 50 | m_mtu (64000), 51 | m_cleared (false) 52 | { 53 | } 54 | 55 | LoraNetDevice::~LoraNetDevice () 56 | { 57 | } 58 | 59 | void 60 | LoraNetDevice::Clear () 61 | { 62 | if (m_cleared) 63 | { 64 | return; 65 | } 66 | m_cleared = true; 67 | m_node = 0; 68 | if (m_channel) 69 | { 70 | m_channel->Clear (); 71 | m_channel = 0; 72 | } 73 | if (m_mac) 74 | { 75 | m_mac->Clear (); 76 | m_mac = 0; 77 | } 78 | if (m_phy) 79 | { 80 | m_phy->Clear (); 81 | m_phy = 0; 82 | } 83 | if (m_trans) 84 | { 85 | m_trans->Clear (); 86 | m_trans = 0; 87 | } 88 | } 89 | 90 | void 91 | LoraNetDevice::DoDispose () 92 | { 93 | Clear (); 94 | NetDevice::DoDispose (); 95 | } 96 | 97 | TypeId 98 | LoraNetDevice::GetTypeId () 99 | { 100 | static TypeId tid = TypeId ("ns3::LoraNetDevice") 101 | .SetParent () 102 | .SetGroupName ("Lora") 103 | .AddAttribute ("Channel", "The channel attached to this device.", 104 | PointerValue (), 105 | MakePointerAccessor (&LoraNetDevice::DoGetChannel, &LoraNetDevice::SetChannel), 106 | MakePointerChecker ()) 107 | .AddAttribute ("Phy", "The PHY layer attached to this device.", 108 | PointerValue (), 109 | MakePointerAccessor (&LoraNetDevice::GetPhy, &LoraNetDevice::SetPhy), 110 | MakePointerChecker ()) 111 | .AddAttribute ("Mac", "The MAC layer attached to this device.", 112 | PointerValue (), 113 | MakePointerAccessor (&LoraNetDevice::GetMac, &LoraNetDevice::SetMac), 114 | MakePointerChecker ()) 115 | .AddAttribute ("Transducer", "The Transducer attached to this device.", 116 | PointerValue (), 117 | MakePointerAccessor (&LoraNetDevice::GetTransducer, 118 | &LoraNetDevice::SetTransducer), 119 | MakePointerChecker ()) 120 | .AddTraceSource ("Rx", "Received payload from the MAC layer.", 121 | MakeTraceSourceAccessor (&LoraNetDevice::m_rxLogger), 122 | "ns3::LoraNetDevice::RxTxTracedCallback") 123 | .AddTraceSource ("Tx", "Send payload to the MAC layer.", 124 | MakeTraceSourceAccessor (&LoraNetDevice::m_txLogger), 125 | "ns3::LoraNetDevice::RxTxTracedCallback") 126 | ; 127 | return tid; 128 | } 129 | 130 | void 131 | LoraNetDevice::SetMac (Ptr mac) 132 | { 133 | if (mac != 0) 134 | { 135 | m_mac = mac; 136 | NS_LOG_DEBUG ("Set MAC"); 137 | 138 | if (m_phy != 0) 139 | { 140 | m_phy->SetMac (mac); 141 | m_mac->AttachPhy (m_phy); 142 | NS_LOG_DEBUG ("Attached MAC to PHY"); 143 | } 144 | m_mac->SetForwardUpCb (MakeCallback (&LoraNetDevice::ForwardUp, this)); 145 | } 146 | 147 | } 148 | 149 | void 150 | LoraNetDevice::SetPhy (Ptr phy) 151 | { 152 | if (phy != 0) 153 | { 154 | m_phy = phy; 155 | m_phy->SetDevice (Ptr (this)); 156 | NS_LOG_DEBUG ("Set PHY"); 157 | if (m_mac != 0) 158 | { 159 | m_mac->AttachPhy (phy); 160 | m_phy->SetMac (m_mac); 161 | NS_LOG_DEBUG ("Attached PHY to MAC"); 162 | } 163 | if (m_trans != 0) 164 | { 165 | m_phy->SetTransducer (m_trans); 166 | NS_LOG_DEBUG ("Added PHY to trans"); 167 | } 168 | 169 | } 170 | } 171 | 172 | void 173 | LoraNetDevice::SetChannel (Ptr channel) 174 | { 175 | if (channel != 0) 176 | { 177 | m_channel = channel; 178 | NS_LOG_DEBUG ("Set CHANNEL"); 179 | if (m_trans != 0) 180 | { 181 | 182 | m_channel->AddDevice (this, m_trans); 183 | NS_LOG_DEBUG ("Added self to channel device list"); 184 | m_trans->SetChannel (m_channel); 185 | NS_LOG_DEBUG ("Set Transducer channel"); 186 | } 187 | if (m_phy != 0 ) 188 | { 189 | m_phy->SetChannel (channel); 190 | } 191 | } 192 | } 193 | 194 | Ptr 195 | LoraNetDevice::DoGetChannel (void) const 196 | { 197 | return m_channel; 198 | 199 | } 200 | Ptr 201 | LoraNetDevice::GetMac () const 202 | { 203 | return m_mac; 204 | } 205 | 206 | Ptr 207 | LoraNetDevice::GetPhy () const 208 | { 209 | return m_phy; 210 | } 211 | 212 | void 213 | LoraNetDevice::SetIfIndex (uint32_t index) 214 | { 215 | m_ifIndex = index; 216 | } 217 | 218 | uint32_t 219 | LoraNetDevice::GetIfIndex () const 220 | { 221 | return m_ifIndex; 222 | } 223 | 224 | Ptr 225 | LoraNetDevice::GetChannel () const 226 | { 227 | return m_channel; 228 | } 229 | 230 | Address 231 | LoraNetDevice::GetAddress () const 232 | { 233 | return m_mac->GetAddress (); 234 | } 235 | 236 | bool 237 | LoraNetDevice::SetMtu (uint16_t mtu) 238 | { 239 | NS_LOG_WARN ("LoraNetDevice: MTU is not implemented"); 240 | m_mtu = mtu; 241 | return true; 242 | } 243 | 244 | uint16_t 245 | LoraNetDevice::GetMtu () const 246 | { 247 | return m_mtu; 248 | } 249 | 250 | void 251 | LoraNetDevice::SetChannelMode (uint32_t mode) { 252 | v_mode = mode; 253 | } 254 | 255 | uint32_t 256 | LoraNetDevice::GetChannelMode (void) { 257 | return v_mode; 258 | } 259 | 260 | void 261 | LoraNetDevice::SetTransmitStartTime (uint32_t transmitStartTime) { 262 | v_transmitStartTime = transmitStartTime; 263 | } 264 | 265 | double 266 | LoraNetDevice::GetTransmitStartTime (void) { 267 | return v_transmitStartTime; 268 | } 269 | 270 | bool 271 | LoraNetDevice::IsLinkUp () const 272 | { 273 | return (m_linkup && (m_phy != 0)); 274 | } 275 | 276 | bool 277 | LoraNetDevice::IsBroadcast () const 278 | { 279 | return true; 280 | } 281 | 282 | Address 283 | LoraNetDevice::GetBroadcast () const 284 | { 285 | return m_mac->GetBroadcast (); 286 | } 287 | 288 | bool 289 | LoraNetDevice::IsMulticast () const 290 | { 291 | return false; 292 | } 293 | 294 | Address 295 | LoraNetDevice::GetMulticast (Ipv4Address multicastGroup) const 296 | { 297 | NS_FATAL_ERROR ("LoraNetDevice does not support multicast"); 298 | return m_mac->GetBroadcast (); 299 | } 300 | 301 | Address 302 | LoraNetDevice::GetMulticast (Ipv6Address addr) const 303 | { 304 | NS_FATAL_ERROR ("LoraNetDevice does not support multicast"); 305 | return m_mac->GetBroadcast (); 306 | } 307 | 308 | bool 309 | LoraNetDevice::IsBridge (void) const 310 | { 311 | return false; 312 | } 313 | bool 314 | LoraNetDevice::IsPointToPoint () const 315 | { 316 | return false; 317 | } 318 | 319 | bool 320 | LoraNetDevice::Send (Ptr packet, const Address &dest, uint16_t protocolNumber) 321 | { 322 | return m_mac->Enqueue (packet, dest, protocolNumber); 323 | } 324 | 325 | bool 326 | LoraNetDevice::SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) 327 | { 328 | NS_ASSERT_MSG (0, "Not yet implemented"); 329 | return false; 330 | } 331 | 332 | 333 | 334 | Ptr 335 | LoraNetDevice::GetNode () const 336 | { 337 | return m_node; 338 | } 339 | 340 | void 341 | LoraNetDevice::SetNode (Ptr node) 342 | { 343 | m_node = node; 344 | } 345 | 346 | bool 347 | LoraNetDevice::NeedsArp () const 348 | { 349 | return false; 350 | } 351 | 352 | void 353 | LoraNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) 354 | { 355 | m_forwardUp = cb; 356 | } 357 | 358 | void 359 | LoraNetDevice::ForwardUp (Ptr pkt, const LoraAddress &src) 360 | { 361 | NS_LOG_DEBUG ("Forwarding packet up to application"); 362 | m_rxLogger (pkt, src); 363 | m_forwardUp (this, pkt, 0, src); 364 | 365 | } 366 | 367 | Ptr 368 | LoraNetDevice::GetTransducer (void) const 369 | { 370 | return m_trans; 371 | } 372 | void 373 | LoraNetDevice::SetTransducer (Ptr trans) 374 | { 375 | 376 | if (trans != 0) 377 | { 378 | m_trans = trans; 379 | NS_LOG_DEBUG ("Set Transducer"); 380 | if (m_phy != 0) 381 | { 382 | m_phy->SetTransducer (m_trans); 383 | NS_LOG_DEBUG ("Attached Phy to transducer"); 384 | } 385 | 386 | if (m_channel != 0) 387 | { 388 | m_channel->AddDevice (this, m_trans); 389 | m_trans->SetChannel (m_channel); 390 | NS_LOG_DEBUG ("Added self to channel device list"); 391 | } 392 | } 393 | 394 | } 395 | 396 | void 397 | LoraNetDevice::AddLinkChangeCallback (Callback callback) 398 | { 399 | m_linkChanges.ConnectWithoutContext (callback); 400 | } 401 | 402 | 403 | void 404 | LoraNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb) 405 | { 406 | NS_ASSERT_MSG (0, "Not yet implemented"); 407 | } 408 | 409 | bool 410 | LoraNetDevice::SupportsSendFrom (void) const 411 | { 412 | return false; 413 | } 414 | 415 | void 416 | LoraNetDevice::SetAddress (Address address) 417 | { 418 | NS_ASSERT_MSG (0, "Tried to set MAC address with no MAC"); 419 | m_mac->SetAddress (LoraAddress::ConvertFrom (address)); 420 | } 421 | 422 | 423 | Address 424 | LoraNetDevice::GetGWAddress () const 425 | { 426 | return m_gwAddress; 427 | } 428 | 429 | 430 | void 431 | LoraNetDevice::SetGWAddress (Address gwAddress) 432 | { 433 | m_gwAddress = gwAddress; 434 | } 435 | 436 | 437 | 438 | void 439 | LoraNetDevice::SetSleepMode (bool sleep) 440 | { 441 | m_phy->SetSleepMode (sleep); 442 | } 443 | 444 | 445 | void 446 | LoraNetDevice::TransmitStart (void) 447 | { 448 | NS_LOG_FUNCTION_NOARGS (); 449 | /* 450 | 451 | NS_ASSERT_MSG ((m_txMachineState == READY) || (m_txMachineState == BACKOFF), 452 | "Must be READY to transmit. Tx state is: " << m_txMachineState); 453 | 454 | // 455 | // Now we have to sense the state of the medium and either start transmitting 456 | // if it is idle, or backoff our transmission if someone else is on the wire. 457 | // 458 | if (m_channel->GetState (m_protocolNumber) != IDLE) 459 | { 460 | // 461 | // The channel is busy -- backoff and rechedule TransmitStart() unless 462 | // we have exhausted all of our retries. 463 | // 464 | m_txMachineState = BACKOFF; 465 | 466 | if (m_backoff.MaxRetriesReached ()) 467 | { 468 | // 469 | // Too many retries, abort transmission of packet 470 | // 471 | TransmitAbort (); 472 | } 473 | else 474 | { 475 | m_backoff.IncrNumRetries (); 476 | Time backoffTime = m_backoff.GetBackoffTime (); 477 | 478 | NS_LOG_LOGIC ("Channel busy, backing off for " << backoffTime.GetSeconds () << " sec"); 479 | 480 | Simulator::Schedule (Seconds(backoffTime), &LoraNetDevice::TransmitStart, this); 481 | } 482 | } 483 | else 484 | { 485 | // The channel is free, transmit the packet 486 | 487 | if (m_mac->Enqueue (m_currentPkt, m_dest, m_protocolNumber) == false) 488 | { 489 | NS_LOG_LOGIC ("Transmitting the packet."); 490 | } 491 | 492 | if (m_channel->TransmitStart (m_currentPkt, m_protocolNumber) == false) 493 | { 494 | NS_LOG_WARN ("Channel TransmitStart returns an error"); 495 | m_currentPkt = 0; 496 | m_txMachineState = READY; 497 | 498 | } 499 | else 500 | { 501 | // 502 | // Transmission succeeded, reset the backoff time parameters and 503 | // schedule a transmit complete event. 504 | // 505 | m_backoff.ResetBackoffTime (); 506 | m_txMachineState = BUSY; 507 | Time tEvent = m_bps.CalculateBytesTxTime (13); 508 | NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec"); 509 | Simulator::Schedule (Seconds(tEvent), &LoraNetDevice::TransmitCompleteEvent, this); 510 | } 511 | 512 | } 513 | */ 514 | 515 | } 516 | 517 | 518 | void 519 | LoraNetDevice::TransmitAbort (void) 520 | { 521 | // 522 | // When we started the process of transmitting the current packet, it was 523 | // placed in m_currentPkt. So we had better find one there. 524 | // 525 | 526 | m_currentPkt = 0; 527 | 528 | // 529 | // We're done with that one, so reset the backoff algorithm and ready the 530 | // transmit state machine. 531 | // 532 | // m_backoff.ResetBackoffTime (); 533 | m_txMachineState = READY; 534 | 535 | } 536 | 537 | 538 | void 539 | LoraNetDevice::TransmitCompleteEvent (void) 540 | { 541 | 542 | NS_LOG_FUNCTION_NOARGS (); 543 | 544 | // 545 | // This function is called to finish the process of transmitting a packet. 546 | // We need to tell the channel that we've stopped wiggling the wire and 547 | // schedule an event that will be executed when it's time to re-enable 548 | // the transmitter after the interframe gap. 549 | // 550 | m_txMachineState = GAP; 551 | 552 | // 553 | // When we started transmitting the current packet, it was placed in 554 | // m_currentPkt. So we had better find one there. 555 | // 556 | 557 | m_channel->TransmitEnd (m_protocolNumber); 558 | 559 | m_currentPkt = 0; 560 | 561 | NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec"); 562 | 563 | Simulator::Schedule (Seconds(m_tInterframeGap.GetSeconds()), &LoraNetDevice::TransmitReadyEvent, this); 564 | 565 | } 566 | 567 | 568 | void 569 | LoraNetDevice::TransmitReadyEvent (void) 570 | { 571 | // NS_LOG_FUNCTION_NOARGS (); 572 | 573 | // 574 | // This function is called to enable the transmitter after the interframe 575 | // gap has passed. If there are pending transmissions, we use this opportunity 576 | // to start the next transmit. 577 | // 578 | 579 | m_txMachineState = READY; 580 | 581 | // 582 | // We expect that the packet we had been transmitting was cleared when the 583 | // TransmitCompleteEvent() was executed. 584 | // 585 | 586 | // 587 | // Get the next packet from the queue for transmitting: Not implement yet. 588 | // 589 | 590 | } 591 | 592 | bool 593 | LoraNetDevice::SendCsma (Ptr packet,const Address& dest, uint16_t protocolNumber) 594 | { 595 | NS_LOG_FUNCTION (packet << dest << protocolNumber); 596 | return SendFromCsma (packet, dest, protocolNumber); 597 | } 598 | 599 | bool 600 | LoraNetDevice::SendFromCsma (Ptr packet, const Address& dest, uint16_t protocolNumber) 601 | { 602 | NS_LOG_FUNCTION (packet << dest << protocolNumber); 603 | NS_LOG_LOGIC ("packet =" << packet); 604 | NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")"); 605 | 606 | // 607 | // Place the packet to be sent on the send queue. Note that the 608 | // queue may fire a drop trace, but we will too. 609 | // 610 | 611 | // 612 | // If the device is idle, we need to start a transmission. Otherwise, 613 | // the transmission will be started when the current packet finished 614 | // transmission (see TransmitCompleteEvent) 615 | // 616 | if (m_txMachineState == READY) 617 | { 618 | { 619 | m_dest = dest; 620 | m_protocolNumber = protocolNumber; 621 | m_currentPkt = packet; 622 | 623 | TransmitStart (); 624 | } 625 | } 626 | return true; 627 | } 628 | 629 | } // namespace ns3 630 | 631 | -------------------------------------------------------------------------------- /model/lora-phy.h: -------------------------------------------------------------------------------- 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: Leonard Tracy 17 | * Andrea Sacco 18 | * To Thanh Hai 19 | */ 20 | 21 | 22 | #ifndef LORA_PHY_H 23 | #define LORA_PHY_H 24 | 25 | #include "ns3/object.h" 26 | #include "ns3/lora-mac.h" 27 | #include "ns3/lora-tx-mode.h" 28 | #include "ns3/lora-prop-model.h" 29 | #include "ns3/lora-transducer.h" 30 | #include "ns3/device-energy-model.h" 31 | 32 | namespace ns3 { 33 | 34 | 35 | /** 36 | * 37 | * Class used for calculating SINR of packet in LoraPhy. 38 | * 39 | */ 40 | class LoraPhyCalcSinr : public Object 41 | { 42 | public: 43 | /** 44 | * Calculate the SINR value for a packet. 45 | * 46 | * \param pkt Packet to calculate SINR for. 47 | * \param arrTime Arrival time of pkt. 48 | * \param rxPowerDb The received signal strength of the packet in dB re 1 uPa. 49 | * \param ambNoiseDb Ambient channel noise in dB re 1 uPa. 50 | * \param mode TX Mode of pkt. 51 | * \param pdp Power delay profile of pkt. 52 | * \param arrivalList List of interfering arrivals given from Transducer. 53 | * \return The SINR in dB re 1 uPa. 54 | */ 55 | virtual double CalcSinrDb (Ptr pkt, 56 | Time arrTime, 57 | double rxPowerDb, 58 | double ambNoiseDb, 59 | LoraTxMode mode, 60 | LoraPdp pdp, 61 | const LoraTransducer::ArrivalList &arrivalList 62 | ) const = 0; 63 | /** 64 | * Register this type. 65 | * \return The object TypeId. 66 | */ 67 | static TypeId GetTypeId (void); 68 | 69 | /** Clear all pointer references. */ 70 | virtual void Clear (void); 71 | 72 | /** 73 | * Convert dB re 1 uPa to kilopascals. 74 | * 75 | * \param db dB value. 76 | * \return Value in kilopascals. 77 | */ 78 | inline double DbToKp (double db) const 79 | { 80 | return std::pow (10, db / 10.0); 81 | } 82 | /** 83 | * Convert kilopascals to dB re 1 uPa. 84 | * 85 | * \param kp Value in kilopascals. 86 | * \return Valeu in dB re 1 uPa 87 | */ 88 | inline double KpToDb (double kp) const 89 | { 90 | return 10 * std::log10 (kp); 91 | } 92 | 93 | protected: 94 | virtual void DoDispose (void); 95 | 96 | }; // class LoraPhyCalcSinr 97 | 98 | /** 99 | * 100 | * Calculate packet error probability, based on received SINR 101 | * and modulation (mode). 102 | * 103 | * Can be set in LoraPhy via attributes. 104 | */ 105 | class LoraPhyPer : public Object 106 | { 107 | public: 108 | /** 109 | * Calculate the packet error probability based on 110 | * SINR at the receiver and a tx mode. 111 | * 112 | * \param pkt Packet which is under consideration. 113 | * \param sinrDb SINR at receiver. 114 | * \param mode TX mode used to transmit packet. 115 | * \return Probability of packet error. 116 | */ 117 | virtual double CalcPer (Ptr pkt, double sinrDb, LoraTxMode mode) = 0; 118 | 119 | /** 120 | * Register this type. 121 | * \return The TypeId. 122 | */ 123 | static TypeId GetTypeId (void); 124 | /** Clear all pointer references. */ 125 | virtual void Clear (void); 126 | 127 | protected: 128 | virtual void DoDispose (void); 129 | 130 | }; // class LoraPhyPer 131 | 132 | 133 | /** 134 | * 135 | * Interface for PHY event listener. 136 | * 137 | * A class which implements this interface may register with Phy object 138 | * to receive notification of TX/RX/CCA events 139 | */ 140 | class LoraPhyListener 141 | { 142 | public: 143 | /** Default destructor */ 144 | virtual ~LoraPhyListener () { } 145 | /** Called when LoraPhy begins receiving packet. */ 146 | virtual void NotifyRxStart (void) = 0; 147 | /** Called when LoraPhy finishes receiving packet without error. */ 148 | virtual void NotifyRxEndOk (void) = 0; 149 | /** Called when LoraPhy finishes receiving packet in error. */ 150 | virtual void NotifyRxEndError (void) = 0; 151 | /** Called when LoraPhy begins sensing channel is busy. */ 152 | virtual void NotifyCcaStart (void) = 0; 153 | /** Called when LoraPhy stops sensing channel is busy. */ 154 | virtual void NotifyCcaEnd (void) = 0; 155 | /** 156 | * Called when transmission starts from Phy object. 157 | * 158 | * \param duration Duration of transmission. 159 | */ 160 | virtual void NotifyTxStart (Time duration) = 0; 161 | 162 | }; // class LoraPhyListener 163 | 164 | /** 165 | * 166 | * Base class for LORA Phy models. 167 | */ 168 | class LoraPhy : public Object 169 | { 170 | public: 171 | /// Enum defining possible Phy states. 172 | enum State 173 | { 174 | IDLE, //!< Idle state. 175 | CCABUSY, //!< Channel busy. 176 | RX, //!< Receiving. 177 | TX, //!< Transmitting. 178 | SLEEP //!< Sleeping. 179 | }; 180 | 181 | /** 182 | * Packet received successfully callback function type. 183 | * 184 | * \pname{arg1} Packet received successfully. 185 | * \pname{arg2} SNIR of packet. 186 | * \pname{arg3} Mode of packet. 187 | */ 188 | typedef Callback, double, LoraTxMode> RxOkCallback; 189 | 190 | /** 191 | * Packet receive error callback function type. 192 | * 193 | * \pname{arg1} Packet received successfully. 194 | * \pname{arg2} SNIR of packet. 195 | */ 196 | typedef Callback, double > RxErrCallback; 197 | 198 | /** 199 | * TracedCallback signature for LoraPhy packet send/receive events. 200 | * 201 | * \param [in] pkt The packet. 202 | * \param [in] sinr The SINR. 203 | * \param [in] mode The channel mode. 204 | */ 205 | typedef void (* TracedCallback) 206 | (const Ptr pkt, const double sinr, const LoraTxMode mode); 207 | 208 | 209 | /** 210 | * Set the DeviceEnergyModel callback for LoraPhy device. 211 | * 212 | * \param callback The DeviceEnergyModel change state callback. 213 | */ 214 | virtual void SetEnergyModelCallback (DeviceEnergyModel::ChangeStateCallback callback) = 0; 215 | /** 216 | * Handle the energy depletion event. 217 | */ 218 | virtual void EnergyDepletionHandler (void) = 0; 219 | /** 220 | * Send a packet using a specific transmission mode. 221 | * 222 | * \param pkt Packet to transmit. 223 | * \param modeNum Index of mode in SupportedModes list to use for transmission. 224 | */ 225 | virtual void SendPacket (Ptr pkt, uint32_t modeNum) = 0; 226 | 227 | /** 228 | * Register a LoraPhyListener to be notified of common LoraPhy events. 229 | * 230 | * \param listener New listener to register. 231 | */ 232 | virtual void RegisterListener (LoraPhyListener *listener) = 0; 233 | 234 | /** 235 | * Packet arriving from channel: i.e. leading bit of packet has arrived. 236 | * 237 | * \param pkt Packet which is arriving. 238 | * \param rxPowerDb Signal power of incoming packet in dB re 1 uPa. 239 | * \param txMode Transmission mode defining modulation of incoming packet. 240 | * \param pdp Power delay profile of incoming packet. 241 | */ 242 | virtual void StartRxPacket (Ptr pkt, double rxPowerDb, LoraTxMode txMode, LoraPdp pdp) = 0; 243 | 244 | /** 245 | * Set the callback to be used when a packet is received without error. 246 | * 247 | * \param cb The callback. 248 | */ 249 | virtual void SetReceiveOkCallback (RxOkCallback cb) = 0; 250 | 251 | /** 252 | * Set the callback to be used when a packet is received with errors. 253 | * 254 | * \param cb The callback. 255 | */ 256 | virtual void SetReceiveErrorCallback (RxErrCallback cb) = 0; 257 | 258 | /** 259 | * Set the receiver gain. 260 | * 261 | * \param gain Gain added at receiver, in dB. 262 | */ 263 | virtual void SetRxGainDb (double gain) = 0; 264 | 265 | /** 266 | * Set the transmit power. 267 | * 268 | * \param txpwr Final output transmission power, in dB. 269 | */ 270 | virtual void SetTxPowerDb (double txpwr) = 0; 271 | 272 | /** 273 | * Set the minimum SINR threshold to receive a packet without errors. 274 | * 275 | * \deprecated See LoraPhyPer. 276 | * 277 | * \param thresh Threshold SINR for propper reception in dB re 1 uPa. 278 | */ 279 | virtual void SetRxThresholdDb (double thresh) = 0; 280 | 281 | /** 282 | * Set the threshold for detecting channel busy. 283 | * 284 | * \param thresh Signal power threshold at receiver. 285 | */ 286 | virtual void SetCcaThresholdDb (double thresh) = 0; 287 | 288 | /** 289 | * Get the receiver gain added to signal at receiver in dB. 290 | * 291 | * \return The gain. 292 | */ 293 | virtual double GetRxGainDb (void) = 0; 294 | 295 | /** 296 | * Get the current transmit power, in dB. 297 | * 298 | * \return The transmit power. 299 | */ 300 | virtual double GetTxPowerDb (void) = 0; 301 | 302 | /** 303 | * Get the minimum received signal strength required 304 | * to receive a packet without errors. 305 | * 306 | * \return The minimum required signal strength, in dB. 307 | */ 308 | virtual double GetRxThresholdDb (void) = 0; 309 | 310 | /** 311 | * Get the CCA threshold signal strength required to detect channel busy. 312 | * 313 | * \return The CCA threshold signal strength in dB. 314 | */ 315 | virtual double GetCcaThresholdDb (void) = 0; 316 | /** \return True if Phy is in SLEEP state. */ 317 | virtual bool IsStateSleep (void) = 0; 318 | /** \return True if Phy is in IDLE state. */ 319 | virtual bool IsStateIdle (void) = 0; 320 | /** \return True if Phy is neither IDLE nor SLEEP. */ 321 | virtual bool IsStateBusy (void) = 0; 322 | /** \return True if Phy is currently in receive mode. */ 323 | virtual bool IsStateRx (void) = 0; 324 | /** \return True if Phy is busy transmitting. */ 325 | virtual bool IsStateTx (void) = 0; 326 | /** \return True if Phy is in CCABUSY state. */ 327 | virtual bool IsStateCcaBusy (void) = 0; 328 | 329 | /** 330 | * Get the attached channel. 331 | * 332 | * \return The channel. 333 | */ 334 | virtual Ptr GetChannel (void) const = 0; 335 | 336 | /** 337 | * Get the device hosting this Phy. 338 | * 339 | * \return The net device. 340 | */ 341 | virtual Ptr GetDevice (void) = 0; 342 | 343 | /** 344 | * Attach to a channel. 345 | * 346 | * \param channel The channel to attach to. 347 | */ 348 | virtual void SetChannel (Ptr channel) = 0; 349 | 350 | /** 351 | * Set the device hosting this Phy. 352 | * 353 | * \param device The device. 354 | */ 355 | virtual void SetDevice (Ptr device) = 0; 356 | 357 | /** 358 | * Set the MAC forwarding messages to this Phy. 359 | * 360 | * \param mac The MAC. 361 | */ 362 | virtual void SetMac (Ptr mac) = 0; 363 | 364 | /** 365 | * Called when a transmission is beginning 366 | * on the attched transducer. 367 | * 368 | * \param packet Packet that is beginning transmission. 369 | * \param txPowerDb Transmit power of packet. 370 | * \param txMode Transmission mode of packet. 371 | */ 372 | virtual void NotifyTransStartTx (Ptr packet, double txPowerDb, LoraTxMode txMode) = 0; 373 | 374 | /** 375 | * Called when there has been a change in the 376 | * ammount of interference this node is experiencing 377 | * from other transmissions. 378 | */ 379 | virtual void NotifyIntChange (void) = 0; 380 | 381 | /** 382 | * Attach a transducer to this Phy. 383 | * 384 | * \param trans The transducer. 385 | */ 386 | virtual void SetTransducer (Ptr trans) = 0; 387 | 388 | /** 389 | * Get the attached transducer. 390 | * 391 | * \return The transducer. 392 | */ 393 | virtual Ptr GetTransducer (void) = 0; 394 | 395 | /** 396 | * Get the number of transmission modes supported by this Phy. 397 | * 398 | * \return The number modes. 399 | */ 400 | virtual uint32_t GetNModes (void) = 0; 401 | 402 | /** 403 | * Get a specific transmission mode. 404 | * 405 | * \param n The mode number. 406 | * \return The mode. 407 | */ 408 | virtual LoraTxMode GetMode (uint32_t n) = 0; 409 | 410 | /** 411 | * Get the packet currently being received. 412 | * 413 | * \warning Returns non-valid pointer if IsStateRx == false. 414 | * \return The packet. 415 | */ 416 | virtual Ptr GetPacketRx (void) const = 0; 417 | 418 | /** Clear all pointer references. */ 419 | virtual void Clear (void) = 0; 420 | 421 | /** 422 | * Set the Phy SLEEP mode. 423 | * 424 | * \param sleep SLEEP on or off. 425 | */ 426 | virtual void SetSleepMode (bool sleep) = 0; 427 | 428 | 429 | /** 430 | * Called when the transducer begins transmitting a packet. 431 | * 432 | * This fires a PhyTxBegin trace. Implemented for encapsulation 433 | * purposes. 434 | * 435 | * \param packet The packet. 436 | */ 437 | void NotifyTxBegin (Ptr packet); 438 | 439 | /** 440 | * Called when the transducer finishes transmitting a packet. 441 | * 442 | * This fires a PhyTxEnd trace. Implemented for encapsulation 443 | * purposes. 444 | * 445 | * \param packet The packet. 446 | */ 447 | void NotifyTxEnd (Ptr packet); 448 | 449 | /** 450 | * Called when the transducer attempts to transmit a new packet while 451 | * already transmitting a prior packet. 452 | * 453 | * This fires a PhyTxDrop trace. Implemented for encapsulation 454 | * purposes. 455 | * 456 | * \param packet The packet. 457 | */ 458 | void NotifyTxDrop (Ptr packet); 459 | 460 | /** 461 | * Called when the Phy begins to receive a packet. 462 | * 463 | * This fires a PhyRxBegin trace. Implemented for encapsulation 464 | * purposes. 465 | * 466 | * \param packet The packet. 467 | */ 468 | void NotifyRxBegin (Ptr packet); 469 | 470 | /** 471 | * Called when a packet is received without error. 472 | * 473 | * This fires a PhyRxEnd trace. Implemented for encapsulation 474 | * purposes. 475 | * 476 | * \param packet The packet. 477 | */ 478 | void NotifyRxEnd (Ptr packet); 479 | 480 | /** 481 | * Called when the Phy drops a packet. 482 | * 483 | * This fires a PhyRxDrop trace. Implemented for encapsulation 484 | * purposes. 485 | * 486 | * \param packet The packet. 487 | */ 488 | void NotifyRxDrop (Ptr packet); 489 | 490 | /** 491 | * Assign a fixed random variable stream number to the random variables 492 | * used by this model. Return the number of streams (possibly zero) that 493 | * have been assigned. 494 | * 495 | * \param stream First stream index to use. 496 | * \return The number of stream indices assigned by this model. 497 | */ 498 | virtual int64_t AssignStreams (int64_t stream) = 0; 499 | 500 | /** 501 | * Register this type. 502 | * \return The TypeId. 503 | */ 504 | static TypeId GetTypeId (void); 505 | 506 | private: 507 | /** 508 | * Trace source indicating a packet has begun transmitting 509 | * over the channel medium. 510 | * 511 | * \see class CallBackTraceSource 512 | */ 513 | ns3::TracedCallback > m_phyTxBeginTrace; 514 | 515 | /** 516 | * Trace source indicating a packet has been completely transmitted 517 | * over the channel. 518 | * 519 | * \see class CallBackTraceSource 520 | */ 521 | ns3::TracedCallback > m_phyTxEndTrace; 522 | 523 | /** 524 | * Trace source indicating a packet has been dropped by the device 525 | * during transmission. 526 | * 527 | * \see class CallBackTraceSource 528 | */ 529 | ns3::TracedCallback > m_phyTxDropTrace; 530 | 531 | /** 532 | * Trace source indicating a packet has begun being received 533 | * from the channel medium by the device. 534 | * 535 | * \see class CallBackTraceSource 536 | */ 537 | ns3::TracedCallback > m_phyRxBeginTrace; 538 | 539 | /** 540 | * Trace source indicating a packet has been completely received 541 | * from the channel medium by the device. 542 | * 543 | * \see class CallBackTraceSource 544 | */ 545 | ns3::TracedCallback > m_phyRxEndTrace; 546 | 547 | /** 548 | * Trace source indicating a packet has been dropped by the device 549 | * during reception. 550 | * 551 | * \see class CallBackTraceSource 552 | */ 553 | ns3::TracedCallback > m_phyRxDropTrace; 554 | 555 | }; // class LoraPhy 556 | 557 | } // namespace ns3 558 | 559 | #endif /* LORA_PHY_H */ 560 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------