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

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

26from scapy.packet import bind_layers, Packet 

27from scapy.fields import ( 

28 BitField, 

29 XBitField, 

30 ByteEnumField, 

31 ByteField, 

32 FieldLenField, 

33 FieldListField, 

34 FlagsField, 

35 IntField, 

36 LEShortEnumField, 

37 LEShortField, 

38 LEIntField, 

39 LenField, 

40 MultipleTypeField, 

41 NBytesField, 

42 PacketListField, 

43 PadField, 

44 ShortField, 

45 SignedByteField, 

46 StrField, 

47 StrFixedLenField, 

48 StrLenField, 

49 StrNullField, 

50 UUIDField, 

51 XByteField, 

52 XLE3BytesField, 

53 XLELongField, 

54 XStrLenField, 

55 XLEShortField, 

56 XLEIntField, 

57 LEMACField, 

58 BitEnumField, 

59 LEThreeBytesField, 

60) 

61from scapy.supersocket import SuperSocket 

62from scapy.sendrecv import sndrcv 

63from scapy.data import MTU 

64from scapy.consts import WINDOWS 

65from scapy.error import warning 

66 

67 

68############ 

69# Consts # 

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

71 

72# From hci.h 

73HCI_CHANNEL_RAW = 0 

74HCI_CHANNEL_USER = 1 

75HCI_CHANNEL_MONITOR = 2 

76HCI_CHANNEL_CONTROL = 3 

77HCI_CHANNEL_LOGGING = 4 

78 

79HCI_DEV_NONE = 0xffff 

80 

81 

82########## 

83# Layers # 

84########## 

85 

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

87 

88# Transport layers 

89 

90class HCI_PHDR_Hdr(Packet): 

91 name = "HCI PHDR transport layer" 

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

93 

94 

95# Real layers 

96 

97_bluetooth_packet_types = { 

98 0: "Acknowledgement", 

99 1: "Command", 

100 2: "ACL Data", 

101 3: "Synchronous", 

102 4: "Event", 

103 5: "Reserve", 

104 14: "Vendor", 

105 15: "Link Control" 

106} 

107 

108_bluetooth_error_codes = { 

109 0x00: "Success", 

110 0x01: "Unknown HCI Command", 

111 0x02: "Unknown Connection Identifier", 

112 0x03: "Hardware Failure", 

113 0x04: "Page Timeout", 

114 0x05: "Authentication Failure", 

115 0x06: "PIN or Key Missing", 

116 0x07: "Memory Capacity Exceeded", 

117 0x08: "Connection Timeout", 

118 0x09: "Connection Limit Exceeded", 

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

120 0x0B: "Connection Already Exists", 

121 0x0C: "Command Disallowed", 

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

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

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

125 0x10: "Connection Accept Timeout Exceeded", 

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

127 0x12: "Invalid HCI Command Parameters", 

128 0x13: "Remote User Terminated Connection", 

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

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

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

132 0x17: "Repeated Attempts", 

133 0x18: "Pairing Not Allowed", 

134 0x19: "Unknown LMP PDU", 

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

136 0x1B: "SCO Offset Rejected", 

137 0x1C: "SCO Interval Rejected", 

138 0x1D: "SCO Air Mode Rejected", 

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

140 0x1F: "Unspecified Error", 

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

142 0x21: "Role Change Not Allowed", 

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

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

145 0x24: "LMP PDU Not Allowed", 

146 0x25: "Encryption Mode Not Acceptable", 

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

148 0x27: "Requested QoS Not Supported", 

149 0x28: "Instant Passed", 

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

151 0x2A: "Different Transaction Collision", 

152 0x2B: "Reserved for future use", 

153 0x2C: "QoS Unacceptable Parameter", 

154 0x2D: "QoS Rejected", 

155 0x2E: "Channel Classification Not Supported", 

156 0x2F: "Insufficient Security", 

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

158 0x31: "Reserved for future use", 

159 0x32: "Role Switch Pending", 

160 0x33: "Reserved for future use", 

161 0x34: "Reserved Slot Violation", 

162 0x35: "Role Switch Failed", 

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

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

165 0x38: "Host Busy - Pairing", 

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

167 0x3A: "Controller Busy", 

168 0x3B: "Unacceptable Connection Parameters", 

169 0x3C: "Advertising Timeout", 

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

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

172 0x3F: "MAC Connection Failed", 

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

174 " Dragging", 

175 0x41: "Type0 Submap Not Defined", 

176 0x42: "Unknown Advertising Identifier", 

177 0x43: "Limit Reached", 

178 0x44: "Operation Cancelled by Host", 

179 0x45: "Packet Too Long" 

180} 

181 

182_att_error_codes = { 

183 0x01: "invalid handle", 

184 0x02: "read not permitted", 

185 0x03: "write not permitted", 

186 0x04: "invalid pdu", 

187 0x05: "insufficient auth", 

188 0x06: "unsupported req", 

189 0x07: "invalid offset", 

190 0x08: "insufficient author", 

191 0x09: "prepare queue full", 

192 0x0a: "attr not found", 

193 0x0b: "attr not long", 

194 0x0c: "insufficient key size", 

195 0x0d: "invalid value size", 

196 0x0e: "unlikely", 

197 0x0f: "insufficiet encrypt", 

198 0x10: "unsupported gpr type", 

199 0x11: "insufficient resources", 

200} 

201 

202_bluetooth_features = [ 

203 '3_slot_packets', 

204 '5_slot_packets', 

205 'encryption', 

206 'slot_offset', 

207 'timing_accuracy', 

208 'role_switch', 

209 'hold_mode', 

210 'sniff_mode', 

211 'park_mode', 

212 'power_control_requests', 

213 'channel_quality_driven_data_rate', 

214 'sco_link', 

215 'hv2_packets', 

216 'hv3_packets', 

217 'u_law_log_synchronous_data', 

218 'a_law_log_synchronous_data', 

219 'cvsd_synchronous_data', 

220 'paging_parameter_negotiation', 

221 'power_control', 

222 'transparent_synchronous_data', 

223 'flow_control_lag_4_bit0', 

224 'flow_control_lag_4_bit1', 

225 'flow_control_lag_4_bit2', 

226 'broadband_encryption', 

227 'cvsd_synchronous_data', 

228 'edr_acl_2_mbps_mode', 

229 'edr_acl_3_mbps_mode', 

230 'enhanced_inquiry_scan', 

231 'interlaced_inquiry_scan', 

232 'interlaced_page_scan', 

233 'rssi_with_inquiry_results', 

234 'ev3_packets', 

235 'ev4_packets', 

236 'ev5_packets', 

237 'reserved', 

238 'afh_capable_slave', 

239 'afh_classification_slave', 

240 'br_edr_not_supported', 

241 'le_supported_controller', 

242 '3_slot_edr_acl_packets', 

243 '5_slot_edr_acl_packets', 

244 'sniff_subrating', 

245 'pause_encryption', 

246 'afh_capable_master', 

247 'afh_classification_master', 

248 'edr_esco_2_mbps_mode', 

249 'edr_esco_3_mbps_mode', 

250 '3_slot_edr_esco_packets', 

251 'extended_inquiry_response', 

252 'simultaneous_le_and_br_edr_to_same_device_capable_controller', 

253 'reserved2', 

254 'secure_simple_pairing', 

255 'encapsulated_pdu', 

256 'erroneous_data_reporting', 

257 'non_flushable_packet_boundary_flag', 

258 'reserved3', 

259 'link_supervision_timeout_changed_event', 

260 'inquiry_tx_power_level', 

261 'enhanced_power_control', 

262 'reserved4_bit0', 

263 'reserved4_bit1', 

264 'reserved4_bit2', 

265 'reserved4_bit3', 

266 'extended_features', 

267] 

268 

269 

270class HCI_Hdr(Packet): 

271 name = "HCI header" 

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

273 

274 def mysummary(self): 

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

276 

277 

278class HCI_ACL_Hdr(Packet): 

279 name = "HCI ACL header" 

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

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

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

283 LEShortField("len", None), ] 

284 

285 def post_build(self, p, pay): 

286 p += pay 

287 if self.len is None: 

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

289 return p 

290 

291 

292class L2CAP_Hdr(Packet): 

293 name = "L2CAP header" 

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

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

296 

297 def post_build(self, p, pay): 

298 p += pay 

299 if self.len is None: 

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

301 return p 

302 

303 

304class L2CAP_CmdHdr(Packet): 

305 name = "L2CAP command header" 

306 fields_desc = [ 

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

308 2: "conn_req", 

309 3: "conn_resp", 

310 4: "conf_req", 

311 5: "conf_resp", 

312 6: "disconn_req", 

313 7: "disconn_resp", 

314 8: "echo_req", 

315 9: "echo_resp", 

316 10: "info_req", 

317 11: "info_resp", 

318 12: "create_channel_req", 

319 13: "create_channel_resp", 

320 14: "move_channel_req", 

321 15: "move_channel_resp", 

322 16: "move_channel_confirm_req", 

323 17: "move_channel_confirm_resp", 

324 18: "conn_param_update_req", 

325 19: "conn_param_update_resp", 

326 20: "LE_credit_based_conn_req", 

327 21: "LE_credit_based_conn_resp", 

328 22: "flow_control_credit_ind", 

329 23: "credit_based_conn_req", 

330 24: "credit_based_conn_resp", 

331 25: "credit_based_reconf_req", 

332 26: "credit_based_reconf_resp"}), 

333 ByteField("id", 0), 

334 LEShortField("len", None)] 

335 

336 def post_build(self, p, pay): 

337 p += pay 

338 if self.len is None: 

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

340 return p 

341 

342 def answers(self, other): 

343 if other.id == self.id: 

344 if self.code == 1: 

345 return 1 

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

347 if other.code == 8: 

348 return 1 

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

350 return 0 

351 

352 

353class L2CAP_ConnReq(Packet): 

354 name = "L2CAP Conn Req" 

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

356 3: "RFCOMM", 

357 5: "TCS-BIN", 

358 7: "TCS-BIN-CORDLESS", 

359 15: "BNEP", 

360 17: "HID-Control", 

361 19: "HID-Interrupt", 

362 21: "UPnP", 

363 23: "AVCTP-Control", 

364 25: "AVDTP", 

365 27: "AVCTP-Browsing", 

366 29: "UDI_C-Plane", 

367 31: "ATT", 

368 33: "3DSP", 

369 35: "IPSP", 

370 37: "OTS"}), 

371 LEShortField("scid", 0), 

372 ] 

373 

374 

375class L2CAP_ConnResp(Packet): 

376 name = "L2CAP Conn Resp" 

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

378 LEShortField("scid", 0), 

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

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

381 ] 

382 

383 def answers(self, other): 

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

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

386 

387 

388class L2CAP_CmdRej(Packet): 

389 name = "L2CAP Command Rej" 

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

391 ] 

392 

393 

394class L2CAP_ConfReq(Packet): 

395 name = "L2CAP Conf Req" 

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

397 LEShortField("flags", 0), 

398 ] 

399 

400 

401class L2CAP_ConfResp(Packet): 

402 name = "L2CAP Conf Resp" 

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

404 LEShortField("flags", 0), 

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

406 ] 

407 

408 def answers(self, other): 

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

410 return isinstance(other, L2CAP_ConfReq) 

411 

412 

413class L2CAP_DisconnReq(Packet): 

414 name = "L2CAP Disconn Req" 

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

416 LEShortField("scid", 0), ] 

417 

418 

419class L2CAP_DisconnResp(Packet): 

420 name = "L2CAP Disconn Resp" 

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

422 LEShortField("scid", 0), ] 

423 

424 def answers(self, other): 

425 return self.scid == other.scid 

426 

427 

428class L2CAP_EchoReq(Packet): 

429 name = "L2CAP Echo Req" 

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

431 

432 

433class L2CAP_EchoResp(Packet): 

434 name = "L2CAP Echo Resp" 

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

436 

437 

438class L2CAP_InfoReq(Packet): 

439 name = "L2CAP Info Req" 

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

441 StrField("data", "") 

442 ] 

443 

444 

445class L2CAP_InfoResp(Packet): 

446 name = "L2CAP Info Resp" 

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

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

449 StrField("data", ""), ] 

450 

451 def answers(self, other): 

452 return self.type == other.type 

453 

454 

455class L2CAP_Create_Channel_Request(Packet): 

456 name = "L2CAP Create Channel Request" 

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

458 3: "RFCOMM", 

459 5: "TCS-BIN", 

460 7: "TCS-BIN-CORDLESS", 

461 15: "BNEP", 

462 17: "HID-Control", 

463 19: "HID-Interrupt", 

464 21: "UPnP", 

465 23: "AVCTP-Control", 

466 25: "AVDTP", 

467 27: "AVCTP-Browsing", 

468 29: "UDI_C-Plane", 

469 31: "ATT", 

470 33: "3DSP", 

471 35: "IPSP", 

472 37: "OTS"}), 

473 LEShortField("scid", 0), 

474 ByteField("controller_id", 0), ] 

475 

476 

477class L2CAP_Create_Channel_Response(Packet): 

478 name = "L2CAP Create Channel Response" 

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

480 LEShortField("scid", 0), 

481 LEShortEnumField("result", 0, { 

482 0: "Connection successful", 

483 1: "Connection pending", 

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

485 3: "Connection refused - security block", 

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

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

488 6: "Connection refused - invalid scid", 

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

490 LEShortEnumField("status", 0, { 

491 0: "No further information available", 

492 1: "Authentication pending", 

493 2: "Authorization pending"}), ] 

494 

495 

496class L2CAP_Move_Channel_Request(Packet): 

497 name = "L2CAP Move Channel Request" 

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

499 ByteField("dest_controller_id", 0), ] 

500 

501 

502class L2CAP_Move_Channel_Response(Packet): 

503 name = "L2CAP Move Channel Response" 

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

505 LEShortEnumField("result", 0, { 

506 0: "Move success", 

507 1: "Move pending", 

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

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

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

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

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

513 

514 

515class L2CAP_Move_Channel_Confirmation_Request(Packet): 

516 name = "L2CAP Move Channel Confirmation Request" 

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

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

519 1: "Move failure"}), ] 

520 

521 

522class L2CAP_Move_Channel_Confirmation_Response(Packet): 

523 name = "L2CAP Move Channel Confirmation Response" 

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

525 

526 

527class L2CAP_Connection_Parameter_Update_Request(Packet): 

528 name = "L2CAP Connection Parameter Update Request" 

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

530 LEShortField("max_interval", 0), 

531 LEShortField("slave_latency", 0), 

532 LEShortField("timeout_mult", 0), ] 

533 

534 

535class L2CAP_Connection_Parameter_Update_Response(Packet): 

536 name = "L2CAP Connection Parameter Update Response" 

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

538 

539 

540class L2CAP_LE_Credit_Based_Connection_Request(Packet): 

541 name = "L2CAP LE Credit Based Connection Request" 

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

543 LEShortField("scid", 0), 

544 LEShortField("mtu", 0), 

545 LEShortField("mps", 0), 

546 LEShortField("initial_credits", 0), ] 

547 

548 

549class L2CAP_LE_Credit_Based_Connection_Response(Packet): 

550 name = "L2CAP LE Credit Based Connection Response" 

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

552 LEShortField("mtu", 0), 

553 LEShortField("mps", 0), 

554 LEShortField("initial_credits", 0), 

555 LEShortEnumField("result", 0, { 

556 0: "Connection successful", 

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

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

559 5: "Connection refused - authentication error", 

560 6: "Connection refused - authorization error", 

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

562 8: "Connection refused - insufficient encryption", 

563 9: "Connection refused - invalid scid", 

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

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

566 

567 

568class L2CAP_Flow_Control_Credit_Ind(Packet): 

569 name = "L2CAP Flow Control Credit Ind" 

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

571 LEShortField("credits", 0), ] 

572 

573 

574class L2CAP_Credit_Based_Connection_Request(Packet): 

575 name = "L2CAP Credit Based Connection Request" 

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

577 LEShortField("mtu", 0), 

578 LEShortField("mps", 0), 

579 LEShortField("initial_credits", 0), 

580 LEShortField("scid", 0), ] 

581 

582 

583class L2CAP_Credit_Based_Connection_Response(Packet): 

584 name = "L2CAP Credit Based Connection Response" 

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

586 LEShortField("mps", 0), 

587 LEShortField("initial_credits", 0), 

588 LEShortEnumField("result", 0, { 

589 0: "All connection successful", 

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

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

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

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

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

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

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

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

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

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

600 LEShortField("dcid", 0), ] 

601 

602 

603class L2CAP_Credit_Based_Reconfigure_Request(Packet): 

604 name = "L2CAP Credit Based Reconfigure Request" 

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

606 LEShortField("mps", 0), 

607 LEShortField("dcid", 0), ] 

608 

609 

610class L2CAP_Credit_Based_Reconfigure_Response(Packet): 

611 name = "L2CAP Credit Based Reconfigure Response" 

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

613 0: "Reconfig successful", 

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

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

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

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

618 

619 

620class ATT_Hdr(Packet): 

621 name = "ATT header" 

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

623 

624 

625class ATT_Handle(Packet): 

626 name = "ATT Short Handle" 

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

628 XLEShortField("value", 0)] 

629 

630 def extract_padding(self, s): 

631 return b'', s 

632 

633 

634class ATT_Handle_UUID128(Packet): 

635 name = "ATT Handle (UUID 128)" 

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

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

638 

639 def extract_padding(self, s): 

640 return b'', s 

641 

642 

643class ATT_Error_Response(Packet): 

644 name = "Error Response" 

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

646 LEShortField("handle", 0), 

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

648 

649 

650class ATT_Exchange_MTU_Request(Packet): 

651 name = "Exchange MTU Request" 

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

653 

654 

655class ATT_Exchange_MTU_Response(Packet): 

656 name = "Exchange MTU Response" 

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

658 

659 

660class ATT_Find_Information_Request(Packet): 

661 name = "Find Information Request" 

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

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

664 

665 

666class ATT_Find_Information_Response(Packet): 

667 name = "Find Information Response" 

668 fields_desc = [ 

669 XByteField("format", 1), 

670 MultipleTypeField( 

671 [ 

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

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

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

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

676 ], 

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

678 ) 

679 ] 

680 

681 

682class ATT_Find_By_Type_Value_Request(Packet): 

683 name = "Find By Type Value Request" 

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

685 XLEShortField("end", 0xffff), 

686 XLEShortField("uuid", None), 

687 StrField("data", ""), ] 

688 

689 

690class ATT_Find_By_Type_Value_Response(Packet): 

691 name = "Find By Type Value Response" 

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

693 

694 

695class ATT_Read_By_Type_Request_128bit(Packet): 

696 name = "Read By Type Request" 

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

698 XLEShortField("end", 0xffff), 

699 XLELongField("uuid1", None), 

700 XLELongField("uuid2", None)] 

701 

702 @classmethod 

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

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

705 return ATT_Read_By_Type_Request 

706 return ATT_Read_By_Type_Request_128bit 

707 

708 

709class ATT_Read_By_Type_Request(Packet): 

710 name = "Read By Type Request" 

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

712 XLEShortField("end", 0xffff), 

713 XLEShortField("uuid", None)] 

714 

715 

716class ATT_Handle_Variable(Packet): 

717 __slots__ = ["val_length"] 

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

719 XStrLenField( 

720 "value", 0, 

721 length_from=lambda pkt: pkt.val_length)] 

722 

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

724 self.val_length = val_length 

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

726 

727 def extract_padding(self, s): 

728 return b"", s 

729 

730 

731class ATT_Read_By_Type_Response(Packet): 

732 name = "Read By Type Response" 

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

734 PacketListField( 

735 "handles", [], 

736 next_cls_cb=lambda pkt, *args: ( 

737 pkt._next_cls_cb(pkt, *args) 

738 ))] 

739 

740 @classmethod 

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

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

743 return functools.partial( 

744 ATT_Handle_Variable, 

745 val_length=pkt.len - 2 

746 ) 

747 return None 

748 

749 

750class ATT_Read_Request(Packet): 

751 name = "Read Request" 

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

753 

754 

755class ATT_Read_Response(Packet): 

756 name = "Read Response" 

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

758 

759 

760class ATT_Read_Multiple_Request(Packet): 

761 name = "Read Multiple Request" 

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

763 

764 

765class ATT_Read_Multiple_Response(Packet): 

766 name = "Read Multiple Response" 

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

768 

769 

770class ATT_Read_By_Group_Type_Request(Packet): 

771 name = "Read By Group Type Request" 

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

773 XLEShortField("end", 0xffff), 

774 XLEShortField("uuid", 0), ] 

775 

776 

777class ATT_Read_By_Group_Type_Response(Packet): 

778 name = "Read By Group Type Response" 

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

780 StrField("data", ""), ] 

781 

782 

783class ATT_Write_Request(Packet): 

784 name = "Write Request" 

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

786 StrField("data", ""), ] 

787 

788 

789class ATT_Write_Command(Packet): 

790 name = "Write Request" 

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

792 StrField("data", ""), ] 

793 

794 

795class ATT_Write_Response(Packet): 

796 name = "Write Response" 

797 

798 

799class ATT_Prepare_Write_Request(Packet): 

800 name = "Prepare Write Request" 

801 fields_desc = [ 

802 XLEShortField("gatt_handle", 0), 

803 LEShortField("offset", 0), 

804 StrField("data", "") 

805 ] 

806 

807 

808class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request): 

809 name = "Prepare Write Response" 

810 

811 

812class ATT_Handle_Value_Notification(Packet): 

813 name = "Handle Value Notification" 

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

815 StrField("value", ""), ] 

816 

817 

818class ATT_Execute_Write_Request(Packet): 

819 name = "Execute Write Request" 

820 fields_desc = [ 

821 ByteEnumField("flags", 1, { 

822 0: "Cancel all prepared writes", 

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

824 }), 

825 ] 

826 

827 

828class ATT_Execute_Write_Response(Packet): 

829 name = "Execute Write Response" 

830 

831 

832class ATT_Read_Blob_Request(Packet): 

833 name = "Read Blob Request" 

834 fields_desc = [ 

835 XLEShortField("gatt_handle", 0), 

836 LEShortField("offset", 0) 

837 ] 

838 

839 

840class ATT_Read_Blob_Response(Packet): 

841 name = "Read Blob Response" 

842 fields_desc = [ 

843 StrField("value", "") 

844 ] 

845 

846 

847class ATT_Handle_Value_Indication(Packet): 

848 name = "Handle Value Indication" 

849 fields_desc = [ 

850 XLEShortField("gatt_handle", 0), 

851 StrField("value", ""), 

852 ] 

853 

854 

855class SM_Hdr(Packet): 

856 name = "SM header" 

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

858 

859 

860class SM_Pairing_Request(Packet): 

861 name = "Pairing Request" 

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

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

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

865 ByteField("max_key_size", 16), 

866 ByteField("initiator_key_distribution", 0), 

867 ByteField("responder_key_distribution", 0), ] 

868 

869 

870class SM_Pairing_Response(Packet): 

871 name = "Pairing Response" 

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

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

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

875 ByteField("max_key_size", 16), 

876 ByteField("initiator_key_distribution", 0), 

877 ByteField("responder_key_distribution", 0), ] 

878 

879 

880class SM_Confirm(Packet): 

881 name = "Pairing Confirm" 

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

883 

884 

885class SM_Random(Packet): 

886 name = "Pairing Random" 

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

888 

889 

890class SM_Failed(Packet): 

891 name = "Pairing Failed" 

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

893 

894 

895class SM_Encryption_Information(Packet): 

896 name = "Encryption Information" 

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

898 

899 

900class SM_Master_Identification(Packet): 

901 name = "Master Identification" 

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

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

904 

905 

906class SM_Identity_Information(Packet): 

907 name = "Identity Information" 

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

909 

910 

911class SM_Identity_Address_Information(Packet): 

912 name = "Identity Address Information" 

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

914 LEMACField("address", None), ] 

915 

916 

917class SM_Signing_Information(Packet): 

918 name = "Signing Information" 

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

920 

921 

922class SM_Security_Request(Packet): 

923 name = "Security Request" 

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

925 

926 

927class SM_Public_Key(Packet): 

928 name = "Public Key" 

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

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

931 

932 

933class SM_DHKey_Check(Packet): 

934 name = "DHKey Check" 

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

936 

937 

938class EIR_Hdr(Packet): 

939 name = "EIR Header" 

940 fields_desc = [ 

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

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

943 ByteEnumField("type", 0, { 

944 0x01: "flags", 

945 0x02: "incomplete_list_16_bit_svc_uuids", 

946 0x03: "complete_list_16_bit_svc_uuids", 

947 0x04: "incomplete_list_32_bit_svc_uuids", 

948 0x05: "complete_list_32_bit_svc_uuids", 

949 0x06: "incomplete_list_128_bit_svc_uuids", 

950 0x07: "complete_list_128_bit_svc_uuids", 

951 0x08: "shortened_local_name", 

952 0x09: "complete_local_name", 

953 0x0a: "tx_power_level", 

954 0x0d: "class_of_device", 

955 0x0e: "simple_pairing_hash", 

956 0x0f: "simple_pairing_rand", 

957 

958 0x10: "sec_mgr_tk", 

959 0x11: "sec_mgr_oob_flags", 

960 0x12: "slave_conn_intvl_range", 

961 0x14: "list_16_bit_svc_sollication_uuids", 

962 0x15: "list_128_bit_svc_sollication_uuids", 

963 0x16: "svc_data_16_bit_uuid", 

964 0x17: "pub_target_addr", 

965 0x18: "rand_target_addr", 

966 0x19: "appearance", 

967 0x1a: "adv_intvl", 

968 0x1b: "le_addr", 

969 0x1c: "le_role", 

970 0x1d: "simple_pairing_hash_256", 

971 0x1e: "simple_pairing_rand_256", 

972 0x1f: "list_32_bit_svc_sollication_uuids", 

973 

974 0x20: "svc_data_32_bit_uuid", 

975 0x21: "svc_data_128_bit_uuid", 

976 0x22: "sec_conn_confirm", 

977 0x23: "sec_conn_rand", 

978 0x24: "uri", 

979 0x25: "indoor_positioning", 

980 0x26: "transport_discovery", 

981 0x27: "le_supported_features", 

982 0x28: "channel_map_update", 

983 0x29: "mesh_pb_adv", 

984 0x2a: "mesh_message", 

985 0x2b: "mesh_beacon", 

986 

987 0x3d: "3d_information", 

988 

989 0xff: "mfg_specific_data", 

990 }), 

991 ] 

992 

993 def mysummary(self): 

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

995 

996 def guess_payload_class(self, payload): 

997 if self.len == 0: 

998 # For Extended_Inquiry_Response, stop when len=0 

999 return conf.padding_layer 

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

1001 

1002 

1003class EIR_Element(Packet): 

1004 name = "EIR Element" 

1005 

1006 def extract_padding(self, s): 

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

1008 return b'', s 

1009 

1010 @staticmethod 

1011 def length_from(pkt): 

1012 if not pkt.underlayer: 

1013 warning("Missing an upper-layer") 

1014 return 0 

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

1016 return pkt.underlayer.len - 1 

1017 

1018 

1019class EIR_Raw(EIR_Element): 

1020 name = "EIR Raw" 

1021 fields_desc = [ 

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

1023 ] 

1024 

1025 

1026class EIR_Flags(EIR_Element): 

1027 name = "Flags" 

1028 fields_desc = [ 

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

1030 ["limited_disc_mode", "general_disc_mode", 

1031 "br_edr_not_supported", "simul_le_br_edr_ctrl", 

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

1033 ] 

1034 

1035 

1036class EIR_CompleteList16BitServiceUUIDs(EIR_Element): 

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

1038 fields_desc = [ 

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

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

1041 length_from=EIR_Element.length_from) 

1042 ] 

1043 

1044 

1045class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs): 

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

1047 

1048 

1049class EIR_CompleteList32BitServiceUUIDs(EIR_Element): 

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

1051 fields_desc = [ 

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

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

1054 length_from=EIR_Element.length_from) 

1055 ] 

1056 

1057 

1058class EIR_IncompleteList32BitServiceUUIDs(EIR_CompleteList32BitServiceUUIDs): 

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

1060 

1061 

1062class EIR_CompleteList128BitServiceUUIDs(EIR_Element): 

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

1064 fields_desc = [ 

1065 FieldListField("svc_uuids", None, 

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

1067 length_from=EIR_Element.length_from) 

1068 ] 

1069 

1070 

1071class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs): 

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

1073 

1074 

1075class EIR_CompleteLocalName(EIR_Element): 

1076 name = "Complete Local Name" 

1077 fields_desc = [ 

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

1079 ] 

1080 

1081 

1082class EIR_ShortenedLocalName(EIR_CompleteLocalName): 

1083 name = "Shortened Local Name" 

1084 

1085 

1086class EIR_TX_Power_Level(EIR_Element): 

1087 name = "TX Power Level" 

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

1089 

1090 

1091class EIR_ClassOfDevice(EIR_Element): 

1092 name = 'Class of device' 

1093 fields_desc = [ 

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

1095 'limited_discoverable_mode', 

1096 'le_audio', 

1097 'reserved', 

1098 'positioning', 

1099 'networking', 

1100 'rendering', 

1101 'capturing', 

1102 'object_transfer', 

1103 'audio', 

1104 'telephony', 

1105 'information' 

1106 ], tot_size=-3), 

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

1108 0x00: 'miscellaneous', 

1109 0x01: 'computer', 

1110 0x02: 'phone', 

1111 0x03: 'lan', 

1112 0x04: 'audio_video', 

1113 0x05: 'peripheral', 

1114 0x06: 'imaging', 

1115 0x07: 'wearable', 

1116 0x08: 'toy', 

1117 0x09: 'health', 

1118 0x1f: 'uncategorized' 

1119 }), 

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

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

1122 ] 

1123 

1124 

1125class EIR_SecureSimplePairingHashC192(EIR_Element): 

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

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

1128 

1129 

1130class EIR_SecureSimplePairingRandomizerR192(EIR_Element): 

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

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

1133 

1134 

1135class EIR_SecurityManagerOOBFlags(EIR_Element): 

1136 name = 'Security Manager Out of Band Flags' 

1137 fields_desc = [ 

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

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

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

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

1142 BitField('reserved', 0, 4) 

1143 ] 

1144 

1145 

1146class EIR_PeripheralConnectionIntervalRange(EIR_Element): 

1147 name = 'Peripheral Connection Interval Range' 

1148 fields_desc = [ 

1149 LEShortField('conn_interval_min', 0xFFFF), 

1150 LEShortField('conn_interval_max', 0xFFFF) 

1151 ] 

1152 

1153 

1154class EIR_Manufacturer_Specific_Data(EIR_Element): 

1155 name = "EIR Manufacturer Specific Data" 

1156 fields_desc = [ 

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

1158 XLEShortField("company_id", None), 

1159 ] 

1160 

1161 registered_magic_payloads = {} 

1162 

1163 @classmethod 

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

1165 """ 

1166 Registers a payload type that uses magic data. 

1167 

1168 Traditional payloads require registration of a Bluetooth Company ID 

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

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

1171 

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

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

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

1175 number of bytes in a beacon frame. 

1176 

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

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

1179 at the start of the Manufacturer Specific Data field. 

1180 

1181 Examples of this are AltBeacon and GeoBeacon. 

1182 

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

1184 

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

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

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

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

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

1190 used instead. 

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

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

1193 """ 

1194 if magic_check is None: 

1195 if hasattr(payload_cls, "magic_check"): 

1196 magic_check = payload_cls.magic_check 

1197 else: 

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

1199 "attribute magic_check".format(payload_cls)) 

1200 

1201 cls.registered_magic_payloads[payload_cls] = magic_check 

1202 

1203 def default_payload_class(self, payload): 

1204 for cls, check in ( 

1205 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items() 

1206 ): 

1207 if check(payload): 

1208 return cls 

1209 

1210 return Packet.default_payload_class(self, payload) 

1211 

1212 def extract_padding(self, s): 

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

1214 plen = EIR_Element.length_from(self) - 2 

1215 return s[:plen], s[plen:] 

1216 

1217 

1218class EIR_Device_ID(EIR_Element): 

1219 name = "Device ID" 

1220 fields_desc = [ 

1221 XLEShortField("vendor_id_source", 0), 

1222 XLEShortField("vendor_id", 0), 

1223 XLEShortField("product_id", 0), 

1224 XLEShortField("version", 0), 

1225 ] 

1226 

1227 

1228class EIR_ServiceSolicitation16BitUUID(EIR_Element): 

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

1230 fields_desc = [ 

1231 XLEShortField("svc_uuid", None) 

1232 ] 

1233 

1234 def extract_padding(self, s): 

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

1236 plen = EIR_Element.length_from(self) - 2 

1237 return s[:plen], s[plen:] 

1238 

1239 

1240class EIR_ServiceSolicitation128BitUUID(EIR_Element): 

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

1242 fields_desc = [ 

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

1244 ] 

1245 

1246 def extract_padding(self, s): 

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

1248 plen = EIR_Element.length_from(self) - 2 

1249 return s[:plen], s[plen:] 

1250 

1251 

1252class EIR_ServiceData16BitUUID(EIR_Element): 

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

1254 fields_desc = [ 

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

1256 XLEShortField("svc_uuid", None), 

1257 ] 

1258 

1259 def extract_padding(self, s): 

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

1261 plen = EIR_Element.length_from(self) - 2 

1262 return s[:plen], s[plen:] 

1263 

1264 

1265class EIR_PublicTargetAddress(EIR_Element): 

1266 name = "Public Target Address" 

1267 fields_desc = [ 

1268 LEMACField('bd_addr', None) 

1269 ] 

1270 

1271 

1272class EIR_AdvertisingInterval(EIR_Element): 

1273 name = "Advertising Interval" 

1274 fields_desc = [ 

1275 MultipleTypeField( 

1276 [ 

1277 (ByteField("advertising_interval", 0), 

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

1279 (LEShortField("advertising_interval", 0), 

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

1281 (LEThreeBytesField("advertising_interval", 0), 

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

1283 (LEIntField("advertising_interval", 0), 

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

1285 ], 

1286 LEShortField("advertising_interval", 0) 

1287 ) 

1288 ] 

1289 

1290 

1291class EIR_LEBluetoothDeviceAddress(EIR_Element): 

1292 name = "LE Bluetooth Device Address" 

1293 fields_desc = [ 

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

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

1296 0x0: 'Public', 

1297 0x1: 'Random' 

1298 }), 

1299 LEMACField('bd_addr', None) 

1300 ] 

1301 

1302 

1303class EIR_Appearance(EIR_Element): 

1304 name = "EIR_Appearance" 

1305 fields_desc = [ 

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

1307 0x000: 'Unknown', 

1308 0x001: 'Phone', 

1309 0x002: 'Computer', 

1310 0x003: 'Watch', 

1311 0x004: 'Clock', 

1312 0x005: 'Display', 

1313 0x006: 'Remote Control', 

1314 0x007: 'Eyeglasses', 

1315 0x008: 'Tag', 

1316 0x009: 'Keyring', 

1317 0x00A: 'Media Player', 

1318 0x00B: 'Barcode Scanner', 

1319 0x00C: 'Thermometer', 

1320 0x00D: 'Heart Rate Sensor', 

1321 0x00E: 'Blood Pressure', 

1322 0x00F: 'Human Interface Device', 

1323 0x010: 'Glucose Meter', 

1324 0x011: 'Running Walking Sensor', 

1325 0x012: 'Cycling', 

1326 0x013: 'Control Device', 

1327 0x014: 'Network Device', 

1328 0x015: 'Sensor', 

1329 0x016: 'Light Fixtures', 

1330 0x017: 'Fan', 

1331 0x018: 'HVAC', 

1332 0x019: 'Air Conditioning', 

1333 0x01A: 'Humidifier', 

1334 0x01B: 'Heating', 

1335 0x01C: 'Access Control', 

1336 0x01D: 'Motorized Device', 

1337 0x01E: 'Power Device', 

1338 0x01F: 'Light Source', 

1339 0x020: 'Window Covering', 

1340 0x021: 'Audio Sink', 

1341 0x022: 'Audio Source', 

1342 0x023: 'Motorized Vehicle', 

1343 0x024: 'Domestic Appliance', 

1344 0x025: 'Wearable Audio Device', 

1345 0x026: 'Aircraft', 

1346 0x027: 'AV Equipment', 

1347 0x028: 'Display Equipment', 

1348 0x029: 'Hearing aid', 

1349 0x02A: 'Gaming', 

1350 0x02B: 'Signage', 

1351 0x031: 'Pulse Oximeter', 

1352 0x032: 'Weight Scale', 

1353 0x033: 'Personal Mobility Device', 

1354 0x034: 'Continuous Glucose Monitor', 

1355 0x035: 'Insulin Pump', 

1356 0x036: 'Medication Delivery', 

1357 0x037: 'Spirometer', 

1358 0x051: 'Outdoor Sports Activity' 

1359 }), 

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

1361 ] 

1362 

1363 @property 

1364 def appearance(self): 

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

1366 

1367 

1368class EIR_ServiceData32BitUUID(EIR_Element): 

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

1370 fields_desc = [ 

1371 XLEIntField('svc_uuid', 0), 

1372 ] 

1373 

1374 def extract_padding(self, s): 

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

1376 plen = EIR_Element.length_from(self) - 4 

1377 return s[:plen], s[plen:] 

1378 

1379 

1380class EIR_ServiceData128BitUUID(EIR_Element): 

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

1382 fields_desc = [ 

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

1384 ] 

1385 

1386 def extract_padding(self, s): 

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

1388 plen = EIR_Element.length_from(self) - 16 

1389 return s[:plen], s[plen:] 

1390 

1391 

1392class EIR_URI(EIR_Element): 

1393 name = 'EIR URI' 

1394 fields_desc = [ 

1395 ByteEnumField('scheme', 0, { 

1396 0x01: '', 

1397 0x02: 'aaa:', 

1398 0x03: 'aaas:', 

1399 0x04: 'about:', 

1400 0x05: 'acap:', 

1401 0x06: 'acct:', 

1402 0x07: 'cap:', 

1403 0x08: 'cid:', 

1404 0x09: 'coap:', 

1405 0x0A: 'coaps:', 

1406 0x0B: 'crid:', 

1407 0x0C: 'data:', 

1408 0x0D: 'dav:', 

1409 0x0E: 'dict:', 

1410 0x0F: 'dns:', 

1411 0x10: 'file:', 

1412 0x11: 'ftp:', 

1413 0x12: 'geo:', 

1414 0x13: 'go:', 

1415 0x14: 'gopher:', 

1416 0x15: 'h323:', 

1417 0x16: 'http:', 

1418 0x17: 'https:', 

1419 0x18: 'iax:', 

1420 0x19: 'icap:', 

1421 0x1A: 'im:', 

1422 0x1B: 'imap:', 

1423 0x1C: 'info:', 

1424 0x1D: 'ipp:', 

1425 0x1E: 'ipps:', 

1426 0x1F: 'iris:', 

1427 0x20: 'iris.beep:', 

1428 0x21: 'iris.xpc:', 

1429 0x22: 'iris.xpcs:', 

1430 0x23: 'iris.lwz:', 

1431 0x24: 'jabber:', 

1432 0x25: 'ldap:', 

1433 0x26: 'mailto:', 

1434 0x27: 'mid:', 

1435 0x28: 'msrp:', 

1436 0x29: 'msrps:', 

1437 0x2A: 'mtqp:', 

1438 0x2B: 'mupdate:', 

1439 0x2C: 'news:', 

1440 0x2D: 'nfs:', 

1441 0x2E: 'ni:', 

1442 0x2F: 'nih:', 

1443 0x30: 'nntp:', 

1444 0x31: 'opaquelocktoken:', 

1445 0x32: 'pop:', 

1446 0x33: 'pres:', 

1447 0x34: 'reload:', 

1448 0x35: 'rtsp:', 

1449 0x36: 'rtsps:', 

1450 0x37: 'rtspu:', 

1451 0x38: 'service:', 

1452 0x39: 'session:', 

1453 0x3A: 'shttp:', 

1454 0x3B: 'sieve:', 

1455 0x3C: 'sip:', 

1456 0x3D: 'sips:', 

1457 0x3E: 'sms:', 

1458 0x3F: 'snmp:', 

1459 0x40: 'soap.beep:', 

1460 0x41: 'soap.beeps:', 

1461 0x42: 'stun:', 

1462 0x43: 'stuns:', 

1463 0x44: 'tag:', 

1464 0x45: 'tel:', 

1465 0x46: 'telnet:', 

1466 0x47: 'tftp:', 

1467 0x48: 'thismessage:', 

1468 0x49: 'tn3270:', 

1469 0x4A: 'tip:', 

1470 0x4B: 'turn:', 

1471 0x4C: 'turns:', 

1472 0x4D: 'tv:', 

1473 0x4E: 'urn:', 

1474 0x4F: 'vemmi:', 

1475 0x50: 'ws:', 

1476 0x51: 'wss:', 

1477 0x52: 'xcon:', 

1478 0x53: 'xconuserid:', 

1479 0x54: 'xmlrpc.beep:', 

1480 0x55: 'xmlrpc.beeps:', 

1481 0x56: 'xmpp:', 

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

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

1484 0x59: 'acr:', 

1485 0x5A: 'adiumxtra:', 

1486 0x5B: 'afp:', 

1487 0x5C: 'afs:', 

1488 0x5D: 'aim:', 

1489 0x5E: 'apt:', 

1490 0x5F: 'attachment:', 

1491 0x60: 'aw:', 

1492 0x61: 'barion:', 

1493 0x62: 'beshare:', 

1494 0x63: 'bitcoin:', 

1495 0x64: 'bolo:', 

1496 0x65: 'callto:', 

1497 0x66: 'chrome:', 

1498 0x67: 'chromeextension:', 

1499 0x68: 'comeventbriteattendee:', 

1500 0x69: 'content:', 

1501 0x6A: 'cvs:', 

1502 0x6B: 'dlnaplaysingle:', 

1503 0x6C: 'dlnaplaycontainer:', 

1504 0x6D: 'dtn:', 

1505 0x6E: 'dvb:', 

1506 0x6F: 'ed2k:', 

1507 0x70: 'facetime:', 

1508 0x71: 'feed:', 

1509 0x72: 'feedready:', 

1510 0x73: 'finger:', 

1511 0x74: 'fish:', 

1512 0x75: 'gg:', 

1513 0x76: 'git:', 

1514 0x77: 'gizmoproject:', 

1515 0x78: 'gtalk:', 

1516 0x79: 'ham:', 

1517 0x7A: 'hcp:', 

1518 0x7B: 'icon:', 

1519 0x7C: 'ipn:', 

1520 0x7D: 'irc:', 

1521 0x7E: 'irc6:', 

1522 0x7F: 'ircs:', 

1523 0x80: 'itms:', 

1524 0x81: 'jar:', 

1525 0x82: 'jms:', 

1526 0x83: 'keyparc:', 

1527 0x84: 'lastfm:', 

1528 0x85: 'ldaps:', 

1529 0x86: 'magnet:', 

1530 0x87: 'maps:', 

1531 0x88: 'market:', 

1532 0x89: 'message:', 

1533 0x8A: 'mms:', 

1534 0x8B: 'mshelp:', 

1535 0x8C: 'mssettingspower:', 

1536 0x8D: 'msnim:', 

1537 0x8E: 'mumble:', 

1538 0x8F: 'mvn:', 

1539 0x90: 'notes:', 

1540 0x91: 'oid:', 

1541 0x92: 'palm:', 

1542 0x93: 'paparazzi:', 

1543 0x94: 'pkcs11:', 

1544 0x95: 'platform:', 

1545 0x96: 'proxy:', 

1546 0x97: 'psyc:', 

1547 0x98: 'query:', 

1548 0x99: 'res:', 

1549 0x9A: 'resource:', 

1550 0x9B: 'rmi:', 

1551 0x9C: 'rsync:', 

1552 0x9D: 'rtmfp:', 

1553 0x9E: 'rtmp:', 

1554 0x9F: 'secondlife:', 

1555 0xA0: 'sftp:', 

1556 0xA1: 'sgn:', 

1557 0xA2: 'skype:', 

1558 0xA3: 'smb:', 

1559 0xA4: 'smtp:', 

1560 0xA5: 'soldat:', 

1561 0xA6: 'spotify:', 

1562 0xA7: 'ssh:', 

1563 0xA8: 'steam:', 

1564 0xA9: 'submit:', 

1565 0xAA: 'svn:', 

1566 0xAB: 'teamspeak:', 

1567 0xAC: 'teliaeid:', 

1568 0xAD: 'things:', 

1569 0xAE: 'udp:', 

1570 0xAF: 'unreal:', 

1571 0xB0: 'ut2004:', 

1572 0xB1: 'ventrilo:', 

1573 0xB2: 'viewsource:', 

1574 0xB3: 'webcal:', 

1575 0xB4: 'wtai:', 

1576 0xB5: 'wyciwyg:', 

1577 0xB6: 'xfire:', 

1578 0xB7: 'xri:', 

1579 0xB8: 'ymsgr:', 

1580 0xB9: 'example:', 

1581 0xBA: 'mssettingscloudstorage:' 

1582 }), 

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

1584 ] 

1585 

1586 @property 

1587 def uri(self): 

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

1589 

1590 

1591class HCI_Command_Hdr(Packet): 

1592 name = "HCI Command header" 

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

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

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

1596 

1597 def answers(self, other): 

1598 return False 

1599 

1600 @property 

1601 def opcode(self): 

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

1603 

1604 def post_build(self, p, pay): 

1605 p += pay 

1606 if self.len is None: 

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

1608 return p 

1609 

1610 

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

1612# 8 EXTENDED INQUIRY RESPONSE 

1613 

1614class HCI_Extended_Inquiry_Response(Packet): 

1615 fields_desc = [ 

1616 PadField( 

1617 PacketListField( 

1618 "eir_data", [], 

1619 next_cls_cb=lambda *args: ( 

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

1621 ) 

1622 ), 

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

1624 ), 

1625 ] 

1626 

1627 

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

1629# 7 HCI COMMANDS AND EVENTS 

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

1631 

1632class HCI_Cmd_Inquiry(Packet): 

1633 """ 

1634 7.1.1 Inquiry command 

1635 """ 

1636 name = "HCI_Inquiry" 

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

1638 ByteField("inquiry_length", 0), 

1639 ByteField("num_responses", 0)] 

1640 

1641 

1642class HCI_Cmd_Inquiry_Cancel(Packet): 

1643 """ 

1644 7.1.2 Inquiry Cancel command 

1645 """ 

1646 name = "HCI_Inquiry_Cancel" 

1647 

1648 

1649class HCI_Cmd_Periodic_Inquiry_Mode(Packet): 

1650 """ 

1651 7.1.3 Periodic Inquiry Mode command 

1652 """ 

1653 name = "HCI_Periodic_Inquiry_Mode" 

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

1655 LEShortField("min_period_length", 0x0002), 

1656 XLE3BytesField("lap", 0x9E8B33), 

1657 ByteField("inquiry_length", 0), 

1658 ByteField("num_responses", 0)] 

1659 

1660 

1661class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet): 

1662 """ 

1663 7.1.4 Exit Periodic Inquiry Mode command 

1664 """ 

1665 name = "HCI_Exit_Periodic_Inquiry_Mode" 

1666 

1667 

1668class HCI_Cmd_Create_Connection(Packet): 

1669 """ 

1670 7.1.5 Create Connection command 

1671 """ 

1672 name = "HCI_Create_Connection" 

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

1674 LEShortField("packet_type", 0xcc18), 

1675 ByteField("page_scan_repetition_mode", 0x02), 

1676 ByteField("reserved", 0x0), 

1677 LEShortField("clock_offset", 0x0), 

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

1679 

1680 

1681class HCI_Cmd_Disconnect(Packet): 

1682 """ 

1683 7.1.6 Disconnect command 

1684 """ 

1685 name = "HCI_Disconnect" 

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

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

1688 

1689 

1690class HCI_Cmd_Create_Connection_Cancel(Packet): 

1691 """ 

1692 7.1.7 Create Connection Cancel command 

1693 """ 

1694 name = "HCI_Create_Connection_Cancel" 

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

1696 

1697 

1698class HCI_Cmd_Accept_Connection_Request(Packet): 

1699 """ 

1700 7.1.8 Accept Connection Request command 

1701 """ 

1702 name = "HCI_Accept_Connection_Request" 

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

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

1705 

1706 

1707class HCI_Cmd_Reject_Connection_Response(Packet): 

1708 """ 

1709 7.1.9 Reject Connection Request command 

1710 """ 

1711 name = "HCI_Reject_Connection_Response" 

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

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

1714 

1715 

1716class HCI_Cmd_Link_Key_Request_Reply(Packet): 

1717 """ 

1718 7.1.10 Link Key Request Reply command 

1719 """ 

1720 name = "HCI_Link_Key_Request_Reply" 

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

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

1723 

1724 

1725class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet): 

1726 """ 

1727 7.1.11 Link Key Request Negative Reply command 

1728 """ 

1729 name = "HCI_Link_Key_Request_Negative_Reply" 

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

1731 

1732 

1733class HCI_Cmd_PIN_Code_Request_Reply(Packet): 

1734 """ 

1735 7.1.12 PIN Code Request Reply command 

1736 """ 

1737 name = "HCI_PIN_Code_Request_Reply" 

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

1739 ByteField("pin_code_length", 7), 

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

1741 

1742 

1743class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet): 

1744 """ 

1745 7.1.13 PIN Code Request Negative Reply command 

1746 """ 

1747 name = "HCI_PIN_Code_Request_Negative_Reply" 

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

1749 

1750 

1751class HCI_Cmd_Change_Connection_Packet_Type(Packet): 

1752 """ 

1753 7.1.14 Change Connection Packet Type command 

1754 """ 

1755 name = "HCI_Cmd_Change_Connection_Packet_Type" 

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

1757 LEShortField("packet_type", 0), ] 

1758 

1759 

1760class HCI_Cmd_Authentication_Requested(Packet): 

1761 """ 

1762 7.1.15 Authentication Requested command 

1763 """ 

1764 name = "HCI_Authentication_Requested" 

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

1766 

1767 

1768class HCI_Cmd_Set_Connection_Encryption(Packet): 

1769 """ 

1770 7.1.16 Set Connection Encryption command 

1771 """ 

1772 name = "HCI_Set_Connection_Encryption" 

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

1774 

1775 

1776class HCI_Cmd_Change_Connection_Link_Key(Packet): 

1777 """ 

1778 7.1.17 Change Connection Link Key command 

1779 """ 

1780 name = "HCI_Change_Connection_Link_Key" 

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

1782 

1783 

1784class HCI_Cmd_Link_Key_Selection(Packet): 

1785 """ 

1786 7.1.18 Change Connection Link Key command 

1787 """ 

1788 name = "HCI_Cmd_Link_Key_Selection" 

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

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

1791 

1792 

1793class HCI_Cmd_Remote_Name_Request(Packet): 

1794 """ 

1795 7.1.19 Remote Name Request command 

1796 """ 

1797 name = "HCI_Remote_Name_Request" 

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

1799 ByteField("page_scan_repetition_mode", 0x02), 

1800 ByteField("reserved", 0x0), 

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

1802 

1803 

1804class HCI_Cmd_Remote_Name_Request_Cancel(Packet): 

1805 """ 

1806 7.1.20 Remote Name Request Cancel command 

1807 """ 

1808 name = "HCI_Remote_Name_Request_Cancel" 

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

1810 

1811 

1812class HCI_Cmd_Read_Remote_Supported_Features(Packet): 

1813 """ 

1814 7.1.21 Read Remote Supported Features command 

1815 """ 

1816 name = "HCI_Read_Remote_Supported_Features" 

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

1818 

1819 

1820class HCI_Cmd_Read_Remote_Extended_Features(Packet): 

1821 """ 

1822 7.1.22 Read Remote Extended Features command 

1823 """ 

1824 name = "HCI_Read_Remote_Supported_Features" 

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

1826 ByteField("page_number", None), ] 

1827 

1828 

1829class HCI_Cmd_IO_Capability_Request_Reply(Packet): 

1830 """ 

1831 7.1.29 IO Capability Request Reply command 

1832 """ 

1833 name = "HCI_Read_Remote_Supported_Features" 

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

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

1836 0x01: "DisplayYesNo", 

1837 0x02: "KeyboardOnly", 

1838 0x03: "NoInputNoOutput", }), 

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

1840 0x01: "P-192", 

1841 0x02: "P-256", 

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

1843 ByteEnumField("authentication_requirement", None, 

1844 {0x00: "MITM Not Required", 

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

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

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

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

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

1850 

1851 

1852class HCI_Cmd_User_Confirmation_Request_Reply(Packet): 

1853 """ 

1854 7.1.30 User Confirmation Request Reply command 

1855 """ 

1856 name = "HCI_User_Confirmation_Request_Reply" 

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

1858 

1859 

1860class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet): 

1861 """ 

1862 7.1.31 User Confirmation Request Negative Reply command 

1863 """ 

1864 name = "HCI_User_Confirmation_Request_Negative_Reply" 

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

1866 

1867 

1868class HCI_Cmd_User_Passkey_Request_Reply(Packet): 

1869 """ 

1870 7.1.32 User Passkey Request Reply command 

1871 """ 

1872 name = "HCI_User_Passkey_Request_Reply" 

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

1874 LEIntField("numeric_value", None), ] 

1875 

1876 

1877class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet): 

1878 """ 

1879 7.1.33 User Passkey Request Negative Reply command 

1880 """ 

1881 name = "HCI_User_Passkey_Request_Negative_Reply" 

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

1883 

1884 

1885class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet): 

1886 """ 

1887 7.1.34 Remote OOB Data Request Reply command 

1888 """ 

1889 name = "HCI_Remote_OOB_Data_Request_Reply" 

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

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

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

1893 

1894 

1895class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet): 

1896 """ 

1897 7.1.35 Remote OOB Data Request Negative Reply command 

1898 """ 

1899 name = "HCI_Remote_OOB_Data_Request_Negative_Reply" 

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

1901 

1902 

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

1904 

1905class HCI_Cmd_Hold_Mode(Packet): 

1906 name = "HCI_Hold_Mode" 

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

1908 LEShortField("hold_mode_max_interval", 0x0002), 

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

1910 

1911 

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

1913 

1914class HCI_Cmd_Set_Event_Mask(Packet): 

1915 """ 

1916 7.3.1 Set Event Mask command 

1917 """ 

1918 name = "HCI_Set_Event_Mask" 

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

1920 

1921 

1922class HCI_Cmd_Reset(Packet): 

1923 """ 

1924 7.3.2 Reset command 

1925 """ 

1926 name = "HCI_Reset" 

1927 

1928 

1929class HCI_Cmd_Set_Event_Filter(Packet): 

1930 """ 

1931 7.3.3 Set Event Filter command 

1932 """ 

1933 name = "HCI_Set_Event_Filter" 

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

1935 

1936 

1937class HCI_Cmd_Write_Local_Name(Packet): 

1938 """ 

1939 7.3.11 Write Local Name command 

1940 """ 

1941 name = "HCI_Write_Local_Name" 

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

1943 

1944 

1945class HCI_Cmd_Read_Local_Name(Packet): 

1946 """ 

1947 7.3.12 Read Local Name command 

1948 """ 

1949 name = "HCI_Read_Local_Name" 

1950 

1951 

1952class HCI_Cmd_Write_Connect_Accept_Timeout(Packet): 

1953 name = "HCI_Write_Connection_Accept_Timeout" 

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

1955 

1956 

1957class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): 

1958 name = "HCI_Write_Extended_Inquiry_Response" 

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

1960 HCI_Extended_Inquiry_Response] 

1961 

1962 

1963class HCI_Cmd_Read_LE_Host_Support(Packet): 

1964 name = "HCI_Read_LE_Host_Support" 

1965 

1966 

1967class HCI_Cmd_Write_LE_Host_Support(Packet): 

1968 name = "HCI_Write_LE_Host_Support" 

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

1970 ByteField("unused", 1), ] 

1971 

1972 

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

1974 

1975class HCI_Cmd_Read_Local_Version_Information(Packet): 

1976 """ 

1977 7.4.1 Read Local Version Information command 

1978 """ 

1979 name = "HCI_Read_Local_Version_Information" 

1980 

1981 

1982class HCI_Cmd_Read_Local_Extended_Features(Packet): 

1983 """ 

1984 7.4.4 Read Local Extended Features command 

1985 """ 

1986 name = "HCI_Read_Local_Extended_Features" 

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

1988 

1989 

1990class HCI_Cmd_Read_BD_Addr(Packet): 

1991 """ 

1992 7.4.6 Read BD_ADDR command 

1993 """ 

1994 name = "HCI_Read_BD_ADDR" 

1995 

1996 

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

1998 

1999class HCI_Cmd_Read_Link_Quality(Packet): 

2000 name = "HCI_Read_Link_Quality" 

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

2002 

2003 

2004class HCI_Cmd_Read_RSSI(Packet): 

2005 name = "HCI_Read_RSSI" 

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

2007 

2008 

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

2010 

2011class HCI_Cmd_Read_Loopback_Mode(Packet): 

2012 name = "HCI_Read_Loopback_Mode" 

2013 

2014 

2015class HCI_Cmd_Write_Loopback_Mode(Packet): 

2016 name = "HCI_Write_Loopback_Mode" 

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

2018 {0: "no loopback", 

2019 1: "enable local loopback", 

2020 2: "enable remote loopback"})] 

2021 

2022 

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

2024 

2025class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet): 

2026 name = "HCI_LE_Read_Buffer_Size [v1]" 

2027 

2028 

2029class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet): 

2030 name = "HCI_LE_Read_Buffer_Size [v2]" 

2031 

2032 

2033class HCI_Cmd_LE_Read_Local_Supported_Features(Packet): 

2034 name = "HCI_LE_Read_Local_Supported_Features" 

2035 

2036 

2037class HCI_Cmd_LE_Set_Random_Address(Packet): 

2038 name = "HCI_LE_Set_Random_Address" 

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

2040 

2041 

2042class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): 

2043 name = "HCI_LE_Set_Advertising_Parameters" 

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

2045 LEShortField("interval_max", 0x0800), 

2046 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 

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

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

2049 LEMACField("daddr", None), 

2050 ByteField("channel_map", 7), 

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

2052 

2053 

2054class HCI_Cmd_LE_Set_Advertising_Data(Packet): 

2055 name = "HCI_LE_Set_Advertising_Data" 

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

2057 PadField( 

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

2059 length_from=lambda pkt: pkt.len), 

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

2061 

2062 

2063class HCI_Cmd_LE_Set_Scan_Response_Data(Packet): 

2064 name = "HCI_LE_Set_Scan_Response_Data" 

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

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

2067 

2068 

2069class HCI_Cmd_LE_Set_Advertise_Enable(Packet): 

2070 name = "HCI_LE_Set_Advertising_Enable" 

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

2072 

2073 

2074class HCI_Cmd_LE_Set_Scan_Parameters(Packet): 

2075 name = "HCI_LE_Set_Scan_Parameters" 

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

2077 XLEShortField("interval", 16), 

2078 XLEShortField("window", 16), 

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

2080 1: "random", 

2081 2: "rpa (pub)", 

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

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

2084 

2085 

2086class HCI_Cmd_LE_Set_Scan_Enable(Packet): 

2087 name = "HCI_LE_Set_Scan_Enable" 

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

2089 ByteField("filter_dups", 1), ] 

2090 

2091 

2092class HCI_Cmd_LE_Create_Connection(Packet): 

2093 name = "HCI_LE_Create_Connection" 

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

2095 LEShortField("window", 48), 

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

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

2098 LEMACField("paddr", None), 

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

2100 LEShortField("min_interval", 40), 

2101 LEShortField("max_interval", 56), 

2102 LEShortField("latency", 0), 

2103 LEShortField("timeout", 42), 

2104 LEShortField("min_ce", 0), 

2105 LEShortField("max_ce", 0), ] 

2106 

2107 

2108class HCI_Cmd_LE_Create_Connection_Cancel(Packet): 

2109 name = "HCI_LE_Create_Connection_Cancel" 

2110 

2111 

2112class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet): 

2113 name = "HCI_LE_Read_Filter_Accept_List_Size" 

2114 

2115 

2116class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet): 

2117 name = "HCI_LE_Clear_Filter_Accept_List" 

2118 

2119 

2120class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet): 

2121 name = "HCI_LE_Add_Device_To_Filter_Accept_List" 

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

2123 1: "random", 

2124 0xff: "anonymous"}), 

2125 LEMACField("address", None)] 

2126 

2127 

2128class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501 

2129 name = "HCI_LE_Remove_Device_From_Filter_Accept_List" 

2130 

2131 

2132class HCI_Cmd_LE_Connection_Update(Packet): 

2133 name = "HCI_LE_Connection_Update" 

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

2135 XLEShortField("min_interval", 0), 

2136 XLEShortField("max_interval", 0), 

2137 XLEShortField("latency", 0), 

2138 XLEShortField("timeout", 0), 

2139 LEShortField("min_ce", 0), 

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

2141 

2142 

2143class HCI_Cmd_LE_Read_Remote_Features(Packet): 

2144 name = "HCI_LE_Read_Remote_Features" 

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

2146 

2147 

2148class HCI_Cmd_LE_Enable_Encryption(Packet): 

2149 name = "HCI_LE_Enable_Encryption" 

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

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

2152 XLEShortField("ediv", 0), 

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

2154 

2155 

2156class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet): 

2157 name = "HCI_LE_Long_Term_Key_Request_Reply" 

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

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

2160 

2161 

2162class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): 

2163 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply" 

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

2165 

2166 

2167class HCI_Event_Hdr(Packet): 

2168 name = "HCI Event header" 

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

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

2171 

2172 def answers(self, other): 

2173 if HCI_Command_Hdr not in other: 

2174 return False 

2175 

2176 # Delegate answers to event types 

2177 return self.payload.answers(other) 

2178 

2179 

2180class HCI_Event_Inquiry_Complete(Packet): 

2181 """ 

2182 7.7.1 Inquiry Complete event 

2183 """ 

2184 name = "HCI_Inquiry_Complete" 

2185 fields_desc = [ 

2186 ByteEnumField('status', 0, _bluetooth_error_codes) 

2187 ] 

2188 

2189 

2190class HCI_Event_Inquiry_Result(Packet): 

2191 """ 

2192 7.7.2 Inquiry Result event 

2193 """ 

2194 name = "HCI_Inquiry_Result" 

2195 fields_desc = [ 

2196 ByteField("num_response", 0x00), 

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

2198 count_from=lambda p: p.num_response), 

2199 FieldListField("page_scan_repetition_mode", None, 

2200 ByteField("page_scan_repetition_mode", 0), 

2201 count_from=lambda p: p.num_response), 

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

2203 count_from=lambda p: p.num_response), 

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

2205 count_from=lambda p: p.num_response), 

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

2207 count_from=lambda p: p.num_response) 

2208 ] 

2209 

2210 

2211class HCI_Event_Connection_Complete(Packet): 

2212 """ 

2213 7.7.3 Connection Complete event 

2214 """ 

2215 name = "HCI_Connection_Complete" 

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

2217 LEShortField("handle", 0x0100), 

2218 LEMACField("bd_addr", None), 

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

2220 1: "ACL connection", }), 

2221 ByteEnumField("encryption_enabled", 0, 

2222 {0: "link level encryption disabled", 

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

2224 

2225 

2226class HCI_Event_Disconnection_Complete(Packet): 

2227 """ 

2228 7.7.5 Disconnection Complete event 

2229 """ 

2230 name = "HCI_Disconnection_Complete" 

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

2232 LEShortField("handle", 0), 

2233 XByteField("reason", 0), ] 

2234 

2235 

2236class HCI_Event_Remote_Name_Request_Complete(Packet): 

2237 """ 

2238 7.7.7 Remote Name Request Complete event 

2239 """ 

2240 name = "HCI_Remote_Name_Request_Complete" 

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

2242 LEMACField("bd_addr", None), 

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

2244 

2245 

2246class HCI_Event_Encryption_Change(Packet): 

2247 """ 

2248 7.7.8 Encryption Change event 

2249 """ 

2250 name = "HCI_Encryption_Change" 

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

2252 LEShortField("handle", 0), 

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

2254 

2255 

2256class HCI_Event_Read_Remote_Supported_Features_Complete(Packet): 

2257 """ 

2258 7.7.11 Read Remote Supported Features Complete event 

2259 """ 

2260 name = "HCI_Read_Remote_Supported_Features_Complete" 

2261 fields_desc = [ 

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

2263 LEShortField('handle', 0), 

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

2265 ] 

2266 

2267 

2268class HCI_Event_Read_Remote_Version_Information_Complete(Packet): 

2269 """ 

2270 7.7.12 Read Remote Version Information Complete event 

2271 """ 

2272 name = "HCI_Read_Remote_Version_Information" 

2273 fields_desc = [ 

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

2275 LEShortField('handle', 0), 

2276 ByteField('version', 0x00), 

2277 LEShortField('manufacturer_name', 0x0000), 

2278 LEShortField('subversion', 0x0000) 

2279 ] 

2280 

2281 

2282class HCI_Event_Command_Complete(Packet): 

2283 """ 

2284 7.7.14 Command Complete event 

2285 """ 

2286 name = "HCI_Command_Complete" 

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

2288 XLEShortField("opcode", 0), 

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

2290 

2291 def answers(self, other): 

2292 if HCI_Command_Hdr not in other: 

2293 return False 

2294 

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

2296 

2297 

2298class HCI_Event_Command_Status(Packet): 

2299 """ 

2300 7.7.15 Command Status event 

2301 """ 

2302 name = "HCI_Command_Status" 

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

2304 ByteField("number", 0), 

2305 XLEShortField("opcode", None), ] 

2306 

2307 def answers(self, other): 

2308 if HCI_Command_Hdr not in other: 

2309 return False 

2310 

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

2312 

2313 

2314class HCI_Event_Number_Of_Completed_Packets(Packet): 

2315 """ 

2316 7.7.19 Number Of Completed Packets event 

2317 """ 

2318 name = "HCI_Number_Of_Completed_Packets" 

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

2320 FieldListField("connection_handle_list", None, 

2321 LEShortField("connection_handle", 0), 

2322 count_from=lambda p: p.num_handles), 

2323 FieldListField("num_completed_packets_list", None, 

2324 LEShortField("num_completed_packets", 0), 

2325 count_from=lambda p: p.num_handles)] 

2326 

2327 

2328class HCI_Event_Link_Key_Request(Packet): 

2329 """ 

2330 7.7.23 Link Key Request event 

2331 """ 

2332 name = 'HCI_Link_Key_Request' 

2333 fields_desc = [ 

2334 LEMACField('bd_addr', None) 

2335 ] 

2336 

2337 

2338class HCI_Event_Inquiry_Result_With_Rssi(Packet): 

2339 """ 

2340 7.7.33 Inquiry Result with RSSI event 

2341 """ 

2342 name = "HCI_Inquiry_Result_with_RSSI" 

2343 fields_desc = [ 

2344 ByteField("num_response", 0x00), 

2345 FieldListField("bd_addr", None, LEMACField, 

2346 count_from=lambda p: p.num_response), 

2347 FieldListField("page_scan_repetition_mode", None, ByteField, 

2348 count_from=lambda p: p.num_response), 

2349 FieldListField("reserved", None, LEShortField, 

2350 count_from=lambda p: p.num_response), 

2351 FieldListField("device_class", None, XLE3BytesField, 

2352 count_from=lambda p: p.num_response), 

2353 FieldListField("clock_offset", None, LEShortField, 

2354 count_from=lambda p: p.num_response), 

2355 FieldListField("rssi", None, SignedByteField, 

2356 count_from=lambda p: p.num_response) 

2357 ] 

2358 

2359 

2360class HCI_Event_Read_Remote_Extended_Features_Complete(Packet): 

2361 """ 

2362 7.7.34 Read Remote Extended Features Complete event 

2363 """ 

2364 name = "HCI_Read_Remote_Extended_Features_Complete" 

2365 fields_desc = [ 

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

2367 LEShortField('handle', 0), 

2368 ByteField('page', 0x00), 

2369 ByteField('max_page', 0x00), 

2370 XLELongField('extended_features', 0) 

2371 ] 

2372 

2373 

2374class HCI_Event_Extended_Inquiry_Result(Packet): 

2375 """ 

2376 7.7.38 Extended Inquiry Result event 

2377 """ 

2378 name = "HCI_Extended_Inquiry_Result" 

2379 fields_desc = [ 

2380 ByteField('num_response', 0x01), 

2381 LEMACField('bd_addr', None), 

2382 ByteField('page_scan_repetition_mode', 0x00), 

2383 ByteField('reserved', 0x00), 

2384 XLE3BytesField('device_class', 0x000000), 

2385 LEShortField('clock_offset', 0x0000), 

2386 SignedByteField('rssi', 0x00), 

2387 HCI_Extended_Inquiry_Response, 

2388 ] 

2389 

2390 

2391class HCI_Event_IO_Capability_Response(Packet): 

2392 """ 

2393 7.7.41 IO Capability Response event 

2394 """ 

2395 name = "HCI_IO_Capability_Response" 

2396 fields_desc = [ 

2397 LEMACField('bd_addr', None), 

2398 ByteField('io_capability', 0x00), 

2399 ByteField('oob_data_present', 0x00), 

2400 ByteField('authentication_requirements', 0x00) 

2401 ] 

2402 

2403 

2404class HCI_Event_LE_Meta(Packet): 

2405 """ 

2406 7.7.65 LE Meta event 

2407 """ 

2408 name = "HCI_LE_Meta" 

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

2410 0x01: "connection_complete", 

2411 0x02: "advertising_report", 

2412 0x03: "connection_update_complete", 

2413 0x04: "read_remote_features_page_0_complete", 

2414 0x05: "long_term_key_request", 

2415 0x06: "remote_connection_parameter_request", 

2416 0x07: "data_length_change", 

2417 0x08: "read_local_p256_public_key_complete", 

2418 0x09: "generate_dhkey_complete", 

2419 0x0a: "enhanced_connection_complete_v1", 

2420 0x0b: "directed_advertising_report", 

2421 0x0c: "phy_update_complete", 

2422 0x0d: "extended_advertising_report", 

2423 0x29: "enhanced_connection_complete_v2" 

2424 }), ] 

2425 

2426 def answers(self, other): 

2427 if not self.payload: 

2428 return False 

2429 

2430 # Delegate answers to payload 

2431 return self.payload.answers(other) 

2432 

2433 

2434class HCI_Cmd_Complete_Read_Local_Name(Packet): 

2435 """ 

2436 7.3.12 Read Local Name command complete 

2437 """ 

2438 name = 'Read Local Name command complete' 

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

2440 

2441 

2442class HCI_Cmd_Complete_Read_Local_Version_Information(Packet): 

2443 """ 

2444 7.4.1 Read Local Version Information command complete 

2445 """ 

2446 name = 'Read Local Version Information' 

2447 fields_desc = [ 

2448 ByteField('hci_version', 0), 

2449 LEShortField('hci_subversion', 0), 

2450 ByteField('lmp_version', 0), 

2451 LEShortField('company_identifier', 0), 

2452 LEShortField('lmp_subversion', 0)] 

2453 

2454 

2455class HCI_Cmd_Complete_Read_Local_Extended_Features(Packet): 

2456 """ 

2457 7.4.4 Read Local Extended Features command complete 

2458 """ 

2459 name = 'Read Local Extended Features command complete' 

2460 fields_desc = [ 

2461 ByteField('page', 0x00), 

2462 ByteField('max_page', 0x00), 

2463 XLELongField('extended_features', 0) 

2464 ] 

2465 

2466 

2467class HCI_Cmd_Complete_Read_BD_Addr(Packet): 

2468 """ 

2469 7.4.6 Read BD_ADDR command complete 

2470 """ 

2471 name = "Read BD Addr" 

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

2473 

2474 

2475class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet): 

2476 name = "LE Read White List Size" 

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

2478 ByteField("size", 0), ] 

2479 

2480 

2481class HCI_LE_Meta_Connection_Complete(Packet): 

2482 name = "Connection Complete" 

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

2484 LEShortField("handle", 0), 

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

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

2487 LEMACField("paddr", None), 

2488 LEShortField("interval", 54), 

2489 LEShortField("latency", 0), 

2490 LEShortField("supervision", 42), 

2491 XByteField("clock_latency", 5), ] 

2492 

2493 def answers(self, other): 

2494 if HCI_Cmd_LE_Create_Connection not in other: 

2495 return False 

2496 

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

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

2499 

2500 

2501class HCI_LE_Meta_Connection_Update_Complete(Packet): 

2502 name = "Connection Update Complete" 

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

2504 LEShortField("handle", 0), 

2505 LEShortField("interval", 54), 

2506 LEShortField("latency", 0), 

2507 LEShortField("timeout", 42), ] 

2508 

2509 

2510class HCI_LE_Meta_Advertising_Report(Packet): 

2511 name = "Advertising Report" 

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

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

2514 LEMACField("addr", None), 

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

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

2517 length_from=lambda pkt: pkt.len), 

2518 SignedByteField("rssi", 0)] 

2519 

2520 def extract_padding(self, s): 

2521 return '', s 

2522 

2523 

2524class HCI_LE_Meta_Advertising_Reports(Packet): 

2525 name = "Advertising Reports" 

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

2527 PacketListField("reports", None, 

2528 HCI_LE_Meta_Advertising_Report, 

2529 count_from=lambda pkt: pkt.len)] 

2530 

2531 

2532class HCI_LE_Meta_Long_Term_Key_Request(Packet): 

2533 name = "Long Term Key Request" 

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

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

2536 XLEShortField("ediv", 0), ] 

2537 

2538 

2539class HCI_LE_Meta_Extended_Advertising_Report(Packet): 

2540 name = "Extended Advertising Report" 

2541 fields_desc = [ 

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

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

2544 0b00: "complete", 

2545 0b01: "incomplete", 

2546 0b10: "incomplete_truncated", 

2547 0b11: "reserved" 

2548 }), 

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

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

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

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

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

2554 ByteField("reserved", 0), 

2555 ByteEnumField("address_type", 0, { 

2556 0x00: "public_device_address", 

2557 0x01: "random_device_address", 

2558 0x02: "public_identity_address", 

2559 0x03: "random_identity_address", 

2560 0xff: "anonymous" 

2561 }), 

2562 LEMACField('address', None), 

2563 ByteEnumField("primary_phy", 0, { 

2564 0x01: "le_1m", 

2565 0x03: "le_coded_s8", 

2566 0x04: "le_coded_s2" 

2567 }), 

2568 ByteEnumField("secondary_phy", 0, { 

2569 0x01: "le_1m", 

2570 0x02: "le_2m", 

2571 0x03: "le_coded_s8", 

2572 0x04: "le_coded_s2" 

2573 }), 

2574 ByteField("advertising_sid", 0xff), 

2575 ByteField("tx_power", 0x7f), 

2576 SignedByteField("rssi", 0x00), 

2577 LEShortField("periodic_advertising_interval", 0x0000), 

2578 ByteEnumField("direct_address_type", 0, { 

2579 0x00: "public_device_address", 

2580 0x01: "non_resolvable_private_address", 

2581 0x02: "resolvable_private_address_resolved_0", 

2582 0x03: "resolvable_private_address_resolved_1", 

2583 0xfe: "resolvable_private_address_unable_resolve"}), 

2584 LEMACField("direct_address", None), 

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

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

2587 length_from=lambda pkt: pkt.data_length), 

2588 ] 

2589 

2590 def extract_padding(self, s): 

2591 return '', s 

2592 

2593 

2594class HCI_LE_Meta_Extended_Advertising_Reports(Packet): 

2595 name = "Extended Advertising Reports" 

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

2597 PacketListField("reports", None, 

2598 HCI_LE_Meta_Extended_Advertising_Report, 

2599 count_from=lambda pkt: pkt.num_reports)] 

2600 

2601 

2602bind_layers(HCI_PHDR_Hdr, HCI_Hdr) 

2603 

2604bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1) 

2605bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2) 

2606bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4) 

2607bind_layers(HCI_Hdr, conf.raw_layer,) 

2608 

2609conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr) 

2610conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr) 

2611 

2612 

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

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

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

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

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

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

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

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

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

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

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

2624bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply, 

2625 ogf=0x01, ocf=0x000c) 

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

2627bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type, 

2628 ogf=0x01, ocf=0x000f) 

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

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

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

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

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

2634bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, 

2635 ogf=0x01, ocf=0x001b) 

2636bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features, 

2637 ogf=0x01, ocf=0x001c) 

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

2639bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply, 

2640 ogf=0x01, ocf=0x002c) 

2641bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply, 

2642 ogf=0x01, ocf=0x002d) 

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

2644bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply, 

2645 ogf=0x01, ocf=0x002f) 

2646bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply, 

2647 ogf=0x01, ocf=0x0030) 

2648bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply, 

2649 ogf=0x01, ocf=0x0033) 

2650 

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

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

2653 

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

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

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

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

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

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

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

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

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

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

2664 

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

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

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

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

2669 

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

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

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

2673 

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

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

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

2677 

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

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

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

2681bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features, 

2682 ogf=0x08, ocf=0x0003) 

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

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

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

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

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

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

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

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

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

2692bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size, 

2693 ogf=0x08, ocf=0x000f) 

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

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

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

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

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

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

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

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

2702 

2703# 7.7 EVENTS 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2721 

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

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

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

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

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

2727 

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

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

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

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

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

2733 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2761bind_layers(EIR_Hdr, EIR_Raw) 

2762 

2763bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,) 

2764bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1) 

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

2766bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1) 

2767bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2) 

2768bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3) 

2769bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4) 

2770bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5) 

2771bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6) 

2772bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7) 

2773bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8) 

2774bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9) 

2775bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10) 

2776bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11) 

2777bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12) 

2778bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13) 

2779bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14) 

2780bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15) 

2781bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16) 

2782bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17) 

2783bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18) 

2784bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19) 

2785bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20) 

2786bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21) 

2787bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22) 

2788bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23) 

2789bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24) 

2790bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25) 

2791bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26) 

2792bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4) 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2820bind_layers(L2CAP_Hdr, SM_Hdr, cid=6) 

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

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

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

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

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

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

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

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

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

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

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

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

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

2834 

2835 

2836############### 

2837# HCI Monitor # 

2838############### 

2839 

2840 

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

2842class HCI_Mon_Hdr(Packet): 

2843 name = 'Bluetooth Linux Monitor Transport Header' 

2844 fields_desc = [ 

2845 LEShortEnumField('opcode', None, { 

2846 0: "New index", 

2847 1: "Delete index", 

2848 2: "Command pkt", 

2849 3: "Event pkt", 

2850 4: "ACL TX pkt", 

2851 5: "ACL RX pkt", 

2852 6: "SCO TX pkt", 

2853 7: "SCO RX pkt", 

2854 8: "Open index", 

2855 9: "Close index", 

2856 10: "Index info", 

2857 11: "Vendor diag", 

2858 12: "System note", 

2859 13: "User logging", 

2860 14: "Ctrl open", 

2861 15: "Ctrl close", 

2862 16: "Ctrl command", 

2863 17: "Ctrl event", 

2864 18: "ISO TX pkt", 

2865 19: "ISO RX pkt", 

2866 }), 

2867 LEShortField('adapter_id', None), 

2868 LEShortField('len', None) 

2869 ] 

2870 

2871 

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

2873class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr): 

2874 name = 'Bluetooth Linux Monitor Transport Pcap Header' 

2875 fields_desc = [ 

2876 ShortField('adapter_id', None), 

2877 ShortField('opcode', None) 

2878 ] 

2879 

2880 

2881class HCI_Mon_New_Index(Packet): 

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

2883 fields_desc = [ 

2884 ByteEnumField('bus', 0, { 

2885 0x00: "BR/EDR", 

2886 0x01: "AMP" 

2887 }), 

2888 ByteEnumField('type', 0, { 

2889 0x00: "Virtual", 

2890 0x01: "USB", 

2891 0x02: "PC Card", 

2892 0x03: "UART", 

2893 0x04: "RS232", 

2894 0x05: "PCI", 

2895 0x06: "SDIO" 

2896 }), 

2897 LEMACField('addr', None), 

2898 StrFixedLenField('devname', None, 8) 

2899 ] 

2900 

2901 

2902class HCI_Mon_Index_Info(Packet): 

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

2904 fields_desc = [ 

2905 LEMACField('addr', None), 

2906 XLEShortField('manufacturer', None) 

2907 ] 

2908 

2909 

2910class HCI_Mon_System_Note(Packet): 

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

2912 fields_desc = [ 

2913 StrNullField('note', None) 

2914 ] 

2915 

2916 

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

2918bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0) 

2919bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2) 

2920bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3) 

2921bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10) 

2922bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12) 

2923 

2924conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr) 

2925 

2926 

2927########### 

2928# Helpers # 

2929########### 

2930 

2931class LowEnergyBeaconHelper: 

2932 """ 

2933 Helpers for building packets for Bluetooth Low Energy Beacons. 

2934 

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

2936 

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

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

2939 """ 

2940 

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

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

2943 "general_disc_mode", "br_edr_not_supported"]), ] 

2944 

2945 def build_eir(self): 

2946 """ 

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

2948 

2949 Users of this helper must implement this method. 

2950 

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

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

2953 """ 

2954 raise NotImplementedError("build_eir") 

2955 

2956 def build_advertising_report(self): 

2957 """ 

2958 Builds a HCI_LE_Meta_Advertising_Report containing this frame. 

2959 

2960 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report 

2961 """ 

2962 

2963 return HCI_LE_Meta_Advertising_Report( 

2964 type=0, # Undirected 

2965 atype=1, # Random address 

2966 data=self.build_eir() 

2967 ) 

2968 

2969 def build_set_advertising_data(self): 

2970 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame. 

2971 

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

2973 

2974 :rtype: scapy.bluetooth.HCI_Hdr 

2975 """ 

2976 

2977 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data( 

2978 data=self.build_eir() 

2979 ) 

2980 

2981 

2982########### 

2983# Sockets # 

2984########### 

2985 

2986class BluetoothSocketError(BaseException): 

2987 pass 

2988 

2989 

2990class BluetoothCommandError(BaseException): 

2991 pass 

2992 

2993 

2994class BluetoothL2CAPSocket(SuperSocket): 

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

2996 

2997 def __init__(self, bt_address): 

2998 if WINDOWS: 

2999 warning("Not available on Windows") 

3000 return 

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

3002 socket.BTPROTO_L2CAP) 

3003 s.connect((bt_address, 0)) 

3004 self.ins = self.outs = s 

3005 

3006 def recv(self, x=MTU): 

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

3008 

3009 

3010class BluetoothRFCommSocket(BluetoothL2CAPSocket): 

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

3012 

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

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

3015 socket.BTPROTO_RFCOMM) 

3016 s.connect((bt_address, port)) 

3017 self.ins = self.outs = s 

3018 

3019 

3020class BluetoothHCISocket(SuperSocket): 

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

3022 

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

3024 if WINDOWS: 

3025 warning("Not available on Windows") 

3026 return 

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

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

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

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

3031 s.bind((iface,)) 

3032 self.ins = self.outs = s 

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

3034 

3035 def recv(self, x=MTU): 

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

3037 

3038 

3039class sockaddr_hci(ctypes.Structure): 

3040 _fields_ = [ 

3041 ("sin_family", ctypes.c_ushort), 

3042 ("hci_dev", ctypes.c_ushort), 

3043 ("hci_channel", ctypes.c_ushort), 

3044 ] 

3045 

3046 

3047class _BluetoothLibcSocket(SuperSocket): 

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

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

3050 if WINDOWS: 

3051 warning("Not available on Windows") 

3052 return 

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

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

3055 # ctypes. 

3056 sockaddr_hcip = ctypes.POINTER(sockaddr_hci) 

3057 from ctypes.util import find_library 

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

3059 

3060 socket_c = libc.socket 

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

3062 socket_c.restype = ctypes.c_int 

3063 

3064 bind = libc.bind 

3065 bind.argtypes = (ctypes.c_int, 

3066 ctypes.POINTER(sockaddr_hci), 

3067 ctypes.c_int) 

3068 bind.restype = ctypes.c_int 

3069 

3070 # Socket 

3071 s = socket_c(socket_domain, socket_type, socket_protocol) 

3072 if s < 0: 

3073 raise BluetoothSocketError( 

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

3075 f"{socket_protocol})") 

3076 

3077 # Bind 

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

3079 if r != 0: 

3080 raise BluetoothSocketError("Unable to bind") 

3081 

3082 self.hci_fd = s 

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

3084 s, socket_domain, socket_type, socket_protocol) 

3085 

3086 def readable(self, timeout=0): 

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

3088 return len(ins) > 0 

3089 

3090 def flush(self): 

3091 while self.readable(): 

3092 self.recv() 

3093 

3094 def close(self): 

3095 if self.closed: 

3096 return 

3097 

3098 # Properly close socket so we can free the device 

3099 from ctypes.util import find_library 

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

3101 

3102 close = libc.close 

3103 close.restype = ctypes.c_int 

3104 self.closed = True 

3105 if hasattr(self, "outs"): 

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

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

3108 close(self.outs.fileno()) 

3109 if hasattr(self, "ins"): 

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

3111 close(self.ins.fileno()) 

3112 if hasattr(self, "hci_fd"): 

3113 close(self.hci_fd) 

3114 

3115 

3116class BluetoothUserSocket(_BluetoothLibcSocket): 

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

3118 

3119 def __init__(self, adapter_index=0): 

3120 sa = sockaddr_hci() 

3121 sa.sin_family = socket.AF_BLUETOOTH 

3122 sa.hci_dev = adapter_index 

3123 sa.hci_channel = HCI_CHANNEL_USER 

3124 super().__init__( 

3125 socket_domain=socket.AF_BLUETOOTH, 

3126 socket_type=socket.SOCK_RAW, 

3127 socket_protocol=socket.BTPROTO_HCI, 

3128 sock_address=sa) 

3129 

3130 def send_command(self, cmd): 

3131 opcode = cmd[HCI_Command_Hdr].opcode 

3132 self.send(cmd) 

3133 while True: 

3134 r = self.recv() 

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

3136 if r.status != 0: 

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

3138 return r 

3139 

3140 def recv(self, x=MTU): 

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

3142 

3143 

3144class BluetoothMonitorSocket(_BluetoothLibcSocket): 

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

3146 

3147 def __init__(self): 

3148 sa = sockaddr_hci() 

3149 sa.sin_family = socket.AF_BLUETOOTH 

3150 sa.hci_dev = HCI_DEV_NONE 

3151 sa.hci_channel = HCI_CHANNEL_MONITOR 

3152 super().__init__( 

3153 socket_domain=socket.AF_BLUETOOTH, 

3154 socket_type=socket.SOCK_RAW, 

3155 socket_protocol=socket.BTPROTO_HCI, 

3156 sock_address=sa) 

3157 

3158 def recv(self, x=MTU): 

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

3160 

3161 

3162conf.BTsocket = BluetoothRFCommSocket 

3163 

3164# Bluetooth 

3165 

3166 

3167@conf.commands.register 

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

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

3170 if "port" in kargs: 

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

3172 else: 

3173 s = conf.BTsocket(bt_address=bt_address) 

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

3175 s.close() 

3176 return a, b 

3177 

3178 

3179@conf.commands.register 

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

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

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

3183 if len(a) > 0: 

3184 return a[0][1]