Init commit for standalone enodebd
Change-Id: I88eeef5135dd7ba8551ddd9fb6a0695f5325337b
diff --git a/lte_utils.py b/lte_utils.py
new file mode 100644
index 0000000..94a96d3
--- /dev/null
+++ b/lte_utils.py
@@ -0,0 +1,153 @@
+"""
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+from enum import Enum
+from typing import Optional
+
+
+class DuplexMode(Enum):
+ FDD = 1
+ TDD = 2
+
+
+class LTEBandInfo:
+ """ Class for holding information related to LTE band.
+ Takes advantage of the following properties of LTE EARFCN assignment:
+ - EARFCN spacing within a band is always 0.1MHz
+ - 1:1 mapping between EARFCNDL and EARFCNUL (for FDD)
+ """
+
+ def __init__(
+ self, duplex_mode, earfcndl, start_freq_dl_mhz,
+ start_earfcnul=None, start_freq_ul_mhz=None,
+ ):
+ """
+ Inputs:
+ - Duplex mode - type = DuplexMode
+ - earfcndl - List/generator of integer EARFCNDLs in band, from lowest to
+ highest
+ - start_freq_dl_mhz - Frequency of lowest numbered EARFCNDL in band
+ (MHz)
+ - start_earfcnul - Lowest numbered EARFCNUL in band
+ (or None if band is TDD)
+ - start_freq_ul_mhz - Frequency of lowest numbered EARFCNUL in band
+ (MHz) (or None if band is TDD)
+ """
+ # Validate inputs
+ assert type(earfcndl) == list or type(earfcndl) == range
+ assert type(start_freq_dl_mhz) == int
+ assert type(duplex_mode) == DuplexMode
+ if duplex_mode == DuplexMode.FDD:
+ assert type(start_earfcnul) == int
+ assert type(start_freq_ul_mhz) == int
+ else:
+ assert start_earfcnul is None
+ assert start_freq_ul_mhz is None
+
+ # DuplexMode.TDD or DuplexMode.FDD
+ self.duplex_mode = duplex_mode
+ # Array of EARFCNDL values
+ self.earfcndl = earfcndl
+ # Array of DL frequencies in MHz, one per EARFCNDL
+ self.freq_mhz_dl = [
+ start_freq_dl_mhz + 0.1 * (earfcn - earfcndl[0])
+ for earfcn in earfcndl
+ ]
+
+ if duplex_mode == DuplexMode.FDD:
+ # Array of EARFCNUL values that map to EARFCNDL
+ self.earfcnul = range(
+ start_earfcnul,
+ start_earfcnul + len(earfcndl),
+ )
+ # Array of UL frequencies in MHz, one per EARFCNUL
+ self.freq_mhz_ul = [
+ start_freq_ul_mhz + 0.1 * (
+ earfcn -
+ self.earfcnul[0]
+ ) for earfcn in self.earfcnul
+ ]
+ else:
+ self.earfcnul = None
+ self.freq_mhz_ul = None
+
+
+# See, for example, http://niviuk.free.fr/lte_band.php for LTE band info
+LTE_BAND_INFO = {
+ # FDD bands
+ # duplex_mode, EARFCNDL, start_freq_dl, start_EARCNUL, start_freq_ul
+ 1: LTEBandInfo(DuplexMode.FDD, range(0, 600), 2110, 18000, 1920),
+ 2: LTEBandInfo(DuplexMode.FDD, range(600, 1200), 1930, 18600, 1850),
+ 3: LTEBandInfo(DuplexMode.FDD, range(1200, 1950), 1805, 19200, 1710),
+ 4: LTEBandInfo(DuplexMode.FDD, range(1950, 2400), 2110, 19950, 1710),
+ 5: LTEBandInfo(DuplexMode.FDD, range(2400, 2649), 869, 20400, 824),
+ 28: LTEBandInfo(DuplexMode.FDD, range(9210, 9660), 758, 27210, 703),
+ # TDD bands
+ # duplex_mode, EARFCNDL, start_freq_dl
+ 33: LTEBandInfo(DuplexMode.TDD, range(36000, 36199), 1900),
+ 34: LTEBandInfo(DuplexMode.TDD, range(36200, 36349), 2010),
+ 35: LTEBandInfo(DuplexMode.TDD, range(36350, 36949), 1850),
+ 36: LTEBandInfo(DuplexMode.TDD, range(36950, 37549), 1930),
+ 37: LTEBandInfo(DuplexMode.TDD, range(37550, 37750), 1910),
+ 38: LTEBandInfo(DuplexMode.TDD, range(37750, 38250), 2570),
+ 39: LTEBandInfo(DuplexMode.TDD, range(38250, 38650), 1880),
+ 40: LTEBandInfo(DuplexMode.TDD, range(38650, 39650), 2300),
+ 41: LTEBandInfo(DuplexMode.TDD, range(39650, 41590), 2496),
+ 42: LTEBandInfo(DuplexMode.TDD, range(41590, 43590), 3400),
+ 43: LTEBandInfo(DuplexMode.TDD, range(43590, 45590), 3600),
+ 44: LTEBandInfo(DuplexMode.TDD, range(45590, 46589), 703),
+ 45: LTEBandInfo(DuplexMode.TDD, range(46590, 46789), 1447),
+ 46: LTEBandInfo(DuplexMode.TDD, range(46790, 54539), 5150),
+ 47: LTEBandInfo(DuplexMode.TDD, range(54540, 55239), 5855),
+ 48: LTEBandInfo(DuplexMode.TDD, range(55240, 56740), 3550),
+ 49: LTEBandInfo(DuplexMode.TDD, range(56740, 58239), 3550),
+ 50: LTEBandInfo(DuplexMode.TDD, range(58240, 59089), 1432),
+ 51: LTEBandInfo(DuplexMode.TDD, range(59090, 59139), 1427),
+ 52: LTEBandInfo(DuplexMode.TDD, range(59140, 60139), 3300),
+ # For the band #53 start_freq_dl is float value which require some changes
+ # in the code
+ # 53: LTEBandInfo(DuplexMode.TDD, range(60140, 60254), 2483.5),
+
+}
+# TODO - add remaining FDD LTE bands
+
+
+def map_earfcndl_to_duplex_mode(earfcndl: int) -> Optional[DuplexMode]:
+ """
+ Returns None if we do not support the EARFCNDL
+ """
+ for band in LTE_BAND_INFO.keys():
+ if earfcndl in LTE_BAND_INFO[band].earfcndl:
+ return LTE_BAND_INFO[band].duplex_mode
+ return None
+
+
+def map_earfcndl_to_band_earfcnul_mode(earfcndl):
+ """ Inputs:
+ - EARFCNDL (integer)
+ Outputs:
+ - Band (integer)
+ - Mode (DuplexMode)
+ - EARFCNUL (integer - or None if TDD)
+ """
+ for band in LTE_BAND_INFO.keys():
+ if earfcndl in LTE_BAND_INFO[band].earfcndl:
+ if LTE_BAND_INFO[band].duplex_mode == DuplexMode.FDD:
+ index = LTE_BAND_INFO[band].earfcndl.index(earfcndl)
+ earfcnul = LTE_BAND_INFO[band].earfcnul[index]
+ else:
+ earfcnul = None
+
+ return band, LTE_BAND_INFO[band].duplex_mode, earfcnul
+
+ raise ValueError('EARFCNDL %d not found in LTE band info' % earfcndl)