blob: 296bc7ab3a53bc9858838f232c461e7efb48337b [file] [log] [blame]
Wei-Yu Chenad55cb82022-02-15 20:07:01 +08001# SPDX-FileCopyrightText: 2020 The Magma Authors.
2# SPDX-FileCopyrightText: 2022 Open Networking Foundation <support@opennetworking.org>
3#
4# SPDX-License-Identifier: BSD-3-Clause
Wei-Yu Chen49950b92021-11-08 19:19:18 +08005
6from enum import Enum
7from typing import Optional
8
9
10class DuplexMode(Enum):
11 FDD = 1
12 TDD = 2
13
14
15class LTEBandInfo:
16 """ Class for holding information related to LTE band.
17 Takes advantage of the following properties of LTE EARFCN assignment:
18 - EARFCN spacing within a band is always 0.1MHz
19 - 1:1 mapping between EARFCNDL and EARFCNUL (for FDD)
20 """
21
22 def __init__(
23 self, duplex_mode, earfcndl, start_freq_dl_mhz,
24 start_earfcnul=None, start_freq_ul_mhz=None,
25 ):
26 """
27 Inputs:
28 - Duplex mode - type = DuplexMode
29 - earfcndl - List/generator of integer EARFCNDLs in band, from lowest to
30 highest
31 - start_freq_dl_mhz - Frequency of lowest numbered EARFCNDL in band
32 (MHz)
33 - start_earfcnul - Lowest numbered EARFCNUL in band
34 (or None if band is TDD)
35 - start_freq_ul_mhz - Frequency of lowest numbered EARFCNUL in band
36 (MHz) (or None if band is TDD)
37 """
38 # Validate inputs
39 assert type(earfcndl) == list or type(earfcndl) == range
40 assert type(start_freq_dl_mhz) == int
41 assert type(duplex_mode) == DuplexMode
42 if duplex_mode == DuplexMode.FDD:
43 assert type(start_earfcnul) == int
44 assert type(start_freq_ul_mhz) == int
45 else:
46 assert start_earfcnul is None
47 assert start_freq_ul_mhz is None
48
49 # DuplexMode.TDD or DuplexMode.FDD
50 self.duplex_mode = duplex_mode
51 # Array of EARFCNDL values
52 self.earfcndl = earfcndl
53 # Array of DL frequencies in MHz, one per EARFCNDL
54 self.freq_mhz_dl = [
55 start_freq_dl_mhz + 0.1 * (earfcn - earfcndl[0])
56 for earfcn in earfcndl
57 ]
58
59 if duplex_mode == DuplexMode.FDD:
60 # Array of EARFCNUL values that map to EARFCNDL
61 self.earfcnul = range(
62 start_earfcnul,
63 start_earfcnul + len(earfcndl),
64 )
65 # Array of UL frequencies in MHz, one per EARFCNUL
66 self.freq_mhz_ul = [
67 start_freq_ul_mhz + 0.1 * (
68 earfcn -
69 self.earfcnul[0]
70 ) for earfcn in self.earfcnul
71 ]
72 else:
73 self.earfcnul = None
74 self.freq_mhz_ul = None
75
76
77# See, for example, http://niviuk.free.fr/lte_band.php for LTE band info
78LTE_BAND_INFO = {
79 # FDD bands
80 # duplex_mode, EARFCNDL, start_freq_dl, start_EARCNUL, start_freq_ul
81 1: LTEBandInfo(DuplexMode.FDD, range(0, 600), 2110, 18000, 1920),
82 2: LTEBandInfo(DuplexMode.FDD, range(600, 1200), 1930, 18600, 1850),
83 3: LTEBandInfo(DuplexMode.FDD, range(1200, 1950), 1805, 19200, 1710),
84 4: LTEBandInfo(DuplexMode.FDD, range(1950, 2400), 2110, 19950, 1710),
85 5: LTEBandInfo(DuplexMode.FDD, range(2400, 2649), 869, 20400, 824),
86 28: LTEBandInfo(DuplexMode.FDD, range(9210, 9660), 758, 27210, 703),
87 # TDD bands
88 # duplex_mode, EARFCNDL, start_freq_dl
89 33: LTEBandInfo(DuplexMode.TDD, range(36000, 36199), 1900),
90 34: LTEBandInfo(DuplexMode.TDD, range(36200, 36349), 2010),
91 35: LTEBandInfo(DuplexMode.TDD, range(36350, 36949), 1850),
92 36: LTEBandInfo(DuplexMode.TDD, range(36950, 37549), 1930),
93 37: LTEBandInfo(DuplexMode.TDD, range(37550, 37750), 1910),
94 38: LTEBandInfo(DuplexMode.TDD, range(37750, 38250), 2570),
95 39: LTEBandInfo(DuplexMode.TDD, range(38250, 38650), 1880),
96 40: LTEBandInfo(DuplexMode.TDD, range(38650, 39650), 2300),
97 41: LTEBandInfo(DuplexMode.TDD, range(39650, 41590), 2496),
98 42: LTEBandInfo(DuplexMode.TDD, range(41590, 43590), 3400),
99 43: LTEBandInfo(DuplexMode.TDD, range(43590, 45590), 3600),
100 44: LTEBandInfo(DuplexMode.TDD, range(45590, 46589), 703),
101 45: LTEBandInfo(DuplexMode.TDD, range(46590, 46789), 1447),
102 46: LTEBandInfo(DuplexMode.TDD, range(46790, 54539), 5150),
103 47: LTEBandInfo(DuplexMode.TDD, range(54540, 55239), 5855),
104 48: LTEBandInfo(DuplexMode.TDD, range(55240, 56740), 3550),
105 49: LTEBandInfo(DuplexMode.TDD, range(56740, 58239), 3550),
106 50: LTEBandInfo(DuplexMode.TDD, range(58240, 59089), 1432),
107 51: LTEBandInfo(DuplexMode.TDD, range(59090, 59139), 1427),
108 52: LTEBandInfo(DuplexMode.TDD, range(59140, 60139), 3300),
109 # For the band #53 start_freq_dl is float value which require some changes
110 # in the code
111 # 53: LTEBandInfo(DuplexMode.TDD, range(60140, 60254), 2483.5),
112
113}
114# TODO - add remaining FDD LTE bands
115
116
117def map_earfcndl_to_duplex_mode(earfcndl: int) -> Optional[DuplexMode]:
118 """
119 Returns None if we do not support the EARFCNDL
120 """
121 for band in LTE_BAND_INFO.keys():
122 if earfcndl in LTE_BAND_INFO[band].earfcndl:
123 return LTE_BAND_INFO[band].duplex_mode
124 return None
125
126
127def map_earfcndl_to_band_earfcnul_mode(earfcndl):
128 """ Inputs:
129 - EARFCNDL (integer)
130 Outputs:
131 - Band (integer)
132 - Mode (DuplexMode)
133 - EARFCNUL (integer - or None if TDD)
134 """
135 for band in LTE_BAND_INFO.keys():
136 if earfcndl in LTE_BAND_INFO[band].earfcndl:
137 if LTE_BAND_INFO[band].duplex_mode == DuplexMode.FDD:
138 index = LTE_BAND_INFO[band].earfcndl.index(earfcndl)
139 earfcnul = LTE_BAND_INFO[band].earfcnul[index]
140 else:
141 earfcnul = None
142
143 return band, LTE_BAND_INFO[band].duplex_mode, earfcnul
144
145 raise ValueError('EARFCNDL %d not found in LTE band info' % earfcndl)