src/eric7/MicroPython/BluetoothDialogs/BluetoothAdvertisement.py

branch
eric7
changeset 10090
8be7dd9460c5
parent 10089
5fe9bfafbc7c
child 10439
21c28b0f9e41
--- a/src/eric7/MicroPython/BluetoothDialogs/BluetoothAdvertisement.py	Thu Jun 15 17:11:14 2023 +0200
+++ b/src/eric7/MicroPython/BluetoothDialogs/BluetoothAdvertisement.py	Thu Jun 15 19:13:51 2023 +0200
@@ -7,9 +7,13 @@
 Module implementing a class to parse and store the Bluetooth device advertisement data.
 """
 
+import contextlib
+import os
 import struct
 import uuid
 
+import yaml
+
 ADV_IND = 0
 ADV_DIRECT_IND = 1
 ADV_SCAN_IND = 2
@@ -28,15 +32,43 @@
 ADV_TYPE_SVC_DATA = 0x16
 ADV_TYPE_MANUFACTURER = 0xFF
 
-ManufacturerId = {
-    0x0006: "Microsoft",
-    0x004C: "Apple, Inc.",
-    0x0075: "Samsung Electronics Co. Ltd.",
-    0x0087: "Garmin International Inc.",
-    0x00E0: "Google",
-    0x0822: "adafruit industries",
-    0xC688: "Logitech, Inc.",
-}
+ManufacturerIDs = None
+ServiceIDs = None
+
+
+def _loadManufacturerIDs():
+    """
+    Function to load the manufacturer IDs.
+    """
+    global ManufacturerIDs
+
+    idsFile = os.path.join(
+        os.path.dirname(__file__), "data", "company_identifiers.yaml"
+    )
+    with contextlib.suppress(OSError):
+        with open(idsFile, "r") as f:
+            idsDict = yaml.safe_load(f)
+
+        ManufacturerIDs = {
+            entry["value"]: entry["name"] for entry in idsDict["company_identifiers"]
+        }
+
+
+def _loadServiceUUIDs():
+    """
+    Function to load the service UUIDs.
+    """
+    global ServiceIDs
+
+    ServiceIDs = {}
+
+    for uuidFilename in ("member_uuids.yaml", "sdo_uuids.yaml", "service_uuids.yaml"):
+        uuidFilepath = os.path.join(os.path.dirname(__file__), "data", uuidFilename)
+        with contextlib.suppress(OSError):
+            with open(uuidFilepath, "r") as f:
+                uuidDict = yaml.safe_load(f)
+
+            ServiceIDs.update({u["uuid"]: u["name"] for u in uuidDict["uuids"]})
 
 
 class BluetoothAdvertisement:
@@ -206,34 +238,39 @@
         """
         Public method to get the service IDs.
 
-        @return list of tuples containing the advertised service ID and a
-            flag indicating a complete ID
+        @return list of tuples containing the advertised service ID, the associated
+            service name (if available) and a flag indicating a complete ID
         @rtype list of tuple of (str, bool)
         """
+        if ServiceIDs is None:
+            _loadServiceUUIDs()
+
         result = []
 
         for u in self.__decodeField(ADV_TYPE_UUID16_INCOMPLETE):
             for v in self.__splitBytes(u, 2):
-                result.append((hex(struct.unpack("<H", v)[0]), False))
+                uid = struct.unpack("<H", v)[0]
+                result.append((hex(uid), ServiceIDs.get(uid, ""), False))
         for u in self.__decodeField(ADV_TYPE_UUID16_COMPLETE):
             for v in self.__splitBytes(u, 2):
-                result.append((hex(struct.unpack("<H", v)[0]), True))
+                uid = struct.unpack("<H", v)[0]
+                result.append((hex(uid), ServiceIDs.get(uid, ""), False))
 
         for u in self.__decodeField(ADV_TYPE_UUID32_INCOMPLETE):
             for v in self.__splitBytes(u, 4):
-                result.append((hex(struct.unpack("<I", v)), False))
+                result.append((hex(struct.unpack("<I", v)), "", False))
         for u in self.__decodeField(ADV_TYPE_UUID32_COMPLETE):
             for v in self.__splitBytes(u, 4):
-                result.append((hex(struct.unpack("<I", v)), True))
+                result.append((hex(struct.unpack("<I", v)), "", True))
 
         for u in self.__decodeField(ADV_TYPE_UUID128_INCOMPLETE):
             for v in self.__splitBytes(u, 16):
                 uid = uuid.UUID(bytes=bytes(reversed(v)))
-                result.append((str(uid), False))
+                result.append((str(uid), "", False))
         for u in self.__decodeField(ADV_TYPE_UUID128_COMPLETE):
             for v in self.__splitBytes(u, 16):
                 uid = uuid.UUID(bytes=bytes(reversed(v)))
-                result.append((str(uid), True))
+                result.append((str(uid), "", True))
 
         return result
 
@@ -250,6 +287,9 @@
             name
         @rtype tuple of (int, bytes, str)
         """
+        if ManufacturerIDs is None:
+            _loadManufacturerIDs()
+
         result = []
         for u in self.__decodeField(ADV_TYPE_MANUFACTURER):
             if len(u) < 2:
@@ -257,7 +297,7 @@
 
             m = struct.unpack("<H", u[0:2])[0]
             if filterId is None or m == filterId:
-                name = ManufacturerId.get(m, "") if withName else None
+                name = ManufacturerIDs.get(m, "") if withName else None
                 result.append((m, u[2:], name))
         return result
 

eric ide

mercurial