Coverage for src / bluetooth_sig / gatt / characteristics / pnp_id.py: 100%
27 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
1"""PnP ID characteristic implementation."""
3from __future__ import annotations
5from enum import IntEnum
7import msgspec
9from ..context import CharacteristicContext
10from .base import BaseCharacteristic
11from .utils import DataParser
14class VendorIdSource(IntEnum):
15 """Vendor ID Source enumeration.
17 Defines the namespace for the Vendor ID field.
18 """
20 RESERVED_0 = 0 # Reserved for Future Use
21 BLUETOOTH_SIG = 1 # Bluetooth SIG Assigned Company Identifier
22 USB_IF = 2 # USB Implementer's Forum assigned Vendor ID
25class PnpIdData(msgspec.Struct, frozen=True, kw_only=True):
26 """PnP ID data.
28 Attributes:
29 vendor_id_source: Vendor ID source namespace
30 vendor_id: Vendor ID from the specified namespace
31 product_id: Manufacturer managed identifier
32 product_version: Manufacturer managed version
33 """
35 vendor_id_source: VendorIdSource
36 vendor_id: int
37 product_id: int
38 product_version: int
41class PnpIdCharacteristic(BaseCharacteristic[PnpIdData]):
42 """PnP ID characteristic (0x2A50).
44 org.bluetooth.characteristic.pnp_id
46 Contains PnP ID information (7 bytes).
47 """
49 _manual_value_type = "PnpIdData"
50 expected_length = 7
52 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> PnpIdData:
53 """Parse PnP ID.
55 Args:
56 data: Raw bytearray (7 bytes).
57 ctx: Optional CharacteristicContext.
59 Returns:
60 PnpIdData with vendor_id_source, vendor_id, product_id, product_version.
61 """
62 return PnpIdData(
63 vendor_id_source=VendorIdSource(data[0]),
64 vendor_id=DataParser.parse_int16(data, 1, signed=False),
65 product_id=DataParser.parse_int16(data, 3, signed=False),
66 product_version=DataParser.parse_int16(data, 5, signed=False),
67 )
69 def _encode_value(self, data: PnpIdData) -> bytearray:
70 """Encode PnP ID.
72 Args:
73 data: PnpIdData to encode
75 Returns:
76 Encoded bytes
77 """
78 result = bytearray()
79 result.append(int(data.vendor_id_source))
80 result.extend(DataParser.encode_int16(data.vendor_id, signed=False))
81 result.extend(DataParser.encode_int16(data.product_id, signed=False))
82 result.extend(DataParser.encode_int16(data.product_version, signed=False))
83 return result