Coverage for src / bluetooth_sig / gatt / characteristics / registered_user.py: 100%

23 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-03 16:41 +0000

1"""Registered User characteristic (0x2B37). 

2 

3Segmented user registration data. 

4 

5References: 

6 Bluetooth SIG User Data Service 1.0 

7""" 

8 

9from __future__ import annotations 

10 

11import msgspec 

12 

13from ..context import CharacteristicContext 

14from .base import BaseCharacteristic 

15from .utils import DataParser 

16 

17 

18class RegisteredUserData(msgspec.Struct, frozen=True, kw_only=True): 

19 """Parsed data from Registered User. 

20 

21 Attributes: 

22 segment_index: Segment index for multi-segment transfers. 

23 user_index: Index of the registered user. 

24 body: Variable-length user data body. 

25 

26 """ 

27 

28 segment_index: int 

29 user_index: int 

30 body: bytes = b"" 

31 

32 

33class RegisteredUserCharacteristic(BaseCharacteristic[RegisteredUserData]): 

34 """Registered User characteristic (0x2B37). 

35 

36 org.bluetooth.characteristic.registered_user 

37 

38 User registration data with segmentation support. Each notification 

39 carries a segment index, user index, and variable-length body. 

40 """ 

41 

42 min_length = 2 

43 allow_variable_length = True 

44 

45 def _decode_value( 

46 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True 

47 ) -> RegisteredUserData: 

48 """Parse Registered User data. 

49 

50 Format: Segment Index (uint8) + User Index (uint8) + Body (variable). 

51 """ 

52 segment_index = DataParser.parse_int8(data, 0, signed=False) 

53 user_index = DataParser.parse_int8(data, 1, signed=False) 

54 body = bytes(data[2:]) 

55 

56 return RegisteredUserData( 

57 segment_index=segment_index, 

58 user_index=user_index, 

59 body=body, 

60 ) 

61 

62 def _encode_value(self, data: RegisteredUserData) -> bytearray: 

63 """Encode Registered User data.""" 

64 result = bytearray() 

65 result.extend(DataParser.encode_int8(data.segment_index, signed=False)) 

66 result.extend(DataParser.encode_int8(data.user_index, signed=False)) 

67 result.extend(data.body) 

68 return result