Coverage for src / bluetooth_sig / types / address.py: 89%

18 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-18 11:17 +0000

1"""Bluetooth address utilities. 

2 

3This module provides utilities for working with Bluetooth device addresses 

4(BD_ADDR), commonly represented as 48-bit MAC addresses. 

5""" 

6 

7from __future__ import annotations 

8 

9from bluetooth_sig.gatt.constants import SIZE_UINT48 

10 

11 

12def mac_address_to_bytes(mac_address: str) -> bytes: 

13 """Convert a MAC address string to 6 bytes. 

14 

15 Args: 

16 mac_address: MAC address string (e.g., "AA:BB:CC:DD:EE:FF") 

17 

18 Returns: 

19 6-byte representation of the MAC address 

20 

21 Raises: 

22 ValueError: If MAC address format is invalid 

23 

24 Example:: 

25 >>> mac_address_to_bytes("AA:BB:CC:DD:EE:FF").hex() 

26 'aabbccddeeff' 

27 """ 

28 # Remove colons/dashes and convert to bytes 

29 cleaned = mac_address.replace(":", "").replace("-", "") 

30 if len(cleaned) != (SIZE_UINT48 * 2): # 6 bytes = 12 hex characters 

31 msg = f"Invalid MAC address format: {mac_address}" 

32 raise ValueError(msg) 

33 

34 try: 

35 return bytes.fromhex(cleaned) 

36 except ValueError as err: 

37 msg = f"Invalid MAC address hex characters: {mac_address}" 

38 raise ValueError(msg) from err 

39 

40 

41def bytes_to_mac_address(data: bytes | bytearray) -> str: 

42 """Convert 6 bytes to a MAC address string. 

43 

44 Args: 

45 data: 6-byte representation of MAC address 

46 

47 Returns: 

48 MAC address string with colon separators (e.g., "AA:BB:CC:DD:EE:FF") 

49 

50 Raises: 

51 ValueError: If data is not exactly 6 bytes 

52 

53 Example:: 

54 >>> bytes_to_mac_address(bytes.fromhex("aabbccddeeff")) 

55 'AA:BB:CC:DD:EE:FF' 

56 """ 

57 if len(data) != SIZE_UINT48: 

58 msg = f"MAC address must be exactly 6 bytes, got {len(data)}" 

59 raise ValueError(msg) 

60 return ":".join(f"{b:02X}" for b in data) 

61 

62 

63__all__ = ["bytes_to_mac_address", "mac_address_to_bytes"]