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

1110 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) 

62from scapy.supersocket import SuperSocket 

63from scapy.sendrecv import sndrcv 

64from scapy.data import MTU 

65from scapy.consts import WINDOWS 

66from scapy.error import warning 

67 

68 

69############ 

70# Consts # 

71############ 

72 

73# From hci.h 

74HCI_CHANNEL_RAW = 0 

75HCI_CHANNEL_USER = 1 

76HCI_CHANNEL_MONITOR = 2 

77HCI_CHANNEL_CONTROL = 3 

78HCI_CHANNEL_LOGGING = 4 

79 

80HCI_DEV_NONE = 0xffff 

81 

82 

83########## 

84# Layers # 

85########## 

86 

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

88 

89# Transport layers 

90 

91class HCI_PHDR_Hdr(Packet): 

92 name = "HCI PHDR transport layer" 

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

94 

95 

96# Real layers 

97 

98_bluetooth_packet_types = { 

99 0: "Acknowledgement", 

100 1: "Command", 

101 2: "ACL Data", 

102 3: "Synchronous", 

103 4: "Event", 

104 5: "Reserve", 

105 14: "Vendor", 

106 15: "Link Control" 

107} 

108 

109_bluetooth_error_codes = { 

110 0x00: "Success", 

111 0x01: "Unknown HCI Command", 

112 0x02: "Unknown Connection Identifier", 

113 0x03: "Hardware Failure", 

114 0x04: "Page Timeout", 

115 0x05: "Authentication Failure", 

116 0x06: "PIN or Key Missing", 

117 0x07: "Memory Capacity Exceeded", 

118 0x08: "Connection Timeout", 

119 0x09: "Connection Limit Exceeded", 

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

121 0x0B: "Connection Already Exists", 

122 0x0C: "Command Disallowed", 

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

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

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

126 0x10: "Connection Accept Timeout Exceeded", 

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

128 0x12: "Invalid HCI Command Parameters", 

129 0x13: "Remote User Terminated Connection", 

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

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

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

133 0x17: "Repeated Attempts", 

134 0x18: "Pairing Not Allowed", 

135 0x19: "Unknown LMP PDU", 

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

137 0x1B: "SCO Offset Rejected", 

138 0x1C: "SCO Interval Rejected", 

139 0x1D: "SCO Air Mode Rejected", 

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

141 0x1F: "Unspecified Error", 

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

143 0x21: "Role Change Not Allowed", 

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

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

146 0x24: "LMP PDU Not Allowed", 

147 0x25: "Encryption Mode Not Acceptable", 

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

149 0x27: "Requested QoS Not Supported", 

150 0x28: "Instant Passed", 

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

152 0x2A: "Different Transaction Collision", 

153 0x2B: "Reserved for future use", 

154 0x2C: "QoS Unacceptable Parameter", 

155 0x2D: "QoS Rejected", 

156 0x2E: "Channel Classification Not Supported", 

157 0x2F: "Insufficient Security", 

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

159 0x31: "Reserved for future use", 

160 0x32: "Role Switch Pending", 

161 0x33: "Reserved for future use", 

162 0x34: "Reserved Slot Violation", 

163 0x35: "Role Switch Failed", 

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

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

166 0x38: "Host Busy - Pairing", 

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

168 0x3A: "Controller Busy", 

169 0x3B: "Unacceptable Connection Parameters", 

170 0x3C: "Advertising Timeout", 

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

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

173 0x3F: "MAC Connection Failed", 

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

175 " Dragging", 

176 0x41: "Type0 Submap Not Defined", 

177 0x42: "Unknown Advertising Identifier", 

178 0x43: "Limit Reached", 

179 0x44: "Operation Cancelled by Host", 

180 0x45: "Packet Too Long" 

181} 

182 

183_att_error_codes = { 

184 0x01: "invalid handle", 

185 0x02: "read not permitted", 

186 0x03: "write not permitted", 

187 0x04: "invalid pdu", 

188 0x05: "insufficient auth", 

189 0x06: "unsupported req", 

190 0x07: "invalid offset", 

191 0x08: "insufficient author", 

192 0x09: "prepare queue full", 

193 0x0a: "attr not found", 

194 0x0b: "attr not long", 

195 0x0c: "insufficient key size", 

196 0x0d: "invalid value size", 

197 0x0e: "unlikely", 

198 0x0f: "insufficiet encrypt", 

199 0x10: "unsupported gpr type", 

200 0x11: "insufficient resources", 

201} 

202 

203_bluetooth_features = [ 

204 '3_slot_packets', 

205 '5_slot_packets', 

206 'encryption', 

207 'slot_offset', 

208 'timing_accuracy', 

209 'role_switch', 

210 'hold_mode', 

211 'sniff_mode', 

212 'park_mode', 

213 'power_control_requests', 

214 'channel_quality_driven_data_rate', 

215 'sco_link', 

216 'hv2_packets', 

217 'hv3_packets', 

218 'u_law_log_synchronous_data', 

219 'a_law_log_synchronous_data', 

220 'cvsd_synchronous_data', 

221 'paging_parameter_negotiation', 

222 'power_control', 

223 'transparent_synchronous_data', 

224 'flow_control_lag_4_bit0', 

225 'flow_control_lag_4_bit1', 

226 'flow_control_lag_4_bit2', 

227 'broadband_encryption', 

228 'cvsd_synchronous_data', 

229 'edr_acl_2_mbps_mode', 

230 'edr_acl_3_mbps_mode', 

231 'enhanced_inquiry_scan', 

232 'interlaced_inquiry_scan', 

233 'interlaced_page_scan', 

234 'rssi_with_inquiry_results', 

235 'ev3_packets', 

236 'ev4_packets', 

237 'ev5_packets', 

238 'reserved', 

239 'afh_capable_slave', 

240 'afh_classification_slave', 

241 'br_edr_not_supported', 

242 'le_supported_controller', 

243 '3_slot_edr_acl_packets', 

244 '5_slot_edr_acl_packets', 

245 'sniff_subrating', 

246 'pause_encryption', 

247 'afh_capable_master', 

248 'afh_classification_master', 

249 'edr_esco_2_mbps_mode', 

250 'edr_esco_3_mbps_mode', 

251 '3_slot_edr_esco_packets', 

252 'extended_inquiry_response', 

253 'simultaneous_le_and_br_edr_to_same_device_capable_controller', 

254 'reserved2', 

255 'secure_simple_pairing', 

256 'encapsulated_pdu', 

257 'erroneous_data_reporting', 

258 'non_flushable_packet_boundary_flag', 

259 'reserved3', 

260 'link_supervision_timeout_changed_event', 

261 'inquiry_tx_power_level', 

262 'enhanced_power_control', 

263 'reserved4_bit0', 

264 'reserved4_bit1', 

265 'reserved4_bit2', 

266 'reserved4_bit3', 

267 'extended_features', 

268] 

269 

270_bluetooth_core_specification_versions = { 

271 0x00: '1.0b', 

272 0x01: '1.1', 

273 0x02: '1.2', 

274 0x03: '2.0+EDR', 

275 0x04: '2.1+EDR', 

276 0x05: '3.0+HS', 

277 0x06: '4.0', 

278 0x07: '4.1', 

279 0x08: '4.2', 

280 0x09: '5.0', 

281 0x0a: '5.1', 

282 0x0b: '5.2', 

283 0x0c: '5.3', 

284 0x0d: '5.4', 

285 0x0e: '6.0', 

286} 

287 

288 

289class HCI_Hdr(Packet): 

290 name = "HCI header" 

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

292 

293 def mysummary(self): 

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

295 

296 

297class HCI_ACL_Hdr(Packet): 

298 name = "HCI ACL header" 

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

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

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

302 LEShortField("len", None), ] 

303 

304 def post_build(self, p, pay): 

305 p += pay 

306 if self.len is None: 

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

308 return p 

309 

310 

311class L2CAP_Hdr(Packet): 

312 name = "L2CAP header" 

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

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

315 

316 def post_build(self, p, pay): 

317 p += pay 

318 if self.len is None: 

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

320 return p 

321 

322 

323class L2CAP_CmdHdr(Packet): 

324 name = "L2CAP command header" 

325 fields_desc = [ 

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

327 2: "conn_req", 

328 3: "conn_resp", 

329 4: "conf_req", 

330 5: "conf_resp", 

331 6: "disconn_req", 

332 7: "disconn_resp", 

333 8: "echo_req", 

334 9: "echo_resp", 

335 10: "info_req", 

336 11: "info_resp", 

337 12: "create_channel_req", 

338 13: "create_channel_resp", 

339 14: "move_channel_req", 

340 15: "move_channel_resp", 

341 16: "move_channel_confirm_req", 

342 17: "move_channel_confirm_resp", 

343 18: "conn_param_update_req", 

344 19: "conn_param_update_resp", 

345 20: "LE_credit_based_conn_req", 

346 21: "LE_credit_based_conn_resp", 

347 22: "flow_control_credit_ind", 

348 23: "credit_based_conn_req", 

349 24: "credit_based_conn_resp", 

350 25: "credit_based_reconf_req", 

351 26: "credit_based_reconf_resp"}), 

352 ByteField("id", 1), 

353 LEShortField("len", None)] 

354 

355 def post_build(self, p, pay): 

356 p += pay 

357 if self.len is None: 

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

359 return p 

360 

361 def answers(self, other): 

362 if other.id == self.id: 

363 if self.code == 1: 

364 return 1 

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

366 if other.code == 8: 

367 return 1 

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

369 return 0 

370 

371 

372class L2CAP_ConnReq(Packet): 

373 name = "L2CAP Conn Req" 

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

375 3: "RFCOMM", 

376 5: "TCS-BIN", 

377 7: "TCS-BIN-CORDLESS", 

378 15: "BNEP", 

379 17: "HID-Control", 

380 19: "HID-Interrupt", 

381 21: "UPnP", 

382 23: "AVCTP-Control", 

383 25: "AVDTP", 

384 27: "AVCTP-Browsing", 

385 29: "UDI_C-Plane", 

386 31: "ATT", 

387 33: "3DSP", 

388 35: "IPSP", 

389 37: "OTS"}), 

390 LEShortField("scid", 0), 

391 ] 

392 

393 

394class L2CAP_ConnResp(Packet): 

395 name = "L2CAP Conn Resp" 

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

397 LEShortField("scid", 0), 

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

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

400 ] 

401 

402 def answers(self, other): 

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

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

405 

406 

407class L2CAP_CmdRej(Packet): 

408 name = "L2CAP Command Rej" 

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

410 ] 

411 

412 

413class L2CAP_ConfReq(Packet): 

414 name = "L2CAP Conf Req" 

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

416 LEShortField("flags", 0), 

417 ] 

418 

419 

420class L2CAP_ConfResp(Packet): 

421 name = "L2CAP Conf Resp" 

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

423 LEShortField("flags", 0), 

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

425 ] 

426 

427 def answers(self, other): 

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

429 return isinstance(other, L2CAP_ConfReq) 

430 

431 

432class L2CAP_DisconnReq(Packet): 

433 name = "L2CAP Disconn Req" 

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

435 LEShortField("scid", 0), ] 

436 

437 

438class L2CAP_DisconnResp(Packet): 

439 name = "L2CAP Disconn Resp" 

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

441 LEShortField("scid", 0), ] 

442 

443 def answers(self, other): 

444 return self.scid == other.scid 

445 

446 

447class L2CAP_EchoReq(Packet): 

448 name = "L2CAP Echo Req" 

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

450 

451 

452class L2CAP_EchoResp(Packet): 

453 name = "L2CAP Echo Resp" 

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

455 

456 

457class L2CAP_InfoReq(Packet): 

458 name = "L2CAP Info Req" 

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

460 StrField("data", "") 

461 ] 

462 

463 

464class L2CAP_InfoResp(Packet): 

465 name = "L2CAP Info Resp" 

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

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

468 StrField("data", ""), ] 

469 

470 def answers(self, other): 

471 return self.type == other.type 

472 

473 

474class L2CAP_Create_Channel_Request(Packet): 

475 name = "L2CAP Create Channel Request" 

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

477 3: "RFCOMM", 

478 5: "TCS-BIN", 

479 7: "TCS-BIN-CORDLESS", 

480 15: "BNEP", 

481 17: "HID-Control", 

482 19: "HID-Interrupt", 

483 21: "UPnP", 

484 23: "AVCTP-Control", 

485 25: "AVDTP", 

486 27: "AVCTP-Browsing", 

487 29: "UDI_C-Plane", 

488 31: "ATT", 

489 33: "3DSP", 

490 35: "IPSP", 

491 37: "OTS"}), 

492 LEShortField("scid", 0), 

493 ByteField("controller_id", 0), ] 

494 

495 

496class L2CAP_Create_Channel_Response(Packet): 

497 name = "L2CAP Create Channel Response" 

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

499 LEShortField("scid", 0), 

500 LEShortEnumField("result", 0, { 

501 0: "Connection successful", 

502 1: "Connection pending", 

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

504 3: "Connection refused - security block", 

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

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

507 6: "Connection refused - invalid scid", 

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

509 LEShortEnumField("status", 0, { 

510 0: "No further information available", 

511 1: "Authentication pending", 

512 2: "Authorization pending"}), ] 

513 

514 

515class L2CAP_Move_Channel_Request(Packet): 

516 name = "L2CAP Move Channel Request" 

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

518 ByteField("dest_controller_id", 0), ] 

519 

520 

521class L2CAP_Move_Channel_Response(Packet): 

522 name = "L2CAP Move Channel Response" 

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

524 LEShortEnumField("result", 0, { 

525 0: "Move success", 

526 1: "Move pending", 

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

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

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

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

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

532 

533 

534class L2CAP_Move_Channel_Confirmation_Request(Packet): 

535 name = "L2CAP Move Channel Confirmation Request" 

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

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

538 1: "Move failure"}), ] 

539 

540 

541class L2CAP_Move_Channel_Confirmation_Response(Packet): 

542 name = "L2CAP Move Channel Confirmation Response" 

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

544 

545 

546class L2CAP_Connection_Parameter_Update_Request(Packet): 

547 name = "L2CAP Connection Parameter Update Request" 

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

549 LEShortField("max_interval", 0), 

550 LEShortField("slave_latency", 0), 

551 LEShortField("timeout_mult", 0), ] 

552 

553 

554class L2CAP_Connection_Parameter_Update_Response(Packet): 

555 name = "L2CAP Connection Parameter Update Response" 

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

557 

558 

559class L2CAP_LE_Credit_Based_Connection_Request(Packet): 

560 name = "L2CAP LE Credit Based Connection Request" 

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

562 LEShortField("scid", 0), 

563 LEShortField("mtu", 0), 

564 LEShortField("mps", 0), 

565 LEShortField("initial_credits", 0), ] 

566 

567 

568class L2CAP_LE_Credit_Based_Connection_Response(Packet): 

569 name = "L2CAP LE Credit Based Connection Response" 

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

571 LEShortField("mtu", 0), 

572 LEShortField("mps", 0), 

573 LEShortField("initial_credits", 0), 

574 LEShortEnumField("result", 0, { 

575 0: "Connection successful", 

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

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

578 5: "Connection refused - authentication error", 

579 6: "Connection refused - authorization error", 

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

581 8: "Connection refused - insufficient encryption", 

582 9: "Connection refused - invalid scid", 

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

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

585 

586 

587class L2CAP_Flow_Control_Credit_Ind(Packet): 

588 name = "L2CAP Flow Control Credit Ind" 

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

590 LEShortField("credits", 0), ] 

591 

592 

593class L2CAP_Credit_Based_Connection_Request(Packet): 

594 name = "L2CAP Credit Based Connection Request" 

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

596 LEShortField("mtu", 0), 

597 LEShortField("mps", 0), 

598 LEShortField("initial_credits", 0), 

599 LEShortField("scid", 0), ] 

600 

601 

602class L2CAP_Credit_Based_Connection_Response(Packet): 

603 name = "L2CAP Credit Based Connection Response" 

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

605 LEShortField("mps", 0), 

606 LEShortField("initial_credits", 0), 

607 LEShortEnumField("result", 0, { 

608 0: "All connection successful", 

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

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

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

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

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

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

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

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

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

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

619 LEShortField("dcid", 0), ] 

620 

621 

622class L2CAP_Credit_Based_Reconfigure_Request(Packet): 

623 name = "L2CAP Credit Based Reconfigure Request" 

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

625 LEShortField("mps", 0), 

626 LEShortField("dcid", 0), ] 

627 

628 

629class L2CAP_Credit_Based_Reconfigure_Response(Packet): 

630 name = "L2CAP Credit Based Reconfigure Response" 

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

632 0: "Reconfig successful", 

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

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

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

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

637 

638 

639class ATT_Hdr(Packet): 

640 name = "ATT header" 

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

642 

643 

644class ATT_Handle(Packet): 

645 name = "ATT Short Handle" 

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

647 XLEShortField("value", 0)] 

648 

649 def extract_padding(self, s): 

650 return b'', s 

651 

652 

653class ATT_Handle_UUID128(Packet): 

654 name = "ATT Handle (UUID 128)" 

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

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

657 

658 def extract_padding(self, s): 

659 return b'', s 

660 

661 

662class ATT_Error_Response(Packet): 

663 name = "Error Response" 

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

665 LEShortField("handle", 0), 

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

667 

668 

669class ATT_Exchange_MTU_Request(Packet): 

670 name = "Exchange MTU Request" 

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

672 

673 

674class ATT_Exchange_MTU_Response(Packet): 

675 name = "Exchange MTU Response" 

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

677 

678 

679class ATT_Find_Information_Request(Packet): 

680 name = "Find Information Request" 

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

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

683 

684 

685class ATT_Find_Information_Response(Packet): 

686 name = "Find Information Response" 

687 fields_desc = [ 

688 XByteField("format", 1), 

689 MultipleTypeField( 

690 [ 

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

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

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

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

695 ], 

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

697 ) 

698 ] 

699 

700 

701class ATT_Find_By_Type_Value_Request(Packet): 

702 name = "Find By Type Value Request" 

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

704 XLEShortField("end", 0xffff), 

705 XLEShortField("uuid", None), 

706 StrField("data", ""), ] 

707 

708 

709class ATT_Find_By_Type_Value_Response(Packet): 

710 name = "Find By Type Value Response" 

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

712 

713 

714class ATT_Read_By_Type_Request_128bit(Packet): 

715 name = "Read By Type Request" 

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

717 XLEShortField("end", 0xffff), 

718 XLELongField("uuid1", None), 

719 XLELongField("uuid2", None)] 

720 

721 @classmethod 

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

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

724 return ATT_Read_By_Type_Request 

725 return ATT_Read_By_Type_Request_128bit 

726 

727 

728class ATT_Read_By_Type_Request(Packet): 

729 name = "Read By Type Request" 

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

731 XLEShortField("end", 0xffff), 

732 XLEShortField("uuid", None)] 

733 

734 

735class ATT_Handle_Variable(Packet): 

736 __slots__ = ["val_length"] 

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

738 XStrLenField( 

739 "value", 0, 

740 length_from=lambda pkt: pkt.val_length)] 

741 

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

743 self.val_length = val_length 

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

745 

746 def extract_padding(self, s): 

747 return b"", s 

748 

749 

750class ATT_Read_By_Type_Response(Packet): 

751 name = "Read By Type Response" 

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

753 PacketListField( 

754 "handles", [], 

755 next_cls_cb=lambda pkt, *args: ( 

756 pkt._next_cls_cb(pkt, *args) 

757 ))] 

758 

759 @classmethod 

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

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

762 return functools.partial( 

763 ATT_Handle_Variable, 

764 val_length=pkt.len - 2 

765 ) 

766 return None 

767 

768 

769class ATT_Read_Request(Packet): 

770 name = "Read Request" 

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

772 

773 

774class ATT_Read_Response(Packet): 

775 name = "Read Response" 

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

777 

778 

779class ATT_Read_Multiple_Request(Packet): 

780 name = "Read Multiple Request" 

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

782 

783 

784class ATT_Read_Multiple_Response(Packet): 

785 name = "Read Multiple Response" 

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

787 

788 

789class ATT_Read_By_Group_Type_Request(Packet): 

790 name = "Read By Group Type Request" 

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

792 XLEShortField("end", 0xffff), 

793 XLEShortField("uuid", 0), ] 

794 

795 

796class ATT_Read_By_Group_Type_Response(Packet): 

797 name = "Read By Group Type Response" 

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

799 StrField("data", ""), ] 

800 

801 

802class ATT_Write_Request(Packet): 

803 name = "Write Request" 

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

805 StrField("data", ""), ] 

806 

807 

808class ATT_Write_Command(Packet): 

809 name = "Write Request" 

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

811 StrField("data", ""), ] 

812 

813 

814class ATT_Write_Response(Packet): 

815 name = "Write Response" 

816 

817 

818class ATT_Prepare_Write_Request(Packet): 

819 name = "Prepare Write Request" 

820 fields_desc = [ 

821 XLEShortField("gatt_handle", 0), 

822 LEShortField("offset", 0), 

823 StrField("data", "") 

824 ] 

825 

826 

827class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request): 

828 name = "Prepare Write Response" 

829 

830 

831class ATT_Handle_Value_Notification(Packet): 

832 name = "Handle Value Notification" 

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

834 StrField("value", ""), ] 

835 

836 

837class ATT_Execute_Write_Request(Packet): 

838 name = "Execute Write Request" 

839 fields_desc = [ 

840 ByteEnumField("flags", 1, { 

841 0: "Cancel all prepared writes", 

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

843 }), 

844 ] 

845 

846 

847class ATT_Execute_Write_Response(Packet): 

848 name = "Execute Write Response" 

849 

850 

851class ATT_Read_Blob_Request(Packet): 

852 name = "Read Blob Request" 

853 fields_desc = [ 

854 XLEShortField("gatt_handle", 0), 

855 LEShortField("offset", 0) 

856 ] 

857 

858 

859class ATT_Read_Blob_Response(Packet): 

860 name = "Read Blob Response" 

861 fields_desc = [ 

862 StrField("value", "") 

863 ] 

864 

865 

866class ATT_Handle_Value_Indication(Packet): 

867 name = "Handle Value Indication" 

868 fields_desc = [ 

869 XLEShortField("gatt_handle", 0), 

870 StrField("value", ""), 

871 ] 

872 

873 

874class SM_Hdr(Packet): 

875 name = "SM header" 

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

877 

878 

879class SM_Pairing_Request(Packet): 

880 name = "Pairing Request" 

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

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

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

884 ByteField("max_key_size", 16), 

885 ByteField("initiator_key_distribution", 0), 

886 ByteField("responder_key_distribution", 0), ] 

887 

888 

889class SM_Pairing_Response(Packet): 

890 name = "Pairing Response" 

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

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

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

894 ByteField("max_key_size", 16), 

895 ByteField("initiator_key_distribution", 0), 

896 ByteField("responder_key_distribution", 0), ] 

897 

898 

899class SM_Confirm(Packet): 

900 name = "Pairing Confirm" 

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

902 

903 

904class SM_Random(Packet): 

905 name = "Pairing Random" 

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

907 

908 

909class SM_Failed(Packet): 

910 name = "Pairing Failed" 

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

912 

913 

914class SM_Encryption_Information(Packet): 

915 name = "Encryption Information" 

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

917 

918 

919class SM_Master_Identification(Packet): 

920 name = "Master Identification" 

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

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

923 

924 

925class SM_Identity_Information(Packet): 

926 name = "Identity Information" 

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

928 

929 

930class SM_Identity_Address_Information(Packet): 

931 name = "Identity Address Information" 

932 fields_desc = [ByteEnumField("atype", 0, {0: "public"}), 

933 LEMACField("address", None), ] 

934 

935 

936class SM_Signing_Information(Packet): 

937 name = "Signing Information" 

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

939 

940 

941class SM_Security_Request(Packet): 

942 name = "Security Request" 

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

944 

945 

946class SM_Public_Key(Packet): 

947 name = "Public Key" 

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

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

950 

951 

952class SM_DHKey_Check(Packet): 

953 name = "DHKey Check" 

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

955 

956 

957class EIR_Hdr(Packet): 

958 name = "EIR Header" 

959 fields_desc = [ 

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

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

962 ByteEnumField("type", 0, { 

963 0x01: "flags", 

964 0x02: "incomplete_list_16_bit_svc_uuids", 

965 0x03: "complete_list_16_bit_svc_uuids", 

966 0x04: "incomplete_list_32_bit_svc_uuids", 

967 0x05: "complete_list_32_bit_svc_uuids", 

968 0x06: "incomplete_list_128_bit_svc_uuids", 

969 0x07: "complete_list_128_bit_svc_uuids", 

970 0x08: "shortened_local_name", 

971 0x09: "complete_local_name", 

972 0x0a: "tx_power_level", 

973 0x0d: "class_of_device", 

974 0x0e: "simple_pairing_hash", 

975 0x0f: "simple_pairing_rand", 

976 

977 0x10: "sec_mgr_tk", 

978 0x11: "sec_mgr_oob_flags", 

979 0x12: "slave_conn_intvl_range", 

980 0x14: "list_16_bit_svc_sollication_uuids", 

981 0x15: "list_128_bit_svc_sollication_uuids", 

982 0x16: "svc_data_16_bit_uuid", 

983 0x17: "pub_target_addr", 

984 0x18: "rand_target_addr", 

985 0x19: "appearance", 

986 0x1a: "adv_intvl", 

987 0x1b: "le_addr", 

988 0x1c: "le_role", 

989 0x1d: "simple_pairing_hash_256", 

990 0x1e: "simple_pairing_rand_256", 

991 0x1f: "list_32_bit_svc_sollication_uuids", 

992 

993 0x20: "svc_data_32_bit_uuid", 

994 0x21: "svc_data_128_bit_uuid", 

995 0x22: "sec_conn_confirm", 

996 0x23: "sec_conn_rand", 

997 0x24: "uri", 

998 0x25: "indoor_positioning", 

999 0x26: "transport_discovery", 

1000 0x27: "le_supported_features", 

1001 0x28: "channel_map_update", 

1002 0x29: "mesh_pb_adv", 

1003 0x2a: "mesh_message", 

1004 0x2b: "mesh_beacon", 

1005 

1006 0x3d: "3d_information", 

1007 

1008 0xff: "mfg_specific_data", 

1009 }), 

1010 ] 

1011 

1012 def mysummary(self): 

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

1014 

1015 def guess_payload_class(self, payload): 

1016 if self.len == 0: 

1017 # For Extended_Inquiry_Response, stop when len=0 

1018 return conf.padding_layer 

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

1020 

1021 

1022class EIR_Element(Packet): 

1023 name = "EIR Element" 

1024 

1025 def extract_padding(self, s): 

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

1027 return b'', s 

1028 

1029 @staticmethod 

1030 def length_from(pkt): 

1031 if not pkt.underlayer: 

1032 warning("Missing an upper-layer") 

1033 return 0 

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

1035 return pkt.underlayer.len - 1 

1036 

1037 

1038class EIR_Raw(EIR_Element): 

1039 name = "EIR Raw" 

1040 fields_desc = [ 

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

1042 ] 

1043 

1044 

1045class EIR_Flags(EIR_Element): 

1046 name = "Flags" 

1047 fields_desc = [ 

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

1049 ["limited_disc_mode", "general_disc_mode", 

1050 "br_edr_not_supported", "simul_le_br_edr_ctrl", 

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

1052 ] 

1053 

1054 

1055class EIR_CompleteList16BitServiceUUIDs(EIR_Element): 

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

1057 fields_desc = [ 

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

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

1060 length_from=EIR_Element.length_from) 

1061 ] 

1062 

1063 

1064class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs): 

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

1066 

1067 

1068class EIR_CompleteList32BitServiceUUIDs(EIR_Element): 

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

1070 fields_desc = [ 

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

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

1073 length_from=EIR_Element.length_from) 

1074 ] 

1075 

1076 

1077class EIR_IncompleteList32BitServiceUUIDs(EIR_CompleteList32BitServiceUUIDs): 

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

1079 

1080 

1081class EIR_CompleteList128BitServiceUUIDs(EIR_Element): 

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

1083 fields_desc = [ 

1084 FieldListField("svc_uuids", None, 

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

1086 length_from=EIR_Element.length_from) 

1087 ] 

1088 

1089 

1090class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs): 

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

1092 

1093 

1094class EIR_CompleteLocalName(EIR_Element): 

1095 name = "Complete Local Name" 

1096 fields_desc = [ 

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

1098 ] 

1099 

1100 

1101class EIR_ShortenedLocalName(EIR_CompleteLocalName): 

1102 name = "Shortened Local Name" 

1103 

1104 

1105class EIR_TX_Power_Level(EIR_Element): 

1106 name = "TX Power Level" 

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

1108 

1109 

1110class EIR_ClassOfDevice(EIR_Element): 

1111 name = 'Class of device' 

1112 fields_desc = [ 

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

1114 'limited_discoverable_mode', 

1115 'le_audio', 

1116 'reserved', 

1117 'positioning', 

1118 'networking', 

1119 'rendering', 

1120 'capturing', 

1121 'object_transfer', 

1122 'audio', 

1123 'telephony', 

1124 'information' 

1125 ], tot_size=-3), 

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

1127 0x00: 'miscellaneous', 

1128 0x01: 'computer', 

1129 0x02: 'phone', 

1130 0x03: 'lan', 

1131 0x04: 'audio_video', 

1132 0x05: 'peripheral', 

1133 0x06: 'imaging', 

1134 0x07: 'wearable', 

1135 0x08: 'toy', 

1136 0x09: 'health', 

1137 0x1f: 'uncategorized' 

1138 }), 

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

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

1141 ] 

1142 

1143 

1144class EIR_SecureSimplePairingHashC192(EIR_Element): 

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

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

1147 

1148 

1149class EIR_SecureSimplePairingRandomizerR192(EIR_Element): 

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

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

1152 

1153 

1154class EIR_SecurityManagerOOBFlags(EIR_Element): 

1155 name = 'Security Manager Out of Band Flags' 

1156 fields_desc = [ 

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

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

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

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

1161 BitField('reserved', 0, 4) 

1162 ] 

1163 

1164 

1165class EIR_PeripheralConnectionIntervalRange(EIR_Element): 

1166 name = 'Peripheral Connection Interval Range' 

1167 fields_desc = [ 

1168 LEShortField('conn_interval_min', 0xFFFF), 

1169 LEShortField('conn_interval_max', 0xFFFF) 

1170 ] 

1171 

1172 

1173class EIR_Manufacturer_Specific_Data(EIR_Element): 

1174 name = "EIR Manufacturer Specific Data" 

1175 deprecated_fields = { 

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

1177 } 

1178 fields_desc = [ 

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

1180 LEShortEnumField("company_identifier", None, 

1181 BLUETOOTH_CORE_COMPANY_IDENTIFIERS), 

1182 ] 

1183 

1184 registered_magic_payloads = {} 

1185 

1186 @classmethod 

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

1188 """ 

1189 Registers a payload type that uses magic data. 

1190 

1191 Traditional payloads require registration of a Bluetooth Company ID 

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

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

1194 

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

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

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

1198 number of bytes in a beacon frame. 

1199 

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

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

1202 at the start of the Manufacturer Specific Data field. 

1203 

1204 Examples of this are AltBeacon and GeoBeacon. 

1205 

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

1207 

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

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

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

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

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

1213 used instead. 

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

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

1216 """ 

1217 if magic_check is None: 

1218 if hasattr(payload_cls, "magic_check"): 

1219 magic_check = payload_cls.magic_check 

1220 else: 

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

1222 "attribute magic_check".format(payload_cls)) 

1223 

1224 cls.registered_magic_payloads[payload_cls] = magic_check 

1225 

1226 def default_payload_class(self, payload): 

1227 for cls, check in ( 

1228 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items() 

1229 ): 

1230 if check(payload): 

1231 return cls 

1232 

1233 return Packet.default_payload_class(self, payload) 

1234 

1235 def extract_padding(self, s): 

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

1237 plen = EIR_Element.length_from(self) - 2 

1238 return s[:plen], s[plen:] 

1239 

1240 

1241class EIR_Device_ID(EIR_Element): 

1242 name = "Device ID" 

1243 fields_desc = [ 

1244 XLEShortField("vendor_id_source", 0), 

1245 XLEShortField("vendor_id", 0), 

1246 XLEShortField("product_id", 0), 

1247 XLEShortField("version", 0), 

1248 ] 

1249 

1250 

1251class EIR_ServiceSolicitation16BitUUID(EIR_Element): 

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

1253 fields_desc = [ 

1254 XLEShortField("svc_uuid", None) 

1255 ] 

1256 

1257 def extract_padding(self, s): 

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

1259 plen = EIR_Element.length_from(self) - 2 

1260 return s[:plen], s[plen:] 

1261 

1262 

1263class EIR_ServiceSolicitation128BitUUID(EIR_Element): 

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

1265 fields_desc = [ 

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

1267 ] 

1268 

1269 def extract_padding(self, s): 

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

1271 plen = EIR_Element.length_from(self) - 2 

1272 return s[:plen], s[plen:] 

1273 

1274 

1275class EIR_ServiceData16BitUUID(EIR_Element): 

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

1277 fields_desc = [ 

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

1279 XLEShortField("svc_uuid", None), 

1280 ] 

1281 

1282 def extract_padding(self, s): 

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

1284 plen = EIR_Element.length_from(self) - 2 

1285 return s[:plen], s[plen:] 

1286 

1287 

1288class EIR_PublicTargetAddress(EIR_Element): 

1289 name = "Public Target Address" 

1290 fields_desc = [ 

1291 LEMACField('bd_addr', None) 

1292 ] 

1293 

1294 

1295class EIR_AdvertisingInterval(EIR_Element): 

1296 name = "Advertising Interval" 

1297 fields_desc = [ 

1298 MultipleTypeField( 

1299 [ 

1300 (ByteField("advertising_interval", 0), 

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

1302 (LEShortField("advertising_interval", 0), 

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

1304 (LEThreeBytesField("advertising_interval", 0), 

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

1306 (LEIntField("advertising_interval", 0), 

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

1308 ], 

1309 LEShortField("advertising_interval", 0) 

1310 ) 

1311 ] 

1312 

1313 

1314class EIR_LEBluetoothDeviceAddress(EIR_Element): 

1315 name = "LE Bluetooth Device Address" 

1316 fields_desc = [ 

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

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

1319 0x0: 'Public', 

1320 0x1: 'Random' 

1321 }), 

1322 LEMACField('bd_addr', None) 

1323 ] 

1324 

1325 

1326class EIR_Appearance(EIR_Element): 

1327 name = "EIR_Appearance" 

1328 fields_desc = [ 

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

1330 0x000: 'Unknown', 

1331 0x001: 'Phone', 

1332 0x002: 'Computer', 

1333 0x003: 'Watch', 

1334 0x004: 'Clock', 

1335 0x005: 'Display', 

1336 0x006: 'Remote Control', 

1337 0x007: 'Eyeglasses', 

1338 0x008: 'Tag', 

1339 0x009: 'Keyring', 

1340 0x00A: 'Media Player', 

1341 0x00B: 'Barcode Scanner', 

1342 0x00C: 'Thermometer', 

1343 0x00D: 'Heart Rate Sensor', 

1344 0x00E: 'Blood Pressure', 

1345 0x00F: 'Human Interface Device', 

1346 0x010: 'Glucose Meter', 

1347 0x011: 'Running Walking Sensor', 

1348 0x012: 'Cycling', 

1349 0x013: 'Control Device', 

1350 0x014: 'Network Device', 

1351 0x015: 'Sensor', 

1352 0x016: 'Light Fixtures', 

1353 0x017: 'Fan', 

1354 0x018: 'HVAC', 

1355 0x019: 'Air Conditioning', 

1356 0x01A: 'Humidifier', 

1357 0x01B: 'Heating', 

1358 0x01C: 'Access Control', 

1359 0x01D: 'Motorized Device', 

1360 0x01E: 'Power Device', 

1361 0x01F: 'Light Source', 

1362 0x020: 'Window Covering', 

1363 0x021: 'Audio Sink', 

1364 0x022: 'Audio Source', 

1365 0x023: 'Motorized Vehicle', 

1366 0x024: 'Domestic Appliance', 

1367 0x025: 'Wearable Audio Device', 

1368 0x026: 'Aircraft', 

1369 0x027: 'AV Equipment', 

1370 0x028: 'Display Equipment', 

1371 0x029: 'Hearing aid', 

1372 0x02A: 'Gaming', 

1373 0x02B: 'Signage', 

1374 0x031: 'Pulse Oximeter', 

1375 0x032: 'Weight Scale', 

1376 0x033: 'Personal Mobility Device', 

1377 0x034: 'Continuous Glucose Monitor', 

1378 0x035: 'Insulin Pump', 

1379 0x036: 'Medication Delivery', 

1380 0x037: 'Spirometer', 

1381 0x051: 'Outdoor Sports Activity' 

1382 }), 

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

1384 ] 

1385 

1386 @property 

1387 def appearance(self): 

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

1389 

1390 

1391class EIR_ServiceData32BitUUID(EIR_Element): 

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

1393 fields_desc = [ 

1394 XLEIntField('svc_uuid', 0), 

1395 ] 

1396 

1397 def extract_padding(self, s): 

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

1399 plen = EIR_Element.length_from(self) - 4 

1400 return s[:plen], s[plen:] 

1401 

1402 

1403class EIR_ServiceData128BitUUID(EIR_Element): 

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

1405 fields_desc = [ 

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

1407 ] 

1408 

1409 def extract_padding(self, s): 

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

1411 plen = EIR_Element.length_from(self) - 16 

1412 return s[:plen], s[plen:] 

1413 

1414 

1415class EIR_URI(EIR_Element): 

1416 name = 'EIR URI' 

1417 fields_desc = [ 

1418 ByteEnumField('scheme', 0, { 

1419 0x01: '', 

1420 0x02: 'aaa:', 

1421 0x03: 'aaas:', 

1422 0x04: 'about:', 

1423 0x05: 'acap:', 

1424 0x06: 'acct:', 

1425 0x07: 'cap:', 

1426 0x08: 'cid:', 

1427 0x09: 'coap:', 

1428 0x0A: 'coaps:', 

1429 0x0B: 'crid:', 

1430 0x0C: 'data:', 

1431 0x0D: 'dav:', 

1432 0x0E: 'dict:', 

1433 0x0F: 'dns:', 

1434 0x10: 'file:', 

1435 0x11: 'ftp:', 

1436 0x12: 'geo:', 

1437 0x13: 'go:', 

1438 0x14: 'gopher:', 

1439 0x15: 'h323:', 

1440 0x16: 'http:', 

1441 0x17: 'https:', 

1442 0x18: 'iax:', 

1443 0x19: 'icap:', 

1444 0x1A: 'im:', 

1445 0x1B: 'imap:', 

1446 0x1C: 'info:', 

1447 0x1D: 'ipp:', 

1448 0x1E: 'ipps:', 

1449 0x1F: 'iris:', 

1450 0x20: 'iris.beep:', 

1451 0x21: 'iris.xpc:', 

1452 0x22: 'iris.xpcs:', 

1453 0x23: 'iris.lwz:', 

1454 0x24: 'jabber:', 

1455 0x25: 'ldap:', 

1456 0x26: 'mailto:', 

1457 0x27: 'mid:', 

1458 0x28: 'msrp:', 

1459 0x29: 'msrps:', 

1460 0x2A: 'mtqp:', 

1461 0x2B: 'mupdate:', 

1462 0x2C: 'news:', 

1463 0x2D: 'nfs:', 

1464 0x2E: 'ni:', 

1465 0x2F: 'nih:', 

1466 0x30: 'nntp:', 

1467 0x31: 'opaquelocktoken:', 

1468 0x32: 'pop:', 

1469 0x33: 'pres:', 

1470 0x34: 'reload:', 

1471 0x35: 'rtsp:', 

1472 0x36: 'rtsps:', 

1473 0x37: 'rtspu:', 

1474 0x38: 'service:', 

1475 0x39: 'session:', 

1476 0x3A: 'shttp:', 

1477 0x3B: 'sieve:', 

1478 0x3C: 'sip:', 

1479 0x3D: 'sips:', 

1480 0x3E: 'sms:', 

1481 0x3F: 'snmp:', 

1482 0x40: 'soap.beep:', 

1483 0x41: 'soap.beeps:', 

1484 0x42: 'stun:', 

1485 0x43: 'stuns:', 

1486 0x44: 'tag:', 

1487 0x45: 'tel:', 

1488 0x46: 'telnet:', 

1489 0x47: 'tftp:', 

1490 0x48: 'thismessage:', 

1491 0x49: 'tn3270:', 

1492 0x4A: 'tip:', 

1493 0x4B: 'turn:', 

1494 0x4C: 'turns:', 

1495 0x4D: 'tv:', 

1496 0x4E: 'urn:', 

1497 0x4F: 'vemmi:', 

1498 0x50: 'ws:', 

1499 0x51: 'wss:', 

1500 0x52: 'xcon:', 

1501 0x53: 'xconuserid:', 

1502 0x54: 'xmlrpc.beep:', 

1503 0x55: 'xmlrpc.beeps:', 

1504 0x56: 'xmpp:', 

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

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

1507 0x59: 'acr:', 

1508 0x5A: 'adiumxtra:', 

1509 0x5B: 'afp:', 

1510 0x5C: 'afs:', 

1511 0x5D: 'aim:', 

1512 0x5E: 'apt:', 

1513 0x5F: 'attachment:', 

1514 0x60: 'aw:', 

1515 0x61: 'barion:', 

1516 0x62: 'beshare:', 

1517 0x63: 'bitcoin:', 

1518 0x64: 'bolo:', 

1519 0x65: 'callto:', 

1520 0x66: 'chrome:', 

1521 0x67: 'chromeextension:', 

1522 0x68: 'comeventbriteattendee:', 

1523 0x69: 'content:', 

1524 0x6A: 'cvs:', 

1525 0x6B: 'dlnaplaysingle:', 

1526 0x6C: 'dlnaplaycontainer:', 

1527 0x6D: 'dtn:', 

1528 0x6E: 'dvb:', 

1529 0x6F: 'ed2k:', 

1530 0x70: 'facetime:', 

1531 0x71: 'feed:', 

1532 0x72: 'feedready:', 

1533 0x73: 'finger:', 

1534 0x74: 'fish:', 

1535 0x75: 'gg:', 

1536 0x76: 'git:', 

1537 0x77: 'gizmoproject:', 

1538 0x78: 'gtalk:', 

1539 0x79: 'ham:', 

1540 0x7A: 'hcp:', 

1541 0x7B: 'icon:', 

1542 0x7C: 'ipn:', 

1543 0x7D: 'irc:', 

1544 0x7E: 'irc6:', 

1545 0x7F: 'ircs:', 

1546 0x80: 'itms:', 

1547 0x81: 'jar:', 

1548 0x82: 'jms:', 

1549 0x83: 'keyparc:', 

1550 0x84: 'lastfm:', 

1551 0x85: 'ldaps:', 

1552 0x86: 'magnet:', 

1553 0x87: 'maps:', 

1554 0x88: 'market:', 

1555 0x89: 'message:', 

1556 0x8A: 'mms:', 

1557 0x8B: 'mshelp:', 

1558 0x8C: 'mssettingspower:', 

1559 0x8D: 'msnim:', 

1560 0x8E: 'mumble:', 

1561 0x8F: 'mvn:', 

1562 0x90: 'notes:', 

1563 0x91: 'oid:', 

1564 0x92: 'palm:', 

1565 0x93: 'paparazzi:', 

1566 0x94: 'pkcs11:', 

1567 0x95: 'platform:', 

1568 0x96: 'proxy:', 

1569 0x97: 'psyc:', 

1570 0x98: 'query:', 

1571 0x99: 'res:', 

1572 0x9A: 'resource:', 

1573 0x9B: 'rmi:', 

1574 0x9C: 'rsync:', 

1575 0x9D: 'rtmfp:', 

1576 0x9E: 'rtmp:', 

1577 0x9F: 'secondlife:', 

1578 0xA0: 'sftp:', 

1579 0xA1: 'sgn:', 

1580 0xA2: 'skype:', 

1581 0xA3: 'smb:', 

1582 0xA4: 'smtp:', 

1583 0xA5: 'soldat:', 

1584 0xA6: 'spotify:', 

1585 0xA7: 'ssh:', 

1586 0xA8: 'steam:', 

1587 0xA9: 'submit:', 

1588 0xAA: 'svn:', 

1589 0xAB: 'teamspeak:', 

1590 0xAC: 'teliaeid:', 

1591 0xAD: 'things:', 

1592 0xAE: 'udp:', 

1593 0xAF: 'unreal:', 

1594 0xB0: 'ut2004:', 

1595 0xB1: 'ventrilo:', 

1596 0xB2: 'viewsource:', 

1597 0xB3: 'webcal:', 

1598 0xB4: 'wtai:', 

1599 0xB5: 'wyciwyg:', 

1600 0xB6: 'xfire:', 

1601 0xB7: 'xri:', 

1602 0xB8: 'ymsgr:', 

1603 0xB9: 'example:', 

1604 0xBA: 'mssettingscloudstorage:' 

1605 }), 

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

1607 ] 

1608 

1609 @property 

1610 def uri(self): 

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

1612 

1613 

1614class HCI_Command_Hdr(Packet): 

1615 name = "HCI Command header" 

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

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

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

1619 

1620 def answers(self, other): 

1621 return False 

1622 

1623 @property 

1624 def opcode(self): 

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

1626 

1627 def post_build(self, p, pay): 

1628 p += pay 

1629 if self.len is None: 

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

1631 return p 

1632 

1633 

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

1635# 8 EXTENDED INQUIRY RESPONSE 

1636 

1637class HCI_Extended_Inquiry_Response(Packet): 

1638 fields_desc = [ 

1639 PadField( 

1640 PacketListField( 

1641 "eir_data", [], 

1642 next_cls_cb=lambda *args: ( 

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

1644 ) 

1645 ), 

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

1647 ), 

1648 ] 

1649 

1650 

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

1652# 7 HCI COMMANDS AND EVENTS 

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

1654 

1655class HCI_Cmd_Inquiry(Packet): 

1656 """ 

1657 7.1.1 Inquiry command 

1658 """ 

1659 name = "HCI_Inquiry" 

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

1661 ByteField("inquiry_length", 0), 

1662 ByteField("num_responses", 0)] 

1663 

1664 

1665class HCI_Cmd_Inquiry_Cancel(Packet): 

1666 """ 

1667 7.1.2 Inquiry Cancel command 

1668 """ 

1669 name = "HCI_Inquiry_Cancel" 

1670 

1671 

1672class HCI_Cmd_Periodic_Inquiry_Mode(Packet): 

1673 """ 

1674 7.1.3 Periodic Inquiry Mode command 

1675 """ 

1676 name = "HCI_Periodic_Inquiry_Mode" 

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

1678 LEShortField("min_period_length", 0x0002), 

1679 XLE3BytesField("lap", 0x9E8B33), 

1680 ByteField("inquiry_length", 0), 

1681 ByteField("num_responses", 0)] 

1682 

1683 

1684class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet): 

1685 """ 

1686 7.1.4 Exit Periodic Inquiry Mode command 

1687 """ 

1688 name = "HCI_Exit_Periodic_Inquiry_Mode" 

1689 

1690 

1691class HCI_Cmd_Create_Connection(Packet): 

1692 """ 

1693 7.1.5 Create Connection command 

1694 """ 

1695 name = "HCI_Create_Connection" 

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

1697 LEShortField("packet_type", 0xcc18), 

1698 ByteField("page_scan_repetition_mode", 0x02), 

1699 ByteField("reserved", 0x0), 

1700 LEShortField("clock_offset", 0x0), 

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

1702 

1703 

1704class HCI_Cmd_Disconnect(Packet): 

1705 """ 

1706 7.1.6 Disconnect command 

1707 """ 

1708 name = "HCI_Disconnect" 

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

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

1711 

1712 

1713class HCI_Cmd_Create_Connection_Cancel(Packet): 

1714 """ 

1715 7.1.7 Create Connection Cancel command 

1716 """ 

1717 name = "HCI_Create_Connection_Cancel" 

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

1719 

1720 

1721class HCI_Cmd_Accept_Connection_Request(Packet): 

1722 """ 

1723 7.1.8 Accept Connection Request command 

1724 """ 

1725 name = "HCI_Accept_Connection_Request" 

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

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

1728 

1729 

1730class HCI_Cmd_Reject_Connection_Response(Packet): 

1731 """ 

1732 7.1.9 Reject Connection Request command 

1733 """ 

1734 name = "HCI_Reject_Connection_Response" 

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

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

1737 

1738 

1739class HCI_Cmd_Link_Key_Request_Reply(Packet): 

1740 """ 

1741 7.1.10 Link Key Request Reply command 

1742 """ 

1743 name = "HCI_Link_Key_Request_Reply" 

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

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

1746 

1747 

1748class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet): 

1749 """ 

1750 7.1.11 Link Key Request Negative Reply command 

1751 """ 

1752 name = "HCI_Link_Key_Request_Negative_Reply" 

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

1754 

1755 

1756class HCI_Cmd_PIN_Code_Request_Reply(Packet): 

1757 """ 

1758 7.1.12 PIN Code Request Reply command 

1759 """ 

1760 name = "HCI_PIN_Code_Request_Reply" 

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

1762 ByteField("pin_code_length", 7), 

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

1764 

1765 

1766class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet): 

1767 """ 

1768 7.1.13 PIN Code Request Negative Reply command 

1769 """ 

1770 name = "HCI_PIN_Code_Request_Negative_Reply" 

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

1772 

1773 

1774class HCI_Cmd_Change_Connection_Packet_Type(Packet): 

1775 """ 

1776 7.1.14 Change Connection Packet Type command 

1777 """ 

1778 name = "HCI_Cmd_Change_Connection_Packet_Type" 

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

1780 LEShortField("packet_type", 0), ] 

1781 

1782 

1783class HCI_Cmd_Authentication_Requested(Packet): 

1784 """ 

1785 7.1.15 Authentication Requested command 

1786 """ 

1787 name = "HCI_Authentication_Requested" 

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

1789 

1790 

1791class HCI_Cmd_Set_Connection_Encryption(Packet): 

1792 """ 

1793 7.1.16 Set Connection Encryption command 

1794 """ 

1795 name = "HCI_Set_Connection_Encryption" 

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

1797 

1798 

1799class HCI_Cmd_Change_Connection_Link_Key(Packet): 

1800 """ 

1801 7.1.17 Change Connection Link Key command 

1802 """ 

1803 name = "HCI_Change_Connection_Link_Key" 

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

1805 

1806 

1807class HCI_Cmd_Link_Key_Selection(Packet): 

1808 """ 

1809 7.1.18 Change Connection Link Key command 

1810 """ 

1811 name = "HCI_Cmd_Link_Key_Selection" 

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

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

1814 

1815 

1816class HCI_Cmd_Remote_Name_Request(Packet): 

1817 """ 

1818 7.1.19 Remote Name Request command 

1819 """ 

1820 name = "HCI_Remote_Name_Request" 

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

1822 ByteField("page_scan_repetition_mode", 0x02), 

1823 ByteField("reserved", 0x0), 

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

1825 

1826 

1827class HCI_Cmd_Remote_Name_Request_Cancel(Packet): 

1828 """ 

1829 7.1.20 Remote Name Request Cancel command 

1830 """ 

1831 name = "HCI_Remote_Name_Request_Cancel" 

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

1833 

1834 

1835class HCI_Cmd_Read_Remote_Supported_Features(Packet): 

1836 """ 

1837 7.1.21 Read Remote Supported Features command 

1838 """ 

1839 name = "HCI_Read_Remote_Supported_Features" 

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

1841 

1842 

1843class HCI_Cmd_Read_Remote_Extended_Features(Packet): 

1844 """ 

1845 7.1.22 Read Remote Extended Features command 

1846 """ 

1847 name = "HCI_Read_Remote_Supported_Features" 

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

1849 ByteField("page_number", None), ] 

1850 

1851 

1852class HCI_Cmd_IO_Capability_Request_Reply(Packet): 

1853 """ 

1854 7.1.29 IO Capability Request Reply command 

1855 """ 

1856 name = "HCI_Read_Remote_Supported_Features" 

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

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

1859 0x01: "DisplayYesNo", 

1860 0x02: "KeyboardOnly", 

1861 0x03: "NoInputNoOutput", }), 

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

1863 0x01: "P-192", 

1864 0x02: "P-256", 

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

1866 ByteEnumField("authentication_requirement", None, 

1867 {0x00: "MITM Not Required", 

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

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

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

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

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

1873 

1874 

1875class HCI_Cmd_User_Confirmation_Request_Reply(Packet): 

1876 """ 

1877 7.1.30 User Confirmation Request Reply command 

1878 """ 

1879 name = "HCI_User_Confirmation_Request_Reply" 

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

1881 

1882 

1883class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet): 

1884 """ 

1885 7.1.31 User Confirmation Request Negative Reply command 

1886 """ 

1887 name = "HCI_User_Confirmation_Request_Negative_Reply" 

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

1889 

1890 

1891class HCI_Cmd_User_Passkey_Request_Reply(Packet): 

1892 """ 

1893 7.1.32 User Passkey Request Reply command 

1894 """ 

1895 name = "HCI_User_Passkey_Request_Reply" 

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

1897 LEIntField("numeric_value", None), ] 

1898 

1899 

1900class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet): 

1901 """ 

1902 7.1.33 User Passkey Request Negative Reply command 

1903 """ 

1904 name = "HCI_User_Passkey_Request_Negative_Reply" 

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

1906 

1907 

1908class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet): 

1909 """ 

1910 7.1.34 Remote OOB Data Request Reply command 

1911 """ 

1912 name = "HCI_Remote_OOB_Data_Request_Reply" 

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

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

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

1916 

1917 

1918class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet): 

1919 """ 

1920 7.1.35 Remote OOB Data Request Negative Reply command 

1921 """ 

1922 name = "HCI_Remote_OOB_Data_Request_Negative_Reply" 

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

1924 

1925 

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

1927 

1928class HCI_Cmd_Hold_Mode(Packet): 

1929 name = "HCI_Hold_Mode" 

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

1931 LEShortField("hold_mode_max_interval", 0x0002), 

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

1933 

1934 

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

1936 

1937class HCI_Cmd_Set_Event_Mask(Packet): 

1938 """ 

1939 7.3.1 Set Event Mask command 

1940 """ 

1941 name = "HCI_Set_Event_Mask" 

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

1943 

1944 

1945class HCI_Cmd_Reset(Packet): 

1946 """ 

1947 7.3.2 Reset command 

1948 """ 

1949 name = "HCI_Reset" 

1950 

1951 

1952class HCI_Cmd_Set_Event_Filter(Packet): 

1953 """ 

1954 7.3.3 Set Event Filter command 

1955 """ 

1956 name = "HCI_Set_Event_Filter" 

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

1958 

1959 

1960class HCI_Cmd_Write_Local_Name(Packet): 

1961 """ 

1962 7.3.11 Write Local Name command 

1963 """ 

1964 name = "HCI_Write_Local_Name" 

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

1966 

1967 

1968class HCI_Cmd_Read_Local_Name(Packet): 

1969 """ 

1970 7.3.12 Read Local Name command 

1971 """ 

1972 name = "HCI_Read_Local_Name" 

1973 

1974 

1975class HCI_Cmd_Write_Connect_Accept_Timeout(Packet): 

1976 name = "HCI_Write_Connection_Accept_Timeout" 

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

1978 

1979 

1980class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): 

1981 name = "HCI_Write_Extended_Inquiry_Response" 

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

1983 HCI_Extended_Inquiry_Response] 

1984 

1985 

1986class HCI_Cmd_Read_LE_Host_Support(Packet): 

1987 name = "HCI_Read_LE_Host_Support" 

1988 

1989 

1990class HCI_Cmd_Write_LE_Host_Support(Packet): 

1991 name = "HCI_Write_LE_Host_Support" 

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

1993 ByteField("unused", 1), ] 

1994 

1995 

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

1997 

1998class HCI_Cmd_Read_Local_Version_Information(Packet): 

1999 """ 

2000 7.4.1 Read Local Version Information command 

2001 """ 

2002 name = "HCI_Read_Local_Version_Information" 

2003 

2004 

2005class HCI_Cmd_Read_Local_Extended_Features(Packet): 

2006 """ 

2007 7.4.4 Read Local Extended Features command 

2008 """ 

2009 name = "HCI_Read_Local_Extended_Features" 

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

2011 

2012 

2013class HCI_Cmd_Read_BD_Addr(Packet): 

2014 """ 

2015 7.4.6 Read BD_ADDR command 

2016 """ 

2017 name = "HCI_Read_BD_ADDR" 

2018 

2019 

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

2021 

2022class HCI_Cmd_Read_Link_Quality(Packet): 

2023 name = "HCI_Read_Link_Quality" 

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

2025 

2026 

2027class HCI_Cmd_Read_RSSI(Packet): 

2028 name = "HCI_Read_RSSI" 

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

2030 

2031 

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

2033 

2034class HCI_Cmd_Read_Loopback_Mode(Packet): 

2035 name = "HCI_Read_Loopback_Mode" 

2036 

2037 

2038class HCI_Cmd_Write_Loopback_Mode(Packet): 

2039 name = "HCI_Write_Loopback_Mode" 

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

2041 {0: "no loopback", 

2042 1: "enable local loopback", 

2043 2: "enable remote loopback"})] 

2044 

2045 

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

2047 

2048class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet): 

2049 name = "HCI_LE_Read_Buffer_Size [v1]" 

2050 

2051 

2052class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet): 

2053 name = "HCI_LE_Read_Buffer_Size [v2]" 

2054 

2055 

2056class HCI_Cmd_LE_Read_Local_Supported_Features(Packet): 

2057 name = "HCI_LE_Read_Local_Supported_Features" 

2058 

2059 

2060class HCI_Cmd_LE_Set_Random_Address(Packet): 

2061 name = "HCI_LE_Set_Random_Address" 

2062 fields_desc = [LEMACField("address", None)] 

2063 

2064 

2065class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): 

2066 name = "HCI_LE_Set_Advertising_Parameters" 

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

2068 LEShortField("interval_max", 0x0800), 

2069 ByteEnumField("adv_type", 0, {0: "ADV_IND", 1: "ADV_DIRECT_IND", 2: "ADV_SCAN_IND", 3: "ADV_NONCONN_IND", 4: "ADV_DIRECT_IND_LOW"}), # noqa: E501 

2070 ByteEnumField("oatype", 0, {0: "public", 1: "random"}), 

2071 ByteEnumField("datype", 0, {0: "public", 1: "random"}), 

2072 LEMACField("daddr", None), 

2073 ByteField("channel_map", 7), 

2074 ByteEnumField("filter_policy", 0, {0: "all:all", 1: "connect:all scan:whitelist", 2: "connect:whitelist scan:all", 3: "all:whitelist"}), ] # noqa: E501 

2075 

2076 

2077class HCI_Cmd_LE_Set_Advertising_Data(Packet): 

2078 name = "HCI_LE_Set_Advertising_Data" 

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

2080 PadField( 

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

2082 length_from=lambda pkt: pkt.len), 

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

2084 

2085 

2086class HCI_Cmd_LE_Set_Scan_Response_Data(Packet): 

2087 name = "HCI_LE_Set_Scan_Response_Data" 

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

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

2090 

2091 

2092class HCI_Cmd_LE_Set_Advertise_Enable(Packet): 

2093 name = "HCI_LE_Set_Advertising_Enable" 

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

2095 

2096 

2097class HCI_Cmd_LE_Set_Scan_Parameters(Packet): 

2098 name = "HCI_LE_Set_Scan_Parameters" 

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

2100 XLEShortField("interval", 16), 

2101 XLEShortField("window", 16), 

2102 ByteEnumField("atype", 0, {0: "public", 

2103 1: "random", 

2104 2: "rpa (pub)", 

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

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

2107 

2108 

2109class HCI_Cmd_LE_Set_Scan_Enable(Packet): 

2110 name = "HCI_LE_Set_Scan_Enable" 

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

2112 ByteField("filter_dups", 1), ] 

2113 

2114 

2115class HCI_Cmd_LE_Create_Connection(Packet): 

2116 name = "HCI_LE_Create_Connection" 

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

2118 LEShortField("window", 48), 

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

2120 ByteEnumField("patype", 0, {0: "public", 1: "random"}), 

2121 LEMACField("paddr", None), 

2122 ByteEnumField("atype", 0, {0: "public", 1: "random"}), 

2123 LEShortField("min_interval", 40), 

2124 LEShortField("max_interval", 56), 

2125 LEShortField("latency", 0), 

2126 LEShortField("timeout", 42), 

2127 LEShortField("min_ce", 0), 

2128 LEShortField("max_ce", 0), ] 

2129 

2130 

2131class HCI_Cmd_LE_Create_Connection_Cancel(Packet): 

2132 name = "HCI_LE_Create_Connection_Cancel" 

2133 

2134 

2135class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet): 

2136 name = "HCI_LE_Read_Filter_Accept_List_Size" 

2137 

2138 

2139class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet): 

2140 name = "HCI_LE_Clear_Filter_Accept_List" 

2141 

2142 

2143class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet): 

2144 name = "HCI_LE_Add_Device_To_Filter_Accept_List" 

2145 fields_desc = [ByteEnumField("address_type", 0, {0: "public", 

2146 1: "random", 

2147 0xff: "anonymous"}), 

2148 LEMACField("address", None)] 

2149 

2150 

2151class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501 

2152 name = "HCI_LE_Remove_Device_From_Filter_Accept_List" 

2153 

2154 

2155class HCI_Cmd_LE_Connection_Update(Packet): 

2156 name = "HCI_LE_Connection_Update" 

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

2158 XLEShortField("min_interval", 0), 

2159 XLEShortField("max_interval", 0), 

2160 XLEShortField("latency", 0), 

2161 XLEShortField("timeout", 0), 

2162 LEShortField("min_ce", 0), 

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

2164 

2165 

2166class HCI_Cmd_LE_Read_Remote_Features(Packet): 

2167 name = "HCI_LE_Read_Remote_Features" 

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

2169 

2170 

2171class HCI_Cmd_LE_Enable_Encryption(Packet): 

2172 name = "HCI_LE_Enable_Encryption" 

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

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

2175 XLEShortField("ediv", 0), 

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

2177 

2178 

2179class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet): 

2180 name = "HCI_LE_Long_Term_Key_Request_Reply" 

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

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

2183 

2184 

2185class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): 

2186 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply" 

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

2188 

2189 

2190class HCI_Event_Hdr(Packet): 

2191 name = "HCI Event header" 

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

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

2194 

2195 def answers(self, other): 

2196 if HCI_Command_Hdr not in other: 

2197 return False 

2198 

2199 # Delegate answers to event types 

2200 return self.payload.answers(other) 

2201 

2202 

2203class HCI_Event_Inquiry_Complete(Packet): 

2204 """ 

2205 7.7.1 Inquiry Complete event 

2206 """ 

2207 name = "HCI_Inquiry_Complete" 

2208 fields_desc = [ 

2209 ByteEnumField('status', 0, _bluetooth_error_codes) 

2210 ] 

2211 

2212 

2213class HCI_Event_Inquiry_Result(Packet): 

2214 """ 

2215 7.7.2 Inquiry Result event 

2216 """ 

2217 name = "HCI_Inquiry_Result" 

2218 fields_desc = [ 

2219 ByteField("num_response", 0x00), 

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

2221 count_from=lambda p: p.num_response), 

2222 FieldListField("page_scan_repetition_mode", None, 

2223 ByteField("page_scan_repetition_mode", 0), 

2224 count_from=lambda p: p.num_response), 

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

2226 count_from=lambda p: p.num_response), 

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

2228 count_from=lambda p: p.num_response), 

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

2230 count_from=lambda p: p.num_response) 

2231 ] 

2232 

2233 

2234class HCI_Event_Connection_Complete(Packet): 

2235 """ 

2236 7.7.3 Connection Complete event 

2237 """ 

2238 name = "HCI_Connection_Complete" 

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

2240 LEShortField("handle", 0x0100), 

2241 LEMACField("bd_addr", None), 

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

2243 1: "ACL connection", }), 

2244 ByteEnumField("encryption_enabled", 0, 

2245 {0: "link level encryption disabled", 

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

2247 

2248 

2249class HCI_Event_Disconnection_Complete(Packet): 

2250 """ 

2251 7.7.5 Disconnection Complete event 

2252 """ 

2253 name = "HCI_Disconnection_Complete" 

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

2255 LEShortField("handle", 0), 

2256 XByteField("reason", 0), ] 

2257 

2258 

2259class HCI_Event_Remote_Name_Request_Complete(Packet): 

2260 """ 

2261 7.7.7 Remote Name Request Complete event 

2262 """ 

2263 name = "HCI_Remote_Name_Request_Complete" 

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

2265 LEMACField("bd_addr", None), 

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

2267 

2268 

2269class HCI_Event_Encryption_Change(Packet): 

2270 """ 

2271 7.7.8 Encryption Change event 

2272 """ 

2273 name = "HCI_Encryption_Change" 

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

2275 LEShortField("handle", 0), 

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

2277 

2278 

2279class HCI_Event_Read_Remote_Supported_Features_Complete(Packet): 

2280 """ 

2281 7.7.11 Read Remote Supported Features Complete event 

2282 """ 

2283 name = "HCI_Read_Remote_Supported_Features_Complete" 

2284 fields_desc = [ 

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

2286 LEShortField('handle', 0), 

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

2288 ] 

2289 

2290 

2291class HCI_Event_Read_Remote_Version_Information_Complete(Packet): 

2292 """ 

2293 7.7.12 Read Remote Version Information Complete event 

2294 """ 

2295 name = "HCI_Read_Remote_Version_Information" 

2296 fields_desc = [ 

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

2298 LEShortField('handle', 0), 

2299 ByteField('version', 0x00), 

2300 LEShortField('manufacturer_name', 0x0000), 

2301 LEShortField('subversion', 0x0000) 

2302 ] 

2303 

2304 

2305class HCI_Event_Command_Complete(Packet): 

2306 """ 

2307 7.7.14 Command Complete event 

2308 """ 

2309 name = "HCI_Command_Complete" 

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

2311 XLEShortField("opcode", 0), 

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

2313 

2314 def answers(self, other): 

2315 if HCI_Command_Hdr not in other: 

2316 return False 

2317 

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

2319 

2320 

2321class HCI_Event_Command_Status(Packet): 

2322 """ 

2323 7.7.15 Command Status event 

2324 """ 

2325 name = "HCI_Command_Status" 

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

2327 ByteField("number", 0), 

2328 XLEShortField("opcode", None), ] 

2329 

2330 def answers(self, other): 

2331 if HCI_Command_Hdr not in other: 

2332 return False 

2333 

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

2335 

2336 

2337class HCI_Event_Number_Of_Completed_Packets(Packet): 

2338 """ 

2339 7.7.19 Number Of Completed Packets event 

2340 """ 

2341 name = "HCI_Number_Of_Completed_Packets" 

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

2343 FieldListField("connection_handle_list", None, 

2344 LEShortField("connection_handle", 0), 

2345 count_from=lambda p: p.num_handles), 

2346 FieldListField("num_completed_packets_list", None, 

2347 LEShortField("num_completed_packets", 0), 

2348 count_from=lambda p: p.num_handles)] 

2349 

2350 

2351class HCI_Event_Link_Key_Request(Packet): 

2352 """ 

2353 7.7.23 Link Key Request event 

2354 """ 

2355 name = 'HCI_Link_Key_Request' 

2356 fields_desc = [ 

2357 LEMACField('bd_addr', None) 

2358 ] 

2359 

2360 

2361class HCI_Event_Inquiry_Result_With_Rssi(Packet): 

2362 """ 

2363 7.7.33 Inquiry Result with RSSI event 

2364 """ 

2365 name = "HCI_Inquiry_Result_with_RSSI" 

2366 fields_desc = [ 

2367 ByteField("num_response", 0x00), 

2368 FieldListField("bd_addr", None, LEMACField, 

2369 count_from=lambda p: p.num_response), 

2370 FieldListField("page_scan_repetition_mode", None, ByteField, 

2371 count_from=lambda p: p.num_response), 

2372 FieldListField("reserved", None, LEShortField, 

2373 count_from=lambda p: p.num_response), 

2374 FieldListField("device_class", None, XLE3BytesField, 

2375 count_from=lambda p: p.num_response), 

2376 FieldListField("clock_offset", None, LEShortField, 

2377 count_from=lambda p: p.num_response), 

2378 FieldListField("rssi", None, SignedByteField, 

2379 count_from=lambda p: p.num_response) 

2380 ] 

2381 

2382 

2383class HCI_Event_Read_Remote_Extended_Features_Complete(Packet): 

2384 """ 

2385 7.7.34 Read Remote Extended Features Complete event 

2386 """ 

2387 name = "HCI_Read_Remote_Extended_Features_Complete" 

2388 fields_desc = [ 

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

2390 LEShortField('handle', 0), 

2391 ByteField('page', 0x00), 

2392 ByteField('max_page', 0x00), 

2393 XLELongField('extended_features', 0) 

2394 ] 

2395 

2396 

2397class HCI_Event_Extended_Inquiry_Result(Packet): 

2398 """ 

2399 7.7.38 Extended Inquiry Result event 

2400 """ 

2401 name = "HCI_Extended_Inquiry_Result" 

2402 fields_desc = [ 

2403 ByteField('num_response', 0x01), 

2404 LEMACField('bd_addr', None), 

2405 ByteField('page_scan_repetition_mode', 0x00), 

2406 ByteField('reserved', 0x00), 

2407 XLE3BytesField('device_class', 0x000000), 

2408 LEShortField('clock_offset', 0x0000), 

2409 SignedByteField('rssi', 0x00), 

2410 HCI_Extended_Inquiry_Response, 

2411 ] 

2412 

2413 

2414class HCI_Event_IO_Capability_Response(Packet): 

2415 """ 

2416 7.7.41 IO Capability Response event 

2417 """ 

2418 name = "HCI_IO_Capability_Response" 

2419 fields_desc = [ 

2420 LEMACField('bd_addr', None), 

2421 ByteField('io_capability', 0x00), 

2422 ByteField('oob_data_present', 0x00), 

2423 ByteField('authentication_requirements', 0x00) 

2424 ] 

2425 

2426 

2427class HCI_Event_LE_Meta(Packet): 

2428 """ 

2429 7.7.65 LE Meta event 

2430 """ 

2431 name = "HCI_LE_Meta" 

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

2433 0x01: "connection_complete", 

2434 0x02: "advertising_report", 

2435 0x03: "connection_update_complete", 

2436 0x04: "read_remote_features_page_0_complete", 

2437 0x05: "long_term_key_request", 

2438 0x06: "remote_connection_parameter_request", 

2439 0x07: "data_length_change", 

2440 0x08: "read_local_p256_public_key_complete", 

2441 0x09: "generate_dhkey_complete", 

2442 0x0a: "enhanced_connection_complete_v1", 

2443 0x0b: "directed_advertising_report", 

2444 0x0c: "phy_update_complete", 

2445 0x0d: "extended_advertising_report", 

2446 0x29: "enhanced_connection_complete_v2" 

2447 }), ] 

2448 

2449 def answers(self, other): 

2450 if not self.payload: 

2451 return False 

2452 

2453 # Delegate answers to payload 

2454 return self.payload.answers(other) 

2455 

2456 

2457class HCI_Cmd_Complete_Read_Local_Name(Packet): 

2458 """ 

2459 7.3.12 Read Local Name command complete 

2460 """ 

2461 name = 'Read Local Name command complete' 

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

2463 

2464 

2465class HCI_Cmd_Complete_Read_Local_Version_Information(Packet): 

2466 """ 

2467 7.4.1 Read Local Version Information command complete 

2468 """ 

2469 name = 'Read Local Version Information' 

2470 fields_desc = [ 

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

2472 LEShortField('hci_subversion', 0), 

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

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

2475 LEShortField('lmp_subversion', 0)] 

2476 

2477 

2478class HCI_Cmd_Complete_Read_Local_Extended_Features(Packet): 

2479 """ 

2480 7.4.4 Read Local Extended Features command complete 

2481 """ 

2482 name = 'Read Local Extended Features command complete' 

2483 fields_desc = [ 

2484 ByteField('page', 0x00), 

2485 ByteField('max_page', 0x00), 

2486 XLELongField('extended_features', 0) 

2487 ] 

2488 

2489 

2490class HCI_Cmd_Complete_Read_BD_Addr(Packet): 

2491 """ 

2492 7.4.6 Read BD_ADDR command complete 

2493 """ 

2494 name = "Read BD Addr" 

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

2496 

2497 

2498class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet): 

2499 name = "LE Read White List Size" 

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

2501 ByteField("size", 0), ] 

2502 

2503 

2504class HCI_LE_Meta_Connection_Complete(Packet): 

2505 name = "Connection Complete" 

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

2507 LEShortField("handle", 0), 

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

2509 ByteEnumField("patype", 0, {0: "public", 1: "random"}), 

2510 LEMACField("paddr", None), 

2511 LEShortField("interval", 54), 

2512 LEShortField("latency", 0), 

2513 LEShortField("supervision", 42), 

2514 XByteField("clock_latency", 5), ] 

2515 

2516 def answers(self, other): 

2517 if HCI_Cmd_LE_Create_Connection not in other: 

2518 return False 

2519 

2520 return (other[HCI_Cmd_LE_Create_Connection].patype == self.patype and 

2521 other[HCI_Cmd_LE_Create_Connection].paddr == self.paddr) 

2522 

2523 

2524class HCI_LE_Meta_Connection_Update_Complete(Packet): 

2525 name = "Connection Update Complete" 

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

2527 LEShortField("handle", 0), 

2528 LEShortField("interval", 54), 

2529 LEShortField("latency", 0), 

2530 LEShortField("timeout", 42), ] 

2531 

2532 

2533class HCI_LE_Meta_Advertising_Report(Packet): 

2534 name = "Advertising Report" 

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

2536 ByteEnumField("atype", 0, {0: "public", 1: "random"}), 

2537 LEMACField("addr", None), 

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

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

2540 length_from=lambda pkt: pkt.len), 

2541 SignedByteField("rssi", 0)] 

2542 

2543 def extract_padding(self, s): 

2544 return '', s 

2545 

2546 

2547class HCI_LE_Meta_Advertising_Reports(Packet): 

2548 name = "Advertising Reports" 

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

2550 PacketListField("reports", None, 

2551 HCI_LE_Meta_Advertising_Report, 

2552 count_from=lambda pkt: pkt.len)] 

2553 

2554 

2555class HCI_LE_Meta_Long_Term_Key_Request(Packet): 

2556 name = "Long Term Key Request" 

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

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

2559 XLEShortField("ediv", 0), ] 

2560 

2561 

2562class HCI_LE_Meta_Extended_Advertising_Report(Packet): 

2563 name = "Extended Advertising Report" 

2564 fields_desc = [ 

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

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

2567 0b00: "complete", 

2568 0b01: "incomplete", 

2569 0b10: "incomplete_truncated", 

2570 0b11: "reserved" 

2571 }), 

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

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

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

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

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

2577 ByteField("reserved", 0), 

2578 ByteEnumField("address_type", 0, { 

2579 0x00: "public_device_address", 

2580 0x01: "random_device_address", 

2581 0x02: "public_identity_address", 

2582 0x03: "random_identity_address", 

2583 0xff: "anonymous" 

2584 }), 

2585 LEMACField('address', None), 

2586 ByteEnumField("primary_phy", 0, { 

2587 0x01: "le_1m", 

2588 0x03: "le_coded_s8", 

2589 0x04: "le_coded_s2" 

2590 }), 

2591 ByteEnumField("secondary_phy", 0, { 

2592 0x01: "le_1m", 

2593 0x02: "le_2m", 

2594 0x03: "le_coded_s8", 

2595 0x04: "le_coded_s2" 

2596 }), 

2597 ByteField("advertising_sid", 0xff), 

2598 ByteField("tx_power", 0x7f), 

2599 SignedByteField("rssi", 0x00), 

2600 LEShortField("periodic_advertising_interval", 0x0000), 

2601 ByteEnumField("direct_address_type", 0, { 

2602 0x00: "public_device_address", 

2603 0x01: "non_resolvable_private_address", 

2604 0x02: "resolvable_private_address_resolved_0", 

2605 0x03: "resolvable_private_address_resolved_1", 

2606 0xfe: "resolvable_private_address_unable_resolve"}), 

2607 LEMACField("direct_address", None), 

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

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

2610 length_from=lambda pkt: pkt.data_length), 

2611 ] 

2612 

2613 def extract_padding(self, s): 

2614 return '', s 

2615 

2616 

2617class HCI_LE_Meta_Extended_Advertising_Reports(Packet): 

2618 name = "Extended Advertising Reports" 

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

2620 PacketListField("reports", None, 

2621 HCI_LE_Meta_Extended_Advertising_Report, 

2622 count_from=lambda pkt: pkt.num_reports)] 

2623 

2624 

2625bind_layers(HCI_PHDR_Hdr, HCI_Hdr) 

2626 

2627bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1) 

2628bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2) 

2629bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4) 

2630bind_layers(HCI_Hdr, conf.raw_layer,) 

2631 

2632conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr) 

2633conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr) 

2634 

2635 

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

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

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

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

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

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

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

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

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

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

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

2647bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply, 

2648 ogf=0x01, ocf=0x000c) 

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

2650bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type, 

2651 ogf=0x01, ocf=0x000f) 

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

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

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

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

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

2657bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, 

2658 ogf=0x01, ocf=0x001b) 

2659bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features, 

2660 ogf=0x01, ocf=0x001c) 

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

2662bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply, 

2663 ogf=0x01, ocf=0x002c) 

2664bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply, 

2665 ogf=0x01, ocf=0x002d) 

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

2667bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply, 

2668 ogf=0x01, ocf=0x002f) 

2669bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply, 

2670 ogf=0x01, ocf=0x0030) 

2671bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply, 

2672 ogf=0x01, ocf=0x0033) 

2673 

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

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

2676 

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

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

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

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

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

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

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

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

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

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

2687 

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

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

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

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

2692 

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

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

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

2696 

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

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

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

2700 

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

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

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

2704bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features, 

2705 ogf=0x08, ocf=0x0003) 

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

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

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

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

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

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

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

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

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

2715bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size, 

2716 ogf=0x08, ocf=0x000f) 

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

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

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

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

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

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

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

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

2725 

2726# 7.7 EVENTS 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2744 

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

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

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

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

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

2750 

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

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

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

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

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

2756 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2784bind_layers(EIR_Hdr, EIR_Raw) 

2785 

2786bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,) 

2787bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1) 

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

2789bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1) 

2790bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2) 

2791bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3) 

2792bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4) 

2793bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5) 

2794bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6) 

2795bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7) 

2796bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8) 

2797bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9) 

2798bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10) 

2799bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11) 

2800bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12) 

2801bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13) 

2802bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14) 

2803bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15) 

2804bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16) 

2805bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17) 

2806bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18) 

2807bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19) 

2808bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20) 

2809bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21) 

2810bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22) 

2811bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23) 

2812bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24) 

2813bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25) 

2814bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26) 

2815bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4) 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2843bind_layers(L2CAP_Hdr, SM_Hdr, cid=6) 

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

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

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

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

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

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

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

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

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

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

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

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

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

2857 

2858 

2859############### 

2860# HCI Monitor # 

2861############### 

2862 

2863 

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

2865class HCI_Mon_Hdr(Packet): 

2866 name = 'Bluetooth Linux Monitor Transport Header' 

2867 fields_desc = [ 

2868 LEShortEnumField('opcode', None, { 

2869 0: "New index", 

2870 1: "Delete index", 

2871 2: "Command pkt", 

2872 3: "Event pkt", 

2873 4: "ACL TX pkt", 

2874 5: "ACL RX pkt", 

2875 6: "SCO TX pkt", 

2876 7: "SCO RX pkt", 

2877 8: "Open index", 

2878 9: "Close index", 

2879 10: "Index info", 

2880 11: "Vendor diag", 

2881 12: "System note", 

2882 13: "User logging", 

2883 14: "Ctrl open", 

2884 15: "Ctrl close", 

2885 16: "Ctrl command", 

2886 17: "Ctrl event", 

2887 18: "ISO TX pkt", 

2888 19: "ISO RX pkt", 

2889 }), 

2890 LEShortField('adapter_id', None), 

2891 LEShortField('len', None) 

2892 ] 

2893 

2894 

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

2896class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr): 

2897 name = 'Bluetooth Linux Monitor Transport Pcap Header' 

2898 fields_desc = [ 

2899 ShortField('adapter_id', None), 

2900 ShortField('opcode', None) 

2901 ] 

2902 

2903 

2904class HCI_Mon_New_Index(Packet): 

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

2906 fields_desc = [ 

2907 ByteEnumField('bus', 0, { 

2908 0x00: "BR/EDR", 

2909 0x01: "AMP" 

2910 }), 

2911 ByteEnumField('type', 0, { 

2912 0x00: "Virtual", 

2913 0x01: "USB", 

2914 0x02: "PC Card", 

2915 0x03: "UART", 

2916 0x04: "RS232", 

2917 0x05: "PCI", 

2918 0x06: "SDIO" 

2919 }), 

2920 LEMACField('addr', None), 

2921 StrFixedLenField('devname', None, 8) 

2922 ] 

2923 

2924 

2925class HCI_Mon_Index_Info(Packet): 

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

2927 fields_desc = [ 

2928 LEMACField('addr', None), 

2929 XLEShortField('manufacturer', None) 

2930 ] 

2931 

2932 

2933class HCI_Mon_System_Note(Packet): 

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

2935 fields_desc = [ 

2936 StrNullField('note', None) 

2937 ] 

2938 

2939 

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

2941bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0) 

2942bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2) 

2943bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3) 

2944bind_layers(HCI_Mon_Hdr, HCI_ACL_Hdr, opcode=5) 

2945bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10) 

2946bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12) 

2947 

2948conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr) 

2949 

2950 

2951########### 

2952# Helpers # 

2953########### 

2954 

2955class LowEnergyBeaconHelper: 

2956 """ 

2957 Helpers for building packets for Bluetooth Low Energy Beacons. 

2958 

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

2960 

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

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

2963 """ 

2964 

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

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

2967 "general_disc_mode", "br_edr_not_supported"]), ] 

2968 

2969 def build_eir(self): 

2970 """ 

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

2972 

2973 Users of this helper must implement this method. 

2974 

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

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

2977 """ 

2978 raise NotImplementedError("build_eir") 

2979 

2980 def build_advertising_report(self): 

2981 """ 

2982 Builds a HCI_LE_Meta_Advertising_Report containing this frame. 

2983 

2984 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report 

2985 """ 

2986 

2987 return HCI_LE_Meta_Advertising_Report( 

2988 type=0, # Undirected 

2989 atype=1, # Random address 

2990 data=self.build_eir() 

2991 ) 

2992 

2993 def build_set_advertising_data(self): 

2994 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame. 

2995 

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

2997 

2998 :rtype: scapy.bluetooth.HCI_Hdr 

2999 """ 

3000 

3001 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data( 

3002 data=self.build_eir() 

3003 ) 

3004 

3005 

3006########### 

3007# Sockets # 

3008########### 

3009 

3010class BluetoothSocketError(BaseException): 

3011 pass 

3012 

3013 

3014class BluetoothCommandError(BaseException): 

3015 pass 

3016 

3017 

3018class BluetoothL2CAPSocket(SuperSocket): 

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

3020 

3021 def __init__(self, bt_address): 

3022 if WINDOWS: 

3023 warning("Not available on Windows") 

3024 return 

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

3026 socket.BTPROTO_L2CAP) 

3027 s.connect((bt_address, 0)) 

3028 self.ins = self.outs = s 

3029 

3030 def recv(self, x=MTU): 

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

3032 

3033 

3034class BluetoothRFCommSocket(BluetoothL2CAPSocket): 

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

3036 

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

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

3039 socket.BTPROTO_RFCOMM) 

3040 s.connect((bt_address, port)) 

3041 self.ins = self.outs = s 

3042 

3043 

3044class BluetoothHCISocket(SuperSocket): 

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

3046 

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

3048 if WINDOWS: 

3049 warning("Not available on Windows") 

3050 return 

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

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

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

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

3055 s.bind((iface,)) 

3056 self.ins = self.outs = s 

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

3058 

3059 def recv(self, x=MTU): 

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

3061 

3062 

3063class sockaddr_hci(ctypes.Structure): 

3064 _fields_ = [ 

3065 ("sin_family", ctypes.c_ushort), 

3066 ("hci_dev", ctypes.c_ushort), 

3067 ("hci_channel", ctypes.c_ushort), 

3068 ] 

3069 

3070 

3071class _BluetoothLibcSocket(SuperSocket): 

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

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

3074 if WINDOWS: 

3075 warning("Not available on Windows") 

3076 return 

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

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

3079 # ctypes. 

3080 sockaddr_hcip = ctypes.POINTER(sockaddr_hci) 

3081 from ctypes.util import find_library 

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

3083 

3084 socket_c = libc.socket 

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

3086 socket_c.restype = ctypes.c_int 

3087 

3088 bind = libc.bind 

3089 bind.argtypes = (ctypes.c_int, 

3090 ctypes.POINTER(sockaddr_hci), 

3091 ctypes.c_int) 

3092 bind.restype = ctypes.c_int 

3093 

3094 # Socket 

3095 s = socket_c(socket_domain, socket_type, socket_protocol) 

3096 if s < 0: 

3097 raise BluetoothSocketError( 

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

3099 f"{socket_protocol})") 

3100 

3101 # Bind 

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

3103 if r != 0: 

3104 raise BluetoothSocketError("Unable to bind") 

3105 

3106 self.hci_fd = s 

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

3108 s, socket_domain, socket_type, socket_protocol) 

3109 

3110 def readable(self, timeout=0): 

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

3112 return len(ins) > 0 

3113 

3114 def flush(self): 

3115 while self.readable(): 

3116 self.recv() 

3117 

3118 def close(self): 

3119 if self.closed: 

3120 return 

3121 

3122 # Properly close socket so we can free the device 

3123 from ctypes.util import find_library 

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

3125 

3126 close = libc.close 

3127 close.restype = ctypes.c_int 

3128 self.closed = True 

3129 if hasattr(self, "outs"): 

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

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

3132 close(self.outs.fileno()) 

3133 if hasattr(self, "ins"): 

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

3135 close(self.ins.fileno()) 

3136 if hasattr(self, "hci_fd"): 

3137 close(self.hci_fd) 

3138 

3139 

3140class BluetoothUserSocket(_BluetoothLibcSocket): 

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

3142 

3143 def __init__(self, adapter_index=0): 

3144 sa = sockaddr_hci() 

3145 sa.sin_family = socket.AF_BLUETOOTH 

3146 sa.hci_dev = adapter_index 

3147 sa.hci_channel = HCI_CHANNEL_USER 

3148 super().__init__( 

3149 socket_domain=socket.AF_BLUETOOTH, 

3150 socket_type=socket.SOCK_RAW, 

3151 socket_protocol=socket.BTPROTO_HCI, 

3152 sock_address=sa) 

3153 

3154 def send_command(self, cmd): 

3155 opcode = cmd[HCI_Command_Hdr].opcode 

3156 self.send(cmd) 

3157 while True: 

3158 r = self.recv() 

3159 if r.type == 0x04 and r.code == 0xe and r.opcode == opcode: 

3160 if r.status != 0: 

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

3162 return r 

3163 

3164 def recv(self, x=MTU): 

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

3166 

3167 

3168class BluetoothMonitorSocket(_BluetoothLibcSocket): 

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

3170 

3171 def __init__(self): 

3172 sa = sockaddr_hci() 

3173 sa.sin_family = socket.AF_BLUETOOTH 

3174 sa.hci_dev = HCI_DEV_NONE 

3175 sa.hci_channel = HCI_CHANNEL_MONITOR 

3176 super().__init__( 

3177 socket_domain=socket.AF_BLUETOOTH, 

3178 socket_type=socket.SOCK_RAW, 

3179 socket_protocol=socket.BTPROTO_HCI, 

3180 sock_address=sa) 

3181 

3182 def recv(self, x=MTU): 

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

3184 

3185 

3186conf.BTsocket = BluetoothRFCommSocket 

3187 

3188# Bluetooth 

3189 

3190 

3191@conf.commands.register 

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

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

3194 if "port" in kargs: 

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

3196 else: 

3197 s = conf.BTsocket(bt_address=bt_address) 

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

3199 s.close() 

3200 return a, b 

3201 

3202 

3203@conf.commands.register 

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

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

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

3207 if len(a) > 0: 

3208 return a[0][1]