Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/scapy/layers/bluetooth.py: 86%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1167 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Copyright (C) Philippe Biondi <phil@secdev.org> 

5# Copyright (C) Mike Ryan <mikeryan@lacklustre.net> 

6# Copyright (C) Michael Farrell <micolous+git@gmail.com> 

7# Copyright (C) Haram Park <freehr94@korea.ac.kr> 

8 

9""" 

10Bluetooth layers, sockets and send/receive functions. 

11""" 

12 

13import ctypes 

14import functools 

15import socket 

16import struct 

17import select 

18from ctypes import sizeof 

19 

20from scapy.config import conf 

21from scapy.data import ( 

22 DLT_BLUETOOTH_HCI_H4, 

23 DLT_BLUETOOTH_HCI_H4_WITH_PHDR, 

24 DLT_BLUETOOTH_LINUX_MONITOR, 

25 BLUETOOTH_CORE_COMPANY_IDENTIFIERS 

26) 

27from scapy.packet import bind_layers, Packet 

28from scapy.fields import ( 

29 BitField, 

30 XBitField, 

31 ByteEnumField, 

32 ByteField, 

33 FieldLenField, 

34 FieldListField, 

35 FlagsField, 

36 IntField, 

37 LEShortEnumField, 

38 LEShortField, 

39 LEIntField, 

40 LenField, 

41 MultipleTypeField, 

42 NBytesField, 

43 PacketListField, 

44 PadField, 

45 ShortField, 

46 SignedByteField, 

47 StrField, 

48 StrFixedLenField, 

49 StrLenField, 

50 StrNullField, 

51 UUIDField, 

52 XByteField, 

53 XLE3BytesField, 

54 XLELongField, 

55 XStrLenField, 

56 XLEShortField, 

57 XLEIntField, 

58 LEMACField, 

59 BitEnumField, 

60 LEThreeBytesField, 

61 ConditionalField 

62) 

63from scapy.supersocket import SuperSocket 

64from scapy.sendrecv import sndrcv 

65from scapy.data import MTU 

66from scapy.consts import WINDOWS 

67from scapy.error import warning 

68 

69 

70############ 

71# Consts # 

72############ 

73 

74# From hci.h 

75HCI_CHANNEL_RAW = 0 

76HCI_CHANNEL_USER = 1 

77HCI_CHANNEL_MONITOR = 2 

78HCI_CHANNEL_CONTROL = 3 

79HCI_CHANNEL_LOGGING = 4 

80 

81HCI_DEV_NONE = 0xffff 

82 

83 

84########## 

85# Layers # 

86########## 

87 

88# See bluez/lib/hci.h for details 

89 

90# Transport layers 

91 

92class HCI_PHDR_Hdr(Packet): 

93 name = "HCI PHDR transport layer" 

94 fields_desc = [IntField("direction", 0)] 

95 

96 

97# Real layers 

98 

99_bluetooth_packet_types = { 

100 0: "Acknowledgement", 

101 1: "Command", 

102 2: "ACL Data", 

103 3: "Synchronous", 

104 4: "Event", 

105 5: "Reserve", 

106 14: "Vendor", 

107 15: "Link Control" 

108} 

109 

110_bluetooth_error_codes = { 

111 0x00: "Success", 

112 0x01: "Unknown HCI Command", 

113 0x02: "Unknown Connection Identifier", 

114 0x03: "Hardware Failure", 

115 0x04: "Page Timeout", 

116 0x05: "Authentication Failure", 

117 0x06: "PIN or Key Missing", 

118 0x07: "Memory Capacity Exceeded", 

119 0x08: "Connection Timeout", 

120 0x09: "Connection Limit Exceeded", 

121 0x0A: "Synchronous Connection Limit To A Device Exceeded", 

122 0x0B: "Connection Already Exists", 

123 0x0C: "Command Disallowed", 

124 0x0D: "Connection Rejected due to Limited Resources", 

125 0x0E: "Connection Rejected Due To Security Reasons", 

126 0x0F: "Connection Rejected due to Unacceptable BD_ADDR", 

127 0x10: "Connection Accept Timeout Exceeded", 

128 0x11: "Unsupported Feature or Parameter Value", 

129 0x12: "Invalid HCI Command Parameters", 

130 0x13: "Remote User Terminated Connection", 

131 0x14: "Remote Device Terminated Connection due to Low Resources", 

132 0x15: "Remote Device Terminated Connection due to Power Off", 

133 0x16: "Connection Terminated By Local Host", 

134 0x17: "Repeated Attempts", 

135 0x18: "Pairing Not Allowed", 

136 0x19: "Unknown LMP PDU", 

137 0x1A: "Unsupported Remote Feature / Unsupported LMP Feature", 

138 0x1B: "SCO Offset Rejected", 

139 0x1C: "SCO Interval Rejected", 

140 0x1D: "SCO Air Mode Rejected", 

141 0x1E: "Invalid LMP Parameters / Invalid LL Parameters", 

142 0x1F: "Unspecified Error", 

143 0x20: "Unsupported LMP Parameter Value / Unsupported LL Parameter Value", 

144 0x21: "Role Change Not Allowed", 

145 0x22: "LMP Response Timeout / LL Response Timeout", 

146 0x23: "LMP Error Transaction Collision / LL Procedure Collision", 

147 0x24: "LMP PDU Not Allowed", 

148 0x25: "Encryption Mode Not Acceptable", 

149 0x26: "Link Key cannot be Changed", 

150 0x27: "Requested QoS Not Supported", 

151 0x28: "Instant Passed", 

152 0x29: "Pairing With Unit Key Not Supported", 

153 0x2A: "Different Transaction Collision", 

154 0x2B: "Reserved for future use", 

155 0x2C: "QoS Unacceptable Parameter", 

156 0x2D: "QoS Rejected", 

157 0x2E: "Channel Classification Not Supported", 

158 0x2F: "Insufficient Security", 

159 0x30: "Parameter Out Of Mandatory Range", 

160 0x31: "Reserved for future use", 

161 0x32: "Role Switch Pending", 

162 0x33: "Reserved for future use", 

163 0x34: "Reserved Slot Violation", 

164 0x35: "Role Switch Failed", 

165 0x36: "Extended Inquiry Response Too Large", 

166 0x37: "Secure Simple Pairing Not Supported By Host", 

167 0x38: "Host Busy - Pairing", 

168 0x39: "Connection Rejected due to No Suitable Channel Found", 

169 0x3A: "Controller Busy", 

170 0x3B: "Unacceptable Connection Parameters", 

171 0x3C: "Advertising Timeout", 

172 0x3D: "Connection Terminated due to MIC Failure", 

173 0x3E: "Connection Failed to be Established / Synchronization Timeout", 

174 0x3F: "MAC Connection Failed", 

175 0x40: "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock" 

176 " Dragging", 

177 0x41: "Type0 Submap Not Defined", 

178 0x42: "Unknown Advertising Identifier", 

179 0x43: "Limit Reached", 

180 0x44: "Operation Cancelled by Host", 

181 0x45: "Packet Too Long" 

182} 

183 

184_att_error_codes = { 

185 0x01: "invalid handle", 

186 0x02: "read not permitted", 

187 0x03: "write not permitted", 

188 0x04: "invalid pdu", 

189 0x05: "insufficient auth", 

190 0x06: "unsupported req", 

191 0x07: "invalid offset", 

192 0x08: "insufficient author", 

193 0x09: "prepare queue full", 

194 0x0a: "attr not found", 

195 0x0b: "attr not long", 

196 0x0c: "insufficient key size", 

197 0x0d: "invalid value size", 

198 0x0e: "unlikely", 

199 0x0f: "insufficiet encrypt", 

200 0x10: "unsupported gpr type", 

201 0x11: "insufficient resources", 

202} 

203 

204_bluetooth_features = [ 

205 '3_slot_packets', 

206 '5_slot_packets', 

207 'encryption', 

208 'slot_offset', 

209 'timing_accuracy', 

210 'role_switch', 

211 'hold_mode', 

212 'sniff_mode', 

213 'park_mode', 

214 'power_control_requests', 

215 'channel_quality_driven_data_rate', 

216 'sco_link', 

217 'hv2_packets', 

218 'hv3_packets', 

219 'u_law_log_synchronous_data', 

220 'a_law_log_synchronous_data', 

221 'cvsd_synchronous_data', 

222 'paging_parameter_negotiation', 

223 'power_control', 

224 'transparent_synchronous_data', 

225 'flow_control_lag_4_bit0', 

226 'flow_control_lag_4_bit1', 

227 'flow_control_lag_4_bit2', 

228 'broadband_encryption', 

229 'cvsd_synchronous_data', 

230 'edr_acl_2_mbps_mode', 

231 'edr_acl_3_mbps_mode', 

232 'enhanced_inquiry_scan', 

233 'interlaced_inquiry_scan', 

234 'interlaced_page_scan', 

235 'rssi_with_inquiry_results', 

236 'ev3_packets', 

237 'ev4_packets', 

238 'ev5_packets', 

239 'reserved', 

240 'afh_capable_slave', 

241 'afh_classification_slave', 

242 'br_edr_not_supported', 

243 'le_supported_controller', 

244 '3_slot_edr_acl_packets', 

245 '5_slot_edr_acl_packets', 

246 'sniff_subrating', 

247 'pause_encryption', 

248 'afh_capable_master', 

249 'afh_classification_master', 

250 'edr_esco_2_mbps_mode', 

251 'edr_esco_3_mbps_mode', 

252 '3_slot_edr_esco_packets', 

253 'extended_inquiry_response', 

254 'simultaneous_le_and_br_edr_to_same_device_capable_controller', 

255 'reserved2', 

256 'secure_simple_pairing', 

257 'encapsulated_pdu', 

258 'erroneous_data_reporting', 

259 'non_flushable_packet_boundary_flag', 

260 'reserved3', 

261 'link_supervision_timeout_changed_event', 

262 'inquiry_tx_power_level', 

263 'enhanced_power_control', 

264 'reserved4_bit0', 

265 'reserved4_bit1', 

266 'reserved4_bit2', 

267 'reserved4_bit3', 

268 'extended_features', 

269] 

270 

271_bluetooth_core_specification_versions = { 

272 0x00: '1.0b', 

273 0x01: '1.1', 

274 0x02: '1.2', 

275 0x03: '2.0+EDR', 

276 0x04: '2.1+EDR', 

277 0x05: '3.0+HS', 

278 0x06: '4.0', 

279 0x07: '4.1', 

280 0x08: '4.2', 

281 0x09: '5.0', 

282 0x0a: '5.1', 

283 0x0b: '5.2', 

284 0x0c: '5.3', 

285 0x0d: '5.4', 

286 0x0e: '6.0', 

287} 

288 

289 

290class HCI_Hdr(Packet): 

291 name = "HCI header" 

292 fields_desc = [ByteEnumField("type", 2, _bluetooth_packet_types)] 

293 

294 def mysummary(self): 

295 return self.sprintf("HCI %type%") 

296 

297 

298class HCI_ACL_Hdr(Packet): 

299 name = "HCI ACL header" 

300 fields_desc = [BitField("BC", 0, 2, tot_size=-2), 

301 BitField("PB", 0, 2), 

302 BitField("handle", 0, 12, end_tot_size=-2), 

303 LEShortField("len", None), ] 

304 

305 def post_build(self, p, pay): 

306 p += pay 

307 if self.len is None: 

308 p = p[:2] + struct.pack("<H", len(pay)) + p[4:] 

309 return p 

310 

311 

312class L2CAP_Hdr(Packet): 

313 name = "L2CAP header" 

314 fields_desc = [LEShortField("len", None), 

315 LEShortEnumField("cid", 0, {1: "control", 4: "attribute"}), ] # noqa: E501 

316 

317 def post_build(self, p, pay): 

318 p += pay 

319 if self.len is None: 

320 p = struct.pack("<H", len(pay)) + p[2:] 

321 return p 

322 

323 

324class L2CAP_CmdHdr(Packet): 

325 name = "L2CAP command header" 

326 fields_desc = [ 

327 ByteEnumField("code", 8, {1: "rej", 

328 2: "conn_req", 

329 3: "conn_resp", 

330 4: "conf_req", 

331 5: "conf_resp", 

332 6: "disconn_req", 

333 7: "disconn_resp", 

334 8: "echo_req", 

335 9: "echo_resp", 

336 10: "info_req", 

337 11: "info_resp", 

338 12: "create_channel_req", 

339 13: "create_channel_resp", 

340 14: "move_channel_req", 

341 15: "move_channel_resp", 

342 16: "move_channel_confirm_req", 

343 17: "move_channel_confirm_resp", 

344 18: "conn_param_update_req", 

345 19: "conn_param_update_resp", 

346 20: "LE_credit_based_conn_req", 

347 21: "LE_credit_based_conn_resp", 

348 22: "flow_control_credit_ind", 

349 23: "credit_based_conn_req", 

350 24: "credit_based_conn_resp", 

351 25: "credit_based_reconf_req", 

352 26: "credit_based_reconf_resp"}), 

353 ByteField("id", 1), 

354 LEShortField("len", None)] 

355 

356 def post_build(self, p, pay): 

357 p += pay 

358 if self.len is None: 

359 p = p[:2] + struct.pack("<H", len(pay)) + p[4:] 

360 return p 

361 

362 def answers(self, other): 

363 if other.id == self.id: 

364 if self.code == 1: 

365 return 1 

366 if other.code in [2, 4, 6, 8, 10, 18] and self.code == other.code + 1: # noqa: E501 

367 if other.code == 8: 

368 return 1 

369 return self.payload.answers(other.payload) 

370 return 0 

371 

372 

373class L2CAP_ConnReq(Packet): 

374 name = "L2CAP Conn Req" 

375 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP", 

376 3: "RFCOMM", 

377 5: "TCS-BIN", 

378 7: "TCS-BIN-CORDLESS", 

379 15: "BNEP", 

380 17: "HID-Control", 

381 19: "HID-Interrupt", 

382 21: "UPnP", 

383 23: "AVCTP-Control", 

384 25: "AVDTP", 

385 27: "AVCTP-Browsing", 

386 29: "UDI_C-Plane", 

387 31: "ATT", 

388 33: "3DSP", 

389 35: "IPSP", 

390 37: "OTS"}), 

391 LEShortField("scid", 0), 

392 ] 

393 

394 

395class L2CAP_ConnResp(Packet): 

396 name = "L2CAP Conn Resp" 

397 fields_desc = [LEShortField("dcid", 0), 

398 LEShortField("scid", 0), 

399 LEShortEnumField("result", 0, ["success", "pend", "cr_bad_psm", "cr_sec_block", "cr_no_mem", "reserved", "cr_inval_scid", "cr_scid_in_use"]), # noqa: E501 

400 LEShortEnumField("status", 0, ["no_info", "authen_pend", "author_pend", "reserved"]), # noqa: E501 

401 ] 

402 

403 def answers(self, other): 

404 # dcid Resp == scid Req. Therefore compare SCIDs 

405 return isinstance(other, L2CAP_ConnReq) and self.scid == other.scid 

406 

407 

408class L2CAP_CmdRej(Packet): 

409 name = "L2CAP Command Rej" 

410 fields_desc = [LEShortField("reason", 0), 

411 ] 

412 

413 

414class L2CAP_ConfReq(Packet): 

415 name = "L2CAP Conf Req" 

416 fields_desc = [LEShortField("dcid", 0), 

417 LEShortField("flags", 0), 

418 ] 

419 

420 

421class L2CAP_ConfResp(Packet): 

422 name = "L2CAP Conf Resp" 

423 fields_desc = [LEShortField("scid", 0), 

424 LEShortField("flags", 0), 

425 LEShortEnumField("result", 0, ["success", "unaccept", "reject", "unknown"]), # noqa: E501 

426 ] 

427 

428 def answers(self, other): 

429 # Req and Resp contain either the SCID or the DCID. 

430 return isinstance(other, L2CAP_ConfReq) 

431 

432 

433class L2CAP_DisconnReq(Packet): 

434 name = "L2CAP Disconn Req" 

435 fields_desc = [LEShortField("dcid", 0), 

436 LEShortField("scid", 0), ] 

437 

438 

439class L2CAP_DisconnResp(Packet): 

440 name = "L2CAP Disconn Resp" 

441 fields_desc = [LEShortField("dcid", 0), 

442 LEShortField("scid", 0), ] 

443 

444 def answers(self, other): 

445 return self.scid == other.scid 

446 

447 

448class L2CAP_EchoReq(Packet): 

449 name = "L2CAP Echo Req" 

450 fields_desc = [StrField("data", ""), ] 

451 

452 

453class L2CAP_EchoResp(Packet): 

454 name = "L2CAP Echo Resp" 

455 fields_desc = [StrField("data", ""), ] 

456 

457 

458class L2CAP_InfoReq(Packet): 

459 name = "L2CAP Info Req" 

460 fields_desc = [LEShortEnumField("type", 0, {1: "CL_MTU", 2: "FEAT_MASK"}), 

461 StrField("data", "") 

462 ] 

463 

464 

465class L2CAP_InfoResp(Packet): 

466 name = "L2CAP Info Resp" 

467 fields_desc = [LEShortField("type", 0), 

468 LEShortEnumField("result", 0, ["success", "not_supp"]), 

469 StrField("data", ""), ] 

470 

471 def answers(self, other): 

472 return self.type == other.type 

473 

474 

475class L2CAP_Create_Channel_Request(Packet): 

476 name = "L2CAP Create Channel Request" 

477 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP", 

478 3: "RFCOMM", 

479 5: "TCS-BIN", 

480 7: "TCS-BIN-CORDLESS", 

481 15: "BNEP", 

482 17: "HID-Control", 

483 19: "HID-Interrupt", 

484 21: "UPnP", 

485 23: "AVCTP-Control", 

486 25: "AVDTP", 

487 27: "AVCTP-Browsing", 

488 29: "UDI_C-Plane", 

489 31: "ATT", 

490 33: "3DSP", 

491 35: "IPSP", 

492 37: "OTS"}), 

493 LEShortField("scid", 0), 

494 ByteField("controller_id", 0), ] 

495 

496 

497class L2CAP_Create_Channel_Response(Packet): 

498 name = "L2CAP Create Channel Response" 

499 fields_desc = [LEShortField("dcid", 0), 

500 LEShortField("scid", 0), 

501 LEShortEnumField("result", 0, { 

502 0: "Connection successful", 

503 1: "Connection pending", 

504 2: "Connection refused - PSM not supported", 

505 3: "Connection refused - security block", 

506 4: "Connection refused - no resources available", 

507 5: "Connection refused - cont_ID not supported", 

508 6: "Connection refused - invalid scid", 

509 7: "Connection refused - scid already allocated"}), 

510 LEShortEnumField("status", 0, { 

511 0: "No further information available", 

512 1: "Authentication pending", 

513 2: "Authorization pending"}), ] 

514 

515 

516class L2CAP_Move_Channel_Request(Packet): 

517 name = "L2CAP Move Channel Request" 

518 fields_desc = [LEShortField("icid", 0), 

519 ByteField("dest_controller_id", 0), ] 

520 

521 

522class L2CAP_Move_Channel_Response(Packet): 

523 name = "L2CAP Move Channel Response" 

524 fields_desc = [LEShortField("icid", 0), 

525 LEShortEnumField("result", 0, { 

526 0: "Move success", 

527 1: "Move pending", 

528 2: "Move refused - Cont_ID not supported", 

529 3: "Move refused - Cont_ID is same as old one", 

530 4: "Move refused - Configuration not supported", 

531 5: "Move refused - Move channel collision", 

532 6: "Move refused - Not allowed to be moved"}), ] 

533 

534 

535class L2CAP_Move_Channel_Confirmation_Request(Packet): 

536 name = "L2CAP Move Channel Confirmation Request" 

537 fields_desc = [LEShortField("icid", 0), 

538 LEShortEnumField("result", 0, {0: "Move success", 

539 1: "Move failure"}), ] 

540 

541 

542class L2CAP_Move_Channel_Confirmation_Response(Packet): 

543 name = "L2CAP Move Channel Confirmation Response" 

544 fields_desc = [LEShortField("icid", 0), ] 

545 

546 

547class L2CAP_Connection_Parameter_Update_Request(Packet): 

548 name = "L2CAP Connection Parameter Update Request" 

549 fields_desc = [LEShortField("min_interval", 0), 

550 LEShortField("max_interval", 0), 

551 LEShortField("slave_latency", 0), 

552 LEShortField("timeout_mult", 0), ] 

553 

554 

555class L2CAP_Connection_Parameter_Update_Response(Packet): 

556 name = "L2CAP Connection Parameter Update Response" 

557 fields_desc = [LEShortField("move_result", 0), ] 

558 

559 

560class L2CAP_LE_Credit_Based_Connection_Request(Packet): 

561 name = "L2CAP LE Credit Based Connection Request" 

562 fields_desc = [LEShortField("spsm", 0), 

563 LEShortField("scid", 0), 

564 LEShortField("mtu", 0), 

565 LEShortField("mps", 0), 

566 LEShortField("initial_credits", 0), ] 

567 

568 

569class L2CAP_LE_Credit_Based_Connection_Response(Packet): 

570 name = "L2CAP LE Credit Based Connection Response" 

571 fields_desc = [LEShortField("dcid", 0), 

572 LEShortField("mtu", 0), 

573 LEShortField("mps", 0), 

574 LEShortField("initial_credits", 0), 

575 LEShortEnumField("result", 0, { 

576 0: "Connection successful", 

577 2: "Connection refused - SPSM not supported", 

578 4: "Connection refused - no resources available", 

579 5: "Connection refused - authentication error", 

580 6: "Connection refused - authorization error", 

581 7: "Connection refused - encrypt_key size error", 

582 8: "Connection refused - insufficient encryption", 

583 9: "Connection refused - invalid scid", 

584 10: "Connection refused - scid already allocated", 

585 11: "Connection refused - parameters error"}), ] 

586 

587 

588class L2CAP_Flow_Control_Credit_Ind(Packet): 

589 name = "L2CAP Flow Control Credit Ind" 

590 fields_desc = [LEShortField("cid", 0), 

591 LEShortField("credits", 0), ] 

592 

593 

594class L2CAP_Credit_Based_Connection_Request(Packet): 

595 name = "L2CAP Credit Based Connection Request" 

596 fields_desc = [LEShortField("spsm", 0), 

597 LEShortField("mtu", 0), 

598 LEShortField("mps", 0), 

599 LEShortField("initial_credits", 0), 

600 LEShortField("scid", 0), ] 

601 

602 

603class L2CAP_Credit_Based_Connection_Response(Packet): 

604 name = "L2CAP Credit Based Connection Response" 

605 fields_desc = [LEShortField("mtu", 0), 

606 LEShortField("mps", 0), 

607 LEShortField("initial_credits", 0), 

608 LEShortEnumField("result", 0, { 

609 0: "All connection successful", 

610 2: "All connection refused - SPSM not supported", 

611 4: "Some connections refused - resources error", 

612 5: "All connection refused - authentication error", 

613 6: "All connection refused - authorization error", 

614 7: "All connection refused - encrypt_key size error", 

615 8: "All connection refused - encryption error", 

616 9: "Some connection refused - invalid scid", 

617 10: "Some connection refused - scid already allocated", 

618 11: "All Connection refused - unacceptable parameters", 

619 12: "All connections refused - invalid parameters"}), 

620 LEShortField("dcid", 0), ] 

621 

622 

623class L2CAP_Credit_Based_Reconfigure_Request(Packet): 

624 name = "L2CAP Credit Based Reconfigure Request" 

625 fields_desc = [LEShortField("mtu", 0), 

626 LEShortField("mps", 0), 

627 LEShortField("dcid", 0), ] 

628 

629 

630class L2CAP_Credit_Based_Reconfigure_Response(Packet): 

631 name = "L2CAP Credit Based Reconfigure Response" 

632 fields_desc = [LEShortEnumField("result", 0, { 

633 0: "Reconfig successful", 

634 1: "Reconfig failed - MTU size reduction not allowed", 

635 2: "Reconfig failed - MPS size reduction not allowed", 

636 3: "Reconfig failed - one or more dcids invalid", 

637 4: "Reconfig failed - unacceptable parameters"}), ] 

638 

639 

640class ATT_Hdr(Packet): 

641 name = "ATT header" 

642 fields_desc = [XByteField("opcode", None), ] 

643 

644 

645class ATT_Handle(Packet): 

646 name = "ATT Short Handle" 

647 fields_desc = [XLEShortField("handle", 0), 

648 XLEShortField("value", 0)] 

649 

650 def extract_padding(self, s): 

651 return b'', s 

652 

653 

654class ATT_Handle_UUID128(Packet): 

655 name = "ATT Handle (UUID 128)" 

656 fields_desc = [XLEShortField("handle", 0), 

657 UUIDField("value", None, uuid_fmt=UUIDField.FORMAT_REV)] 

658 

659 def extract_padding(self, s): 

660 return b'', s 

661 

662 

663class ATT_Error_Response(Packet): 

664 name = "Error Response" 

665 fields_desc = [XByteField("request", 0), 

666 LEShortField("handle", 0), 

667 ByteEnumField("ecode", 0, _att_error_codes), ] 

668 

669 

670class ATT_Exchange_MTU_Request(Packet): 

671 name = "Exchange MTU Request" 

672 fields_desc = [LEShortField("mtu", 0), ] 

673 

674 

675class ATT_Exchange_MTU_Response(Packet): 

676 name = "Exchange MTU Response" 

677 fields_desc = [LEShortField("mtu", 0), ] 

678 

679 

680class ATT_Find_Information_Request(Packet): 

681 name = "Find Information Request" 

682 fields_desc = [XLEShortField("start", 0x0000), 

683 XLEShortField("end", 0xffff), ] 

684 

685 

686class ATT_Find_Information_Response(Packet): 

687 name = "Find Information Response" 

688 fields_desc = [ 

689 XByteField("format", 1), 

690 MultipleTypeField( 

691 [ 

692 (PacketListField("handles", [], ATT_Handle), 

693 lambda pkt: pkt.format == 1), 

694 (PacketListField("handles", [], ATT_Handle_UUID128), 

695 lambda pkt: pkt.format == 2), 

696 ], 

697 StrFixedLenField("handles", "", length=0) 

698 ) 

699 ] 

700 

701 

702class ATT_Find_By_Type_Value_Request(Packet): 

703 name = "Find By Type Value Request" 

704 fields_desc = [XLEShortField("start", 0x0001), 

705 XLEShortField("end", 0xffff), 

706 XLEShortField("uuid", None), 

707 StrField("data", ""), ] 

708 

709 

710class ATT_Find_By_Type_Value_Response(Packet): 

711 name = "Find By Type Value Response" 

712 fields_desc = [PacketListField("handles", [], ATT_Handle)] 

713 

714 

715class ATT_Read_By_Type_Request_128bit(Packet): 

716 name = "Read By Type Request" 

717 fields_desc = [XLEShortField("start", 0x0001), 

718 XLEShortField("end", 0xffff), 

719 XLELongField("uuid1", None), 

720 XLELongField("uuid2", None)] 

721 

722 @classmethod 

723 def dispatch_hook(cls, _pkt=None, *args, **kargs): 

724 if _pkt and len(_pkt) == 6: 

725 return ATT_Read_By_Type_Request 

726 return ATT_Read_By_Type_Request_128bit 

727 

728 

729class ATT_Read_By_Type_Request(Packet): 

730 name = "Read By Type Request" 

731 fields_desc = [XLEShortField("start", 0x0001), 

732 XLEShortField("end", 0xffff), 

733 XLEShortField("uuid", None)] 

734 

735 

736class ATT_Handle_Variable(Packet): 

737 __slots__ = ["val_length"] 

738 fields_desc = [XLEShortField("handle", 0), 

739 XStrLenField( 

740 "value", 0, 

741 length_from=lambda pkt: pkt.val_length)] 

742 

743 def __init__(self, _pkt=b"", val_length=2, **kwargs): 

744 self.val_length = val_length 

745 Packet.__init__(self, _pkt, **kwargs) 

746 

747 def extract_padding(self, s): 

748 return b"", s 

749 

750 

751class ATT_Read_By_Type_Response(Packet): 

752 name = "Read By Type Response" 

753 fields_desc = [ByteField("len", 4), 

754 PacketListField( 

755 "handles", [], 

756 next_cls_cb=lambda pkt, *args: ( 

757 pkt._next_cls_cb(pkt, *args) 

758 ))] 

759 

760 @classmethod 

761 def _next_cls_cb(cls, pkt, lst, p, remain): 

762 if len(remain) >= pkt.len: 

763 return functools.partial( 

764 ATT_Handle_Variable, 

765 val_length=pkt.len - 2 

766 ) 

767 return None 

768 

769 

770class ATT_Read_Request(Packet): 

771 name = "Read Request" 

772 fields_desc = [XLEShortField("gatt_handle", 0), ] 

773 

774 

775class ATT_Read_Response(Packet): 

776 name = "Read Response" 

777 fields_desc = [StrField("value", "")] 

778 

779 

780class ATT_Read_Multiple_Request(Packet): 

781 name = "Read Multiple Request" 

782 fields_desc = [FieldListField("handles", [], XLEShortField("", 0))] 

783 

784 

785class ATT_Read_Multiple_Response(Packet): 

786 name = "Read Multiple Response" 

787 fields_desc = [StrField("values", "")] 

788 

789 

790class ATT_Read_By_Group_Type_Request(Packet): 

791 name = "Read By Group Type Request" 

792 fields_desc = [XLEShortField("start", 0), 

793 XLEShortField("end", 0xffff), 

794 XLEShortField("uuid", 0), ] 

795 

796 

797class ATT_Read_By_Group_Type_Response(Packet): 

798 name = "Read By Group Type Response" 

799 fields_desc = [XByteField("length", 0), 

800 StrField("data", ""), ] 

801 

802 

803class ATT_Write_Request(Packet): 

804 name = "Write Request" 

805 fields_desc = [XLEShortField("gatt_handle", 0), 

806 StrField("data", ""), ] 

807 

808 

809class ATT_Write_Command(Packet): 

810 name = "Write Request" 

811 fields_desc = [XLEShortField("gatt_handle", 0), 

812 StrField("data", ""), ] 

813 

814 

815class ATT_Write_Response(Packet): 

816 name = "Write Response" 

817 

818 

819class ATT_Prepare_Write_Request(Packet): 

820 name = "Prepare Write Request" 

821 fields_desc = [ 

822 XLEShortField("gatt_handle", 0), 

823 LEShortField("offset", 0), 

824 StrField("data", "") 

825 ] 

826 

827 

828class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request): 

829 name = "Prepare Write Response" 

830 

831 

832class ATT_Handle_Value_Notification(Packet): 

833 name = "Handle Value Notification" 

834 fields_desc = [XLEShortField("gatt_handle", 0), 

835 StrField("value", ""), ] 

836 

837 

838class ATT_Execute_Write_Request(Packet): 

839 name = "Execute Write Request" 

840 fields_desc = [ 

841 ByteEnumField("flags", 1, { 

842 0: "Cancel all prepared writes", 

843 1: "Immediately write all pending prepared values", 

844 }), 

845 ] 

846 

847 

848class ATT_Execute_Write_Response(Packet): 

849 name = "Execute Write Response" 

850 

851 

852class ATT_Read_Blob_Request(Packet): 

853 name = "Read Blob Request" 

854 fields_desc = [ 

855 XLEShortField("gatt_handle", 0), 

856 LEShortField("offset", 0) 

857 ] 

858 

859 

860class ATT_Read_Blob_Response(Packet): 

861 name = "Read Blob Response" 

862 fields_desc = [ 

863 StrField("value", "") 

864 ] 

865 

866 

867class ATT_Handle_Value_Indication(Packet): 

868 name = "Handle Value Indication" 

869 fields_desc = [ 

870 XLEShortField("gatt_handle", 0), 

871 StrField("value", ""), 

872 ] 

873 

874 

875class SM_Hdr(Packet): 

876 name = "SM header" 

877 fields_desc = [ByteField("sm_command", None)] 

878 

879 

880class SM_Pairing_Request(Packet): 

881 name = "Pairing Request" 

882 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501 

883 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501 

884 BitField("authentication", 0, 8), 

885 ByteField("max_key_size", 16), 

886 ByteField("initiator_key_distribution", 0), 

887 ByteField("responder_key_distribution", 0), ] 

888 

889 

890class SM_Pairing_Response(Packet): 

891 name = "Pairing Response" 

892 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501 

893 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501 

894 BitField("authentication", 0, 8), 

895 ByteField("max_key_size", 16), 

896 ByteField("initiator_key_distribution", 0), 

897 ByteField("responder_key_distribution", 0), ] 

898 

899 

900class SM_Confirm(Packet): 

901 name = "Pairing Confirm" 

902 fields_desc = [StrFixedLenField("confirm", b'\x00' * 16, 16)] 

903 

904 

905class SM_Random(Packet): 

906 name = "Pairing Random" 

907 fields_desc = [StrFixedLenField("random", b'\x00' * 16, 16)] 

908 

909 

910class SM_Failed(Packet): 

911 name = "Pairing Failed" 

912 fields_desc = [XByteField("reason", 0)] 

913 

914 

915class SM_Encryption_Information(Packet): 

916 name = "Encryption Information" 

917 fields_desc = [StrFixedLenField("ltk", b"\x00" * 16, 16), ] 

918 

919 

920class SM_Master_Identification(Packet): 

921 name = "Master Identification" 

922 fields_desc = [XLEShortField("ediv", 0), 

923 StrFixedLenField("rand", b'\x00' * 8, 8), ] 

924 

925 

926class SM_Identity_Information(Packet): 

927 name = "Identity Information" 

928 fields_desc = [StrFixedLenField("irk", b'\x00' * 16, 16), ] 

929 

930 

931class SM_Identity_Address_Information(Packet): 

932 name = "Identity Address Information" 

933 fields_desc = [ByteEnumField("addr_type", 0, {0: "public"}), 

934 LEMACField("addr", None), ] 

935 deprecated_fields = { 

936 "atype": ("addr_type", "2.7.0"), 

937 "address": ("addr", "2.7.0"), 

938 } 

939 

940 

941class SM_Signing_Information(Packet): 

942 name = "Signing Information" 

943 fields_desc = [StrFixedLenField("csrk", b'\x00' * 16, 16), ] 

944 

945 

946class SM_Security_Request(Packet): 

947 name = "Security Request" 

948 fields_desc = [BitField("auth_req", 0, 8), ] 

949 

950 

951class SM_Public_Key(Packet): 

952 name = "Public Key" 

953 fields_desc = [StrFixedLenField("key_x", b'\x00' * 32, 32), 

954 StrFixedLenField("key_y", b'\x00' * 32, 32), ] 

955 

956 

957class SM_DHKey_Check(Packet): 

958 name = "DHKey Check" 

959 fields_desc = [StrFixedLenField("dhkey_check", b'\x00' * 16, 16), ] 

960 

961 

962class EIR_Hdr(Packet): 

963 name = "EIR Header" 

964 fields_desc = [ 

965 LenField("len", None, fmt="B", adjust=lambda x: x + 1), # Add bytes mark # noqa: E501 

966 # https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile 

967 ByteEnumField("type", 0, { 

968 0x01: "flags", 

969 0x02: "incomplete_list_16_bit_svc_uuids", 

970 0x03: "complete_list_16_bit_svc_uuids", 

971 0x04: "incomplete_list_32_bit_svc_uuids", 

972 0x05: "complete_list_32_bit_svc_uuids", 

973 0x06: "incomplete_list_128_bit_svc_uuids", 

974 0x07: "complete_list_128_bit_svc_uuids", 

975 0x08: "shortened_local_name", 

976 0x09: "complete_local_name", 

977 0x0a: "tx_power_level", 

978 0x0d: "class_of_device", 

979 0x0e: "simple_pairing_hash", 

980 0x0f: "simple_pairing_rand", 

981 

982 0x10: "sec_mgr_tk", 

983 0x11: "sec_mgr_oob_flags", 

984 0x12: "slave_conn_intvl_range", 

985 0x14: "list_16_bit_svc_sollication_uuids", 

986 0x15: "list_128_bit_svc_sollication_uuids", 

987 0x16: "svc_data_16_bit_uuid", 

988 0x17: "pub_target_addr", 

989 0x18: "rand_target_addr", 

990 0x19: "appearance", 

991 0x1a: "adv_intvl", 

992 0x1b: "le_addr", 

993 0x1c: "le_role", 

994 0x1d: "simple_pairing_hash_256", 

995 0x1e: "simple_pairing_rand_256", 

996 0x1f: "list_32_bit_svc_sollication_uuids", 

997 

998 0x20: "svc_data_32_bit_uuid", 

999 0x21: "svc_data_128_bit_uuid", 

1000 0x22: "sec_conn_confirm", 

1001 0x23: "sec_conn_rand", 

1002 0x24: "uri", 

1003 0x25: "indoor_positioning", 

1004 0x26: "transport_discovery", 

1005 0x27: "le_supported_features", 

1006 0x28: "channel_map_update", 

1007 0x29: "mesh_pb_adv", 

1008 0x2a: "mesh_message", 

1009 0x2b: "mesh_beacon", 

1010 

1011 0x3d: "3d_information", 

1012 

1013 0xff: "mfg_specific_data", 

1014 }), 

1015 ] 

1016 

1017 def mysummary(self): 

1018 return self.sprintf("EIR %type%") 

1019 

1020 def guess_payload_class(self, payload): 

1021 if self.len == 0: 

1022 # For Extended_Inquiry_Response, stop when len=0 

1023 return conf.padding_layer 

1024 return super(EIR_Hdr, self).guess_payload_class(payload) 

1025 

1026 

1027class EIR_Element(Packet): 

1028 name = "EIR Element" 

1029 

1030 def extract_padding(self, s): 

1031 # Needed to end each EIR_Element packet and make PacketListField work. 

1032 return b'', s 

1033 

1034 @staticmethod 

1035 def length_from(pkt): 

1036 if not pkt.underlayer: 

1037 warning("Missing an upper-layer") 

1038 return 0 

1039 # 'type' byte is included in the length, so subtract 1: 

1040 return pkt.underlayer.len - 1 

1041 

1042 

1043class EIR_Raw(EIR_Element): 

1044 name = "EIR Raw" 

1045 fields_desc = [ 

1046 StrLenField("data", "", length_from=EIR_Element.length_from) 

1047 ] 

1048 

1049 

1050class EIR_Flags(EIR_Element): 

1051 name = "Flags" 

1052 fields_desc = [ 

1053 FlagsField("flags", 0x2, 8, 

1054 ["limited_disc_mode", "general_disc_mode", 

1055 "br_edr_not_supported", "simul_le_br_edr_ctrl", 

1056 "simul_le_br_edr_host"] + 3 * ["reserved"]) 

1057 ] 

1058 

1059 

1060class EIR_CompleteList16BitServiceUUIDs(EIR_Element): 

1061 name = "Complete list of 16-bit service UUIDs" 

1062 fields_desc = [ 

1063 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members 

1064 FieldListField("svc_uuids", None, XLEShortField("uuid", 0), 

1065 length_from=EIR_Element.length_from) 

1066 ] 

1067 

1068 

1069class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs): 

1070 name = "Incomplete list of 16-bit service UUIDs" 

1071 

1072 

1073class EIR_CompleteList32BitServiceUUIDs(EIR_Element): 

1074 name = 'Complete list of 32-bit service UUIDs' 

1075 fields_desc = [ 

1076 # https://www.bluetooth.com/specifications/assigned-numbers 

1077 FieldListField('svc_uuids', None, XLEIntField('uuid', 0), 

1078 length_from=EIR_Element.length_from) 

1079 ] 

1080 

1081 

1082class EIR_IncompleteList32BitServiceUUIDs(EIR_CompleteList32BitServiceUUIDs): 

1083 name = 'Incomplete list of 32-bit service UUIDs' 

1084 

1085 

1086class EIR_CompleteList128BitServiceUUIDs(EIR_Element): 

1087 name = "Complete list of 128-bit service UUIDs" 

1088 fields_desc = [ 

1089 FieldListField("svc_uuids", None, 

1090 UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV), 

1091 length_from=EIR_Element.length_from) 

1092 ] 

1093 

1094 

1095class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs): 

1096 name = "Incomplete list of 128-bit service UUIDs" 

1097 

1098 

1099class EIR_CompleteLocalName(EIR_Element): 

1100 name = "Complete Local Name" 

1101 fields_desc = [ 

1102 StrLenField("local_name", "", length_from=EIR_Element.length_from) 

1103 ] 

1104 

1105 

1106class EIR_ShortenedLocalName(EIR_CompleteLocalName): 

1107 name = "Shortened Local Name" 

1108 

1109 

1110class EIR_TX_Power_Level(EIR_Element): 

1111 name = "TX Power Level" 

1112 fields_desc = [SignedByteField("level", 0)] 

1113 

1114 

1115class EIR_ClassOfDevice(EIR_Element): 

1116 name = 'Class of device' 

1117 fields_desc = [ 

1118 FlagsField('major_service_classes', 0, 11, [ 

1119 'limited_discoverable_mode', 

1120 'le_audio', 

1121 'reserved', 

1122 'positioning', 

1123 'networking', 

1124 'rendering', 

1125 'capturing', 

1126 'object_transfer', 

1127 'audio', 

1128 'telephony', 

1129 'information' 

1130 ], tot_size=-3), 

1131 BitEnumField('major_device_class', 0, 5, { 

1132 0x00: 'miscellaneous', 

1133 0x01: 'computer', 

1134 0x02: 'phone', 

1135 0x03: 'lan', 

1136 0x04: 'audio_video', 

1137 0x05: 'peripheral', 

1138 0x06: 'imaging', 

1139 0x07: 'wearable', 

1140 0x08: 'toy', 

1141 0x09: 'health', 

1142 0x1f: 'uncategorized' 

1143 }), 

1144 BitField('minor_device_class', 0, 6), 

1145 BitField('fixed', 0, 2, end_tot_size=-3) 

1146 ] 

1147 

1148 

1149class EIR_SecureSimplePairingHashC192(EIR_Element): 

1150 name = 'Secure Simple Pairing Hash C-192' 

1151 fields_desc = [NBytesField('hash', 0, 16)] 

1152 

1153 

1154class EIR_SecureSimplePairingRandomizerR192(EIR_Element): 

1155 name = 'Secure Simple Pairing Randomizer R-192' 

1156 fields_desc = [NBytesField('randomizer', 0, 16)] 

1157 

1158 

1159class EIR_SecurityManagerOOBFlags(EIR_Element): 

1160 name = 'Security Manager Out of Band Flags' 

1161 fields_desc = [ 

1162 BitField('oob_flags_field', 0, 1), 

1163 BitField('le_supported', 0, 1), 

1164 BitField('previously_used', 0, 1), 

1165 BitField('address_type', 0, 1), 

1166 BitField('reserved', 0, 4) 

1167 ] 

1168 

1169 

1170class EIR_PeripheralConnectionIntervalRange(EIR_Element): 

1171 name = 'Peripheral Connection Interval Range' 

1172 fields_desc = [ 

1173 LEShortField('conn_interval_min', 0xFFFF), 

1174 LEShortField('conn_interval_max', 0xFFFF) 

1175 ] 

1176 

1177 

1178class EIR_Manufacturer_Specific_Data(EIR_Element): 

1179 name = "EIR Manufacturer Specific Data" 

1180 deprecated_fields = { 

1181 "company_id": ("company_identifier", "2.6.2"), 

1182 } 

1183 fields_desc = [ 

1184 # https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers 

1185 LEShortEnumField("company_identifier", None, 

1186 BLUETOOTH_CORE_COMPANY_IDENTIFIERS), 

1187 ] 

1188 

1189 registered_magic_payloads = {} 

1190 

1191 @classmethod 

1192 def register_magic_payload(cls, payload_cls, magic_check=None): 

1193 """ 

1194 Registers a payload type that uses magic data. 

1195 

1196 Traditional payloads require registration of a Bluetooth Company ID 

1197 (requires company membership of the Bluetooth SIG), or a Bluetooth 

1198 Short UUID (requires a once-off payment). 

1199 

1200 There are alternatives which don't require registration (such as 

1201 128-bit UUIDs), but the biggest consumer of energy in a beacon is the 

1202 radio -- so the energy consumption of a beacon is proportional to the 

1203 number of bytes in a beacon frame. 

1204 

1205 Some beacon formats side-step this issue by using the Company ID of 

1206 their beacon hardware manufacturer, and adding a "magic data sequence" 

1207 at the start of the Manufacturer Specific Data field. 

1208 

1209 Examples of this are AltBeacon and GeoBeacon. 

1210 

1211 For an example of this method in use, see ``scapy.contrib.altbeacon``. 

1212 

1213 :param Type[scapy.packet.Packet] payload_cls: 

1214 A reference to a Packet subclass to register as a payload. 

1215 :param Callable[[bytes], bool] magic_check: 

1216 (optional) callable to use to if a payload should be associated 

1217 with this type. If not supplied, ``payload_cls.magic_check`` is 

1218 used instead. 

1219 :raises TypeError: If ``magic_check`` is not specified, 

1220 and ``payload_cls.magic_check`` is not implemented. 

1221 """ 

1222 if magic_check is None: 

1223 if hasattr(payload_cls, "magic_check"): 

1224 magic_check = payload_cls.magic_check 

1225 else: 

1226 raise TypeError("magic_check not specified, and {} has no " 

1227 "attribute magic_check".format(payload_cls)) 

1228 

1229 cls.registered_magic_payloads[payload_cls] = magic_check 

1230 

1231 def default_payload_class(self, payload): 

1232 for cls, check in ( 

1233 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items() 

1234 ): 

1235 if check(payload): 

1236 return cls 

1237 

1238 return Packet.default_payload_class(self, payload) 

1239 

1240 def extract_padding(self, s): 

1241 # Needed to end each EIR_Element packet and make PacketListField work. 

1242 plen = EIR_Element.length_from(self) - 2 

1243 return s[:plen], s[plen:] 

1244 

1245 

1246class EIR_Device_ID(EIR_Element): 

1247 name = "Device ID" 

1248 fields_desc = [ 

1249 XLEShortField("vendor_id_source", 0), 

1250 XLEShortField("vendor_id", 0), 

1251 XLEShortField("product_id", 0), 

1252 XLEShortField("version", 0), 

1253 ] 

1254 

1255 

1256class EIR_ServiceSolicitation16BitUUID(EIR_Element): 

1257 name = "EIR Service Solicitation - 16-bit UUID" 

1258 fields_desc = [ 

1259 XLEShortField("svc_uuid", None) 

1260 ] 

1261 

1262 def extract_padding(self, s): 

1263 # Needed to end each EIR_Element packet and make PacketListField work. 

1264 plen = EIR_Element.length_from(self) - 2 

1265 return s[:plen], s[plen:] 

1266 

1267 

1268class EIR_ServiceSolicitation128BitUUID(EIR_Element): 

1269 name = "EIR Service Solicitation - 128-bit UUID" 

1270 fields_desc = [ 

1271 UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV) 

1272 ] 

1273 

1274 def extract_padding(self, s): 

1275 # Needed to end each EIR_Element packet and make PacketListField work. 

1276 plen = EIR_Element.length_from(self) - 2 

1277 return s[:plen], s[plen:] 

1278 

1279 

1280class EIR_ServiceData16BitUUID(EIR_Element): 

1281 name = "EIR Service Data - 16-bit UUID" 

1282 fields_desc = [ 

1283 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members 

1284 XLEShortField("svc_uuid", None), 

1285 ] 

1286 

1287 def extract_padding(self, s): 

1288 # Needed to end each EIR_Element packet and make PacketListField work. 

1289 plen = EIR_Element.length_from(self) - 2 

1290 return s[:plen], s[plen:] 

1291 

1292 

1293class EIR_PublicTargetAddress(EIR_Element): 

1294 name = "Public Target Address" 

1295 fields_desc = [ 

1296 LEMACField('bd_addr', None) 

1297 ] 

1298 

1299 

1300class EIR_AdvertisingInterval(EIR_Element): 

1301 name = "Advertising Interval" 

1302 fields_desc = [ 

1303 MultipleTypeField( 

1304 [ 

1305 (ByteField("advertising_interval", 0), 

1306 lambda p: p.underlayer.len - 1 == 1), 

1307 (LEShortField("advertising_interval", 0), 

1308 lambda p: p.underlayer.len - 1 == 2), 

1309 (LEThreeBytesField("advertising_interval", 0), 

1310 lambda p: p.underlayer.len - 1 == 3), 

1311 (LEIntField("advertising_interval", 0), 

1312 lambda p: p.underlayer.len - 1 == 4), 

1313 ], 

1314 LEShortField("advertising_interval", 0) 

1315 ) 

1316 ] 

1317 

1318 

1319class EIR_LEBluetoothDeviceAddress(EIR_Element): 

1320 name = "LE Bluetooth Device Address" 

1321 fields_desc = [ 

1322 XBitField('reserved', 0, 7, tot_size=-1), 

1323 BitEnumField('addr_type', 0, 1, end_tot_size=-1, enum={ 

1324 0x0: 'Public', 

1325 0x1: 'Random' 

1326 }), 

1327 LEMACField('bd_addr', None) 

1328 ] 

1329 

1330 

1331class EIR_Appearance(EIR_Element): 

1332 name = "EIR_Appearance" 

1333 fields_desc = [ 

1334 BitEnumField('category', 0, 10, tot_size=-2, enum={ 

1335 0x000: 'Unknown', 

1336 0x001: 'Phone', 

1337 0x002: 'Computer', 

1338 0x003: 'Watch', 

1339 0x004: 'Clock', 

1340 0x005: 'Display', 

1341 0x006: 'Remote Control', 

1342 0x007: 'Eyeglasses', 

1343 0x008: 'Tag', 

1344 0x009: 'Keyring', 

1345 0x00A: 'Media Player', 

1346 0x00B: 'Barcode Scanner', 

1347 0x00C: 'Thermometer', 

1348 0x00D: 'Heart Rate Sensor', 

1349 0x00E: 'Blood Pressure', 

1350 0x00F: 'Human Interface Device', 

1351 0x010: 'Glucose Meter', 

1352 0x011: 'Running Walking Sensor', 

1353 0x012: 'Cycling', 

1354 0x013: 'Control Device', 

1355 0x014: 'Network Device', 

1356 0x015: 'Sensor', 

1357 0x016: 'Light Fixtures', 

1358 0x017: 'Fan', 

1359 0x018: 'HVAC', 

1360 0x019: 'Air Conditioning', 

1361 0x01A: 'Humidifier', 

1362 0x01B: 'Heating', 

1363 0x01C: 'Access Control', 

1364 0x01D: 'Motorized Device', 

1365 0x01E: 'Power Device', 

1366 0x01F: 'Light Source', 

1367 0x020: 'Window Covering', 

1368 0x021: 'Audio Sink', 

1369 0x022: 'Audio Source', 

1370 0x023: 'Motorized Vehicle', 

1371 0x024: 'Domestic Appliance', 

1372 0x025: 'Wearable Audio Device', 

1373 0x026: 'Aircraft', 

1374 0x027: 'AV Equipment', 

1375 0x028: 'Display Equipment', 

1376 0x029: 'Hearing aid', 

1377 0x02A: 'Gaming', 

1378 0x02B: 'Signage', 

1379 0x031: 'Pulse Oximeter', 

1380 0x032: 'Weight Scale', 

1381 0x033: 'Personal Mobility Device', 

1382 0x034: 'Continuous Glucose Monitor', 

1383 0x035: 'Insulin Pump', 

1384 0x036: 'Medication Delivery', 

1385 0x037: 'Spirometer', 

1386 0x051: 'Outdoor Sports Activity' 

1387 }), 

1388 XBitField('subcategory', 0, 6, end_tot_size=-2) 

1389 ] 

1390 

1391 @property 

1392 def appearance(self): 

1393 return (self.category << 6) + self.subcategory 

1394 

1395 

1396class EIR_ServiceData32BitUUID(EIR_Element): 

1397 name = 'EIR Service Data - 32-bit UUID' 

1398 fields_desc = [ 

1399 XLEIntField('svc_uuid', 0), 

1400 ] 

1401 

1402 def extract_padding(self, s): 

1403 # Needed to end each EIR_Element packet and make PacketListField work. 

1404 plen = EIR_Element.length_from(self) - 4 

1405 return s[:plen], s[plen:] 

1406 

1407 

1408class EIR_ServiceData128BitUUID(EIR_Element): 

1409 name = 'EIR Service Data - 128-bit UUID' 

1410 fields_desc = [ 

1411 UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV) 

1412 ] 

1413 

1414 def extract_padding(self, s): 

1415 # Needed to end each EIR_Element packet and make PacketListField work. 

1416 plen = EIR_Element.length_from(self) - 16 

1417 return s[:plen], s[plen:] 

1418 

1419 

1420class EIR_URI(EIR_Element): 

1421 name = 'EIR URI' 

1422 fields_desc = [ 

1423 ByteEnumField('scheme', 0, { 

1424 0x01: '', 

1425 0x02: 'aaa:', 

1426 0x03: 'aaas:', 

1427 0x04: 'about:', 

1428 0x05: 'acap:', 

1429 0x06: 'acct:', 

1430 0x07: 'cap:', 

1431 0x08: 'cid:', 

1432 0x09: 'coap:', 

1433 0x0A: 'coaps:', 

1434 0x0B: 'crid:', 

1435 0x0C: 'data:', 

1436 0x0D: 'dav:', 

1437 0x0E: 'dict:', 

1438 0x0F: 'dns:', 

1439 0x10: 'file:', 

1440 0x11: 'ftp:', 

1441 0x12: 'geo:', 

1442 0x13: 'go:', 

1443 0x14: 'gopher:', 

1444 0x15: 'h323:', 

1445 0x16: 'http:', 

1446 0x17: 'https:', 

1447 0x18: 'iax:', 

1448 0x19: 'icap:', 

1449 0x1A: 'im:', 

1450 0x1B: 'imap:', 

1451 0x1C: 'info:', 

1452 0x1D: 'ipp:', 

1453 0x1E: 'ipps:', 

1454 0x1F: 'iris:', 

1455 0x20: 'iris.beep:', 

1456 0x21: 'iris.xpc:', 

1457 0x22: 'iris.xpcs:', 

1458 0x23: 'iris.lwz:', 

1459 0x24: 'jabber:', 

1460 0x25: 'ldap:', 

1461 0x26: 'mailto:', 

1462 0x27: 'mid:', 

1463 0x28: 'msrp:', 

1464 0x29: 'msrps:', 

1465 0x2A: 'mtqp:', 

1466 0x2B: 'mupdate:', 

1467 0x2C: 'news:', 

1468 0x2D: 'nfs:', 

1469 0x2E: 'ni:', 

1470 0x2F: 'nih:', 

1471 0x30: 'nntp:', 

1472 0x31: 'opaquelocktoken:', 

1473 0x32: 'pop:', 

1474 0x33: 'pres:', 

1475 0x34: 'reload:', 

1476 0x35: 'rtsp:', 

1477 0x36: 'rtsps:', 

1478 0x37: 'rtspu:', 

1479 0x38: 'service:', 

1480 0x39: 'session:', 

1481 0x3A: 'shttp:', 

1482 0x3B: 'sieve:', 

1483 0x3C: 'sip:', 

1484 0x3D: 'sips:', 

1485 0x3E: 'sms:', 

1486 0x3F: 'snmp:', 

1487 0x40: 'soap.beep:', 

1488 0x41: 'soap.beeps:', 

1489 0x42: 'stun:', 

1490 0x43: 'stuns:', 

1491 0x44: 'tag:', 

1492 0x45: 'tel:', 

1493 0x46: 'telnet:', 

1494 0x47: 'tftp:', 

1495 0x48: 'thismessage:', 

1496 0x49: 'tn3270:', 

1497 0x4A: 'tip:', 

1498 0x4B: 'turn:', 

1499 0x4C: 'turns:', 

1500 0x4D: 'tv:', 

1501 0x4E: 'urn:', 

1502 0x4F: 'vemmi:', 

1503 0x50: 'ws:', 

1504 0x51: 'wss:', 

1505 0x52: 'xcon:', 

1506 0x53: 'xconuserid:', 

1507 0x54: 'xmlrpc.beep:', 

1508 0x55: 'xmlrpc.beeps:', 

1509 0x56: 'xmpp:', 

1510 0x57: 'z39.50r:', 

1511 0x58: 'z39.50s:', 

1512 0x59: 'acr:', 

1513 0x5A: 'adiumxtra:', 

1514 0x5B: 'afp:', 

1515 0x5C: 'afs:', 

1516 0x5D: 'aim:', 

1517 0x5E: 'apt:', 

1518 0x5F: 'attachment:', 

1519 0x60: 'aw:', 

1520 0x61: 'barion:', 

1521 0x62: 'beshare:', 

1522 0x63: 'bitcoin:', 

1523 0x64: 'bolo:', 

1524 0x65: 'callto:', 

1525 0x66: 'chrome:', 

1526 0x67: 'chromeextension:', 

1527 0x68: 'comeventbriteattendee:', 

1528 0x69: 'content:', 

1529 0x6A: 'cvs:', 

1530 0x6B: 'dlnaplaysingle:', 

1531 0x6C: 'dlnaplaycontainer:', 

1532 0x6D: 'dtn:', 

1533 0x6E: 'dvb:', 

1534 0x6F: 'ed2k:', 

1535 0x70: 'facetime:', 

1536 0x71: 'feed:', 

1537 0x72: 'feedready:', 

1538 0x73: 'finger:', 

1539 0x74: 'fish:', 

1540 0x75: 'gg:', 

1541 0x76: 'git:', 

1542 0x77: 'gizmoproject:', 

1543 0x78: 'gtalk:', 

1544 0x79: 'ham:', 

1545 0x7A: 'hcp:', 

1546 0x7B: 'icon:', 

1547 0x7C: 'ipn:', 

1548 0x7D: 'irc:', 

1549 0x7E: 'irc6:', 

1550 0x7F: 'ircs:', 

1551 0x80: 'itms:', 

1552 0x81: 'jar:', 

1553 0x82: 'jms:', 

1554 0x83: 'keyparc:', 

1555 0x84: 'lastfm:', 

1556 0x85: 'ldaps:', 

1557 0x86: 'magnet:', 

1558 0x87: 'maps:', 

1559 0x88: 'market:', 

1560 0x89: 'message:', 

1561 0x8A: 'mms:', 

1562 0x8B: 'mshelp:', 

1563 0x8C: 'mssettingspower:', 

1564 0x8D: 'msnim:', 

1565 0x8E: 'mumble:', 

1566 0x8F: 'mvn:', 

1567 0x90: 'notes:', 

1568 0x91: 'oid:', 

1569 0x92: 'palm:', 

1570 0x93: 'paparazzi:', 

1571 0x94: 'pkcs11:', 

1572 0x95: 'platform:', 

1573 0x96: 'proxy:', 

1574 0x97: 'psyc:', 

1575 0x98: 'query:', 

1576 0x99: 'res:', 

1577 0x9A: 'resource:', 

1578 0x9B: 'rmi:', 

1579 0x9C: 'rsync:', 

1580 0x9D: 'rtmfp:', 

1581 0x9E: 'rtmp:', 

1582 0x9F: 'secondlife:', 

1583 0xA0: 'sftp:', 

1584 0xA1: 'sgn:', 

1585 0xA2: 'skype:', 

1586 0xA3: 'smb:', 

1587 0xA4: 'smtp:', 

1588 0xA5: 'soldat:', 

1589 0xA6: 'spotify:', 

1590 0xA7: 'ssh:', 

1591 0xA8: 'steam:', 

1592 0xA9: 'submit:', 

1593 0xAA: 'svn:', 

1594 0xAB: 'teamspeak:', 

1595 0xAC: 'teliaeid:', 

1596 0xAD: 'things:', 

1597 0xAE: 'udp:', 

1598 0xAF: 'unreal:', 

1599 0xB0: 'ut2004:', 

1600 0xB1: 'ventrilo:', 

1601 0xB2: 'viewsource:', 

1602 0xB3: 'webcal:', 

1603 0xB4: 'wtai:', 

1604 0xB5: 'wyciwyg:', 

1605 0xB6: 'xfire:', 

1606 0xB7: 'xri:', 

1607 0xB8: 'ymsgr:', 

1608 0xB9: 'example:', 

1609 0xBA: 'mssettingscloudstorage:' 

1610 }), 

1611 StrLenField('uri_hier_part', None, length_from=EIR_Element.length_from) 

1612 ] 

1613 

1614 @property 

1615 def uri(self): 

1616 return EIR_URI.scheme.i2s[self.scheme] + self.uri_hier_part.decode('utf-8') 

1617 

1618 

1619class HCI_Command_Hdr(Packet): 

1620 name = "HCI Command header" 

1621 fields_desc = [XBitField("ogf", 0, 6, tot_size=-2), 

1622 XBitField("ocf", 0, 10, end_tot_size=-2), 

1623 LenField("len", None, fmt="B"), ] 

1624 

1625 def answers(self, other): 

1626 return False 

1627 

1628 @property 

1629 def opcode(self): 

1630 return (self.ogf << 10) + self.ocf 

1631 

1632 def post_build(self, p, pay): 

1633 p += pay 

1634 if self.len is None: 

1635 p = p[:2] + struct.pack("B", len(pay)) + p[3:] 

1636 return p 

1637 

1638 

1639# BUETOOTH CORE SPECIFICATION 5.4 | Vol 3, Part C 

1640# 8 EXTENDED INQUIRY RESPONSE 

1641 

1642class HCI_Extended_Inquiry_Response(Packet): 

1643 fields_desc = [ 

1644 PadField( 

1645 PacketListField( 

1646 "eir_data", [], 

1647 next_cls_cb=lambda *args: ( 

1648 (not args[2] or args[2].len != 0) and EIR_Hdr or conf.raw_layer 

1649 ) 

1650 ), 

1651 align=31, padwith=b"\0", 

1652 ), 

1653 ] 

1654 

1655 

1656# BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E 

1657# 7 HCI COMMANDS AND EVENTS 

1658# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01 

1659 

1660class HCI_Cmd_Inquiry(Packet): 

1661 """ 

1662 7.1.1 Inquiry command 

1663 """ 

1664 name = "HCI_Inquiry" 

1665 fields_desc = [XLE3BytesField("lap", 0x9E8B33), 

1666 ByteField("inquiry_length", 0), 

1667 ByteField("num_responses", 0)] 

1668 

1669 

1670class HCI_Cmd_Inquiry_Cancel(Packet): 

1671 """ 

1672 7.1.2 Inquiry Cancel command 

1673 """ 

1674 name = "HCI_Inquiry_Cancel" 

1675 

1676 

1677class HCI_Cmd_Periodic_Inquiry_Mode(Packet): 

1678 """ 

1679 7.1.3 Periodic Inquiry Mode command 

1680 """ 

1681 name = "HCI_Periodic_Inquiry_Mode" 

1682 fields_desc = [LEShortField("max_period_length", 0x0003), 

1683 LEShortField("min_period_length", 0x0002), 

1684 XLE3BytesField("lap", 0x9E8B33), 

1685 ByteField("inquiry_length", 0), 

1686 ByteField("num_responses", 0)] 

1687 

1688 

1689class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet): 

1690 """ 

1691 7.1.4 Exit Periodic Inquiry Mode command 

1692 """ 

1693 name = "HCI_Exit_Periodic_Inquiry_Mode" 

1694 

1695 

1696class HCI_Cmd_Create_Connection(Packet): 

1697 """ 

1698 7.1.5 Create Connection command 

1699 """ 

1700 name = "HCI_Create_Connection" 

1701 fields_desc = [LEMACField("bd_addr", None), 

1702 LEShortField("packet_type", 0xcc18), 

1703 ByteField("page_scan_repetition_mode", 0x02), 

1704 ByteField("reserved", 0x0), 

1705 LEShortField("clock_offset", 0x0), 

1706 ByteField("allow_role_switch", 0x1), ] 

1707 

1708 

1709class HCI_Cmd_Disconnect(Packet): 

1710 """ 

1711 7.1.6 Disconnect command 

1712 """ 

1713 name = "HCI_Disconnect" 

1714 fields_desc = [XLEShortField("handle", 0), 

1715 ByteField("reason", 0x13), ] 

1716 

1717 

1718class HCI_Cmd_Create_Connection_Cancel(Packet): 

1719 """ 

1720 7.1.7 Create Connection Cancel command 

1721 """ 

1722 name = "HCI_Create_Connection_Cancel" 

1723 fields_desc = [LEMACField("bd_addr", None), ] 

1724 

1725 

1726class HCI_Cmd_Accept_Connection_Request(Packet): 

1727 """ 

1728 7.1.8 Accept Connection Request command 

1729 """ 

1730 name = "HCI_Accept_Connection_Request" 

1731 fields_desc = [LEMACField("bd_addr", None), 

1732 ByteField("role", 0x1), ] 

1733 

1734 

1735class HCI_Cmd_Reject_Connection_Response(Packet): 

1736 """ 

1737 7.1.9 Reject Connection Request command 

1738 """ 

1739 name = "HCI_Reject_Connection_Response" 

1740 fields_desc = [LEMACField("bd_addr", None), 

1741 ByteField("reason", 0x1), ] 

1742 

1743 

1744class HCI_Cmd_Link_Key_Request_Reply(Packet): 

1745 """ 

1746 7.1.10 Link Key Request Reply command 

1747 """ 

1748 name = "HCI_Link_Key_Request_Reply" 

1749 fields_desc = [LEMACField("bd_addr", None), 

1750 NBytesField("link_key", None, 16), ] 

1751 

1752 

1753class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet): 

1754 """ 

1755 7.1.11 Link Key Request Negative Reply command 

1756 """ 

1757 name = "HCI_Link_Key_Request_Negative_Reply" 

1758 fields_desc = [LEMACField("bd_addr", None), ] 

1759 

1760 

1761class HCI_Cmd_PIN_Code_Request_Reply(Packet): 

1762 """ 

1763 7.1.12 PIN Code Request Reply command 

1764 """ 

1765 name = "HCI_PIN_Code_Request_Reply" 

1766 fields_desc = [LEMACField("bd_addr", None), 

1767 ByteField("pin_code_length", 7), 

1768 NBytesField("pin_code", b"\x00" * 16, sz=16), ] 

1769 

1770 

1771class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet): 

1772 """ 

1773 7.1.13 PIN Code Request Negative Reply command 

1774 """ 

1775 name = "HCI_PIN_Code_Request_Negative_Reply" 

1776 fields_desc = [LEMACField("bd_addr", None), ] 

1777 

1778 

1779class HCI_Cmd_Change_Connection_Packet_Type(Packet): 

1780 """ 

1781 7.1.14 Change Connection Packet Type command 

1782 """ 

1783 name = "HCI_Cmd_Change_Connection_Packet_Type" 

1784 fields_desc = [XLEShortField("connection_handle", None), 

1785 LEShortField("packet_type", 0), ] 

1786 

1787 

1788class HCI_Cmd_Authentication_Requested(Packet): 

1789 """ 

1790 7.1.15 Authentication Requested command 

1791 """ 

1792 name = "HCI_Authentication_Requested" 

1793 fields_desc = [LEShortField("handle", 0)] 

1794 

1795 

1796class HCI_Cmd_Set_Connection_Encryption(Packet): 

1797 """ 

1798 7.1.16 Set Connection Encryption command 

1799 """ 

1800 name = "HCI_Set_Connection_Encryption" 

1801 fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)] 

1802 

1803 

1804class HCI_Cmd_Change_Connection_Link_Key(Packet): 

1805 """ 

1806 7.1.17 Change Connection Link Key command 

1807 """ 

1808 name = "HCI_Change_Connection_Link_Key" 

1809 fields_desc = [LEShortField("handle", 0), ] 

1810 

1811 

1812class HCI_Cmd_Link_Key_Selection(Packet): 

1813 """ 

1814 7.1.18 Change Connection Link Key command 

1815 """ 

1816 name = "HCI_Cmd_Link_Key_Selection" 

1817 fields_desc = [ByteEnumField("handle", 0, {0: "Use semi-permanent Link Keys", 

1818 1: "Use Temporary Link Key", }), ] 

1819 

1820 

1821class HCI_Cmd_Remote_Name_Request(Packet): 

1822 """ 

1823 7.1.19 Remote Name Request command 

1824 """ 

1825 name = "HCI_Remote_Name_Request" 

1826 fields_desc = [LEMACField("bd_addr", None), 

1827 ByteField("page_scan_repetition_mode", 0x02), 

1828 ByteField("reserved", 0x0), 

1829 LEShortField("clock_offset", 0x0), ] 

1830 

1831 

1832class HCI_Cmd_Remote_Name_Request_Cancel(Packet): 

1833 """ 

1834 7.1.20 Remote Name Request Cancel command 

1835 """ 

1836 name = "HCI_Remote_Name_Request_Cancel" 

1837 fields_desc = [LEMACField("bd_addr", None), ] 

1838 

1839 

1840class HCI_Cmd_Read_Remote_Supported_Features(Packet): 

1841 """ 

1842 7.1.21 Read Remote Supported Features command 

1843 """ 

1844 name = "HCI_Read_Remote_Supported_Features" 

1845 fields_desc = [LEShortField("connection_handle", None), ] 

1846 

1847 

1848class HCI_Cmd_Read_Remote_Extended_Features(Packet): 

1849 """ 

1850 7.1.22 Read Remote Extended Features command 

1851 """ 

1852 name = "HCI_Read_Remote_Supported_Features" 

1853 fields_desc = [LEShortField("connection_handle", None), 

1854 ByteField("page_number", None), ] 

1855 

1856 

1857class HCI_Cmd_IO_Capability_Request_Reply(Packet): 

1858 """ 

1859 7.1.29 IO Capability Request Reply command 

1860 """ 

1861 name = "HCI_Read_Remote_Supported_Features" 

1862 fields_desc = [LEMACField("bd_addr", None), 

1863 ByteEnumField("io_capability", None, {0x00: "DisplayOnly", 

1864 0x01: "DisplayYesNo", 

1865 0x02: "KeyboardOnly", 

1866 0x03: "NoInputNoOutput", }), 

1867 ByteEnumField("oob_data_present", None, {0x00: "Not Present", 

1868 0x01: "P-192", 

1869 0x02: "P-256", 

1870 0x03: "P-192 + P-256", }), 

1871 ByteEnumField("authentication_requirement", None, 

1872 {0x00: "MITM Not Required", 

1873 0x01: "MITM Required, No Bonding", 

1874 0x02: "MITM Not Required + Dedicated Pairing", 

1875 0x03: "MITM Required + Dedicated Pairing", 

1876 0x04: "MITM Not Required, General Bonding", 

1877 0x05: "MITM Required + General Bonding"}), ] 

1878 

1879 

1880class HCI_Cmd_User_Confirmation_Request_Reply(Packet): 

1881 """ 

1882 7.1.30 User Confirmation Request Reply command 

1883 """ 

1884 name = "HCI_User_Confirmation_Request_Reply" 

1885 fields_desc = [LEMACField("bd_addr", None), ] 

1886 

1887 

1888class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet): 

1889 """ 

1890 7.1.31 User Confirmation Request Negative Reply command 

1891 """ 

1892 name = "HCI_User_Confirmation_Request_Negative_Reply" 

1893 fields_desc = [LEMACField("bd_addr", None), ] 

1894 

1895 

1896class HCI_Cmd_User_Passkey_Request_Reply(Packet): 

1897 """ 

1898 7.1.32 User Passkey Request Reply command 

1899 """ 

1900 name = "HCI_User_Passkey_Request_Reply" 

1901 fields_desc = [LEMACField("bd_addr", None), 

1902 LEIntField("numeric_value", None), ] 

1903 

1904 

1905class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet): 

1906 """ 

1907 7.1.33 User Passkey Request Negative Reply command 

1908 """ 

1909 name = "HCI_User_Passkey_Request_Negative_Reply" 

1910 fields_desc = [LEMACField("bd_addr", None), ] 

1911 

1912 

1913class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet): 

1914 """ 

1915 7.1.34 Remote OOB Data Request Reply command 

1916 """ 

1917 name = "HCI_Remote_OOB_Data_Request_Reply" 

1918 fields_desc = [LEMACField("bd_addr", None), 

1919 NBytesField("C", b"\x00" * 16, sz=16), 

1920 NBytesField("R", b"\x00" * 16, sz=16), ] 

1921 

1922 

1923class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet): 

1924 """ 

1925 7.1.35 Remote OOB Data Request Negative Reply command 

1926 """ 

1927 name = "HCI_Remote_OOB_Data_Request_Negative_Reply" 

1928 fields_desc = [LEMACField("bd_addr", None), ] 

1929 

1930 

1931# 7.2 Link Policy commands, the OGF is defined as 0x02 

1932 

1933class HCI_Cmd_Hold_Mode(Packet): 

1934 name = "HCI_Hold_Mode" 

1935 fields_desc = [LEShortField("connection_handle", 0), 

1936 LEShortField("hold_mode_max_interval", 0x0002), 

1937 LEShortField("hold_mode_min_interval", 0x0002), ] 

1938 

1939 

1940# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03 

1941 

1942class HCI_Cmd_Set_Event_Mask(Packet): 

1943 """ 

1944 7.3.1 Set Event Mask command 

1945 """ 

1946 name = "HCI_Set_Event_Mask" 

1947 fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501 

1948 

1949 

1950class HCI_Cmd_Reset(Packet): 

1951 """ 

1952 7.3.2 Reset command 

1953 """ 

1954 name = "HCI_Reset" 

1955 

1956 

1957class HCI_Cmd_Set_Event_Filter(Packet): 

1958 """ 

1959 7.3.3 Set Event Filter command 

1960 """ 

1961 name = "HCI_Set_Event_Filter" 

1962 fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ] 

1963 

1964 

1965class HCI_Cmd_Write_Local_Name(Packet): 

1966 """ 

1967 7.3.11 Write Local Name command 

1968 """ 

1969 name = "HCI_Write_Local_Name" 

1970 fields_desc = [StrFixedLenField('name', '', length=248)] 

1971 

1972 

1973class HCI_Cmd_Read_Local_Name(Packet): 

1974 """ 

1975 7.3.12 Read Local Name command 

1976 """ 

1977 name = "HCI_Read_Local_Name" 

1978 

1979 

1980class HCI_Cmd_Write_Connect_Accept_Timeout(Packet): 

1981 name = "HCI_Write_Connection_Accept_Timeout" 

1982 fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec 

1983 

1984 

1985class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): 

1986 name = "HCI_Write_Extended_Inquiry_Response" 

1987 fields_desc = [ByteField("fec_required", 0), 

1988 HCI_Extended_Inquiry_Response] 

1989 

1990 

1991class HCI_Cmd_Read_LE_Host_Support(Packet): 

1992 name = "HCI_Read_LE_Host_Support" 

1993 

1994 

1995class HCI_Cmd_Write_LE_Host_Support(Packet): 

1996 name = "HCI_Write_LE_Host_Support" 

1997 fields_desc = [ByteField("supported", 1), 

1998 ByteField("unused", 1), ] 

1999 

2000 

2001# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04 

2002 

2003class HCI_Cmd_Read_Local_Version_Information(Packet): 

2004 """ 

2005 7.4.1 Read Local Version Information command 

2006 """ 

2007 name = "HCI_Read_Local_Version_Information" 

2008 

2009 

2010class HCI_Cmd_Read_Local_Extended_Features(Packet): 

2011 """ 

2012 7.4.4 Read Local Extended Features command 

2013 """ 

2014 name = "HCI_Read_Local_Extended_Features" 

2015 fields_desc = [ByteField("page_number", 0)] 

2016 

2017 

2018class HCI_Cmd_Read_BD_Addr(Packet): 

2019 """ 

2020 7.4.6 Read BD_ADDR command 

2021 """ 

2022 name = "HCI_Read_BD_ADDR" 

2023 

2024 

2025# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05 

2026 

2027class HCI_Cmd_Read_Link_Quality(Packet): 

2028 name = "HCI_Read_Link_Quality" 

2029 fields_desc = [LEShortField("handle", 0)] 

2030 

2031 

2032class HCI_Cmd_Read_RSSI(Packet): 

2033 name = "HCI_Read_RSSI" 

2034 fields_desc = [LEShortField("handle", 0)] 

2035 

2036 

2037# 7.6 TESTING COMMANDS, the OGF is defined as 0x06 

2038 

2039class HCI_Cmd_Read_Loopback_Mode(Packet): 

2040 name = "HCI_Read_Loopback_Mode" 

2041 

2042 

2043class HCI_Cmd_Write_Loopback_Mode(Packet): 

2044 name = "HCI_Write_Loopback_Mode" 

2045 fields_desc = [ByteEnumField("loopback_mode", 0, 

2046 {0: "no loopback", 

2047 1: "enable local loopback", 

2048 2: "enable remote loopback"})] 

2049 

2050 

2051# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08 

2052 

2053class HCI_Cmd_LE_Set_Event_Mask(Packet): 

2054 name = 'HCI_LE_Set_Event_Mask' 

2055 fields_desc = [StrFixedLenField('mask', b'\xff\xff\xff\xff\xff\x1f\x00\x00', 8)] 

2056 

2057 

2058class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet): 

2059 name = "HCI_LE_Read_Buffer_Size [v1]" 

2060 

2061 

2062class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet): 

2063 name = "HCI_LE_Read_Buffer_Size [v2]" 

2064 

2065 

2066class HCI_Cmd_LE_Read_Local_Supported_Features(Packet): 

2067 name = "HCI_LE_Read_Local_Supported_Features" 

2068 

2069 

2070class HCI_Cmd_LE_Set_Random_Address(Packet): 

2071 name = "HCI_LE_Set_Random_Address" 

2072 fields_desc = [LEMACField("addr", None)] 

2073 deprecated_fields = {"address": ("addr", "2.7.0")} 

2074 

2075 

2076class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): 

2077 name = "HCI_LE_Set_Advertising_Parameters" 

2078 fields_desc = [LEShortField("interval_min", 0x0800), 

2079 LEShortField("interval_max", 0x0800), 

2080 ByteEnumField("adv_type", 0, { 

2081 0: "ADV_IND", 

2082 1: "ADV_DIRECT_IND", 

2083 2: "ADV_SCAN_IND", 

2084 3: "ADV_NONCONN_IND", 

2085 4: "ADV_DIRECT_IND_LOW"}), 

2086 ByteEnumField("own_addr_type", 0, { 

2087 0: "public", 

2088 1: "random"}), 

2089 ByteEnumField("peer_addr_type", 0, { 

2090 0: "public", 

2091 1: "random"}), 

2092 LEMACField("peer_addr", None), 

2093 ByteField("channel_map", 7), 

2094 ByteEnumField("filter_policy", 0, { 

2095 0: "all:all", 

2096 1: "connect:all scan:whitelist", 

2097 2: "connect:whitelist scan:all", 

2098 3: "all:whitelist"}), ] 

2099 deprecated_fields = { 

2100 "oatype": ("own_addr_type", "2.7.0"), 

2101 "datype": ("peer_addr_type", "2.7.0"), 

2102 "daddr": ("peer_addr", "2.7.0"), 

2103 } 

2104 

2105 

2106class HCI_Cmd_LE_Set_Extended_Advertising_Parameters(Packet): 

2107 name = 'HCI_LE_Set_Extended_Advertising_Parameters' 

2108 fields_desc = [ByteField('handle', 0), 

2109 LEShortField('properties', 19), 

2110 LEThreeBytesField('pri_interval_min', 160), 

2111 LEThreeBytesField('pri_interval_max', 160), 

2112 ByteField('pri_channel_map', 7), 

2113 ByteEnumField('own_addr_type', 0, { 

2114 0: 'public', 

2115 1: 'random', 

2116 2: 'rpa_pub', 

2117 3: 'rpa_rand'}), 

2118 ByteEnumField('peer_addr_type', 0, { 

2119 0: 'public', 

2120 1: 'random', 

2121 2: 'rpa_pub', 

2122 3: 'rpa_rand'}), 

2123 LEMACField('peer_addr', None), 

2124 ByteEnumField("filter_policy", 0, { 

2125 0: "all:all", 

2126 1: "connect:all scan:whitelist", 

2127 2: "connect:whitelist scan:all", 

2128 3: "all:whitelist"}), 

2129 SignedByteField('tx_power', 127), 

2130 ByteEnumField('pri_phy', 1, {1: '1M', 3: 'Coded'}), 

2131 ByteField('sec_max_skip', 0), 

2132 ByteEnumField('sec_phy', 1, {1: '1M', 2: '2M', 3: 'Coded'}), 

2133 ByteField('sid', 0), 

2134 ByteField('scan_req_notify_enable', 0)] 

2135 

2136 

2137class HCI_Cmd_LE_Set_Advertising_Set_Random_Address(Packet): 

2138 name = 'HCI_LE_Set_Advertising_Set_Random_Address' 

2139 fields_desc = [ByteField('handle', 0), LEMACField('addr', None)] 

2140 

2141 

2142class HCI_Cmd_LE_Set_Advertising_Data(Packet): 

2143 name = "HCI_LE_Set_Advertising_Data" 

2144 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"), 

2145 PadField( 

2146 PacketListField("data", [], EIR_Hdr, 

2147 length_from=lambda pkt: pkt.len), 

2148 align=31, padwith=b"\0"), ] 

2149 

2150 

2151class HCI_Cmd_LE_Set_Extended_Advertising_Data(Packet): 

2152 name = 'HCI_LE_Set_Extended_Advertising_Data' 

2153 fields_desc = [ByteField('handle', 0), 

2154 ByteEnumField('operation', 3, { 

2155 0: 'intermediate_frag', 

2156 1: 'first_frag', 

2157 2: 'last_frag', 

2158 3: 'complete', 

2159 4: 'unchanged_data'}), 

2160 ByteEnumField('frag_pref', 1, {0: 'allow_frag', 1: 'no_frag'}), 

2161 FieldLenField('len', None, length_of='data', fmt='B'), 

2162 PacketListField('data', [], EIR_Hdr, length_from=lambda pkt: pkt.len)] # noqa: E501 

2163 

2164 

2165class HCI_Cmd_LE_Set_Scan_Response_Data(Packet): 

2166 name = "HCI_LE_Set_Scan_Response_Data" 

2167 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"), 

2168 StrLenField("data", "", length_from=lambda pkt: pkt.len), ] 

2169 

2170 

2171class HCI_Cmd_LE_Set_Advertise_Enable(Packet): 

2172 name = "HCI_LE_Set_Advertising_Enable" 

2173 fields_desc = [ByteField("enable", 0)] 

2174 

2175 

2176class Extended_Advertise_Set(Packet): 

2177 name = 'Extended Advertising Set' 

2178 fields_desc = [ByteField('handle', 0), 

2179 LEShortField('duration', 0), 

2180 ByteField('max_events', 0)] 

2181 

2182 

2183class HCI_Cmd_LE_Set_Extended_Advertise_Enable(Packet): 

2184 name = 'HCI_LE_Set_Extended_Advertising_Enable' 

2185 fields_desc = [ByteEnumField('enable', 1, {0: 'disable', 1: 'enable'}), 

2186 FieldLenField('num_sets', None, count_of='sets', fmt='B'), 

2187 PacketListField('sets', [], Extended_Advertise_Set, count_from=lambda pkt: pkt.num_sets)] # noqa: E501 

2188 

2189 

2190class HCI_Cmd_LE_Set_Scan_Parameters(Packet): 

2191 name = "HCI_LE_Set_Scan_Parameters" 

2192 fields_desc = [ByteEnumField("type", 0, {0: "passive", 1: "active"}), 

2193 XLEShortField("interval", 16), 

2194 XLEShortField("window", 16), 

2195 ByteEnumField("addr_type", 0, { 

2196 0: "public", 

2197 1: "random", 

2198 2: "rpa (pub)", 

2199 3: "rpa (random)"}), 

2200 ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})] 

2201 deprecated_fields = {"atype": ("addr_type", "2.7.0")} 

2202 

2203 

2204class HCI_Cmd_LE_Set_Extended_Scan_Parameters(Packet): 

2205 name = 'HCI_LE_Set_Extended_Scan_Parameters' 

2206 fields_desc = [ 

2207 ByteEnumField('own_address_type', 0, { 

2208 0: 'public', 

2209 1: 'random', 

2210 2: 'rpa_pub', 

2211 3: 'rpa_rand'}), 

2212 ByteEnumField('scanning_filter_policy', 0, { 

2213 0: 'basic', 

2214 1: 'whitelist', 

2215 2: 'basic_rpa', 

2216 3: 'whitelist_rpa'}), 

2217 ByteField('scanning_phys', 1), 

2218 ConditionalField(ByteEnumField('scan_type_1m', 1, { 

2219 0: 'passive', 

2220 1: 'active'}), lambda pkt: pkt.scanning_phys & 1), 

2221 ConditionalField(LEShortField('scan_interval_1m', 16), 

2222 lambda pkt: pkt.scanning_phys & 1), 

2223 ConditionalField(LEShortField('scan_window_1m', 16), 

2224 lambda pkt: pkt.scanning_phys & 1), 

2225 ConditionalField(ByteEnumField('scan_type_2m', 1, { 

2226 0: 'passive', 

2227 1: 'active'}), lambda pkt: pkt.scanning_phys & 2), 

2228 ConditionalField(LEShortField('scan_interval_2m', 16), 

2229 lambda pkt: pkt.scanning_phys & 2), 

2230 ConditionalField(LEShortField('scan_window_2m', 16), 

2231 lambda pkt: pkt.scanning_phys & 2), 

2232 ConditionalField(ByteEnumField('scan_type_coded', 1, { 

2233 0: 'passive', 

2234 1: 'active'}), lambda pkt: pkt.scanning_phys & 4), 

2235 ConditionalField(LEShortField('scan_interval_coded', 16), 

2236 lambda pkt: pkt.scanning_phys & 4), 

2237 ConditionalField(LEShortField('scan_window_coded', 16), 

2238 lambda pkt: pkt.scanning_phys & 4)] 

2239 

2240 

2241class HCI_Cmd_LE_Set_Scan_Enable(Packet): 

2242 name = "HCI_LE_Set_Scan_Enable" 

2243 fields_desc = [ByteField("enable", 1), 

2244 ByteField("filter_dups", 1), ] 

2245 

2246 

2247class HCI_Cmd_LE_Set_Extended_Scan_Enable(Packet): 

2248 name = 'HCI_LE_Set_Extended_Scan_Enable' 

2249 fields_desc = [ByteEnumField('enable', 1, {0: 'disabled', 1: 'enabled'}), 

2250 ByteEnumField('filter_dups', 1, { 

2251 0: 'disabled', 

2252 1: 'enabled', 

2253 2: 'reset_period'}), 

2254 LEShortField('duration', 500), 

2255 LEShortField('period', 0)] 

2256 

2257 

2258class HCI_Cmd_LE_Create_Connection(Packet): 

2259 name = "HCI_LE_Create_Connection" 

2260 fields_desc = [LEShortField("interval", 96), 

2261 LEShortField("window", 48), 

2262 ByteEnumField("filter", 0, {0: "address"}), 

2263 ByteEnumField("peer_addr_type", 0, {0: "public", 1: "random"}), 

2264 LEMACField("peer_addr", None), 

2265 ByteEnumField("own_addr_type", 0, {0: "public", 1: "random"}), 

2266 LEShortField("min_interval", 40), 

2267 LEShortField("max_interval", 56), 

2268 LEShortField("latency", 0), 

2269 LEShortField("timeout", 42), 

2270 LEShortField("min_ce", 0), 

2271 LEShortField("max_ce", 0), ] 

2272 deprecated_fields = { 

2273 "patype": ("peer_addr_type", "2.7.0"), 

2274 "paddr": ("peer_addr", "2.7.0"), 

2275 "atype": ("own_addr_type", "2.7.0"), 

2276 } 

2277 

2278 

2279class HCI_Cmd_LE_Extended_Create_Connection(Packet): 

2280 name = 'HCI_LE_Extended_Create_Connection' 

2281 fields_desc = [ByteEnumField('filter_policy', 0, {0: 'peer_addr', 1: 'accept_list'}), # noqa: E501 

2282 ByteEnumField('address_type', 0, { 

2283 0: 'public', 

2284 1: 'random', 

2285 2: 'rpa_pub', 

2286 3: 'rpa_rand'}), 

2287 ByteEnumField('peer_addr_type', 0, { 

2288 0: 'public', 

2289 1: 'random', 

2290 2: 'rpa_pub', 

2291 3: 'rpa_rand'}), 

2292 LEMACField('peer_addr', None), 

2293 ByteField('phys', 1), 

2294 ConditionalField(LEShortField('interval_1m', 96), 

2295 lambda pkt: pkt.phys & 1), 

2296 ConditionalField(LEShortField('window_1m', 96), 

2297 lambda pkt: pkt.phys & 1), 

2298 ConditionalField(LEShortField('min_interval_1m', 40), 

2299 lambda pkt: pkt.phys & 1), 

2300 ConditionalField(LEShortField('max_interval_1m', 56), 

2301 lambda pkt: pkt.phys & 1), 

2302 ConditionalField(LEShortField('latency_1m', 0), 

2303 lambda pkt: pkt.phys & 1), 

2304 ConditionalField(LEShortField('timeout_1m', 42), 

2305 lambda pkt: pkt.phys & 1), 

2306 ConditionalField(LEShortField('min_ce_1m', 0), 

2307 lambda pkt: pkt.phys & 1), 

2308 ConditionalField(LEShortField('max_ce_1m', 0), 

2309 lambda pkt: pkt.phys & 1), 

2310 ConditionalField(LEShortField('interval_2m', 96), 

2311 lambda pkt: pkt.phys & 2), 

2312 ConditionalField(LEShortField('window_2m', 96), 

2313 lambda pkt: pkt.phys & 2), 

2314 ConditionalField(LEShortField('min_interval_2m', 40), 

2315 lambda pkt: pkt.phys & 2), 

2316 ConditionalField(LEShortField('max_interval_2m', 56), 

2317 lambda pkt: pkt.phys & 2), 

2318 ConditionalField(LEShortField('latency_2m', 0), 

2319 lambda pkt: pkt.phys & 2), 

2320 ConditionalField(LEShortField('timeout_2m', 42), 

2321 lambda pkt: pkt.phys & 2), 

2322 ConditionalField(LEShortField('min_ce_2m', 0), 

2323 lambda pkt: pkt.phys & 2), 

2324 ConditionalField(LEShortField('max_ce_2m', 0), 

2325 lambda pkt: pkt.phys & 2), 

2326 ConditionalField(LEShortField('interval_coded', 96), 

2327 lambda pkt: pkt.phys & 4), 

2328 ConditionalField(LEShortField('window_coded', 96), 

2329 lambda pkt: pkt.phys & 4), 

2330 ConditionalField(LEShortField('min_interval_coded', 40), 

2331 lambda pkt: pkt.phys & 4), 

2332 ConditionalField(LEShortField('max_interval_coded', 56), 

2333 lambda pkt: pkt.phys & 4), 

2334 ConditionalField(LEShortField('latency_coded', 0), 

2335 lambda pkt: pkt.phys & 4), 

2336 ConditionalField(LEShortField('timeout_coded', 42), 

2337 lambda pkt: pkt.phys & 4), 

2338 ConditionalField(LEShortField('min_ce_coded', 0), 

2339 lambda pkt: pkt.phys & 4), 

2340 ConditionalField(LEShortField('max_ce_coded', 0), 

2341 lambda pkt: pkt.phys & 4)] 

2342 

2343 

2344class HCI_Cmd_LE_Create_Connection_Cancel(Packet): 

2345 name = "HCI_LE_Create_Connection_Cancel" 

2346 

2347 

2348class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet): 

2349 name = "HCI_LE_Read_Filter_Accept_List_Size" 

2350 

2351 

2352class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet): 

2353 name = "HCI_LE_Clear_Filter_Accept_List" 

2354 

2355 

2356class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet): 

2357 name = "HCI_LE_Add_Device_To_Filter_Accept_List" 

2358 fields_desc = [ByteEnumField("addr_type", 0, {0: "public", 

2359 1: "random", 

2360 0xff: "anonymous"}), 

2361 LEMACField("addr", None)] 

2362 

2363 

2364class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501 

2365 name = "HCI_LE_Remove_Device_From_Filter_Accept_List" 

2366 

2367 

2368class HCI_Cmd_LE_Connection_Update(Packet): 

2369 name = "HCI_LE_Connection_Update" 

2370 fields_desc = [XLEShortField("handle", 0), 

2371 XLEShortField("min_interval", 0), 

2372 XLEShortField("max_interval", 0), 

2373 XLEShortField("latency", 0), 

2374 XLEShortField("timeout", 0), 

2375 LEShortField("min_ce", 0), 

2376 LEShortField("max_ce", 0xffff), ] 

2377 

2378 

2379class HCI_Cmd_LE_Read_Remote_Features(Packet): 

2380 name = "HCI_LE_Read_Remote_Features" 

2381 fields_desc = [LEShortField("handle", 64)] 

2382 

2383 

2384class HCI_Cmd_LE_Enable_Encryption(Packet): 

2385 name = "HCI_LE_Enable_Encryption" 

2386 fields_desc = [LEShortField("handle", 0), 

2387 StrFixedLenField("rand", None, 8), 

2388 XLEShortField("ediv", 0), 

2389 StrFixedLenField("ltk", b'\x00' * 16, 16), ] 

2390 

2391 

2392class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet): 

2393 name = "HCI_LE_Long_Term_Key_Request_Reply" 

2394 fields_desc = [LEShortField("handle", 0), 

2395 StrFixedLenField("ltk", b'\x00' * 16, 16), ] 

2396 

2397 

2398class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): 

2399 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply" 

2400 fields_desc = [LEShortField("handle", 0), ] 

2401 

2402 

2403class HCI_Event_Hdr(Packet): 

2404 name = "HCI Event header" 

2405 fields_desc = [XByteField("code", 0), 

2406 LenField("len", None, fmt="B"), ] 

2407 

2408 def answers(self, other): 

2409 if HCI_Command_Hdr not in other: 

2410 return False 

2411 

2412 # Delegate answers to event types 

2413 return self.payload.answers(other) 

2414 

2415 

2416class HCI_Event_Inquiry_Complete(Packet): 

2417 """ 

2418 7.7.1 Inquiry Complete event 

2419 """ 

2420 name = "HCI_Inquiry_Complete" 

2421 fields_desc = [ 

2422 ByteEnumField('status', 0, _bluetooth_error_codes) 

2423 ] 

2424 

2425 

2426class HCI_Event_Inquiry_Result(Packet): 

2427 """ 

2428 7.7.2 Inquiry Result event 

2429 """ 

2430 name = "HCI_Inquiry_Result" 

2431 fields_desc = [ 

2432 ByteField("num_response", 0x00), 

2433 FieldListField("addr", None, LEMACField("addr", None), 

2434 count_from=lambda p: p.num_response), 

2435 FieldListField("page_scan_repetition_mode", None, 

2436 ByteField("page_scan_repetition_mode", 0), 

2437 count_from=lambda p: p.num_response), 

2438 FieldListField("reserved", None, LEShortField("reserved", 0), 

2439 count_from=lambda p: p.num_response), 

2440 FieldListField("device_class", None, XLE3BytesField("device_class", 0), 

2441 count_from=lambda p: p.num_response), 

2442 FieldListField("clock_offset", None, LEShortField("clock_offset", 0), 

2443 count_from=lambda p: p.num_response) 

2444 ] 

2445 

2446 

2447class HCI_Event_Connection_Complete(Packet): 

2448 """ 

2449 7.7.3 Connection Complete event 

2450 """ 

2451 name = "HCI_Connection_Complete" 

2452 fields_desc = [ByteEnumField('status', 0, _bluetooth_error_codes), 

2453 LEShortField("handle", 0x0100), 

2454 LEMACField("bd_addr", None), 

2455 ByteEnumField("link_type", 0, {0: "SCO connection", 

2456 1: "ACL connection", }), 

2457 ByteEnumField("encryption_enabled", 0, 

2458 {0: "link level encryption disabled", 

2459 1: "link level encryption enabled", }), ] 

2460 

2461 

2462class HCI_Event_Disconnection_Complete(Packet): 

2463 """ 

2464 7.7.5 Disconnection Complete event 

2465 """ 

2466 name = "HCI_Disconnection_Complete" 

2467 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes), 

2468 LEShortField("handle", 0), 

2469 XByteField("reason", 0), ] 

2470 

2471 

2472class HCI_Event_Remote_Name_Request_Complete(Packet): 

2473 """ 

2474 7.7.7 Remote Name Request Complete event 

2475 """ 

2476 name = "HCI_Remote_Name_Request_Complete" 

2477 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes), 

2478 LEMACField("bd_addr", None), 

2479 StrFixedLenField("remote_name", b"\x00", 248), ] 

2480 

2481 

2482class HCI_Event_Encryption_Change(Packet): 

2483 """ 

2484 7.7.8 Encryption Change event 

2485 """ 

2486 name = "HCI_Encryption_Change" 

2487 fields_desc = [ByteEnumField("status", 0, {0: "change has occurred"}), 

2488 LEShortField("handle", 0), 

2489 ByteEnumField("enabled", 0, {0: "OFF", 1: "ON (LE)", 2: "ON (BR/EDR)"}), ] # noqa: E501 

2490 

2491 

2492class HCI_Event_Read_Remote_Supported_Features_Complete(Packet): 

2493 """ 

2494 7.7.11 Read Remote Supported Features Complete event 

2495 """ 

2496 name = "HCI_Read_Remote_Supported_Features_Complete" 

2497 fields_desc = [ 

2498 ByteEnumField('status', 0, _bluetooth_error_codes), 

2499 LEShortField('handle', 0), 

2500 FlagsField('lmp_features', 0, -64, _bluetooth_features) 

2501 ] 

2502 

2503 

2504class HCI_Event_Read_Remote_Version_Information_Complete(Packet): 

2505 """ 

2506 7.7.12 Read Remote Version Information Complete event 

2507 """ 

2508 name = "HCI_Read_Remote_Version_Information" 

2509 fields_desc = [ 

2510 ByteEnumField('status', 0, _bluetooth_error_codes), 

2511 LEShortField('handle', 0), 

2512 ByteField('version', 0x00), 

2513 LEShortField('manufacturer_name', 0x0000), 

2514 LEShortField('subversion', 0x0000) 

2515 ] 

2516 

2517 

2518class HCI_Event_Command_Complete(Packet): 

2519 """ 

2520 7.7.14 Command Complete event 

2521 """ 

2522 name = "HCI_Command_Complete" 

2523 fields_desc = [ByteField("number", 0), 

2524 XLEShortField("opcode", 0), 

2525 ByteEnumField("status", 0, _bluetooth_error_codes)] 

2526 

2527 def answers(self, other): 

2528 if HCI_Command_Hdr not in other: 

2529 return False 

2530 

2531 return other[HCI_Command_Hdr].opcode == self.opcode 

2532 

2533 

2534class HCI_Event_Command_Status(Packet): 

2535 """ 

2536 7.7.15 Command Status event 

2537 """ 

2538 name = "HCI_Command_Status" 

2539 fields_desc = [ByteEnumField("status", 0, {0: "pending"}), 

2540 ByteField("number", 0), 

2541 XLEShortField("opcode", None), ] 

2542 

2543 def answers(self, other): 

2544 if HCI_Command_Hdr not in other: 

2545 return False 

2546 

2547 return other[HCI_Command_Hdr].opcode == self.opcode 

2548 

2549 

2550class HCI_Event_Number_Of_Completed_Packets(Packet): 

2551 """ 

2552 7.7.19 Number Of Completed Packets event 

2553 """ 

2554 name = "HCI_Number_Of_Completed_Packets" 

2555 fields_desc = [ByteField("num_handles", 0), 

2556 FieldListField("connection_handle_list", None, 

2557 LEShortField("connection_handle", 0), 

2558 count_from=lambda p: p.num_handles), 

2559 FieldListField("num_completed_packets_list", None, 

2560 LEShortField("num_completed_packets", 0), 

2561 count_from=lambda p: p.num_handles)] 

2562 

2563 

2564class HCI_Event_Link_Key_Request(Packet): 

2565 """ 

2566 7.7.23 Link Key Request event 

2567 """ 

2568 name = 'HCI_Link_Key_Request' 

2569 fields_desc = [ 

2570 LEMACField('bd_addr', None) 

2571 ] 

2572 

2573 

2574class HCI_Event_Inquiry_Result_With_Rssi(Packet): 

2575 """ 

2576 7.7.33 Inquiry Result with RSSI event 

2577 """ 

2578 name = "HCI_Inquiry_Result_with_RSSI" 

2579 fields_desc = [ 

2580 ByteField("num_response", 0x00), 

2581 FieldListField("bd_addr", None, LEMACField, 

2582 count_from=lambda p: p.num_response), 

2583 FieldListField("page_scan_repetition_mode", None, ByteField, 

2584 count_from=lambda p: p.num_response), 

2585 FieldListField("reserved", None, LEShortField, 

2586 count_from=lambda p: p.num_response), 

2587 FieldListField("device_class", None, XLE3BytesField, 

2588 count_from=lambda p: p.num_response), 

2589 FieldListField("clock_offset", None, LEShortField, 

2590 count_from=lambda p: p.num_response), 

2591 FieldListField("rssi", None, SignedByteField, 

2592 count_from=lambda p: p.num_response) 

2593 ] 

2594 

2595 

2596class HCI_Event_Read_Remote_Extended_Features_Complete(Packet): 

2597 """ 

2598 7.7.34 Read Remote Extended Features Complete event 

2599 """ 

2600 name = "HCI_Read_Remote_Extended_Features_Complete" 

2601 fields_desc = [ 

2602 ByteEnumField('status', 0, _bluetooth_error_codes), 

2603 LEShortField('handle', 0), 

2604 ByteField('page', 0x00), 

2605 ByteField('max_page', 0x00), 

2606 XLELongField('extended_features', 0) 

2607 ] 

2608 

2609 

2610class HCI_Event_Extended_Inquiry_Result(Packet): 

2611 """ 

2612 7.7.38 Extended Inquiry Result event 

2613 """ 

2614 name = "HCI_Extended_Inquiry_Result" 

2615 fields_desc = [ 

2616 ByteField('num_response', 0x01), 

2617 LEMACField('bd_addr', None), 

2618 ByteField('page_scan_repetition_mode', 0x00), 

2619 ByteField('reserved', 0x00), 

2620 XLE3BytesField('device_class', 0x000000), 

2621 LEShortField('clock_offset', 0x0000), 

2622 SignedByteField('rssi', 0x00), 

2623 HCI_Extended_Inquiry_Response, 

2624 ] 

2625 

2626 

2627class HCI_Event_IO_Capability_Response(Packet): 

2628 """ 

2629 7.7.41 IO Capability Response event 

2630 """ 

2631 name = "HCI_IO_Capability_Response" 

2632 fields_desc = [ 

2633 LEMACField('bd_addr', None), 

2634 ByteField('io_capability', 0x00), 

2635 ByteField('oob_data_present', 0x00), 

2636 ByteField('authentication_requirements', 0x00) 

2637 ] 

2638 

2639 

2640class HCI_Event_LE_Meta(Packet): 

2641 """ 

2642 7.7.65 LE Meta event 

2643 """ 

2644 name = "HCI_LE_Meta" 

2645 fields_desc = [ByteEnumField("event", 0, { 

2646 0x01: "connection_complete", 

2647 0x02: "advertising_report", 

2648 0x03: "connection_update_complete", 

2649 0x04: "read_remote_features_page_0_complete", 

2650 0x05: "long_term_key_request", 

2651 0x06: "remote_connection_parameter_request", 

2652 0x07: "data_length_change", 

2653 0x08: "read_local_p256_public_key_complete", 

2654 0x09: "generate_dhkey_complete", 

2655 0x0a: "enhanced_connection_complete_v1", 

2656 0x0b: "directed_advertising_report", 

2657 0x0c: "phy_update_complete", 

2658 0x0d: "extended_advertising_report", 

2659 0x29: "enhanced_connection_complete_v2" 

2660 }), ] 

2661 

2662 def answers(self, other): 

2663 if not self.payload: 

2664 return False 

2665 

2666 # Delegate answers to payload 

2667 return self.payload.answers(other) 

2668 

2669 

2670class HCI_Cmd_Complete_Read_Local_Name(Packet): 

2671 """ 

2672 7.3.12 Read Local Name command complete 

2673 """ 

2674 name = 'Read Local Name command complete' 

2675 fields_desc = [StrFixedLenField('local_name', '', length=248)] 

2676 

2677 

2678class HCI_Cmd_Complete_Read_Local_Version_Information(Packet): 

2679 """ 

2680 7.4.1 Read Local Version Information command complete 

2681 """ 

2682 name = 'Read Local Version Information' 

2683 fields_desc = [ 

2684 ByteEnumField('hci_version', 0, _bluetooth_core_specification_versions), 

2685 LEShortField('hci_subversion', 0), 

2686 ByteEnumField('lmp_version', 0, _bluetooth_core_specification_versions), 

2687 LEShortEnumField('company_identifier', 0, BLUETOOTH_CORE_COMPANY_IDENTIFIERS), 

2688 LEShortField('lmp_subversion', 0)] 

2689 

2690 

2691class HCI_Cmd_Complete_Read_Local_Extended_Features(Packet): 

2692 """ 

2693 7.4.4 Read Local Extended Features command complete 

2694 """ 

2695 name = 'Read Local Extended Features command complete' 

2696 fields_desc = [ 

2697 ByteField('page', 0x00), 

2698 ByteField('max_page', 0x00), 

2699 XLELongField('extended_features', 0) 

2700 ] 

2701 

2702 

2703class HCI_Cmd_Complete_Read_BD_Addr(Packet): 

2704 """ 

2705 7.4.6 Read BD_ADDR command complete 

2706 """ 

2707 name = "Read BD Addr" 

2708 fields_desc = [LEMACField("addr", None), ] 

2709 

2710 

2711class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet): 

2712 name = "LE Read White List Size" 

2713 fields_desc = [ByteField("status", 0), 

2714 ByteField("size", 0), ] 

2715 

2716 

2717class HCI_LE_Meta_Connection_Complete(Packet): 

2718 name = "Connection Complete" 

2719 fields_desc = [ByteEnumField("status", 0, {0: "success"}), 

2720 LEShortField("handle", 0), 

2721 ByteEnumField("role", 0, {0: "master"}), 

2722 ByteEnumField("peer_addr_type", 0, {0: "public", 1: "random"}), 

2723 LEMACField("peer_addr", None), 

2724 LEShortField("interval", 54), 

2725 LEShortField("latency", 0), 

2726 LEShortField("supervision", 42), 

2727 XByteField("master_clock_accuracy", 5)] 

2728 deprecated_fields = { 

2729 "patype": ("peer_addr_type", "2.7.0"), 

2730 "paddr": ("peer_addr", "2.7.0"), 

2731 "clock_latency": ("master_clock_accuracy", "2.7.0"), 

2732 } 

2733 

2734 def answers(self, other): 

2735 if HCI_Cmd_LE_Create_Connection in other: 

2736 cmd = other[HCI_Cmd_LE_Create_Connection] 

2737 elif HCI_Cmd_LE_Extended_Create_Connection in other: 

2738 cmd = other[HCI_Cmd_LE_Extended_Create_Connection] 

2739 else: 

2740 return False 

2741 

2742 return (cmd.peer_addr_type == self.peer_addr_type and 

2743 cmd.peer_addr == self.peer_addr) 

2744 

2745 

2746class HCI_LE_Meta_Enhanced_Connection_Complete(Packet): 

2747 name = 'LE Enhanced Connection Complete' 

2748 fields_desc = [ByteEnumField('status', 0, {0: 'success'}), 

2749 LEShortField('handle', 0), 

2750 ByteEnumField('role', 0, {0: 'master', 1: 'slave'}), 

2751 ByteEnumField('peer_addr_type', 0, { 

2752 0: 'public', 

2753 1: 'random', 

2754 2: 'public_identity', 

2755 3: 'random_identity'}), 

2756 LEMACField('peer_addr', None), 

2757 LEMACField('local_rpa', None), 

2758 LEMACField('peer_rpa', None), 

2759 LEShortField('interval', 54), 

2760 LEShortField('latency', 0), 

2761 LEShortField('supervision', 42), 

2762 XByteField('master_clock_accuracy', 5)] 

2763 

2764 def answers(self, other): 

2765 if HCI_Cmd_LE_Create_Connection in other: 

2766 cmd = other[HCI_Cmd_LE_Create_Connection] 

2767 elif HCI_Cmd_LE_Extended_Create_Connection in other: 

2768 cmd = other[HCI_Cmd_LE_Extended_Create_Connection] 

2769 else: 

2770 return False 

2771 

2772 return cmd.peer_addr_type == self.peer_addr_type and cmd.peer_addr == self.peer_addr # noqa: E501 

2773 

2774 

2775class HCI_LE_Meta_Connection_Update_Complete(Packet): 

2776 name = "Connection Update Complete" 

2777 fields_desc = [ByteEnumField("status", 0, {0: "success"}), 

2778 LEShortField("handle", 0), 

2779 LEShortField("interval", 54), 

2780 LEShortField("latency", 0), 

2781 LEShortField("timeout", 42), ] 

2782 

2783 

2784class HCI_LE_Meta_Advertising_Report(Packet): 

2785 name = "Advertising Report" 

2786 fields_desc = [ByteEnumField("type", 0, {0: "conn_und", 4: "scan_rsp"}), 

2787 ByteEnumField("addr_type", 0, {0: "public", 1: "random"}), 

2788 LEMACField("addr", None), 

2789 FieldLenField("len", None, length_of="data", fmt="B"), 

2790 PacketListField("data", [], EIR_Hdr, 

2791 length_from=lambda pkt: pkt.len), 

2792 SignedByteField("rssi", 0)] 

2793 deprecated_fields = {"atype": ("addr_type", "2.7.0")} 

2794 

2795 def extract_padding(self, s): 

2796 return '', s 

2797 

2798 

2799class HCI_LE_Meta_Advertising_Reports(Packet): 

2800 name = "Advertising Reports" 

2801 fields_desc = [FieldLenField("len", None, count_of="reports", fmt="B"), 

2802 PacketListField("reports", None, 

2803 HCI_LE_Meta_Advertising_Report, 

2804 count_from=lambda pkt: pkt.len)] 

2805 

2806 

2807class HCI_LE_Meta_Long_Term_Key_Request(Packet): 

2808 name = "Long Term Key Request" 

2809 fields_desc = [LEShortField("handle", 0), 

2810 StrFixedLenField("rand", None, 8), 

2811 XLEShortField("ediv", 0), ] 

2812 

2813 

2814class HCI_LE_Meta_Extended_Advertising_Report(Packet): 

2815 name = "Extended Advertising Report" 

2816 fields_desc = [ 

2817 BitField("reserved0", 0, 1), 

2818 BitEnumField("data_status", 0, 2, { 

2819 0b00: "complete", 

2820 0b01: "incomplete", 

2821 0b10: "incomplete_truncated", 

2822 0b11: "reserved" 

2823 }), 

2824 BitField("legacy", 0, 1), 

2825 BitField("scan_response", 0, 1), 

2826 BitField("directed", 0, 1), 

2827 BitField("scannable", 0, 1), 

2828 BitField("connectable", 0, 1), 

2829 ByteField("reserved", 0), 

2830 ByteEnumField("addr_type", 0, { 

2831 0x00: "public_device_address", 

2832 0x01: "random_device_address", 

2833 0x02: "public_identity_address", 

2834 0x03: "random_identity_address", 

2835 0xff: "anonymous" 

2836 }), 

2837 LEMACField('addr', None), 

2838 ByteEnumField("primary_phy", 0, { 

2839 0x01: "le_1m", 

2840 0x03: "le_coded_s8", 

2841 0x04: "le_coded_s2" 

2842 }), 

2843 ByteEnumField("secondary_phy", 0, { 

2844 0x01: "le_1m", 

2845 0x02: "le_2m", 

2846 0x03: "le_coded_s8", 

2847 0x04: "le_coded_s2" 

2848 }), 

2849 ByteField("advertising_sid", 0xff), 

2850 ByteField("tx_power", 0x7f), 

2851 SignedByteField("rssi", 0x00), 

2852 LEShortField("periodic_advertising_interval", 0x0000), 

2853 ByteEnumField("direct_addr_type", 0, { 

2854 0x00: "public_device_address", 

2855 0x01: "non_resolvable_private_address", 

2856 0x02: "resolvable_private_address_resolved_0", 

2857 0x03: "resolvable_private_address_resolved_1", 

2858 0xfe: "resolvable_private_address_unable_resolve"}), 

2859 LEMACField("direct_addr", None), 

2860 FieldLenField("data_length", None, length_of="data", fmt="B"), 

2861 PacketListField("data", [], EIR_Hdr, 

2862 length_from=lambda pkt: pkt.data_length), 

2863 ] 

2864 deprecated_fields = { 

2865 "address_type": ("addr_type", "2.7.0"), 

2866 "address": ("addr", "2.7.0"), 

2867 "direct_address_type": ("direct_addr_type", "2.7.0"), 

2868 "direct_address": ("direct_addr", "2.7.0"), 

2869 } 

2870 

2871 def extract_padding(self, s): 

2872 return '', s 

2873 

2874 

2875class HCI_LE_Meta_Extended_Advertising_Reports(Packet): 

2876 name = "Extended Advertising Reports" 

2877 fields_desc = [FieldLenField("num_reports", None, count_of="reports", fmt="B"), 

2878 PacketListField("reports", None, 

2879 HCI_LE_Meta_Extended_Advertising_Report, 

2880 count_from=lambda pkt: pkt.num_reports)] 

2881 

2882 

2883bind_layers(HCI_PHDR_Hdr, HCI_Hdr) 

2884 

2885bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1) 

2886bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2) 

2887bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4) 

2888bind_layers(HCI_Hdr, conf.raw_layer,) 

2889 

2890conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr) 

2891conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr) 

2892 

2893 

2894# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01 

2895bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry, ogf=0x01, ocf=0x0001) 

2896bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry_Cancel, ogf=0x01, ocf=0x0002) 

2897bind_layers(HCI_Command_Hdr, HCI_Cmd_Periodic_Inquiry_Mode, ogf=0x01, ocf=0x0003) 

2898bind_layers(HCI_Command_Hdr, HCI_Cmd_Exit_Peiodic_Inquiry_Mode, ogf=0x01, ocf=0x0004) 

2899bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, ogf=0x01, ocf=0x0005) 

2900bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, ogf=0x01, ocf=0x0006) 

2901bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection_Cancel, ogf=0x01, ocf=0x0008) 

2902bind_layers(HCI_Command_Hdr, HCI_Cmd_Accept_Connection_Request, ogf=0x01, ocf=0x0009) 

2903bind_layers(HCI_Command_Hdr, HCI_Cmd_Reject_Connection_Response, ogf=0x01, ocf=0x000a) 

2904bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b) 

2905bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply, 

2906 ogf=0x01, ocf=0x000c) 

2907bind_layers(HCI_Command_Hdr, HCI_Cmd_PIN_Code_Request_Reply, ogf=0x01, ocf=0x000d) 

2908bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type, 

2909 ogf=0x01, ocf=0x000f) 

2910bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, ogf=0x01, ocf=0x0011) 

2911bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, ogf=0x01, ocf=0x0013) 

2912bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Link_Key, ogf=0x01, ocf=0x0017) 

2913bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019) 

2914bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request_Cancel, ogf=0x01, ocf=0x001a) 

2915bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, 

2916 ogf=0x01, ocf=0x001b) 

2917bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features, 

2918 ogf=0x01, ocf=0x001c) 

2919bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b) 

2920bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply, 

2921 ogf=0x01, ocf=0x002c) 

2922bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply, 

2923 ogf=0x01, ocf=0x002d) 

2924bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Reply, ogf=0x01, ocf=0x002e) 

2925bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply, 

2926 ogf=0x01, ocf=0x002f) 

2927bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply, 

2928 ogf=0x01, ocf=0x0030) 

2929bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply, 

2930 ogf=0x01, ocf=0x0033) 

2931 

2932# 7.2 Link Policy commands, the OGF is defined as 0x02 

2933bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001) 

2934 

2935# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03 

2936bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, ogf=0x03, ocf=0x0001) 

2937bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, ogf=0x03, ocf=0x0003) 

2938bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, ogf=0x03, ocf=0x0005) 

2939bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, ogf=0x03, ocf=0x0013) 

2940bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Name, ogf=0x03, ocf=0x0014) 

2941bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Connect_Accept_Timeout, ogf=0x03, ocf=0x0016) 

2942bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, ogf=0x03, ocf=0x0052) # noqa: E501 

2943bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_LE_Host_Support, ogf=0x03, ocf=0x006c) 

2944bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_LE_Host_Support, ogf=0x03, ocf=0x006d) 

2945 

2946# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04 

2947bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Version_Information, ogf=0x04, ocf=0x0001) # noqa: E501 

2948bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Extended_Features, ogf=0x04, ocf=0x0004) 

2949bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, ogf=0x04, ocf=0x0009) 

2950 

2951# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05 

2952bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Link_Quality, ogf=0x05, ocf=0x0003) 

2953bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_RSSI, ogf=0x05, ocf=0x0005) 

2954 

2955# 7.6 TESTING COMMANDS, the OGF is defined as 0x06 

2956bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Loopback_Mode, ogf=0x06, ocf=0x0001) 

2957bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Loopback_Mode, ogf=0x06, ocf=0x0002) 

2958 

2959# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08 

2960bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Event_Mask, ogf=0x08, ocf=0x0001) 

2961bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V1, ogf=0x08, ocf=0x0002) 

2962bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V2, ogf=0x08, ocf=0x0060) 

2963bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features, 

2964 ogf=0x08, ocf=0x0003) 

2965bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, ogf=0x08, ocf=0x0005) 

2966bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, ogf=0x08, ocf=0x0006) # noqa: E501 

2967bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Set_Random_Address, ogf=0x08, ocf=0x0035) # noqa: E501 

2968bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Advertising_Parameters, ogf=0x08, ocf=0x0036) # noqa: E501 

2969bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, ogf=0x08, ocf=0x0008) 

2970bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Advertising_Data, ogf=0x08, ocf=0x0037) # noqa: E501 

2971bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, ogf=0x08, ocf=0x0009) 

2972bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, ogf=0x08, ocf=0x000a) 

2973bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Advertise_Enable, ogf=0x08, ocf=0x0039) # noqa: E501 

2974bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, ogf=0x08, ocf=0x000b) 

2975bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Scan_Parameters, ogf=0x08, ocf=0x0041) # noqa: E501 

2976bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, ogf=0x08, ocf=0x000c) 

2977bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Scan_Enable, ogf=0x08, ocf=0x0042) 

2978bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, ogf=0x08, ocf=0x000d) 

2979bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Extended_Create_Connection, ogf=0x08, ocf=0x0043) # noqa: E501 

2980bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, ogf=0x08, ocf=0x000e) # noqa: E501 

2981bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size, 

2982 ogf=0x08, ocf=0x000f) 

2983bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_Filter_Accept_List, ogf=0x08, ocf=0x0010) 

2984bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_Filter_Accept_List, ogf=0x08, ocf=0x0011) # noqa: E501 

2985bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List, ogf=0x08, ocf=0x0012) # noqa: E501 

2986bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, ogf=0x08, ocf=0x0013) 

2987bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Features, ogf=0x08, ocf=0x0016) # noqa: E501 

2988bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Enable_Encryption, ogf=0x08, ocf=0x0019) # noqa: E501 

2989bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, ogf=0x08, ocf=0x001a) # noqa: E501 

2990bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, ogf=0x08, ocf=0x001b) # noqa: E501 

2991 

2992# 7.7 EVENTS 

2993bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Complete, code=0x01) 

2994bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result, code=0x02) 

2995bind_layers(HCI_Event_Hdr, HCI_Event_Connection_Complete, code=0x03) 

2996bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x05) 

2997bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Name_Request_Complete, code=0x07) 

2998bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x08) 

2999bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Supported_Features_Complete, code=0x0b) 

3000bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Version_Information_Complete, code=0x0c) # noqa: E501 

3001bind_layers(HCI_Event_Hdr, HCI_Event_Command_Complete, code=0x0e) 

3002bind_layers(HCI_Event_Hdr, HCI_Event_Command_Status, code=0x0f) 

3003bind_layers(HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13) 

3004bind_layers(HCI_Event_Hdr, HCI_Event_Link_Key_Request, code=0x17) 

3005bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result_With_Rssi, code=0x22) 

3006bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Extended_Features_Complete, code=0x23) 

3007bind_layers(HCI_Event_Hdr, HCI_Event_Extended_Inquiry_Result, code=0x2f) 

3008bind_layers(HCI_Event_Hdr, HCI_Event_IO_Capability_Response, code=0x32) 

3009bind_layers(HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e) 

3010 

3011bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Name, opcode=0x0c14) # noqa: E501 

3012bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Version_Information, opcode=0x1001) # noqa: E501 

3013bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Extended_Features, opcode=0x1004) # noqa: E501 

3014bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009) # noqa: E501 

3015bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_LE_Read_White_List_Size, opcode=0x200f) # noqa: E501 

3016 

3017bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=0x01) 

3018bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Enhanced_Connection_Complete, event=0x0a) 

3019bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=0x02) 

3020bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=0x03) 

3021bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=0x05) 

3022bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Extended_Advertising_Reports, event=0x0d) 

3023 

3024bind_layers(EIR_Hdr, EIR_Flags, type=0x01) 

3025bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02) 

3026bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03) 

3027bind_layers(EIR_Hdr, EIR_IncompleteList32BitServiceUUIDs, type=0x04) 

3028bind_layers(EIR_Hdr, EIR_CompleteList32BitServiceUUIDs, type=0x05) 

3029bind_layers(EIR_Hdr, EIR_IncompleteList128BitServiceUUIDs, type=0x06) 

3030bind_layers(EIR_Hdr, EIR_CompleteList128BitServiceUUIDs, type=0x07) 

3031bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08) 

3032bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09) 

3033bind_layers(EIR_Hdr, EIR_Device_ID, type=0x10) 

3034bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a) 

3035bind_layers(EIR_Hdr, EIR_ClassOfDevice, type=0x0d) 

3036bind_layers(EIR_Hdr, EIR_SecureSimplePairingHashC192, type=0x0e) 

3037bind_layers(EIR_Hdr, EIR_SecureSimplePairingRandomizerR192, type=0x0f) 

3038bind_layers(EIR_Hdr, EIR_SecurityManagerOOBFlags, type=0x11) 

3039bind_layers(EIR_Hdr, EIR_PeripheralConnectionIntervalRange, type=0x12) 

3040bind_layers(EIR_Hdr, EIR_ServiceSolicitation16BitUUID, type=0x14) 

3041bind_layers(EIR_Hdr, EIR_ServiceSolicitation128BitUUID, type=0x15) 

3042bind_layers(EIR_Hdr, EIR_ServiceData16BitUUID, type=0x16) 

3043bind_layers(EIR_Hdr, EIR_PublicTargetAddress, type=0x17) 

3044bind_layers(EIR_Hdr, EIR_Appearance, type=0x19) 

3045bind_layers(EIR_Hdr, EIR_AdvertisingInterval, type=0x1a) 

3046bind_layers(EIR_Hdr, EIR_LEBluetoothDeviceAddress, type=0x1b) 

3047bind_layers(EIR_Hdr, EIR_ServiceData32BitUUID, type=0x20) 

3048bind_layers(EIR_Hdr, EIR_ServiceData128BitUUID, type=0x21) 

3049bind_layers(EIR_Hdr, EIR_URI, type=0x24) 

3050bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff) 

3051bind_layers(EIR_Hdr, EIR_Raw) 

3052 

3053bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,) 

3054bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1) 

3055bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=5) # LE L2CAP Signaling Channel 

3056bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1) 

3057bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2) 

3058bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3) 

3059bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4) 

3060bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5) 

3061bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6) 

3062bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7) 

3063bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8) 

3064bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9) 

3065bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10) 

3066bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11) 

3067bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12) 

3068bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13) 

3069bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14) 

3070bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15) 

3071bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16) 

3072bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17) 

3073bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18) 

3074bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19) 

3075bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20) 

3076bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21) 

3077bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22) 

3078bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23) 

3079bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24) 

3080bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25) 

3081bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26) 

3082bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4) 

3083bind_layers(ATT_Hdr, ATT_Error_Response, opcode=0x1) 

3084bind_layers(ATT_Hdr, ATT_Exchange_MTU_Request, opcode=0x2) 

3085bind_layers(ATT_Hdr, ATT_Exchange_MTU_Response, opcode=0x3) 

3086bind_layers(ATT_Hdr, ATT_Find_Information_Request, opcode=0x4) 

3087bind_layers(ATT_Hdr, ATT_Find_Information_Response, opcode=0x5) 

3088bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Request, opcode=0x6) 

3089bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Response, opcode=0x7) 

3090bind_layers(ATT_Hdr, ATT_Read_By_Type_Request_128bit, opcode=0x8) 

3091bind_layers(ATT_Hdr, ATT_Read_By_Type_Request, opcode=0x8) 

3092bind_layers(ATT_Hdr, ATT_Read_By_Type_Response, opcode=0x9) 

3093bind_layers(ATT_Hdr, ATT_Read_Request, opcode=0xa) 

3094bind_layers(ATT_Hdr, ATT_Read_Response, opcode=0xb) 

3095bind_layers(ATT_Hdr, ATT_Read_Blob_Request, opcode=0xc) 

3096bind_layers(ATT_Hdr, ATT_Read_Blob_Response, opcode=0xd) 

3097bind_layers(ATT_Hdr, ATT_Read_Multiple_Request, opcode=0xe) 

3098bind_layers(ATT_Hdr, ATT_Read_Multiple_Response, opcode=0xf) 

3099bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Request, opcode=0x10) 

3100bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Response, opcode=0x11) 

3101bind_layers(ATT_Hdr, ATT_Write_Request, opcode=0x12) 

3102bind_layers(ATT_Hdr, ATT_Write_Response, opcode=0x13) 

3103bind_layers(ATT_Hdr, ATT_Prepare_Write_Request, opcode=0x16) 

3104bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17) 

3105bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18) 

3106bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19) 

3107bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52) 

3108bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b) 

3109bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d) 

3110bind_layers(L2CAP_Hdr, SM_Hdr, cid=6) 

3111bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=0x01) 

3112bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=0x02) 

3113bind_layers(SM_Hdr, SM_Confirm, sm_command=0x03) 

3114bind_layers(SM_Hdr, SM_Random, sm_command=0x04) 

3115bind_layers(SM_Hdr, SM_Failed, sm_command=0x05) 

3116bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=0x06) 

3117bind_layers(SM_Hdr, SM_Master_Identification, sm_command=0x07) 

3118bind_layers(SM_Hdr, SM_Identity_Information, sm_command=0x08) 

3119bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=0x09) 

3120bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a) 

3121bind_layers(SM_Hdr, SM_Security_Request, sm_command=0x0b) 

3122bind_layers(SM_Hdr, SM_Public_Key, sm_command=0x0c) 

3123bind_layers(SM_Hdr, SM_DHKey_Check, sm_command=0x0d) 

3124 

3125 

3126############### 

3127# HCI Monitor # 

3128############### 

3129 

3130 

3131# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L27 

3132class HCI_Mon_Hdr(Packet): 

3133 name = 'Bluetooth Linux Monitor Transport Header' 

3134 fields_desc = [ 

3135 LEShortEnumField('opcode', None, { 

3136 0: "New index", 

3137 1: "Delete index", 

3138 2: "Command pkt", 

3139 3: "Event pkt", 

3140 4: "ACL TX pkt", 

3141 5: "ACL RX pkt", 

3142 6: "SCO TX pkt", 

3143 7: "SCO RX pkt", 

3144 8: "Open index", 

3145 9: "Close index", 

3146 10: "Index info", 

3147 11: "Vendor diag", 

3148 12: "System note", 

3149 13: "User logging", 

3150 14: "Ctrl open", 

3151 15: "Ctrl close", 

3152 16: "Ctrl command", 

3153 17: "Ctrl event", 

3154 18: "ISO TX pkt", 

3155 19: "ISO RX pkt", 

3156 }), 

3157 LEShortField('adapter_id', None), 

3158 LEShortField('len', None) 

3159 ] 

3160 

3161 

3162# https://www.tcpdump.org/linktypes/LINKTYPE_BLUETOOTH_LINUX_MONITOR.html 

3163class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr): 

3164 name = 'Bluetooth Linux Monitor Transport Pcap Header' 

3165 fields_desc = [ 

3166 ShortField('adapter_id', None), 

3167 ShortField('opcode', None) 

3168 ] 

3169 

3170 

3171class HCI_Mon_New_Index(Packet): 

3172 name = 'Bluetooth Linux Monitor Transport New Index Packet' 

3173 fields_desc = [ 

3174 ByteEnumField('bus', 0, { 

3175 0x00: "BR/EDR", 

3176 0x01: "AMP" 

3177 }), 

3178 ByteEnumField('type', 0, { 

3179 0x00: "Virtual", 

3180 0x01: "USB", 

3181 0x02: "PC Card", 

3182 0x03: "UART", 

3183 0x04: "RS232", 

3184 0x05: "PCI", 

3185 0x06: "SDIO" 

3186 }), 

3187 LEMACField('addr', None), 

3188 StrFixedLenField('devname', None, 8) 

3189 ] 

3190 

3191 

3192class HCI_Mon_Index_Info(Packet): 

3193 name = 'Bluetooth Linux Monitor Transport Index Info Packet' 

3194 fields_desc = [ 

3195 LEMACField('addr', None), 

3196 XLEShortField('manufacturer', None) 

3197 ] 

3198 

3199 

3200class HCI_Mon_System_Note(Packet): 

3201 name = 'Bluetooth Linux Monitor Transport System Note Packet' 

3202 fields_desc = [ 

3203 StrNullField('note', None) 

3204 ] 

3205 

3206 

3207# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L34 

3208bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0) 

3209bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2) 

3210bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3) 

3211bind_layers(HCI_Mon_Hdr, HCI_ACL_Hdr, opcode=5) 

3212bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10) 

3213bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12) 

3214 

3215conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr) 

3216 

3217 

3218########### 

3219# Helpers # 

3220########### 

3221 

3222class LowEnergyBeaconHelper: 

3223 """ 

3224 Helpers for building packets for Bluetooth Low Energy Beacons. 

3225 

3226 Implementers provide a :meth:`build_eir` implementation. 

3227 

3228 This is designed to be used as a mix-in -- see 

3229 ``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples. 

3230 """ 

3231 

3232 # Basic flags that should be used by most beacons. 

3233 base_eir = [EIR_Hdr() / EIR_Flags(flags=[ 

3234 "general_disc_mode", "br_edr_not_supported"]), ] 

3235 

3236 def build_eir(self): 

3237 """ 

3238 Builds a list of EIR messages to wrap this frame. 

3239 

3240 Users of this helper must implement this method. 

3241 

3242 :return: List of HCI_Hdr with payloads that describe this beacon type 

3243 :rtype: list[scapy.bluetooth.HCI_Hdr] 

3244 """ 

3245 raise NotImplementedError("build_eir") 

3246 

3247 def build_advertising_report(self): 

3248 """ 

3249 Builds a HCI_LE_Meta_Advertising_Report containing this frame. 

3250 

3251 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report 

3252 """ 

3253 

3254 return HCI_LE_Meta_Advertising_Report( 

3255 type=0, # Undirected 

3256 addr_type=1, # Random address 

3257 data=self.build_eir() 

3258 ) 

3259 

3260 def build_set_advertising_data(self): 

3261 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame. 

3262 

3263 This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers. 

3264 

3265 :rtype: scapy.bluetooth.HCI_Hdr 

3266 """ 

3267 

3268 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data( 

3269 data=self.build_eir() 

3270 ) 

3271 

3272 

3273########### 

3274# Sockets # 

3275########### 

3276 

3277class BluetoothSocketError(BaseException): 

3278 pass 

3279 

3280 

3281class BluetoothCommandError(BaseException): 

3282 pass 

3283 

3284 

3285class BluetoothL2CAPSocket(SuperSocket): 

3286 desc = "read/write packets on a connected L2CAP socket" 

3287 

3288 def __init__(self, bt_address): 

3289 if WINDOWS: 

3290 warning("Not available on Windows") 

3291 return 

3292 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, 

3293 socket.BTPROTO_L2CAP) 

3294 s.connect((bt_address, 0)) 

3295 self.ins = self.outs = s 

3296 

3297 def recv(self, x=MTU): 

3298 return L2CAP_CmdHdr(self.ins.recv(x)) 

3299 

3300 

3301class BluetoothRFCommSocket(BluetoothL2CAPSocket): 

3302 """read/write packets on a connected RFCOMM socket""" 

3303 

3304 def __init__(self, bt_address, port=0): 

3305 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, 

3306 socket.BTPROTO_RFCOMM) 

3307 s.connect((bt_address, port)) 

3308 self.ins = self.outs = s 

3309 

3310 

3311class BluetoothHCISocket(SuperSocket): 

3312 desc = "read/write on a BlueTooth HCI socket" 

3313 

3314 def __init__(self, iface=0x10000, type=None): 

3315 if WINDOWS: 

3316 warning("Not available on Windows") 

3317 return 

3318 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) # noqa: E501 

3319 s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR, 1) 

3320 s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP, 1) 

3321 s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff, 0xffffffff, 0xffffffff, 0)) # type mask, event mask, event mask, opcode # noqa: E501 

3322 s.bind((iface,)) 

3323 self.ins = self.outs = s 

3324# s.connect((peer,0)) 

3325 

3326 def recv(self, x=MTU): 

3327 return HCI_Hdr(self.ins.recv(x)) 

3328 

3329 

3330class sockaddr_hci(ctypes.Structure): 

3331 _fields_ = [ 

3332 ("sin_family", ctypes.c_ushort), 

3333 ("hci_dev", ctypes.c_ushort), 

3334 ("hci_channel", ctypes.c_ushort), 

3335 ] 

3336 

3337 

3338class _BluetoothLibcSocket(SuperSocket): 

3339 def __init__(self, socket_domain, socket_type, socket_protocol, sock_address): 

3340 # type: (int, int, int, sockaddr_hci) -> None 

3341 if WINDOWS: 

3342 warning("Not available on Windows") 

3343 return 

3344 # Python socket and bind implementations do not allow us to pass down 

3345 # the correct parameters. We must call libc functions directly via 

3346 # ctypes. 

3347 sockaddr_hcip = ctypes.POINTER(sockaddr_hci) 

3348 from ctypes.util import find_library 

3349 libc = ctypes.cdll.LoadLibrary(find_library("c")) 

3350 

3351 socket_c = libc.socket 

3352 socket_c.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int) 

3353 socket_c.restype = ctypes.c_int 

3354 

3355 bind = libc.bind 

3356 bind.argtypes = (ctypes.c_int, 

3357 ctypes.POINTER(sockaddr_hci), 

3358 ctypes.c_int) 

3359 bind.restype = ctypes.c_int 

3360 

3361 # Socket 

3362 s = socket_c(socket_domain, socket_type, socket_protocol) 

3363 if s < 0: 

3364 raise BluetoothSocketError( 

3365 f"Unable to open socket({socket_domain}, {socket_type}, " 

3366 f"{socket_protocol})") 

3367 

3368 # Bind 

3369 r = bind(s, sockaddr_hcip(sock_address), sizeof(sock_address)) 

3370 if r != 0: 

3371 raise BluetoothSocketError("Unable to bind") 

3372 

3373 self.hci_fd = s 

3374 self.ins = self.outs = socket.fromfd( 

3375 s, socket_domain, socket_type, socket_protocol) 

3376 

3377 def readable(self, timeout=0): 

3378 (ins, _, _) = select.select([self.ins], [], [], timeout) 

3379 return len(ins) > 0 

3380 

3381 def flush(self): 

3382 while self.readable(): 

3383 self.recv() 

3384 

3385 def close(self): 

3386 if self.closed: 

3387 return 

3388 

3389 # Properly close socket so we can free the device 

3390 from ctypes.util import find_library 

3391 libc = ctypes.cdll.LoadLibrary(find_library("c")) 

3392 

3393 close = libc.close 

3394 close.restype = ctypes.c_int 

3395 self.closed = True 

3396 if hasattr(self, "outs"): 

3397 if not hasattr(self, "ins") or self.ins != self.outs: 

3398 if self.outs and (WINDOWS or self.outs.fileno() != -1): 

3399 close(self.outs.fileno()) 

3400 if hasattr(self, "ins"): 

3401 if self.ins and (WINDOWS or self.ins.fileno() != -1): 

3402 close(self.ins.fileno()) 

3403 if hasattr(self, "hci_fd"): 

3404 close(self.hci_fd) 

3405 

3406 

3407class BluetoothUserSocket(_BluetoothLibcSocket): 

3408 desc = "read/write H4 over a Bluetooth user channel" 

3409 

3410 def __init__(self, adapter_index=0): 

3411 sa = sockaddr_hci() 

3412 sa.sin_family = socket.AF_BLUETOOTH 

3413 sa.hci_dev = adapter_index 

3414 sa.hci_channel = HCI_CHANNEL_USER 

3415 super().__init__( 

3416 socket_domain=socket.AF_BLUETOOTH, 

3417 socket_type=socket.SOCK_RAW, 

3418 socket_protocol=socket.BTPROTO_HCI, 

3419 sock_address=sa) 

3420 

3421 def send_command(self, cmd): 

3422 opcode = cmd[HCI_Command_Hdr].opcode 

3423 self.send(cmd) 

3424 while True: 

3425 r = self.recv() 

3426 if r.type == 0x04 and r.code in (0xe, 0xf) and r.opcode == opcode: 

3427 if hasattr(r, 'status') and r.status != 0: 

3428 raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status)) # noqa: E501 

3429 return r 

3430 

3431 def recv(self, x=MTU): 

3432 return HCI_Hdr(self.ins.recv(x)) 

3433 

3434 

3435class BluetoothMonitorSocket(_BluetoothLibcSocket): 

3436 desc = "Read/write over a Bluetooth monitor channel" 

3437 

3438 def __init__(self): 

3439 sa = sockaddr_hci() 

3440 sa.sin_family = socket.AF_BLUETOOTH 

3441 sa.hci_dev = HCI_DEV_NONE 

3442 sa.hci_channel = HCI_CHANNEL_MONITOR 

3443 super().__init__( 

3444 socket_domain=socket.AF_BLUETOOTH, 

3445 socket_type=socket.SOCK_RAW, 

3446 socket_protocol=socket.BTPROTO_HCI, 

3447 sock_address=sa) 

3448 

3449 def recv(self, x=MTU): 

3450 return HCI_Mon_Hdr(self.ins.recv(x)) 

3451 

3452 

3453conf.BTsocket = BluetoothRFCommSocket 

3454 

3455# Bluetooth 

3456 

3457 

3458@conf.commands.register 

3459def srbt(bt_address, pkts, inter=0.1, *args, **kargs): 

3460 """send and receive using a bluetooth socket""" 

3461 if "port" in kargs: 

3462 s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port")) 

3463 else: 

3464 s = conf.BTsocket(bt_address=bt_address) 

3465 a, b = sndrcv(s, pkts, inter=inter, *args, **kargs) 

3466 s.close() 

3467 return a, b 

3468 

3469 

3470@conf.commands.register 

3471def srbt1(bt_address, pkts, *args, **kargs): 

3472 """send and receive 1 packet using a bluetooth socket""" 

3473 a, b = srbt(bt_address, pkts, *args, **kargs) 

3474 if len(a) > 0: 

3475 return a[0][1]