Coverage for src / bluetooth_sig / types / advertising / ad_structures.py: 93%

89 statements  

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

1"""Parsed AD structure categories. 

2 

3Organized by Bluetooth Core Specification Supplement AD type categories. 

4""" 

5 

6from __future__ import annotations 

7 

8import msgspec 

9 

10from bluetooth_sig.types.advertising.channel_map_update import ChannelMapUpdateIndication 

11from bluetooth_sig.types.advertising.features import LEFeatures 

12from bluetooth_sig.types.advertising.flags import BLEAdvertisingFlags 

13from bluetooth_sig.types.advertising.indoor_positioning import IndoorPositioningData 

14from bluetooth_sig.types.advertising.pdu import BLEAdvertisingPDU 

15from bluetooth_sig.types.advertising.three_d_information import ThreeDInformationData 

16from bluetooth_sig.types.advertising.transport_discovery import TransportDiscoveryData 

17from bluetooth_sig.types.appearance import AppearanceData 

18from bluetooth_sig.types.company import ManufacturerData 

19from bluetooth_sig.types.mesh import ( 

20 MeshMessage, 

21 ProvisioningBearerData, 

22 SecureNetworkBeacon, 

23 UnprovisionedDeviceBeacon, 

24) 

25from bluetooth_sig.types.registry.class_of_device import ClassOfDeviceInfo 

26from bluetooth_sig.types.uri import URIData 

27from bluetooth_sig.types.uuid import BluetoothUUID 

28 

29 

30class ConnectionIntervalRange(msgspec.Struct, kw_only=True): 

31 """Peripheral preferred connection interval range (Core Spec Supplement, Part A, Section 1.9). 

32 

33 Attributes: 

34 min_interval: Minimum connection interval in 1.25ms units 

35 max_interval: Maximum connection interval in 1.25ms units 

36 min_interval_ms: Minimum connection interval in milliseconds 

37 max_interval_ms: Maximum connection interval in milliseconds 

38 """ 

39 

40 INTERVAL_UNIT_MS: float = 1.25 # Connection interval unit in milliseconds 

41 

42 min_interval: int # In 1.25ms units 

43 max_interval: int # In 1.25ms units 

44 

45 @property 

46 def min_interval_ms(self) -> float: 

47 """Get minimum interval in milliseconds.""" 

48 return self.min_interval * self.INTERVAL_UNIT_MS 

49 

50 @property 

51 def max_interval_ms(self) -> float: 

52 """Get maximum interval in milliseconds.""" 

53 return self.max_interval * self.INTERVAL_UNIT_MS 

54 

55 

56class CoreAdvertisingData(msgspec.Struct, kw_only=True): 

57 """Core advertising data - device identification and services. 

58 

59 Attributes: 

60 manufacturer_data: Manufacturer-specific data keyed by company ID. 

61 Each entry contains resolved company info and payload bytes. 

62 service_uuids: List of advertised service UUIDs 

63 service_data: Service-specific data keyed by service UUID 

64 solicited_service_uuids: List of service UUIDs the device is seeking 

65 local_name: Device's local name (complete or shortened) 

66 uri_data: Parsed URI with scheme info from UriSchemesRegistry 

67 """ 

68 

69 manufacturer_data: dict[int, ManufacturerData] = msgspec.field(default_factory=dict) 

70 service_uuids: list[BluetoothUUID] = msgspec.field(default_factory=list) 

71 service_data: dict[BluetoothUUID, bytes] = msgspec.field(default_factory=dict) 

72 solicited_service_uuids: list[BluetoothUUID] = msgspec.field(default_factory=list) 

73 local_name: str = "" 

74 uri_data: URIData | None = None 

75 

76 

77class DeviceProperties(msgspec.Struct, kw_only=True): 

78 """Device capability and appearance properties. 

79 

80 Attributes: 

81 flags: BLE advertising flags (discoverable mode, capabilities) 

82 appearance: Device appearance category and subcategory 

83 tx_power: Transmission power level in dBm 

84 le_role: LE role (peripheral, central, etc.) 

85 le_supported_features: LE supported features with property accessors 

86 class_of_device: Classic Bluetooth Class of Device value 

87 class_of_device_info: Parsed Class of Device information 

88 """ 

89 

90 flags: BLEAdvertisingFlags = BLEAdvertisingFlags(0) 

91 appearance: AppearanceData | None = None 

92 tx_power: int = 0 

93 le_role: int | None = None 

94 le_supported_features: LEFeatures | None = None 

95 class_of_device: ClassOfDeviceInfo | None = None 

96 

97 

98class DirectedAdvertisingData(msgspec.Struct, kw_only=True): 

99 """Directed advertising and timing parameters. 

100 

101 These AD types specify target devices and advertising timing. 

102 

103 Attributes: 

104 public_target_address: List of public target addresses (AD 0x17) 

105 random_target_address: List of random target addresses (AD 0x18) 

106 le_bluetooth_device_address: LE Bluetooth device address (AD 0x1B) 

107 advertising_interval: Advertising interval in 0.625ms units (AD 0x1A) 

108 advertising_interval_long: Long advertising interval (AD 0x2F) 

109 peripheral_connection_interval_range: Preferred connection interval with min/max (AD 0x12) 

110 """ 

111 

112 public_target_address: list[str] = msgspec.field(default_factory=list) 

113 random_target_address: list[str] = msgspec.field(default_factory=list) 

114 le_bluetooth_device_address: str = "" 

115 advertising_interval: int | None = None 

116 advertising_interval_long: int | None = None 

117 peripheral_connection_interval_range: ConnectionIntervalRange | None = None 

118 

119 

120class OOBSecurityData(msgspec.Struct, kw_only=True): 

121 """Out-of-Band (OOB) security data advertised for pairing. 

122 

123 These AD types provide security material for OOB pairing mechanisms. 

124 

125 Attributes: 

126 simple_pairing_hash_c: Simple Pairing Hash C-192/C-256 (AD 0x0E, 0x1D) 

127 simple_pairing_randomizer_r: Simple Pairing Randomizer R-192/R-256 (AD 0x0F, 0x1E) 

128 secure_connections_confirmation: LE SC Confirmation Value (AD 0x22) 

129 secure_connections_random: LE SC Random Value (AD 0x23) 

130 security_manager_tk_value: Security Manager TK Value (AD 0x10) 

131 security_manager_oob_flags: SM Out of Band Flags (AD 0x11) 

132 """ 

133 

134 simple_pairing_hash_c: bytes = b"" 

135 simple_pairing_randomizer_r: bytes = b"" 

136 secure_connections_confirmation: bytes = b"" 

137 secure_connections_random: bytes = b"" 

138 security_manager_tk_value: bytes = b"" 

139 security_manager_oob_flags: bytes = b"" 

140 

141 

142class LocationAndSensingData(msgspec.Struct, kw_only=True): 

143 """Location, positioning, and sensing related data. 

144 

145 Attributes: 

146 indoor_positioning: Parsed Indoor Positioning AD (0x25), or ``None`` if absent. 

147 three_d_information: Parsed 3D Information AD (0x3D), or ``None`` if absent. 

148 transport_discovery_data: Parsed Transport Discovery AD (0x26), or ``None`` if absent. 

149 channel_map_update_indication: Parsed Channel Map Update AD (0x28), or ``None`` if absent. 

150 """ 

151 

152 indoor_positioning: IndoorPositioningData | None = None 

153 three_d_information: ThreeDInformationData | None = None 

154 transport_discovery_data: TransportDiscoveryData | None = None 

155 channel_map_update_indication: ChannelMapUpdateIndication | None = None 

156 

157 

158class MeshAndBroadcastData(msgspec.Struct, kw_only=True): 

159 """Bluetooth Mesh and audio broadcast related data. 

160 

161 Attributes: 

162 mesh_message: Parsed Mesh Network PDU message 

163 secure_network_beacon: Parsed Secure Network Beacon (provisioned nodes) 

164 unprovisioned_device_beacon: Parsed Unprovisioned Device Beacon 

165 provisioning_bearer: Parsed Provisioning Bearer (PB-ADV) data 

166 broadcast_name: Broadcast name for LE Audio 

167 broadcast_code: Broadcast Code for encrypted audio 

168 biginfo: BIG Info for Broadcast Isochronous Groups 

169 periodic_advertising_response_timing: Periodic Advertising Response Timing Info 

170 electronic_shelf_label: Electronic Shelf Label data 

171 

172 """ 

173 

174 mesh_message: MeshMessage | None = None 

175 secure_network_beacon: SecureNetworkBeacon | None = None 

176 unprovisioned_device_beacon: UnprovisionedDeviceBeacon | None = None 

177 provisioning_bearer: ProvisioningBearerData | None = None 

178 broadcast_name: str = "" 

179 broadcast_code: bytes = b"" 

180 biginfo: bytes = b"" 

181 periodic_advertising_response_timing: bytes = b"" 

182 electronic_shelf_label: bytes = b"" 

183 

184 

185class SecurityData(msgspec.Struct, kw_only=True): 

186 """Security and encryption related advertising data. 

187 

188 Attributes: 

189 encrypted_advertising_data: Encrypted Advertising Data 

190 resolvable_set_identifier: Resolvable Set Identifier 

191 """ 

192 

193 encrypted_advertising_data: bytes = b"" 

194 resolvable_set_identifier: bytes = b"" 

195 

196 

197class ExtendedAdvertisingData(msgspec.Struct, kw_only=True): 

198 """Extended advertising PDU-level metadata (BLE 5.0+). 

199 

200 This contains PDU-level information specific to extended advertising, 

201 NOT AD types (which go in AdvertisingDataStructures). 

202 

203 Attributes: 

204 extended_payload: Raw extended advertising payload bytes 

205 auxiliary_packets: Chained AUX_ADV_IND packets via AuxPtr 

206 periodic_advertising_data: Data from periodic advertising train 

207 """ 

208 

209 extended_payload: bytes = b"" 

210 auxiliary_packets: list[BLEAdvertisingPDU] = msgspec.field(default_factory=list) 

211 periodic_advertising_data: bytes = b"" 

212 

213 

214class AdvertisingDataStructures(msgspec.Struct, kw_only=True): 

215 """Complete parsed advertising data structures organized by category. 

216 

217 Contains all AD Types parsed from advertising PDUs (both legacy and extended). 

218 These are payload content, not PDU-level metadata. 

219 

220 Attributes: 

221 core: Device identification and services (manufacturer data, UUIDs, name) 

222 properties: Device capabilities (flags, appearance, tx_power, features) 

223 directed: Directed advertising parameters (target addresses, intervals) 

224 oob_security: Out-of-Band security data for pairing 

225 location: Location and sensing data 

226 mesh: Mesh network and broadcast audio data 

227 security: Encrypted advertising and privacy data 

228 """ 

229 

230 core: CoreAdvertisingData = msgspec.field(default_factory=CoreAdvertisingData) 

231 properties: DeviceProperties = msgspec.field(default_factory=DeviceProperties) 

232 directed: DirectedAdvertisingData = msgspec.field(default_factory=DirectedAdvertisingData) 

233 oob_security: OOBSecurityData = msgspec.field(default_factory=OOBSecurityData) 

234 location: LocationAndSensingData = msgspec.field(default_factory=LocationAndSensingData) 

235 mesh: MeshAndBroadcastData = msgspec.field(default_factory=MeshAndBroadcastData) 

236 security: SecurityData = msgspec.field(default_factory=SecurityData) 

237 

238 @classmethod 

239 def from_common_fields( 

240 cls, 

241 *, 

242 manufacturer_data: dict[int, ManufacturerData] | None = None, 

243 service_data: dict[BluetoothUUID, bytes] | None = None, 

244 service_uuids: list[BluetoothUUID] | None = None, 

245 local_name: str = "", 

246 tx_power: int = 0, 

247 address: str = "", 

248 connectable: bool = False, 

249 ) -> AdvertisingDataStructures: 

250 """Create from common platform advertisement fields. 

251 

252 Builds an ``AdvertisingDataStructures`` with sensible defaults for 

253 fields that are typically unavailable from BLE platform APIs 

254 (OOB security, mesh, location, etc.). 

255 

256 Args: 

257 manufacturer_data: Manufacturer-specific data keyed by company ID. 

258 service_data: Service data keyed by service UUID. 

259 service_uuids: Advertised service UUIDs. 

260 local_name: Device local name. 

261 tx_power: Transmission power level in dBm. 

262 address: BLE device address (MAC). 

263 connectable: Whether the device is connectable. 

264 

265 Returns: 

266 Populated ``AdvertisingDataStructures`` instance. 

267 

268 """ 

269 flags = BLEAdvertisingFlags.BR_EDR_NOT_SUPPORTED 

270 if connectable: 

271 flags |= BLEAdvertisingFlags.LE_GENERAL_DISCOVERABLE_MODE 

272 

273 return cls( 

274 core=CoreAdvertisingData( 

275 manufacturer_data=manufacturer_data or {}, 

276 service_data=service_data or {}, 

277 service_uuids=service_uuids or [], 

278 local_name=local_name, 

279 ), 

280 properties=DeviceProperties( 

281 flags=flags, 

282 tx_power=tx_power, 

283 ), 

284 directed=DirectedAdvertisingData( 

285 le_bluetooth_device_address=address, 

286 ), 

287 )