Init commit for standalone enodebd
Change-Id: I88eeef5135dd7ba8551ddd9fb6a0695f5325337b
diff --git a/devices/device_utils.py b/devices/device_utils.py
new file mode 100644
index 0000000..3eb91cb
--- /dev/null
+++ b/devices/device_utils.py
@@ -0,0 +1,114 @@
+"""
+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.
+"""
+
+import re
+
+from exceptions import UnrecognizedEnodebError
+from logger import EnodebdLogger as logger
+
+
+class EnodebDeviceName:
+ """
+ This exists only to break a circular dependency. Otherwise there's no
+ point of having these names for the devices
+ """
+
+ BAICELLS = "Baicells"
+ BAICELLS_OLD = "Baicells Old"
+ BAICELLS_QAFA = "Baicells QAFA"
+ BAICELLS_QAFB = "Baicells QAFB"
+ BAICELLS_RTS = "Baicells RTS"
+ CAVIUM = "Cavium"
+ FREEDOMFI_ONE = "FREEDOMFI ONE"
+
+
+def get_device_name(device_oui: str, sw_version: str,) -> str:
+ """
+ Use the manufacturer organization unique identifier read during INFORM
+ to select the TR data model used for configuration and status reports
+
+ Qualcomm-based Baicells eNodeBs use a TR098-based model different
+ from the Intel units. The software version on the Qualcomm models
+ also further limits the model usable by that device.
+
+ Args:
+ device_oui: string, OUI representing device vendor
+ sw_version: string, firmware version of eNodeB device
+
+ Returns:
+ DataModel
+ """
+ if device_oui in {"34ED0B", "48BF74"}:
+ if sw_version.startswith("BaiBS_QAFB"):
+ return EnodebDeviceName.BAICELLS_QAFB
+ elif sw_version.startswith("BaiBS_QAFA"):
+ return EnodebDeviceName.BAICELLS_QAFA
+ elif sw_version.startswith("BaiStation_"):
+ # Note: to disable flag inversion completely (for all builds),
+ # set to BaiStation_V000R000C00B000SPC000
+ # Note: to force flag inversion always (for all builds),
+ # set to BaiStation_V999R999C99B999SPC999
+ invert_before_version = _parse_sw_version(
+ "BaiStation_V100R001C00B110SPC003"
+ )
+ if _parse_sw_version(sw_version) < invert_before_version:
+ return EnodebDeviceName.BAICELLS_OLD
+ return EnodebDeviceName.BAICELLS
+ elif sw_version.startswith("BaiBS_RTS_"):
+ return EnodebDeviceName.BAICELLS_RTS
+ elif sw_version.startswith("BaiBS_RTSH_"):
+ return EnodebDeviceName.BAICELLS_RTS
+ else:
+ raise UnrecognizedEnodebError(
+ "Device %s unsupported: Software (%s)" % (device_oui, sw_version),
+ )
+ elif device_oui in {"000FB7", "744D28"}:
+ return EnodebDeviceName.CAVIUM
+ elif device_oui == "000E8F":
+ return EnodebDeviceName.FREEDOMFI_ONE
+ else:
+ raise UnrecognizedEnodebError("Device %s unsupported" % device_oui)
+
+
+def _parse_sw_version(version_str):
+ """
+ Parse SW version string.
+ Expects format: BaiStation_V100R001C00B110SPC003
+ For the above version string, returns: [100, 1, 0, 110, 3]
+ Note: trailing characters (for dev builds) are ignored. Null is returned
+ for version strings that don't match the above format.
+ """
+ logger.debug("Got firmware version: %s", version_str)
+
+ version = re.findall(
+ r"BaiStation_V(\d{3})R(\d{3})C(\d{2})B(\d{3})SPC(\d{3})", version_str,
+ )
+ if not version:
+ return None
+ elif len(version) > 1:
+ logger.warning(
+ "SW version (%s) not formatted as expected", version_str,
+ )
+ version_int = []
+ for num in version[0]:
+ try:
+ version_int.append(int(num))
+ except ValueError:
+ logger.warning(
+ "SW version (%s) not formatted as expected", version_str,
+ )
+ return None
+
+ logger.debug("Parsed firmware version: %s", version_int)
+
+ return version_int