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

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

989 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 LEMACField, 

57) 

58from scapy.supersocket import SuperSocket 

59from scapy.sendrecv import sndrcv 

60from scapy.data import MTU 

61from scapy.consts import WINDOWS 

62from scapy.error import warning 

63 

64 

65############ 

66# Consts # 

67############ 

68 

69# From hci.h 

70HCI_CHANNEL_RAW = 0 

71HCI_CHANNEL_USER = 1 

72HCI_CHANNEL_MONITOR = 2 

73HCI_CHANNEL_CONTROL = 3 

74HCI_CHANNEL_LOGGING = 4 

75 

76HCI_DEV_NONE = 0xffff 

77 

78 

79########## 

80# Layers # 

81########## 

82 

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

84 

85# Transport layers 

86 

87class HCI_PHDR_Hdr(Packet): 

88 name = "HCI PHDR transport layer" 

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

90 

91 

92# Real layers 

93 

94_bluetooth_packet_types = { 

95 0: "Acknowledgement", 

96 1: "Command", 

97 2: "ACL Data", 

98 3: "Synchronous", 

99 4: "Event", 

100 5: "Reserve", 

101 14: "Vendor", 

102 15: "Link Control" 

103} 

104 

105_bluetooth_error_codes = { 

106 0x00: "Success", 

107 0x01: "Unknown HCI Command", 

108 0x02: "Unknown Connection Identifier", 

109 0x03: "Hardware Failure", 

110 0x04: "Page Timeout", 

111 0x05: "Authentication Failure", 

112 0x06: "PIN or Key Missing", 

113 0x07: "Memory Capacity Exceeded", 

114 0x08: "Connection Timeout", 

115 0x09: "Connection Limit Exceeded", 

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

117 0x0B: "Connection Already Exists", 

118 0x0C: "Command Disallowed", 

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

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

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

122 0x10: "Connection Accept Timeout Exceeded", 

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

124 0x12: "Invalid HCI Command Parameters", 

125 0x13: "Remote User Terminated Connection", 

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

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

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

129 0x17: "Repeated Attempts", 

130 0x18: "Pairing Not Allowed", 

131 0x19: "Unknown LMP PDU", 

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

133 0x1B: "SCO Offset Rejected", 

134 0x1C: "SCO Interval Rejected", 

135 0x1D: "SCO Air Mode Rejected", 

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

137 0x1F: "Unspecified Error", 

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

139 0x21: "Role Change Not Allowed", 

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

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

142 0x24: "LMP PDU Not Allowed", 

143 0x25: "Encryption Mode Not Acceptable", 

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

145 0x27: "Requested QoS Not Supported", 

146 0x28: "Instant Passed", 

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

148 0x2A: "Different Transaction Collision", 

149 0x2B: "Reserved for future use", 

150 0x2C: "QoS Unacceptable Parameter", 

151 0x2D: "QoS Rejected", 

152 0x2E: "Channel Classification Not Supported", 

153 0x2F: "Insufficient Security", 

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

155 0x31: "Reserved for future use", 

156 0x32: "Role Switch Pending", 

157 0x33: "Reserved for future use", 

158 0x34: "Reserved Slot Violation", 

159 0x35: "Role Switch Failed", 

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

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

162 0x38: "Host Busy - Pairing", 

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

164 0x3A: "Controller Busy", 

165 0x3B: "Unacceptable Connection Parameters", 

166 0x3C: "Advertising Timeout", 

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

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

169 0x3F: "MAC Connection Failed", 

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

171 " Dragging", 

172 0x41: "Type0 Submap Not Defined", 

173 0x42: "Unknown Advertising Identifier", 

174 0x43: "Limit Reached", 

175 0x44: "Operation Cancelled by Host", 

176 0x45: "Packet Too Long" 

177} 

178 

179_att_error_codes = { 

180 0x01: "invalid handle", 

181 0x02: "read not permitted", 

182 0x03: "write not permitted", 

183 0x04: "invalid pdu", 

184 0x05: "insufficient auth", 

185 0x06: "unsupported req", 

186 0x07: "invalid offset", 

187 0x08: "insufficient author", 

188 0x09: "prepare queue full", 

189 0x0a: "attr not found", 

190 0x0b: "attr not long", 

191 0x0c: "insufficient key size", 

192 0x0d: "invalid value size", 

193 0x0e: "unlikely", 

194 0x0f: "insufficiet encrypt", 

195 0x10: "unsupported gpr type", 

196 0x11: "insufficient resources", 

197} 

198 

199_bluetooth_features = [ 

200 '3_slot_packets', 

201 '5_slot_packets', 

202 'encryption', 

203 'slot_offset', 

204 'timing_accuracy', 

205 'role_switch', 

206 'hold_mode', 

207 'sniff_mode', 

208 'park_mode', 

209 'power_control_requests', 

210 'channel_quality_driven_data_rate', 

211 'sco_link', 

212 'hv2_packets', 

213 'hv3_packets', 

214 'u_law_log_synchronous_data', 

215 'a_law_log_synchronous_data', 

216 'cvsd_synchronous_data', 

217 'paging_parameter_negotiation', 

218 'power_control', 

219 'transparent_synchronous_data', 

220 'flow_control_lag_4_bit0', 

221 'flow_control_lag_4_bit1', 

222 'flow_control_lag_4_bit2', 

223 'broadband_encryption', 

224 'cvsd_synchronous_data', 

225 'edr_acl_2_mbps_mode', 

226 'edr_acl_3_mbps_mode', 

227 'enhanced_inquiry_scan', 

228 'interlaced_inquiry_scan', 

229 'interlaced_page_scan', 

230 'rssi_with_inquiry_results', 

231 'ev3_packets', 

232 'ev4_packets', 

233 'ev5_packets', 

234 'reserved', 

235 'afh_capable_slave', 

236 'afh_classification_slave', 

237 'br_edr_not_supported', 

238 'le_supported_controller', 

239 '3_slot_edr_acl_packets', 

240 '5_slot_edr_acl_packets', 

241 'sniff_subrating', 

242 'pause_encryption', 

243 'afh_capable_master', 

244 'afh_classification_master', 

245 'edr_esco_2_mbps_mode', 

246 'edr_esco_3_mbps_mode', 

247 '3_slot_edr_esco_packets', 

248 'extended_inquiry_response', 

249 'simultaneous_le_and_br_edr_to_same_device_capable_controller', 

250 'reserved2', 

251 'secure_simple_pairing', 

252 'encapsulated_pdu', 

253 'erroneous_data_reporting', 

254 'non_flushable_packet_boundary_flag', 

255 'reserved3', 

256 'link_supervision_timeout_changed_event', 

257 'inquiry_tx_power_level', 

258 'enhanced_power_control', 

259 'reserved4_bit0', 

260 'reserved4_bit1', 

261 'reserved4_bit2', 

262 'reserved4_bit3', 

263 'extended_features', 

264] 

265 

266 

267class HCI_Hdr(Packet): 

268 name = "HCI header" 

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

270 

271 def mysummary(self): 

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

273 

274 

275class HCI_ACL_Hdr(Packet): 

276 name = "HCI ACL header" 

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

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

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

280 LEShortField("len", None), ] 

281 

282 def post_build(self, p, pay): 

283 p += pay 

284 if self.len is None: 

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

286 return p 

287 

288 

289class L2CAP_Hdr(Packet): 

290 name = "L2CAP header" 

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

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

293 

294 def post_build(self, p, pay): 

295 p += pay 

296 if self.len is None: 

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

298 return p 

299 

300 

301class L2CAP_CmdHdr(Packet): 

302 name = "L2CAP command header" 

303 fields_desc = [ 

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

305 2: "conn_req", 

306 3: "conn_resp", 

307 4: "conf_req", 

308 5: "conf_resp", 

309 6: "disconn_req", 

310 7: "disconn_resp", 

311 8: "echo_req", 

312 9: "echo_resp", 

313 10: "info_req", 

314 11: "info_resp", 

315 12: "create_channel_req", 

316 13: "create_channel_resp", 

317 14: "move_channel_req", 

318 15: "move_channel_resp", 

319 16: "move_channel_confirm_req", 

320 17: "move_channel_confirm_resp", 

321 18: "conn_param_update_req", 

322 19: "conn_param_update_resp", 

323 20: "LE_credit_based_conn_req", 

324 21: "LE_credit_based_conn_resp", 

325 22: "flow_control_credit_ind", 

326 23: "credit_based_conn_req", 

327 24: "credit_based_conn_resp", 

328 25: "credit_based_reconf_req", 

329 26: "credit_based_reconf_resp"}), 

330 ByteField("id", 0), 

331 LEShortField("len", None)] 

332 

333 def post_build(self, p, pay): 

334 p += pay 

335 if self.len is None: 

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

337 return p 

338 

339 def answers(self, other): 

340 if other.id == self.id: 

341 if self.code == 1: 

342 return 1 

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

344 if other.code == 8: 

345 return 1 

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

347 return 0 

348 

349 

350class L2CAP_ConnReq(Packet): 

351 name = "L2CAP Conn Req" 

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

353 3: "RFCOMM", 

354 5: "TCS-BIN", 

355 7: "TCS-BIN-CORDLESS", 

356 15: "BNEP", 

357 17: "HID-Control", 

358 19: "HID-Interrupt", 

359 21: "UPnP", 

360 23: "AVCTP-Control", 

361 25: "AVDTP", 

362 27: "AVCTP-Browsing", 

363 29: "UDI_C-Plane", 

364 31: "ATT", 

365 33: "3DSP", 

366 35: "IPSP", 

367 37: "OTS"}), 

368 LEShortField("scid", 0), 

369 ] 

370 

371 

372class L2CAP_ConnResp(Packet): 

373 name = "L2CAP Conn Resp" 

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

375 LEShortField("scid", 0), 

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

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

378 ] 

379 

380 def answers(self, other): 

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

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

383 

384 

385class L2CAP_CmdRej(Packet): 

386 name = "L2CAP Command Rej" 

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

388 ] 

389 

390 

391class L2CAP_ConfReq(Packet): 

392 name = "L2CAP Conf Req" 

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

394 LEShortField("flags", 0), 

395 ] 

396 

397 

398class L2CAP_ConfResp(Packet): 

399 name = "L2CAP Conf Resp" 

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

401 LEShortField("flags", 0), 

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

403 ] 

404 

405 def answers(self, other): 

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

407 return isinstance(other, L2CAP_ConfReq) 

408 

409 

410class L2CAP_DisconnReq(Packet): 

411 name = "L2CAP Disconn Req" 

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

413 LEShortField("scid", 0), ] 

414 

415 

416class L2CAP_DisconnResp(Packet): 

417 name = "L2CAP Disconn Resp" 

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

419 LEShortField("scid", 0), ] 

420 

421 def answers(self, other): 

422 return self.scid == other.scid 

423 

424 

425class L2CAP_EchoReq(Packet): 

426 name = "L2CAP Echo Req" 

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

428 

429 

430class L2CAP_EchoResp(Packet): 

431 name = "L2CAP Echo Resp" 

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

433 

434 

435class L2CAP_InfoReq(Packet): 

436 name = "L2CAP Info Req" 

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

438 StrField("data", "") 

439 ] 

440 

441 

442class L2CAP_InfoResp(Packet): 

443 name = "L2CAP Info Resp" 

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

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

446 StrField("data", ""), ] 

447 

448 def answers(self, other): 

449 return self.type == other.type 

450 

451 

452class L2CAP_Create_Channel_Request(Packet): 

453 name = "L2CAP Create Channel Request" 

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

455 3: "RFCOMM", 

456 5: "TCS-BIN", 

457 7: "TCS-BIN-CORDLESS", 

458 15: "BNEP", 

459 17: "HID-Control", 

460 19: "HID-Interrupt", 

461 21: "UPnP", 

462 23: "AVCTP-Control", 

463 25: "AVDTP", 

464 27: "AVCTP-Browsing", 

465 29: "UDI_C-Plane", 

466 31: "ATT", 

467 33: "3DSP", 

468 35: "IPSP", 

469 37: "OTS"}), 

470 LEShortField("scid", 0), 

471 ByteField("controller_id", 0), ] 

472 

473 

474class L2CAP_Create_Channel_Response(Packet): 

475 name = "L2CAP Create Channel Response" 

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

477 LEShortField("scid", 0), 

478 LEShortEnumField("result", 0, { 

479 0: "Connection successful", 

480 1: "Connection pending", 

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

482 3: "Connection refused - security block", 

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

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

485 6: "Connection refused - invalid scid", 

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

487 LEShortEnumField("status", 0, { 

488 0: "No further information available", 

489 1: "Authentication pending", 

490 2: "Authorization pending"}), ] 

491 

492 

493class L2CAP_Move_Channel_Request(Packet): 

494 name = "L2CAP Move Channel Request" 

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

496 ByteField("dest_controller_id", 0), ] 

497 

498 

499class L2CAP_Move_Channel_Response(Packet): 

500 name = "L2CAP Move Channel Response" 

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

502 LEShortEnumField("result", 0, { 

503 0: "Move success", 

504 1: "Move pending", 

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

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

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

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

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

510 

511 

512class L2CAP_Move_Channel_Confirmation_Request(Packet): 

513 name = "L2CAP Move Channel Confirmation Request" 

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

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

516 1: "Move failure"}), ] 

517 

518 

519class L2CAP_Move_Channel_Confirmation_Response(Packet): 

520 name = "L2CAP Move Channel Confirmation Response" 

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

522 

523 

524class L2CAP_Connection_Parameter_Update_Request(Packet): 

525 name = "L2CAP Connection Parameter Update Request" 

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

527 LEShortField("max_interval", 0), 

528 LEShortField("slave_latency", 0), 

529 LEShortField("timeout_mult", 0), ] 

530 

531 

532class L2CAP_Connection_Parameter_Update_Response(Packet): 

533 name = "L2CAP Connection Parameter Update Response" 

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

535 

536 

537class L2CAP_LE_Credit_Based_Connection_Request(Packet): 

538 name = "L2CAP LE Credit Based Connection Request" 

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

540 LEShortField("scid", 0), 

541 LEShortField("mtu", 0), 

542 LEShortField("mps", 0), 

543 LEShortField("initial_credits", 0), ] 

544 

545 

546class L2CAP_LE_Credit_Based_Connection_Response(Packet): 

547 name = "L2CAP LE Credit Based Connection Response" 

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

549 LEShortField("mtu", 0), 

550 LEShortField("mps", 0), 

551 LEShortField("initial_credits", 0), 

552 LEShortEnumField("result", 0, { 

553 0: "Connection successful", 

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

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

556 5: "Connection refused - authentication error", 

557 6: "Connection refused - authorization error", 

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

559 8: "Connection refused - insufficient encryption", 

560 9: "Connection refused - invalid scid", 

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

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

563 

564 

565class L2CAP_Flow_Control_Credit_Ind(Packet): 

566 name = "L2CAP Flow Control Credit Ind" 

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

568 LEShortField("credits", 0), ] 

569 

570 

571class L2CAP_Credit_Based_Connection_Request(Packet): 

572 name = "L2CAP Credit Based Connection Request" 

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

574 LEShortField("mtu", 0), 

575 LEShortField("mps", 0), 

576 LEShortField("initial_credits", 0), 

577 LEShortField("scid", 0), ] 

578 

579 

580class L2CAP_Credit_Based_Connection_Response(Packet): 

581 name = "L2CAP Credit Based Connection Response" 

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

583 LEShortField("mps", 0), 

584 LEShortField("initial_credits", 0), 

585 LEShortEnumField("result", 0, { 

586 0: "All connection successful", 

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

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

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

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

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

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

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

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

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

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

597 LEShortField("dcid", 0), ] 

598 

599 

600class L2CAP_Credit_Based_Reconfigure_Request(Packet): 

601 name = "L2CAP Credit Based Reconfigure Request" 

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

603 LEShortField("mps", 0), 

604 LEShortField("dcid", 0), ] 

605 

606 

607class L2CAP_Credit_Based_Reconfigure_Response(Packet): 

608 name = "L2CAP Credit Based Reconfigure Response" 

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

610 0: "Reconfig successful", 

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

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

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

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

615 

616 

617class ATT_Hdr(Packet): 

618 name = "ATT header" 

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

620 

621 

622class ATT_Handle(Packet): 

623 name = "ATT Short Handle" 

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

625 XLEShortField("value", 0)] 

626 

627 def extract_padding(self, s): 

628 return b'', s 

629 

630 

631class ATT_Handle_UUID128(Packet): 

632 name = "ATT Handle (UUID 128)" 

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

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

635 

636 def extract_padding(self, s): 

637 return b'', s 

638 

639 

640class ATT_Error_Response(Packet): 

641 name = "Error Response" 

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

643 LEShortField("handle", 0), 

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

645 

646 

647class ATT_Exchange_MTU_Request(Packet): 

648 name = "Exchange MTU Request" 

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

650 

651 

652class ATT_Exchange_MTU_Response(Packet): 

653 name = "Exchange MTU Response" 

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

655 

656 

657class ATT_Find_Information_Request(Packet): 

658 name = "Find Information Request" 

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

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

661 

662 

663class ATT_Find_Information_Response(Packet): 

664 name = "Find Information Response" 

665 fields_desc = [ 

666 XByteField("format", 1), 

667 MultipleTypeField( 

668 [ 

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

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

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

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

673 ], 

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

675 ) 

676 ] 

677 

678 

679class ATT_Find_By_Type_Value_Request(Packet): 

680 name = "Find By Type Value Request" 

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

682 XLEShortField("end", 0xffff), 

683 XLEShortField("uuid", None), 

684 StrField("data", ""), ] 

685 

686 

687class ATT_Find_By_Type_Value_Response(Packet): 

688 name = "Find By Type Value Response" 

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

690 

691 

692class ATT_Read_By_Type_Request_128bit(Packet): 

693 name = "Read By Type Request" 

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

695 XLEShortField("end", 0xffff), 

696 XLELongField("uuid1", None), 

697 XLELongField("uuid2", None)] 

698 

699 @classmethod 

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

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

702 return ATT_Read_By_Type_Request 

703 return ATT_Read_By_Type_Request_128bit 

704 

705 

706class ATT_Read_By_Type_Request(Packet): 

707 name = "Read By Type Request" 

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

709 XLEShortField("end", 0xffff), 

710 XLEShortField("uuid", None)] 

711 

712 

713class ATT_Handle_Variable(Packet): 

714 __slots__ = ["val_length"] 

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

716 XStrLenField( 

717 "value", 0, 

718 length_from=lambda pkt: pkt.val_length)] 

719 

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

721 self.val_length = val_length 

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

723 

724 def extract_padding(self, s): 

725 return b"", s 

726 

727 

728class ATT_Read_By_Type_Response(Packet): 

729 name = "Read By Type Response" 

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

731 PacketListField( 

732 "handles", [], 

733 next_cls_cb=lambda pkt, *args: ( 

734 pkt._next_cls_cb(pkt, *args) 

735 ))] 

736 

737 @classmethod 

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

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

740 return functools.partial( 

741 ATT_Handle_Variable, 

742 val_length=pkt.len - 2 

743 ) 

744 return None 

745 

746 

747class ATT_Read_Request(Packet): 

748 name = "Read Request" 

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

750 

751 

752class ATT_Read_Response(Packet): 

753 name = "Read Response" 

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

755 

756 

757class ATT_Read_Multiple_Request(Packet): 

758 name = "Read Multiple Request" 

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

760 

761 

762class ATT_Read_Multiple_Response(Packet): 

763 name = "Read Multiple Response" 

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

765 

766 

767class ATT_Read_By_Group_Type_Request(Packet): 

768 name = "Read By Group Type Request" 

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

770 XLEShortField("end", 0xffff), 

771 XLEShortField("uuid", 0), ] 

772 

773 

774class ATT_Read_By_Group_Type_Response(Packet): 

775 name = "Read By Group Type Response" 

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

777 StrField("data", ""), ] 

778 

779 

780class ATT_Write_Request(Packet): 

781 name = "Write Request" 

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

783 StrField("data", ""), ] 

784 

785 

786class ATT_Write_Command(Packet): 

787 name = "Write Request" 

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

789 StrField("data", ""), ] 

790 

791 

792class ATT_Write_Response(Packet): 

793 name = "Write Response" 

794 

795 

796class ATT_Prepare_Write_Request(Packet): 

797 name = "Prepare Write Request" 

798 fields_desc = [ 

799 XLEShortField("gatt_handle", 0), 

800 LEShortField("offset", 0), 

801 StrField("data", "") 

802 ] 

803 

804 

805class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request): 

806 name = "Prepare Write Response" 

807 

808 

809class ATT_Handle_Value_Notification(Packet): 

810 name = "Handle Value Notification" 

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

812 StrField("value", ""), ] 

813 

814 

815class ATT_Execute_Write_Request(Packet): 

816 name = "Execute Write Request" 

817 fields_desc = [ 

818 ByteEnumField("flags", 1, { 

819 0: "Cancel all prepared writes", 

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

821 }), 

822 ] 

823 

824 

825class ATT_Execute_Write_Response(Packet): 

826 name = "Execute Write Response" 

827 

828 

829class ATT_Read_Blob_Request(Packet): 

830 name = "Read Blob Request" 

831 fields_desc = [ 

832 XLEShortField("gatt_handle", 0), 

833 LEShortField("offset", 0) 

834 ] 

835 

836 

837class ATT_Read_Blob_Response(Packet): 

838 name = "Read Blob Response" 

839 fields_desc = [ 

840 StrField("value", "") 

841 ] 

842 

843 

844class ATT_Handle_Value_Indication(Packet): 

845 name = "Handle Value Indication" 

846 fields_desc = [ 

847 XLEShortField("gatt_handle", 0), 

848 StrField("value", ""), 

849 ] 

850 

851 

852class SM_Hdr(Packet): 

853 name = "SM header" 

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

855 

856 

857class SM_Pairing_Request(Packet): 

858 name = "Pairing Request" 

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

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

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

862 ByteField("max_key_size", 16), 

863 ByteField("initiator_key_distribution", 0), 

864 ByteField("responder_key_distribution", 0), ] 

865 

866 

867class SM_Pairing_Response(Packet): 

868 name = "Pairing Response" 

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

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

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

872 ByteField("max_key_size", 16), 

873 ByteField("initiator_key_distribution", 0), 

874 ByteField("responder_key_distribution", 0), ] 

875 

876 

877class SM_Confirm(Packet): 

878 name = "Pairing Confirm" 

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

880 

881 

882class SM_Random(Packet): 

883 name = "Pairing Random" 

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

885 

886 

887class SM_Failed(Packet): 

888 name = "Pairing Failed" 

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

890 

891 

892class SM_Encryption_Information(Packet): 

893 name = "Encryption Information" 

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

895 

896 

897class SM_Master_Identification(Packet): 

898 name = "Master Identification" 

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

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

901 

902 

903class SM_Identity_Information(Packet): 

904 name = "Identity Information" 

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

906 

907 

908class SM_Identity_Address_Information(Packet): 

909 name = "Identity Address Information" 

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

911 LEMACField("address", None), ] 

912 

913 

914class SM_Signing_Information(Packet): 

915 name = "Signing Information" 

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

917 

918 

919class SM_Public_Key(Packet): 

920 name = "Public Key" 

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

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

923 

924 

925class SM_DHKey_Check(Packet): 

926 name = "DHKey Check" 

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

928 

929 

930class EIR_Hdr(Packet): 

931 name = "EIR Header" 

932 fields_desc = [ 

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

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

935 ByteEnumField("type", 0, { 

936 0x01: "flags", 

937 0x02: "incomplete_list_16_bit_svc_uuids", 

938 0x03: "complete_list_16_bit_svc_uuids", 

939 0x04: "incomplete_list_32_bit_svc_uuids", 

940 0x05: "complete_list_32_bit_svc_uuids", 

941 0x06: "incomplete_list_128_bit_svc_uuids", 

942 0x07: "complete_list_128_bit_svc_uuids", 

943 0x08: "shortened_local_name", 

944 0x09: "complete_local_name", 

945 0x0a: "tx_power_level", 

946 0x0d: "class_of_device", 

947 0x0e: "simple_pairing_hash", 

948 0x0f: "simple_pairing_rand", 

949 

950 0x10: "sec_mgr_tk", 

951 0x11: "sec_mgr_oob_flags", 

952 0x12: "slave_conn_intvl_range", 

953 0x14: "list_16_bit_svc_sollication_uuids", 

954 0x15: "list_128_bit_svc_sollication_uuids", 

955 0x16: "svc_data_16_bit_uuid", 

956 0x17: "pub_target_addr", 

957 0x18: "rand_target_addr", 

958 0x19: "appearance", 

959 0x1a: "adv_intvl", 

960 0x1b: "le_addr", 

961 0x1c: "le_role", 

962 0x1d: "simple_pairing_hash_256", 

963 0x1e: "simple_pairing_rand_256", 

964 0x1f: "list_32_bit_svc_sollication_uuids", 

965 

966 0x20: "svc_data_32_bit_uuid", 

967 0x21: "svc_data_128_bit_uuid", 

968 0x22: "sec_conn_confirm", 

969 0x23: "sec_conn_rand", 

970 0x24: "uri", 

971 0x25: "indoor_positioning", 

972 0x26: "transport_discovery", 

973 0x27: "le_supported_features", 

974 0x28: "channel_map_update", 

975 0x29: "mesh_pb_adv", 

976 0x2a: "mesh_message", 

977 0x2b: "mesh_beacon", 

978 

979 0x3d: "3d_information", 

980 

981 0xff: "mfg_specific_data", 

982 }), 

983 ] 

984 

985 def mysummary(self): 

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

987 

988 def guess_payload_class(self, payload): 

989 if self.len == 0: 

990 # For Extended_Inquiry_Response, stop when len=0 

991 return conf.padding_layer 

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

993 

994 

995class EIR_Element(Packet): 

996 name = "EIR Element" 

997 

998 def extract_padding(self, s): 

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

1000 return b'', s 

1001 

1002 @staticmethod 

1003 def length_from(pkt): 

1004 if not pkt.underlayer: 

1005 warning("Missing an upper-layer") 

1006 return 0 

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

1008 return pkt.underlayer.len - 1 

1009 

1010 

1011class EIR_Raw(EIR_Element): 

1012 name = "EIR Raw" 

1013 fields_desc = [ 

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

1015 ] 

1016 

1017 

1018class EIR_Flags(EIR_Element): 

1019 name = "Flags" 

1020 fields_desc = [ 

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

1022 ["limited_disc_mode", "general_disc_mode", 

1023 "br_edr_not_supported", "simul_le_br_edr_ctrl", 

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

1025 ] 

1026 

1027 

1028class EIR_CompleteList16BitServiceUUIDs(EIR_Element): 

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

1030 fields_desc = [ 

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

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

1033 length_from=EIR_Element.length_from) 

1034 ] 

1035 

1036 

1037class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs): 

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

1039 

1040 

1041class EIR_CompleteList128BitServiceUUIDs(EIR_Element): 

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

1043 fields_desc = [ 

1044 FieldListField("svc_uuids", None, 

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

1046 length_from=EIR_Element.length_from) 

1047 ] 

1048 

1049 

1050class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs): 

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

1052 

1053 

1054class EIR_CompleteLocalName(EIR_Element): 

1055 name = "Complete Local Name" 

1056 fields_desc = [ 

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

1058 ] 

1059 

1060 

1061class EIR_ShortenedLocalName(EIR_CompleteLocalName): 

1062 name = "Shortened Local Name" 

1063 

1064 

1065class EIR_TX_Power_Level(EIR_Element): 

1066 name = "TX Power Level" 

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

1068 

1069 

1070class EIR_Manufacturer_Specific_Data(EIR_Element): 

1071 name = "EIR Manufacturer Specific Data" 

1072 fields_desc = [ 

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

1074 XLEShortField("company_id", None), 

1075 ] 

1076 

1077 registered_magic_payloads = {} 

1078 

1079 @classmethod 

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

1081 """ 

1082 Registers a payload type that uses magic data. 

1083 

1084 Traditional payloads require registration of a Bluetooth Company ID 

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

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

1087 

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

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

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

1091 number of bytes in a beacon frame. 

1092 

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

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

1095 at the start of the Manufacturer Specific Data field. 

1096 

1097 Examples of this are AltBeacon and GeoBeacon. 

1098 

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

1100 

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

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

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

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

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

1106 used instead. 

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

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

1109 """ 

1110 if magic_check is None: 

1111 if hasattr(payload_cls, "magic_check"): 

1112 magic_check = payload_cls.magic_check 

1113 else: 

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

1115 "attribute magic_check".format(payload_cls)) 

1116 

1117 cls.registered_magic_payloads[payload_cls] = magic_check 

1118 

1119 def default_payload_class(self, payload): 

1120 for cls, check in ( 

1121 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items() 

1122 ): 

1123 if check(payload): 

1124 return cls 

1125 

1126 return Packet.default_payload_class(self, payload) 

1127 

1128 def extract_padding(self, s): 

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

1130 plen = EIR_Element.length_from(self) - 2 

1131 return s[:plen], s[plen:] 

1132 

1133 

1134class EIR_Device_ID(EIR_Element): 

1135 name = "Device ID" 

1136 fields_desc = [ 

1137 XLEShortField("vendor_id_source", 0), 

1138 XLEShortField("vendor_id", 0), 

1139 XLEShortField("product_id", 0), 

1140 XLEShortField("version", 0), 

1141 ] 

1142 

1143 

1144class EIR_ServiceData16BitUUID(EIR_Element): 

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

1146 fields_desc = [ 

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

1148 XLEShortField("svc_uuid", None), 

1149 ] 

1150 

1151 def extract_padding(self, s): 

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

1153 plen = EIR_Element.length_from(self) - 2 

1154 return s[:plen], s[plen:] 

1155 

1156 

1157class HCI_Command_Hdr(Packet): 

1158 name = "HCI Command header" 

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

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

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

1162 

1163 def answers(self, other): 

1164 return False 

1165 

1166 @property 

1167 def opcode(self): 

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

1169 

1170 def post_build(self, p, pay): 

1171 p += pay 

1172 if self.len is None: 

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

1174 return p 

1175 

1176 

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

1178# 8 EXTENDED INQUIRY RESPONSE 

1179 

1180class HCI_Extended_Inquiry_Response(Packet): 

1181 fields_desc = [ 

1182 PadField( 

1183 PacketListField( 

1184 "eir_data", [], 

1185 next_cls_cb=lambda *args: ( 

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

1187 ) 

1188 ), 

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

1190 ), 

1191 ] 

1192 

1193 

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

1195# 7 HCI COMMANDS AND EVENTS 

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

1197 

1198 

1199class HCI_Cmd_Inquiry(Packet): 

1200 """ 

1201 

1202 7.1.1 Inquiry command 

1203 

1204 """ 

1205 

1206 name = "HCI_Inquiry" 

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

1208 ByteField("inquiry_length", 0), 

1209 ByteField("num_responses", 0)] 

1210 

1211 

1212class HCI_Cmd_Inquiry_Cancel(Packet): 

1213 """ 

1214 

1215 7.1.2 Inquiry Cancel command 

1216 

1217 """ 

1218 

1219 name = "HCI_Inquiry_Cancel" 

1220 

1221 

1222class HCI_Cmd_Periodic_Inquiry_Mode(Packet): 

1223 """ 

1224 

1225 7.1.3 Periodic Inquiry Mode command 

1226 

1227 """ 

1228 

1229 name = "HCI_Periodic_Inquiry_Mode" 

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

1231 LEShortField("min_period_length", 0x0002), 

1232 XLE3BytesField("lap", 0x9E8B33), 

1233 ByteField("inquiry_length", 0), 

1234 ByteField("num_responses", 0)] 

1235 

1236 

1237class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet): 

1238 """ 

1239 

1240 7.1.4 Exit Periodic Inquiry Mode command 

1241 

1242 """ 

1243 

1244 name = "HCI_Exit_Periodic_Inquiry_Mode" 

1245 

1246 

1247class HCI_Cmd_Create_Connection(Packet): 

1248 """ 

1249 

1250 7.1.5 Create Connection command 

1251 

1252 """ 

1253 

1254 name = "HCI_Create_Connection" 

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

1256 LEShortField("packet_type", 0xcc18), 

1257 ByteField("page_scan_repetition_mode", 0x02), 

1258 ByteField("reserved", 0x0), 

1259 LEShortField("clock_offset", 0x0), 

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

1261 

1262 

1263class HCI_Cmd_Disconnect(Packet): 

1264 """ 

1265 

1266 7.1.6 Disconnect command 

1267 

1268 """ 

1269 

1270 name = "HCI_Disconnect" 

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

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

1273 

1274 

1275class HCI_Cmd_Create_Connection_Cancel(Packet): 

1276 """ 

1277 

1278 7.1.7 Create Connection Cancel command 

1279 

1280 """ 

1281 

1282 name = "HCI_Create_Connection_Cancel" 

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

1284 

1285 

1286class HCI_Cmd_Accept_Connection_Request(Packet): 

1287 """ 

1288 

1289 7.1.8 Accept Connection Request command 

1290 

1291 """ 

1292 

1293 name = "HCI_Accept_Connection_Request" 

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

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

1296 

1297 

1298class HCI_Cmd_Reject_Connection_Response(Packet): 

1299 """ 

1300 

1301 7.1.9 Reject Connection Request command 

1302 

1303 """ 

1304 name = "HCI_Reject_Connection_Response" 

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

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

1307 

1308 

1309class HCI_Cmd_Link_Key_Request_Reply(Packet): 

1310 """ 

1311 

1312 7.1.10 Link Key Request Reply command 

1313 

1314 """ 

1315 

1316 name = "HCI_Link_Key_Request_Reply" 

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

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

1319 

1320 

1321class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet): 

1322 """ 

1323 

1324 7.1.11 Link Key Request Negative Reply command 

1325 

1326 """ 

1327 

1328 name = "HCI_Link_Key_Request_Negative_Reply" 

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

1330 

1331 

1332class HCI_Cmd_PIN_Code_Request_Reply(Packet): 

1333 """ 

1334 

1335 7.1.12 PIN Code Request Reply command 

1336 

1337 """ 

1338 

1339 name = "HCI_PIN_Code_Request_Reply" 

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

1341 ByteField("pin_code_length", 7), 

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

1343 

1344 

1345class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet): 

1346 """ 

1347 

1348 7.1.13 PIN Code Request Negative Reply command 

1349 

1350 """ 

1351 

1352 name = "HCI_PIN_Code_Request_Negative_Reply" 

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

1354 

1355 

1356class HCI_Cmd_Change_Connection_Packet_Type(Packet): 

1357 """ 

1358 

1359 7.1.14 Change Connection Packet Type command 

1360 

1361 """ 

1362 

1363 name = "HCI_Cmd_Change_Connection_Packet_Type" 

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

1365 LEShortField("packet_type", 0), ] 

1366 

1367 

1368class HCI_Cmd_Authentication_Requested(Packet): 

1369 """ 

1370 

1371 7.1.15 Authentication Requested command 

1372 

1373 """ 

1374 

1375 name = "HCI_Authentication_Requested" 

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

1377 

1378 

1379class HCI_Cmd_Set_Connection_Encryption(Packet): 

1380 """ 

1381 

1382 7.1.16 Set Connection Encryption command 

1383 

1384 """ 

1385 

1386 name = "HCI_Set_Connection_Encryption" 

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

1388 

1389 

1390class HCI_Cmd_Change_Connection_Link_Key(Packet): 

1391 """ 

1392 

1393 7.1.17 Change Connection Link Key command 

1394 

1395 """ 

1396 

1397 name = "HCI_Change_Connection_Link_Key" 

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

1399 

1400 

1401class HCI_Cmd_Link_Key_Selection(Packet): 

1402 """ 

1403 

1404 7.1.18 Change Connection Link Key command 

1405 

1406 """ 

1407 

1408 name = "HCI_Cmd_Link_Key_Selection" 

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

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

1411 

1412 

1413class HCI_Cmd_Remote_Name_Request(Packet): 

1414 """ 

1415 

1416 7.1.19 Remote Name Request command 

1417 

1418 """ 

1419 

1420 name = "HCI_Remote_Name_Request" 

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

1422 ByteField("page_scan_repetition_mode", 0x02), 

1423 ByteField("reserved", 0x0), 

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

1425 

1426 

1427class HCI_Cmd_Remote_Name_Request_Cancel(Packet): 

1428 """ 

1429 

1430 7.1.20 Remote Name Request Cancel command 

1431 

1432 """ 

1433 

1434 name = "HCI_Remote_Name_Request_Cancel" 

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

1436 

1437 

1438class HCI_Cmd_Read_Remote_Supported_Features(Packet): 

1439 """ 

1440 

1441 7.1.21 Read Remote Supported Features command 

1442 

1443 """ 

1444 

1445 name = "HCI_Read_Remote_Supported_Features" 

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

1447 

1448 

1449class HCI_Cmd_Read_Remote_Extended_Features(Packet): 

1450 """ 

1451 

1452 7.1.22 Read Remote Extended Features command 

1453 

1454 """ 

1455 

1456 name = "HCI_Read_Remote_Supported_Features" 

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

1458 ByteField("page_number", None), ] 

1459 

1460 

1461class HCI_Cmd_IO_Capability_Request_Reply(Packet): 

1462 """ 

1463 

1464 7.1.29 IO Capability Request Reply command 

1465 

1466 """ 

1467 

1468 name = "HCI_Read_Remote_Supported_Features" 

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

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

1471 0x01: "DisplayYesNo", 

1472 0x02: "KeyboardOnly", 

1473 0x03: "NoInputNoOutput", }), 

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

1475 0x01: "P-192", 

1476 0x02: "P-256", 

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

1478 ByteEnumField("authentication_requirement", None, 

1479 {0x00: "MITM Not Required", 

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

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

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

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

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

1485 

1486 

1487class HCI_Cmd_User_Confirmation_Request_Reply(Packet): 

1488 """ 

1489 

1490 7.1.30 User Confirmation Request Reply command 

1491 

1492 """ 

1493 

1494 name = "HCI_User_Confirmation_Request_Reply" 

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

1496 

1497 

1498class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet): 

1499 """ 

1500 

1501 7.1.31 User Confirmation Request Negative Reply command 

1502 

1503 """ 

1504 

1505 name = "HCI_User_Confirmation_Request_Negative_Reply" 

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

1507 

1508 

1509class HCI_Cmd_User_Passkey_Request_Reply(Packet): 

1510 """ 

1511 

1512 7.1.32 User Passkey Request Reply command 

1513 

1514 """ 

1515 

1516 name = "HCI_User_Passkey_Request_Reply" 

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

1518 LEIntField("numeric_value", None), ] 

1519 

1520 

1521class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet): 

1522 """ 

1523 

1524 7.1.33 User Passkey Request Negative Reply command 

1525 

1526 """ 

1527 

1528 name = "HCI_User_Passkey_Request_Negative_Reply" 

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

1530 

1531 

1532class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet): 

1533 """ 

1534 

1535 7.1.34 Remote OOB Data Request Reply command 

1536 

1537 """ 

1538 

1539 name = "HCI_Remote_OOB_Data_Request_Reply" 

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

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

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

1543 

1544 

1545class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet): 

1546 """ 

1547 

1548 7.1.35 Remote OOB Data Request Negative Reply command 

1549 

1550 """ 

1551 

1552 name = "HCI_Remote_OOB_Data_Request_Negative_Reply" 

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

1554 

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

1556 

1557 

1558class HCI_Cmd_Hold_Mode(Packet): 

1559 name = "HCI_Hold_Mode" 

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

1561 LEShortField("hold_mode_max_interval", 0x0002), 

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

1563 

1564 

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

1566 

1567class HCI_Cmd_Set_Event_Mask(Packet): 

1568 name = "HCI_Set_Event_Mask" 

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

1570 

1571 

1572class HCI_Cmd_Reset(Packet): 

1573 name = "HCI_Reset" 

1574 

1575 

1576class HCI_Cmd_Set_Event_Filter(Packet): 

1577 name = "HCI_Set_Event_Filter" 

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

1579 

1580 

1581class HCI_Cmd_Write_Local_Name(Packet): 

1582 name = "HCI_Write_Local_Name" 

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

1584 

1585 

1586class HCI_Cmd_Write_Connect_Accept_Timeout(Packet): 

1587 name = "HCI_Write_Connection_Accept_Timeout" 

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

1589 

1590 

1591class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): 

1592 name = "HCI_Write_Extended_Inquiry_Response" 

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

1594 HCI_Extended_Inquiry_Response] 

1595 

1596 

1597class HCI_Cmd_Read_LE_Host_Support(Packet): 

1598 name = "HCI_Read_LE_Host_Support" 

1599 

1600 

1601class HCI_Cmd_Write_LE_Host_Support(Packet): 

1602 name = "HCI_Write_LE_Host_Support" 

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

1604 ByteField("unused", 1), ] 

1605 

1606 

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

1608class HCI_Cmd_Read_BD_Addr(Packet): 

1609 name = "HCI_Read_BD_ADDR" 

1610 

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

1612 

1613 

1614class HCI_Cmd_Read_Link_Quality(Packet): 

1615 name = "HCI_Read_Link_Quality" 

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

1617 

1618 

1619class HCI_Cmd_Read_RSSI(Packet): 

1620 name = "HCI_Read_RSSI" 

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

1622 

1623 

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

1625class HCI_Cmd_Read_Loopback_Mode(Packet): 

1626 name = "HCI_Read_Loopback_Mode" 

1627 

1628 

1629class HCI_Cmd_Write_Loopback_Mode(Packet): 

1630 name = "HCI_Write_Loopback_Mode" 

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

1632 {0: "no loopback", 

1633 1: "enable local loopback", 

1634 2: "enable remote loopback"})] 

1635 

1636 

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

1638class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet): 

1639 name = "HCI_LE_Read_Buffer_Size [v1]" 

1640 

1641 

1642class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet): 

1643 name = "HCI_LE_Read_Buffer_Size [v2]" 

1644 

1645 

1646class HCI_Cmd_LE_Read_Local_Supported_Features(Packet): 

1647 name = "HCI_LE_Read_Local_Supported_Features" 

1648 

1649 

1650class HCI_Cmd_LE_Set_Random_Address(Packet): 

1651 name = "HCI_LE_Set_Random_Address" 

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

1653 

1654 

1655class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): 

1656 name = "HCI_LE_Set_Advertising_Parameters" 

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

1658 LEShortField("interval_max", 0x0800), 

1659 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 

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

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

1662 LEMACField("daddr", None), 

1663 ByteField("channel_map", 7), 

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

1665 

1666 

1667class HCI_Cmd_LE_Set_Advertising_Data(Packet): 

1668 name = "HCI_LE_Set_Advertising_Data" 

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

1670 PadField( 

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

1672 length_from=lambda pkt: pkt.len), 

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

1674 

1675 

1676class HCI_Cmd_LE_Set_Scan_Response_Data(Packet): 

1677 name = "HCI_LE_Set_Scan_Response_Data" 

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

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

1680 

1681 

1682class HCI_Cmd_LE_Set_Advertise_Enable(Packet): 

1683 name = "HCI_LE_Set_Advertising_Enable" 

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

1685 

1686 

1687class HCI_Cmd_LE_Set_Scan_Parameters(Packet): 

1688 name = "HCI_LE_Set_Scan_Parameters" 

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

1690 XLEShortField("interval", 16), 

1691 XLEShortField("window", 16), 

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

1693 1: "random", 

1694 2: "rpa (pub)", 

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

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

1697 

1698 

1699class HCI_Cmd_LE_Set_Scan_Enable(Packet): 

1700 name = "HCI_LE_Set_Scan_Enable" 

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

1702 ByteField("filter_dups", 1), ] 

1703 

1704 

1705class HCI_Cmd_LE_Create_Connection(Packet): 

1706 name = "HCI_LE_Create_Connection" 

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

1708 LEShortField("window", 48), 

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

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

1711 LEMACField("paddr", None), 

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

1713 LEShortField("min_interval", 40), 

1714 LEShortField("max_interval", 56), 

1715 LEShortField("latency", 0), 

1716 LEShortField("timeout", 42), 

1717 LEShortField("min_ce", 0), 

1718 LEShortField("max_ce", 0), ] 

1719 

1720 

1721class HCI_Cmd_LE_Create_Connection_Cancel(Packet): 

1722 name = "HCI_LE_Create_Connection_Cancel" 

1723 

1724 

1725class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet): 

1726 name = "HCI_LE_Read_Filter_Accept_List_Size" 

1727 

1728 

1729class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet): 

1730 name = "HCI_LE_Clear_Filter_Accept_List" 

1731 

1732 

1733class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet): 

1734 name = "HCI_LE_Add_Device_To_Filter_Accept_List" 

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

1736 1: "random", 

1737 0xff: "anonymous"}), 

1738 LEMACField("address", None)] 

1739 

1740 

1741class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501 

1742 name = "HCI_LE_Remove_Device_From_Filter_Accept_List" 

1743 

1744 

1745class HCI_Cmd_LE_Connection_Update(Packet): 

1746 name = "HCI_LE_Connection_Update" 

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

1748 XLEShortField("min_interval", 0), 

1749 XLEShortField("max_interval", 0), 

1750 XLEShortField("latency", 0), 

1751 XLEShortField("timeout", 0), 

1752 LEShortField("min_ce", 0), 

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

1754 

1755 

1756class HCI_Cmd_LE_Read_Remote_Features(Packet): 

1757 name = "HCI_LE_Read_Remote_Features" 

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

1759 

1760 

1761class HCI_Cmd_LE_Enable_Encryption(Packet): 

1762 name = "HCI_LE_Enable_Encryption" 

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

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

1765 XLEShortField("ediv", 0), 

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

1767 

1768 

1769class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet): 

1770 name = "HCI_LE_Long_Term_Key_Request_Reply" 

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

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

1773 

1774 

1775class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): 

1776 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply" 

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

1778 

1779 

1780class HCI_Event_Hdr(Packet): 

1781 name = "HCI Event header" 

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

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

1784 

1785 def answers(self, other): 

1786 if HCI_Command_Hdr not in other: 

1787 return False 

1788 

1789 # Delegate answers to event types 

1790 return self.payload.answers(other) 

1791 

1792 

1793class HCI_Event_Inquiry_Complete(Packet): 

1794 """ 

1795 7.7.1 Inquiry Complete event 

1796 """ 

1797 name = "HCI_Inquiry_Complete" 

1798 fields_desc = [ 

1799 ByteEnumField('status', 0, _bluetooth_error_codes) 

1800 ] 

1801 

1802 

1803class HCI_Event_Inquiry_Result(Packet): 

1804 """ 

1805 7.7.2 Inquiry Result event 

1806 """ 

1807 name = "HCI_Inquiry_Result" 

1808 fields_desc = [ 

1809 ByteField("num_response", 0x00), 

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

1811 count_from=lambda p: p.num_response), 

1812 FieldListField("page_scan_repetition_mode", None, 

1813 ByteField("page_scan_repetition_mode", 0), 

1814 count_from=lambda p: p.num_response), 

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

1816 count_from=lambda p: p.num_response), 

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

1818 count_from=lambda p: p.num_response), 

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

1820 count_from=lambda p: p.num_response) 

1821 ] 

1822 

1823 

1824class HCI_Event_Connection_Complete(Packet): 

1825 """ 

1826 7.7.3 Connection Complete event 

1827 """ 

1828 name = "HCI_Connection_Complete" 

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

1830 LEShortField("handle", 0x0100), 

1831 LEMACField("bd_addr", None), 

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

1833 1: "ACL connection", }), 

1834 ByteEnumField("encryption_enabled", 0, 

1835 {0: "link level encryption disabled", 

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

1837 

1838 

1839class HCI_Event_Disconnection_Complete(Packet): 

1840 """ 

1841 7.7.5 Disconnection Complete event 

1842 """ 

1843 name = "HCI_Disconnection_Complete" 

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

1845 LEShortField("handle", 0), 

1846 XByteField("reason", 0), ] 

1847 

1848 

1849class HCI_Event_Remote_Name_Request_Complete(Packet): 

1850 """ 

1851 7.7.7 Remote Name Request Complete event 

1852 """ 

1853 name = "HCI_Remote_Name_Request_Complete" 

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

1855 LEMACField("bd_addr", None), 

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

1857 

1858 

1859class HCI_Event_Encryption_Change(Packet): 

1860 """ 

1861 7.7.8 Encryption Change event 

1862 """ 

1863 name = "HCI_Encryption_Change" 

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

1865 LEShortField("handle", 0), 

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

1867 

1868 

1869class HCI_Event_Read_Remote_Supported_Features_Complete(Packet): 

1870 """ 

1871 7.7.11 Read Remote Supported Features Complete event 

1872 """ 

1873 name = "HCI_Read_Remote_Supported_Features_Complete" 

1874 fields_desc = [ 

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

1876 LEShortField('handle', 0), 

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

1878 ] 

1879 

1880 

1881class HCI_Event_Read_Remote_Version_Information_Complete(Packet): 

1882 """ 

1883 7.7.12 Read Remote Version Information Complete event 

1884 """ 

1885 name = "HCI_Read_Remote_Version_Information" 

1886 fields_desc = [ 

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

1888 LEShortField('handle', 0), 

1889 ByteField('version', 0x00), 

1890 LEShortField('manufacturer_name', 0x0000), 

1891 LEShortField('subversion', 0x0000) 

1892 ] 

1893 

1894 

1895class HCI_Event_Command_Complete(Packet): 

1896 """ 

1897 7.7.14 Command Complete event 

1898 """ 

1899 name = "HCI_Command_Complete" 

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

1901 XLEShortField("opcode", 0), 

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

1903 

1904 def answers(self, other): 

1905 if HCI_Command_Hdr not in other: 

1906 return False 

1907 

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

1909 

1910 

1911class HCI_Event_Command_Status(Packet): 

1912 """ 

1913 7.7.15 Command Status event 

1914 """ 

1915 name = "HCI_Command_Status" 

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

1917 ByteField("number", 0), 

1918 XLEShortField("opcode", None), ] 

1919 

1920 def answers(self, other): 

1921 if HCI_Command_Hdr not in other: 

1922 return False 

1923 

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

1925 

1926 

1927class HCI_Event_Number_Of_Completed_Packets(Packet): 

1928 """ 

1929 7.7.19 Number Of Completed Packets event 

1930 """ 

1931 name = "HCI_Number_Of_Completed_Packets" 

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

1933 FieldListField("connection_handle_list", None, 

1934 LEShortField("connection_handle", 0), 

1935 count_from=lambda p: p.num_handles), 

1936 FieldListField("num_completed_packets_list", None, 

1937 LEShortField("num_completed_packets", 0), 

1938 count_from=lambda p: p.num_handles)] 

1939 

1940 

1941class HCI_Event_Link_Key_Request(Packet): 

1942 """ 

1943 7.7.23 Link Key Request event 

1944 """ 

1945 name = 'HCI_Link_Key_Request' 

1946 fields_desc = [ 

1947 LEMACField('bd_addr', None) 

1948 ] 

1949 

1950 

1951class HCI_Event_Inquiry_Result_With_Rssi(Packet): 

1952 """ 

1953 7.7.33 Inquiry Result with RSSI event 

1954 """ 

1955 name = "HCI_Inquiry_Result_with_RSSI" 

1956 fields_desc = [ 

1957 ByteField("num_response", 0x00), 

1958 FieldListField("bd_addr", None, LEMACField, 

1959 count_from=lambda p: p.num_response), 

1960 FieldListField("page_scan_repetition_mode", None, ByteField, 

1961 count_from=lambda p: p.num_response), 

1962 FieldListField("reserved", None, LEShortField, 

1963 count_from=lambda p: p.num_response), 

1964 FieldListField("device_class", None, XLE3BytesField, 

1965 count_from=lambda p: p.num_response), 

1966 FieldListField("clock_offset", None, LEShortField, 

1967 count_from=lambda p: p.num_response), 

1968 FieldListField("rssi", None, SignedByteField, 

1969 count_from=lambda p: p.num_response) 

1970 ] 

1971 

1972 

1973class HCI_Event_Read_Remote_Extended_Features_Complete(Packet): 

1974 """ 

1975 7.7.34 Read Remote Extended Features Complete event 

1976 """ 

1977 name = "HCI_Read_Remote_Extended_Features_Complete" 

1978 fields_desc = [ 

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

1980 LEShortField('handle', 0), 

1981 ByteField('page', 0x00), 

1982 ByteField('max_page', 0x00), 

1983 XLELongField('extended_features', 0) 

1984 ] 

1985 

1986 

1987class HCI_Event_Extended_Inquiry_Result(Packet): 

1988 """ 

1989 7.7.38 Extended Inquiry Result event 

1990 """ 

1991 name = "HCI_Extended_Inquiry_Result" 

1992 fields_desc = [ 

1993 ByteField('num_response', 0x01), 

1994 LEMACField('bd_addr', None), 

1995 ByteField('page_scan_repetition_mode', 0x00), 

1996 ByteField('reserved', 0x00), 

1997 XLE3BytesField('device_class', 0x000000), 

1998 LEShortField('clock_offset', 0x0000), 

1999 SignedByteField('rssi', 0x00), 

2000 HCI_Extended_Inquiry_Response, 

2001 ] 

2002 

2003 

2004class HCI_Event_IO_Capability_Response(Packet): 

2005 """ 

2006 7.7.41 IO Capability Response event 

2007 """ 

2008 name = "HCI_IO_Capability_Response" 

2009 fields_desc = [ 

2010 LEMACField('bd_addr', None), 

2011 ByteField('io_capability', 0x00), 

2012 ByteField('oob_data_present', 0x00), 

2013 ByteField('authentication_requirements', 0x00) 

2014 ] 

2015 

2016 

2017class HCI_Event_LE_Meta(Packet): 

2018 """ 

2019 7.7.65 LE Meta event 

2020 """ 

2021 name = "HCI_LE_Meta" 

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

2023 1: "connection_complete", 

2024 2: "advertising_report", 

2025 3: "connection_update_complete", 

2026 5: "long_term_key_request", 

2027 }), ] 

2028 

2029 def answers(self, other): 

2030 if not self.payload: 

2031 return False 

2032 

2033 # Delegate answers to payload 

2034 return self.payload.answers(other) 

2035 

2036 

2037class HCI_Cmd_Complete_Read_BD_Addr(Packet): 

2038 name = "Read BD Addr" 

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

2040 

2041 

2042class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet): 

2043 name = "LE Read White List Size" 

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

2045 ByteField("size", 0), ] 

2046 

2047 

2048class HCI_LE_Meta_Connection_Complete(Packet): 

2049 name = "Connection Complete" 

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

2051 LEShortField("handle", 0), 

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

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

2054 LEMACField("paddr", None), 

2055 LEShortField("interval", 54), 

2056 LEShortField("latency", 0), 

2057 LEShortField("supervision", 42), 

2058 XByteField("clock_latency", 5), ] 

2059 

2060 def answers(self, other): 

2061 if HCI_Cmd_LE_Create_Connection not in other: 

2062 return False 

2063 

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

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

2066 

2067 

2068class HCI_LE_Meta_Connection_Update_Complete(Packet): 

2069 name = "Connection Update Complete" 

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

2071 LEShortField("handle", 0), 

2072 LEShortField("interval", 54), 

2073 LEShortField("latency", 0), 

2074 LEShortField("timeout", 42), ] 

2075 

2076 

2077class HCI_LE_Meta_Advertising_Report(Packet): 

2078 name = "Advertising Report" 

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

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

2081 LEMACField("addr", None), 

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

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

2084 length_from=lambda pkt: pkt.len), 

2085 SignedByteField("rssi", 0)] 

2086 

2087 def extract_padding(self, s): 

2088 return '', s 

2089 

2090 

2091class HCI_LE_Meta_Advertising_Reports(Packet): 

2092 name = "Advertising Reports" 

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

2094 PacketListField("reports", None, 

2095 HCI_LE_Meta_Advertising_Report, 

2096 count_from=lambda pkt: pkt.len)] 

2097 

2098 

2099class HCI_LE_Meta_Long_Term_Key_Request(Packet): 

2100 name = "Long Term Key Request" 

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

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

2103 XLEShortField("ediv", 0), ] 

2104 

2105 

2106bind_layers(HCI_PHDR_Hdr, HCI_Hdr) 

2107 

2108bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1) 

2109bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2) 

2110bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4) 

2111bind_layers(HCI_Hdr, conf.raw_layer,) 

2112 

2113conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr) 

2114conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr) 

2115 

2116 

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

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

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

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

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

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

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

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

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

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

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

2128bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply, 

2129 ogf=0x01, ocf=0x000c) 

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

2131bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type, 

2132 ogf=0x01, ocf=0x000f) 

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

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

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

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

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

2138bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, 

2139 ogf=0x01, ocf=0x001b) 

2140bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features, 

2141 ogf=0x01, ocf=0x001c) 

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

2143bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply, 

2144 ogf=0x01, ocf=0x002c) 

2145bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply, 

2146 ogf=0x01, ocf=0x002d) 

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

2148bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply, 

2149 ogf=0x01, ocf=0x002f) 

2150bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply, 

2151 ogf=0x01, ocf=0x0030) 

2152bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply, 

2153 ogf=0x01, ocf=0x0033) 

2154 

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

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

2157 

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

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

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

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

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

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

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

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

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

2167 

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

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

2170 

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

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

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

2174 

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

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

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

2178 

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

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

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

2182bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features, 

2183 ogf=0x08, ocf=0x0003) 

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

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

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

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

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

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

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

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

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

2193bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size, 

2194 ogf=0x08, ocf=0x000f) 

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

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

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

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

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

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

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

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

2203 

2204# 7.7 EVENTS 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2222 

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

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

2225 

2226bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=1) 

2227bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=2) 

2228bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=3) 

2229bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=5) 

2230 

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

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

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

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

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

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

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

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

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

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

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

2242bind_layers(EIR_Hdr, EIR_Raw) 

2243 

2244bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,) 

2245bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1) 

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

2247bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1) 

2248bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2) 

2249bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3) 

2250bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4) 

2251bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5) 

2252bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6) 

2253bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7) 

2254bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8) 

2255bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9) 

2256bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10) 

2257bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11) 

2258bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12) 

2259bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13) 

2260bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14) 

2261bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15) 

2262bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16) 

2263bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17) 

2264bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18) 

2265bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19) 

2266bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20) 

2267bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21) 

2268bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22) 

2269bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23) 

2270bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24) 

2271bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25) 

2272bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26) 

2273bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4) 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2301bind_layers(L2CAP_Hdr, SM_Hdr, cid=6) 

2302bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=1) 

2303bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=2) 

2304bind_layers(SM_Hdr, SM_Confirm, sm_command=3) 

2305bind_layers(SM_Hdr, SM_Random, sm_command=4) 

2306bind_layers(SM_Hdr, SM_Failed, sm_command=5) 

2307bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=6) 

2308bind_layers(SM_Hdr, SM_Master_Identification, sm_command=7) 

2309bind_layers(SM_Hdr, SM_Identity_Information, sm_command=8) 

2310bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=9) 

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

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

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

2314 

2315 

2316############### 

2317# HCI Monitor # 

2318############### 

2319 

2320 

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

2322class HCI_Mon_Hdr(Packet): 

2323 name = 'Bluetooth Linux Monitor Transport Header' 

2324 fields_desc = [ 

2325 LEShortEnumField('opcode', None, { 

2326 0: "New index", 

2327 1: "Delete index", 

2328 2: "Command pkt", 

2329 3: "Event pkt", 

2330 4: "ACL TX pkt", 

2331 5: "ACL RX pkt", 

2332 6: "SCO TX pkt", 

2333 7: "SCO RX pkt", 

2334 8: "Open index", 

2335 9: "Close index", 

2336 10: "Index info", 

2337 11: "Vendor diag", 

2338 12: "System note", 

2339 13: "User logging", 

2340 14: "Ctrl open", 

2341 15: "Ctrl close", 

2342 16: "Ctrl command", 

2343 17: "Ctrl event", 

2344 18: "ISO TX pkt", 

2345 19: "ISO RX pkt", 

2346 }), 

2347 LEShortField('adapter_id', None), 

2348 LEShortField('len', None) 

2349 ] 

2350 

2351 

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

2353class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr): 

2354 name = 'Bluetooth Linux Monitor Transport Pcap Header' 

2355 fields_desc = [ 

2356 ShortField('adapter_id', None), 

2357 ShortField('opcode', None) 

2358 ] 

2359 

2360 

2361class HCI_Mon_New_Index(Packet): 

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

2363 fields_desc = [ 

2364 ByteEnumField('bus', 0, { 

2365 0x00: "BR/EDR", 

2366 0x01: "AMP" 

2367 }), 

2368 ByteEnumField('type', 0, { 

2369 0x00: "Virtual", 

2370 0x01: "USB", 

2371 0x02: "PC Card", 

2372 0x03: "UART", 

2373 0x04: "RS232", 

2374 0x05: "PCI", 

2375 0x06: "SDIO" 

2376 }), 

2377 LEMACField('addr', None), 

2378 StrFixedLenField('devname', None, 8) 

2379 ] 

2380 

2381 

2382class HCI_Mon_Index_Info(Packet): 

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

2384 fields_desc = [ 

2385 LEMACField('addr', None), 

2386 XLEShortField('manufacturer', None) 

2387 ] 

2388 

2389 

2390class HCI_Mon_System_Note(Packet): 

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

2392 fields_desc = [ 

2393 StrNullField('note', None) 

2394 ] 

2395 

2396 

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

2398bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0) 

2399bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2) 

2400bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3) 

2401bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10) 

2402bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12) 

2403 

2404conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr) 

2405 

2406 

2407########### 

2408# Helpers # 

2409########### 

2410 

2411class LowEnergyBeaconHelper: 

2412 """ 

2413 Helpers for building packets for Bluetooth Low Energy Beacons. 

2414 

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

2416 

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

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

2419 """ 

2420 

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

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

2423 "general_disc_mode", "br_edr_not_supported"]), ] 

2424 

2425 def build_eir(self): 

2426 """ 

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

2428 

2429 Users of this helper must implement this method. 

2430 

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

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

2433 """ 

2434 raise NotImplementedError("build_eir") 

2435 

2436 def build_advertising_report(self): 

2437 """ 

2438 Builds a HCI_LE_Meta_Advertising_Report containing this frame. 

2439 

2440 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report 

2441 """ 

2442 

2443 return HCI_LE_Meta_Advertising_Report( 

2444 type=0, # Undirected 

2445 atype=1, # Random address 

2446 data=self.build_eir() 

2447 ) 

2448 

2449 def build_set_advertising_data(self): 

2450 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame. 

2451 

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

2453 

2454 :rtype: scapy.bluetooth.HCI_Hdr 

2455 """ 

2456 

2457 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data( 

2458 data=self.build_eir() 

2459 ) 

2460 

2461 

2462########### 

2463# Sockets # 

2464########### 

2465 

2466class BluetoothSocketError(BaseException): 

2467 pass 

2468 

2469 

2470class BluetoothCommandError(BaseException): 

2471 pass 

2472 

2473 

2474class BluetoothL2CAPSocket(SuperSocket): 

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

2476 

2477 def __init__(self, bt_address): 

2478 if WINDOWS: 

2479 warning("Not available on Windows") 

2480 return 

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

2482 socket.BTPROTO_L2CAP) 

2483 s.connect((bt_address, 0)) 

2484 self.ins = self.outs = s 

2485 

2486 def recv(self, x=MTU): 

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

2488 

2489 

2490class BluetoothRFCommSocket(BluetoothL2CAPSocket): 

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

2492 

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

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

2495 socket.BTPROTO_RFCOMM) 

2496 s.connect((bt_address, port)) 

2497 self.ins = self.outs = s 

2498 

2499 

2500class BluetoothHCISocket(SuperSocket): 

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

2502 

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

2504 if WINDOWS: 

2505 warning("Not available on Windows") 

2506 return 

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

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

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

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

2511 s.bind((iface,)) 

2512 self.ins = self.outs = s 

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

2514 

2515 def recv(self, x=MTU): 

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

2517 

2518 

2519class sockaddr_hci(ctypes.Structure): 

2520 _fields_ = [ 

2521 ("sin_family", ctypes.c_ushort), 

2522 ("hci_dev", ctypes.c_ushort), 

2523 ("hci_channel", ctypes.c_ushort), 

2524 ] 

2525 

2526 

2527class _BluetoothLibcSocket(SuperSocket): 

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

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

2530 if WINDOWS: 

2531 warning("Not available on Windows") 

2532 return 

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

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

2535 # ctypes. 

2536 sockaddr_hcip = ctypes.POINTER(sockaddr_hci) 

2537 from ctypes.util import find_library 

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

2539 

2540 socket_c = libc.socket 

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

2542 socket_c.restype = ctypes.c_int 

2543 

2544 bind = libc.bind 

2545 bind.argtypes = (ctypes.c_int, 

2546 ctypes.POINTER(sockaddr_hci), 

2547 ctypes.c_int) 

2548 bind.restype = ctypes.c_int 

2549 

2550 # Socket 

2551 s = socket_c(socket_domain, socket_type, socket_protocol) 

2552 if s < 0: 

2553 raise BluetoothSocketError( 

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

2555 f"{socket_protocol})") 

2556 

2557 # Bind 

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

2559 if r != 0: 

2560 raise BluetoothSocketError("Unable to bind") 

2561 

2562 self.hci_fd = s 

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

2564 s, socket_domain, socket_type, socket_protocol) 

2565 

2566 def readable(self, timeout=0): 

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

2568 return len(ins) > 0 

2569 

2570 def flush(self): 

2571 while self.readable(): 

2572 self.recv() 

2573 

2574 def close(self): 

2575 if self.closed: 

2576 return 

2577 

2578 # Properly close socket so we can free the device 

2579 from ctypes.util import find_library 

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

2581 

2582 close = libc.close 

2583 close.restype = ctypes.c_int 

2584 self.closed = True 

2585 if hasattr(self, "outs"): 

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

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

2588 close(self.outs.fileno()) 

2589 if hasattr(self, "ins"): 

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

2591 close(self.ins.fileno()) 

2592 if hasattr(self, "hci_fd"): 

2593 close(self.hci_fd) 

2594 

2595 

2596class BluetoothUserSocket(_BluetoothLibcSocket): 

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

2598 

2599 def __init__(self, adapter_index=0): 

2600 sa = sockaddr_hci() 

2601 sa.sin_family = socket.AF_BLUETOOTH 

2602 sa.hci_dev = adapter_index 

2603 sa.hci_channel = HCI_CHANNEL_USER 

2604 super().__init__( 

2605 socket_domain=socket.AF_BLUETOOTH, 

2606 socket_type=socket.SOCK_RAW, 

2607 socket_protocol=socket.BTPROTO_HCI, 

2608 sock_address=sa) 

2609 

2610 def send_command(self, cmd): 

2611 opcode = cmd.opcode 

2612 self.send(cmd) 

2613 while True: 

2614 r = self.recv() 

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

2616 if r.status != 0: 

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

2618 return r 

2619 

2620 def recv(self, x=MTU): 

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

2622 

2623 

2624class BluetoothMonitorSocket(_BluetoothLibcSocket): 

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

2626 

2627 def __init__(self): 

2628 sa = sockaddr_hci() 

2629 sa.sin_family = socket.AF_BLUETOOTH 

2630 sa.hci_dev = HCI_DEV_NONE 

2631 sa.hci_channel = HCI_CHANNEL_MONITOR 

2632 super().__init__( 

2633 socket_domain=socket.AF_BLUETOOTH, 

2634 socket_type=socket.SOCK_RAW, 

2635 socket_protocol=socket.BTPROTO_HCI, 

2636 sock_address=sa) 

2637 

2638 def recv(self, x=MTU): 

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

2640 

2641 

2642conf.BTsocket = BluetoothRFCommSocket 

2643 

2644# Bluetooth 

2645 

2646 

2647@conf.commands.register 

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

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

2650 if "port" in kargs: 

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

2652 else: 

2653 s = conf.BTsocket(bt_address=bt_address) 

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

2655 s.close() 

2656 return a, b 

2657 

2658 

2659@conf.commands.register 

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

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

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

2663 if len(a) > 0: 

2664 return a[0][1]