"""Bluetooth Class of Device decoder""" class BluetoothClassDecoder: """Decode Bluetooth Class of Device (CoD) codes""" MAJOR_DEVICE_CLASSES = { 0: "Miscellaneous", 1: "Computer", 2: "Phone", 3: "LAN/Network", 4: "Audio/Video", 5: "Peripheral", 6: "Imaging", 7: "Wearable", 8: "Toy", 9: "Health", 31: "Uncategorized" } MINOR_COMPUTER = { 0: "Uncategorized", 1: "Desktop", 2: "Server", 3: "Laptop", 4: "Handheld/PDA", 5: "Palm/PDA", 6: "Wearable" } MINOR_PHONE = { 0: "Uncategorized", 1: "Cellular", 2: "Cordless", 3: "Smartphone", 4: "Modem/Gateway", 5: "ISDN" } MINOR_AV = { 0: "Uncategorized", 1: "Wearable Headset", 2: "Hands-free", 4: "Microphone", 5: "Loudspeaker", 6: "Headphones", 7: "Portable Audio", 8: "Car Audio", 9: "Set-top Box", 10: "HiFi Audio", 11: "VCR", 12: "Video Camera", 13: "Camcorder", 14: "Video Monitor", 15: "Video Display and Loudspeaker", 16: "Video Conferencing", 18: "Gaming/Toy" } MINOR_PERIPHERAL = { 0: "Uncategorized", 1: "Keyboard", 2: "Pointing Device", 3: "Combo Keyboard/Pointing" } MINOR_IMAGING = { 1: "Display", 2: "Camera", 4: "Scanner", 8: "Printer" } MINOR_WEARABLE = { 1: "Wristwatch", 2: "Pager", 3: "Jacket", 4: "Helmet", 5: "Glasses" } @classmethod def decode(cls, class_hex: str) -> tuple[str, str]: """ Decode Class of Device hex string into device type and category. Args: class_hex: Hex string of Class of Device (e.g., "0x240404") Returns: Tuple of (major_class, minor_class) """ try: cod = int(class_hex, 16) major = (cod >> 8) & 0x1F minor = (cod >> 2) & 0x3F major_str = cls.MAJOR_DEVICE_CLASSES.get(major, f"Unknown ({major})") minor_str = "" if major == 1: minor_str = cls.MINOR_COMPUTER.get(minor, f"Unknown ({minor})") elif major == 2: minor_str = cls.MINOR_PHONE.get(minor, f"Unknown ({minor})") elif major == 4: minor_str = cls.MINOR_AV.get(minor, f"Unknown ({minor})") elif major == 5: minor_str = cls.MINOR_PERIPHERAL.get(minor & 0x03, f"Unknown ({minor})") elif major == 6: minor_str = cls.MINOR_IMAGING.get(minor & 0x0F, f"Unknown ({minor})") elif major == 7: minor_str = cls.MINOR_WEARABLE.get(minor, f"Unknown ({minor})") else: minor_str = str(minor) if minor else "" return major_str, minor_str except (ValueError, TypeError): return "Unknown", "" @classmethod def decode_to_string(cls, class_hex: str) -> str: """Decode to a single descriptive string""" major, minor = cls.decode(class_hex) if minor: return f"{major} ({minor})" return major