blob: 3eb91cb17ffcc4795afcad749d6f4335e5607eea [file] [log] [blame]
Wei-Yu Chen49950b92021-11-08 19:19:18 +08001"""
2Copyright 2020 The Magma Authors.
3
4This source code is licensed under the BSD-style license found in the
5LICENSE file in the root directory of this source tree.
6
7Unless required by applicable law or agreed to in writing, software
8distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions and
11limitations under the License.
12"""
13
14import re
15
16from exceptions import UnrecognizedEnodebError
17from logger import EnodebdLogger as logger
18
19
20class EnodebDeviceName:
21 """
22 This exists only to break a circular dependency. Otherwise there's no
23 point of having these names for the devices
24 """
25
26 BAICELLS = "Baicells"
27 BAICELLS_OLD = "Baicells Old"
28 BAICELLS_QAFA = "Baicells QAFA"
29 BAICELLS_QAFB = "Baicells QAFB"
30 BAICELLS_RTS = "Baicells RTS"
31 CAVIUM = "Cavium"
32 FREEDOMFI_ONE = "FREEDOMFI ONE"
33
34
35def get_device_name(device_oui: str, sw_version: str,) -> str:
36 """
37 Use the manufacturer organization unique identifier read during INFORM
38 to select the TR data model used for configuration and status reports
39
40 Qualcomm-based Baicells eNodeBs use a TR098-based model different
41 from the Intel units. The software version on the Qualcomm models
42 also further limits the model usable by that device.
43
44 Args:
45 device_oui: string, OUI representing device vendor
46 sw_version: string, firmware version of eNodeB device
47
48 Returns:
49 DataModel
50 """
51 if device_oui in {"34ED0B", "48BF74"}:
52 if sw_version.startswith("BaiBS_QAFB"):
53 return EnodebDeviceName.BAICELLS_QAFB
54 elif sw_version.startswith("BaiBS_QAFA"):
55 return EnodebDeviceName.BAICELLS_QAFA
56 elif sw_version.startswith("BaiStation_"):
57 # Note: to disable flag inversion completely (for all builds),
58 # set to BaiStation_V000R000C00B000SPC000
59 # Note: to force flag inversion always (for all builds),
60 # set to BaiStation_V999R999C99B999SPC999
61 invert_before_version = _parse_sw_version(
62 "BaiStation_V100R001C00B110SPC003"
63 )
64 if _parse_sw_version(sw_version) < invert_before_version:
65 return EnodebDeviceName.BAICELLS_OLD
66 return EnodebDeviceName.BAICELLS
67 elif sw_version.startswith("BaiBS_RTS_"):
68 return EnodebDeviceName.BAICELLS_RTS
69 elif sw_version.startswith("BaiBS_RTSH_"):
70 return EnodebDeviceName.BAICELLS_RTS
71 else:
72 raise UnrecognizedEnodebError(
73 "Device %s unsupported: Software (%s)" % (device_oui, sw_version),
74 )
75 elif device_oui in {"000FB7", "744D28"}:
76 return EnodebDeviceName.CAVIUM
77 elif device_oui == "000E8F":
78 return EnodebDeviceName.FREEDOMFI_ONE
79 else:
80 raise UnrecognizedEnodebError("Device %s unsupported" % device_oui)
81
82
83def _parse_sw_version(version_str):
84 """
85 Parse SW version string.
86 Expects format: BaiStation_V100R001C00B110SPC003
87 For the above version string, returns: [100, 1, 0, 110, 3]
88 Note: trailing characters (for dev builds) are ignored. Null is returned
89 for version strings that don't match the above format.
90 """
91 logger.debug("Got firmware version: %s", version_str)
92
93 version = re.findall(
94 r"BaiStation_V(\d{3})R(\d{3})C(\d{2})B(\d{3})SPC(\d{3})", version_str,
95 )
96 if not version:
97 return None
98 elif len(version) > 1:
99 logger.warning(
100 "SW version (%s) not formatted as expected", version_str,
101 )
102 version_int = []
103 for num in version[0]:
104 try:
105 version_int.append(int(num))
106 except ValueError:
107 logger.warning(
108 "SW version (%s) not formatted as expected", version_str,
109 )
110 return None
111
112 logger.debug("Parsed firmware version: %s", version_int)
113
114 return version_int