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 socket
14import struct
15import select
16
17try:
18 import ctypes
19 from ctypes import sizeof
20except OSError:
21 ctypes = None
22 sizeof = None
23
24from scapy.config import conf
25from scapy.data import (
26 DLT_BLUETOOTH_HCI_H4,
27 DLT_BLUETOOTH_HCI_H4_WITH_PHDR,
28 DLT_BLUETOOTH_LINUX_MONITOR,
29 BLUETOOTH_CORE_COMPANY_IDENTIFIERS
30)
31from scapy.packet import bind_layers, Packet
32from scapy.fields import (
33 BitField,
34 LEFieldLenField,
35 XBitField,
36 ByteEnumField,
37 ByteField,
38 FieldLenField,
39 FieldListField,
40 FlagsField,
41 IntField,
42 LEShortEnumField,
43 LEShortField,
44 LEIntField,
45 LenField,
46 MultipleTypeField,
47 NBytesField,
48 PacketListField,
49 PadField,
50 ShortField,
51 SignedByteField,
52 StrField,
53 StrFixedLenField,
54 StrLenField,
55 StrNullField,
56 UUIDField,
57 XByteField,
58 XLE3BytesField,
59 XLELongField,
60 XStrLenField,
61 XLEShortField,
62 XLEIntField,
63 LEMACField,
64 BitEnumField,
65 LEThreeBytesField,
66 ConditionalField
67)
68from scapy.supersocket import SuperSocket
69from scapy.sendrecv import sndrcv
70from scapy.data import MTU
71from scapy.consts import WINDOWS
72from scapy.error import Scapy_Exception, warning
73
74
75############
76# Consts #
77############
78
79# From hci.h
80HCI_CHANNEL_RAW = 0
81HCI_CHANNEL_USER = 1
82HCI_CHANNEL_MONITOR = 2
83HCI_CHANNEL_CONTROL = 3
84HCI_CHANNEL_LOGGING = 4
85
86HCI_DEV_NONE = 0xffff
87
88
89##########
90# Layers #
91##########
92
93# See bluez/lib/hci.h for details
94
95# Transport layers
96
97class HCI_PHDR_Hdr(Packet):
98 name = "HCI PHDR transport layer"
99 fields_desc = [IntField("direction", 0)]
100
101
102# Real layers
103
104_bluetooth_packet_types = {
105 0: "Acknowledgement",
106 1: "Command",
107 2: "ACL Data",
108 3: "Synchronous",
109 4: "Event",
110 5: "Reserve",
111 14: "Vendor",
112 15: "Link Control"
113}
114
115_bluetooth_error_codes = {
116 0x00: "Success",
117 0x01: "Unknown HCI Command",
118 0x02: "Unknown Connection Identifier",
119 0x03: "Hardware Failure",
120 0x04: "Page Timeout",
121 0x05: "Authentication Failure",
122 0x06: "PIN or Key Missing",
123 0x07: "Memory Capacity Exceeded",
124 0x08: "Connection Timeout",
125 0x09: "Connection Limit Exceeded",
126 0x0A: "Synchronous Connection Limit To A Device Exceeded",
127 0x0B: "Connection Already Exists",
128 0x0C: "Command Disallowed",
129 0x0D: "Connection Rejected due to Limited Resources",
130 0x0E: "Connection Rejected Due To Security Reasons",
131 0x0F: "Connection Rejected due to Unacceptable BD_ADDR",
132 0x10: "Connection Accept Timeout Exceeded",
133 0x11: "Unsupported Feature or Parameter Value",
134 0x12: "Invalid HCI Command Parameters",
135 0x13: "Remote User Terminated Connection",
136 0x14: "Remote Device Terminated Connection due to Low Resources",
137 0x15: "Remote Device Terminated Connection due to Power Off",
138 0x16: "Connection Terminated By Local Host",
139 0x17: "Repeated Attempts",
140 0x18: "Pairing Not Allowed",
141 0x19: "Unknown LMP PDU",
142 0x1A: "Unsupported Remote Feature / Unsupported LMP Feature",
143 0x1B: "SCO Offset Rejected",
144 0x1C: "SCO Interval Rejected",
145 0x1D: "SCO Air Mode Rejected",
146 0x1E: "Invalid LMP Parameters / Invalid LL Parameters",
147 0x1F: "Unspecified Error",
148 0x20: "Unsupported LMP Parameter Value / Unsupported LL Parameter Value",
149 0x21: "Role Change Not Allowed",
150 0x22: "LMP Response Timeout / LL Response Timeout",
151 0x23: "LMP Error Transaction Collision / LL Procedure Collision",
152 0x24: "LMP PDU Not Allowed",
153 0x25: "Encryption Mode Not Acceptable",
154 0x26: "Link Key cannot be Changed",
155 0x27: "Requested QoS Not Supported",
156 0x28: "Instant Passed",
157 0x29: "Pairing With Unit Key Not Supported",
158 0x2A: "Different Transaction Collision",
159 0x2B: "Reserved for future use",
160 0x2C: "QoS Unacceptable Parameter",
161 0x2D: "QoS Rejected",
162 0x2E: "Channel Classification Not Supported",
163 0x2F: "Insufficient Security",
164 0x30: "Parameter Out Of Mandatory Range",
165 0x31: "Reserved for future use",
166 0x32: "Role Switch Pending",
167 0x33: "Reserved for future use",
168 0x34: "Reserved Slot Violation",
169 0x35: "Role Switch Failed",
170 0x36: "Extended Inquiry Response Too Large",
171 0x37: "Secure Simple Pairing Not Supported By Host",
172 0x38: "Host Busy - Pairing",
173 0x39: "Connection Rejected due to No Suitable Channel Found",
174 0x3A: "Controller Busy",
175 0x3B: "Unacceptable Connection Parameters",
176 0x3C: "Advertising Timeout",
177 0x3D: "Connection Terminated due to MIC Failure",
178 0x3E: "Connection Failed to be Established / Synchronization Timeout",
179 0x3F: "MAC Connection Failed",
180 0x40: "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock"
181 " Dragging",
182 0x41: "Type0 Submap Not Defined",
183 0x42: "Unknown Advertising Identifier",
184 0x43: "Limit Reached",
185 0x44: "Operation Cancelled by Host",
186 0x45: "Packet Too Long"
187}
188
189_att_error_codes = {
190 0x01: "invalid handle",
191 0x02: "read not permitted",
192 0x03: "write not permitted",
193 0x04: "invalid pdu",
194 0x05: "insufficient auth",
195 0x06: "unsupported req",
196 0x07: "invalid offset",
197 0x08: "insufficient author",
198 0x09: "prepare queue full",
199 0x0a: "attr not found",
200 0x0b: "attr not long",
201 0x0c: "insufficient key size",
202 0x0d: "invalid value size",
203 0x0e: "unlikely",
204 0x0f: "insufficiet encrypt",
205 0x10: "unsupported gpr type",
206 0x11: "insufficient resources",
207}
208
209_bluetooth_features = [
210 '3_slot_packets',
211 '5_slot_packets',
212 'encryption',
213 'slot_offset',
214 'timing_accuracy',
215 'role_switch',
216 'hold_mode',
217 'sniff_mode',
218 'park_mode',
219 'power_control_requests',
220 'channel_quality_driven_data_rate',
221 'sco_link',
222 'hv2_packets',
223 'hv3_packets',
224 'u_law_log_synchronous_data',
225 'a_law_log_synchronous_data',
226 'cvsd_synchronous_data',
227 'paging_parameter_negotiation',
228 'power_control',
229 'transparent_synchronous_data',
230 'flow_control_lag_4_bit0',
231 'flow_control_lag_4_bit1',
232 'flow_control_lag_4_bit2',
233 'broadband_encryption',
234 'cvsd_synchronous_data',
235 'edr_acl_2_mbps_mode',
236 'edr_acl_3_mbps_mode',
237 'enhanced_inquiry_scan',
238 'interlaced_inquiry_scan',
239 'interlaced_page_scan',
240 'rssi_with_inquiry_results',
241 'ev3_packets',
242 'ev4_packets',
243 'ev5_packets',
244 'reserved',
245 'afh_capable_slave',
246 'afh_classification_slave',
247 'br_edr_not_supported',
248 'le_supported_controller',
249 '3_slot_edr_acl_packets',
250 '5_slot_edr_acl_packets',
251 'sniff_subrating',
252 'pause_encryption',
253 'afh_capable_master',
254 'afh_classification_master',
255 'edr_esco_2_mbps_mode',
256 'edr_esco_3_mbps_mode',
257 '3_slot_edr_esco_packets',
258 'extended_inquiry_response',
259 'simultaneous_le_and_br_edr_to_same_device_capable_controller',
260 'reserved2',
261 'secure_simple_pairing',
262 'encapsulated_pdu',
263 'erroneous_data_reporting',
264 'non_flushable_packet_boundary_flag',
265 'reserved3',
266 'link_supervision_timeout_changed_event',
267 'inquiry_tx_power_level',
268 'enhanced_power_control',
269 'reserved4_bit0',
270 'reserved4_bit1',
271 'reserved4_bit2',
272 'reserved4_bit3',
273 'extended_features',
274]
275
276_bluetooth_core_specification_versions = {
277 0x00: '1.0b',
278 0x01: '1.1',
279 0x02: '1.2',
280 0x03: '2.0+EDR',
281 0x04: '2.1+EDR',
282 0x05: '3.0+HS',
283 0x06: '4.0',
284 0x07: '4.1',
285 0x08: '4.2',
286 0x09: '5.0',
287 0x0a: '5.1',
288 0x0b: '5.2',
289 0x0c: '5.3',
290 0x0d: '5.4',
291 0x0e: '6.0',
292}
293
294
295class HCI_Hdr(Packet):
296 name = "HCI header"
297 fields_desc = [ByteEnumField("type", 2, _bluetooth_packet_types)]
298
299 def mysummary(self):
300 return self.sprintf("HCI %type%")
301
302
303class HCI_ACL_Hdr(Packet):
304 name = "HCI ACL header"
305 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
306 fields_desc = [BitField("BC", 0, 2, tot_size=-2),
307 BitField("PB", 0, 2),
308 BitField("connection_handle", 0, 12, end_tot_size=-2),
309 LEShortField("len", None), ]
310
311 def post_build(self, p, pay):
312 p += pay
313 if self.len is None:
314 p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
315 return p
316
317
318class L2CAP_Hdr(Packet):
319 name = "L2CAP header"
320 fields_desc = [LEShortField("len", None),
321 LEShortEnumField("cid", 0, {1: "control", 4: "attribute"}), ] # noqa: E501
322
323 def post_build(self, p, pay):
324 p += pay
325 if self.len is None:
326 p = struct.pack("<H", len(pay)) + p[2:]
327 return p
328
329
330class L2CAP_CmdHdr(Packet):
331 name = "L2CAP command header"
332 fields_desc = [
333 ByteEnumField("code", 8, {1: "rej",
334 2: "conn_req",
335 3: "conn_resp",
336 4: "conf_req",
337 5: "conf_resp",
338 6: "disconn_req",
339 7: "disconn_resp",
340 8: "echo_req",
341 9: "echo_resp",
342 10: "info_req",
343 11: "info_resp",
344 12: "create_channel_req",
345 13: "create_channel_resp",
346 14: "move_channel_req",
347 15: "move_channel_resp",
348 16: "move_channel_confirm_req",
349 17: "move_channel_confirm_resp",
350 18: "conn_param_update_req",
351 19: "conn_param_update_resp",
352 20: "LE_credit_based_conn_req",
353 21: "LE_credit_based_conn_resp",
354 22: "flow_control_credit_ind",
355 23: "credit_based_conn_req",
356 24: "credit_based_conn_resp",
357 25: "credit_based_reconf_req",
358 26: "credit_based_reconf_resp"}),
359 ByteField("id", 1),
360 LEShortField("len", None)]
361
362 def post_build(self, p, pay):
363 p += pay
364 if self.len is None:
365 p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
366 return p
367
368 def answers(self, other):
369 if other.id == self.id:
370 if self.code == 1:
371 return 1
372 if other.code in [2, 4, 6, 8, 10, 18] and self.code == other.code + 1: # noqa: E501
373 if other.code == 8:
374 return 1
375 return self.payload.answers(other.payload)
376 return 0
377
378
379class L2CAP_ConnReq(Packet):
380 name = "L2CAP Conn Req"
381 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
382 3: "RFCOMM",
383 5: "TCS-BIN",
384 7: "TCS-BIN-CORDLESS",
385 15: "BNEP",
386 17: "HID-Control",
387 19: "HID-Interrupt",
388 21: "UPnP",
389 23: "AVCTP-Control",
390 25: "AVDTP",
391 27: "AVCTP-Browsing",
392 29: "UDI_C-Plane",
393 31: "ATT",
394 33: "3DSP",
395 35: "IPSP",
396 37: "OTS"}),
397 LEShortField("scid", 0),
398 ]
399
400
401class L2CAP_ConnResp(Packet):
402 name = "L2CAP Conn Resp"
403 fields_desc = [LEShortField("dcid", 0),
404 LEShortField("scid", 0),
405 LEShortEnumField("result", 0, ["success", "pend", "cr_bad_psm", "cr_sec_block", "cr_no_mem", "reserved", "cr_inval_scid", "cr_scid_in_use"]), # noqa: E501
406 LEShortEnumField("status", 0, ["no_info", "authen_pend", "author_pend", "reserved"]), # noqa: E501
407 ]
408
409 def answers(self, other):
410 # dcid Resp == scid Req. Therefore compare SCIDs
411 return isinstance(other, L2CAP_ConnReq) and self.scid == other.scid
412
413
414class L2CAP_CmdRej(Packet):
415 name = "L2CAP Command Rej"
416 fields_desc = [LEShortField("reason", 0),
417 ]
418
419
420class L2CAP_ConfReq(Packet):
421 name = "L2CAP Conf Req"
422 fields_desc = [LEShortField("dcid", 0),
423 LEShortField("flags", 0),
424 ]
425
426
427class L2CAP_ConfResp(Packet):
428 name = "L2CAP Conf Resp"
429 fields_desc = [LEShortField("scid", 0),
430 LEShortField("flags", 0),
431 LEShortEnumField("result", 0, ["success", "unaccept", "reject", "unknown"]), # noqa: E501
432 ]
433
434 def answers(self, other):
435 # Req and Resp contain either the SCID or the DCID.
436 return isinstance(other, L2CAP_ConfReq)
437
438
439class L2CAP_DisconnReq(Packet):
440 name = "L2CAP Disconn Req"
441 fields_desc = [LEShortField("dcid", 0),
442 LEShortField("scid", 0), ]
443
444
445class L2CAP_DisconnResp(Packet):
446 name = "L2CAP Disconn Resp"
447 fields_desc = [LEShortField("dcid", 0),
448 LEShortField("scid", 0), ]
449
450 def answers(self, other):
451 return self.scid == other.scid
452
453
454class L2CAP_EchoReq(Packet):
455 name = "L2CAP Echo Req"
456 fields_desc = [StrField("data", ""), ]
457
458
459class L2CAP_EchoResp(Packet):
460 name = "L2CAP Echo Resp"
461 fields_desc = [StrField("data", ""), ]
462
463
464class L2CAP_InfoReq(Packet):
465 name = "L2CAP Info Req"
466 fields_desc = [LEShortEnumField("type", 0, {1: "CL_MTU", 2: "FEAT_MASK"}),
467 StrField("data", "")
468 ]
469
470
471class L2CAP_InfoResp(Packet):
472 name = "L2CAP Info Resp"
473 fields_desc = [LEShortField("type", 0),
474 LEShortEnumField("result", 0, ["success", "not_supp"]),
475 StrField("data", ""), ]
476
477 def answers(self, other):
478 return self.type == other.type
479
480
481class L2CAP_Create_Channel_Request(Packet):
482 name = "L2CAP Create Channel Request"
483 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
484 3: "RFCOMM",
485 5: "TCS-BIN",
486 7: "TCS-BIN-CORDLESS",
487 15: "BNEP",
488 17: "HID-Control",
489 19: "HID-Interrupt",
490 21: "UPnP",
491 23: "AVCTP-Control",
492 25: "AVDTP",
493 27: "AVCTP-Browsing",
494 29: "UDI_C-Plane",
495 31: "ATT",
496 33: "3DSP",
497 35: "IPSP",
498 37: "OTS"}),
499 LEShortField("scid", 0),
500 ByteField("controller_id", 0), ]
501
502
503class L2CAP_Create_Channel_Response(Packet):
504 name = "L2CAP Create Channel Response"
505 fields_desc = [LEShortField("dcid", 0),
506 LEShortField("scid", 0),
507 LEShortEnumField("result", 0, {
508 0: "Connection successful",
509 1: "Connection pending",
510 2: "Connection refused - PSM not supported",
511 3: "Connection refused - security block",
512 4: "Connection refused - no resources available",
513 5: "Connection refused - cont_ID not supported",
514 6: "Connection refused - invalid scid",
515 7: "Connection refused - scid already allocated"}),
516 LEShortEnumField("status", 0, {
517 0: "No further information available",
518 1: "Authentication pending",
519 2: "Authorization pending"}), ]
520
521
522class L2CAP_Move_Channel_Request(Packet):
523 name = "L2CAP Move Channel Request"
524 fields_desc = [LEShortField("icid", 0),
525 ByteField("dest_controller_id", 0), ]
526
527
528class L2CAP_Move_Channel_Response(Packet):
529 name = "L2CAP Move Channel Response"
530 fields_desc = [LEShortField("icid", 0),
531 LEShortEnumField("result", 0, {
532 0: "Move success",
533 1: "Move pending",
534 2: "Move refused - Cont_ID not supported",
535 3: "Move refused - Cont_ID is same as old one",
536 4: "Move refused - Configuration not supported",
537 5: "Move refused - Move channel collision",
538 6: "Move refused - Not allowed to be moved"}), ]
539
540
541class L2CAP_Move_Channel_Confirmation_Request(Packet):
542 name = "L2CAP Move Channel Confirmation Request"
543 fields_desc = [LEShortField("icid", 0),
544 LEShortEnumField("result", 0, {0: "Move success",
545 1: "Move failure"}), ]
546
547
548class L2CAP_Move_Channel_Confirmation_Response(Packet):
549 name = "L2CAP Move Channel Confirmation Response"
550 fields_desc = [LEShortField("icid", 0), ]
551
552
553class L2CAP_Connection_Parameter_Update_Request(Packet):
554 name = "L2CAP Connection Parameter Update Request"
555 fields_desc = [LEShortField("min_interval", 0),
556 LEShortField("max_interval", 0),
557 LEShortField("slave_latency", 0),
558 LEShortField("timeout_mult", 0), ]
559
560
561class L2CAP_Connection_Parameter_Update_Response(Packet):
562 name = "L2CAP Connection Parameter Update Response"
563 fields_desc = [LEShortField("move_result", 0), ]
564
565
566class L2CAP_LE_Credit_Based_Connection_Request(Packet):
567 name = "L2CAP LE Credit Based Connection Request"
568 fields_desc = [LEShortField("spsm", 0),
569 LEShortField("scid", 0),
570 LEShortField("mtu", 0),
571 LEShortField("mps", 0),
572 LEShortField("initial_credits", 0), ]
573
574
575class L2CAP_LE_Credit_Based_Connection_Response(Packet):
576 name = "L2CAP LE Credit Based Connection Response"
577 fields_desc = [LEShortField("dcid", 0),
578 LEShortField("mtu", 0),
579 LEShortField("mps", 0),
580 LEShortField("initial_credits", 0),
581 LEShortEnumField("result", 0, {
582 0: "Connection successful",
583 2: "Connection refused - SPSM not supported",
584 4: "Connection refused - no resources available",
585 5: "Connection refused - authentication error",
586 6: "Connection refused - authorization error",
587 7: "Connection refused - encrypt_key size error",
588 8: "Connection refused - insufficient encryption",
589 9: "Connection refused - invalid scid",
590 10: "Connection refused - scid already allocated",
591 11: "Connection refused - parameters error"}), ]
592
593
594class L2CAP_Flow_Control_Credit_Ind(Packet):
595 name = "L2CAP Flow Control Credit Ind"
596 fields_desc = [LEShortField("cid", 0),
597 LEShortField("credits", 0), ]
598
599
600class L2CAP_Credit_Based_Connection_Request(Packet):
601 name = "L2CAP Credit Based Connection Request"
602 fields_desc = [LEShortField("spsm", 0),
603 LEShortField("mtu", 0),
604 LEShortField("mps", 0),
605 LEShortField("initial_credits", 0),
606 LEShortField("scid", 0), ]
607
608
609class L2CAP_Credit_Based_Connection_Response(Packet):
610 name = "L2CAP Credit Based Connection Response"
611 fields_desc = [LEShortField("mtu", 0),
612 LEShortField("mps", 0),
613 LEShortField("initial_credits", 0),
614 LEShortEnumField("result", 0, {
615 0: "All connection successful",
616 2: "All connection refused - SPSM not supported",
617 4: "Some connections refused - resources error",
618 5: "All connection refused - authentication error",
619 6: "All connection refused - authorization error",
620 7: "All connection refused - encrypt_key size error",
621 8: "All connection refused - encryption error",
622 9: "Some connection refused - invalid scid",
623 10: "Some connection refused - scid already allocated",
624 11: "All Connection refused - unacceptable parameters",
625 12: "All connections refused - invalid parameters"}),
626 LEShortField("dcid", 0), ]
627
628
629class L2CAP_Credit_Based_Reconfigure_Request(Packet):
630 name = "L2CAP Credit Based Reconfigure Request"
631 fields_desc = [LEShortField("mtu", 0),
632 LEShortField("mps", 0),
633 LEShortField("dcid", 0), ]
634
635
636class L2CAP_Credit_Based_Reconfigure_Response(Packet):
637 name = "L2CAP Credit Based Reconfigure Response"
638 fields_desc = [LEShortEnumField("result", 0, {
639 0: "Reconfig successful",
640 1: "Reconfig failed - MTU size reduction not allowed",
641 2: "Reconfig failed - MPS size reduction not allowed",
642 3: "Reconfig failed - one or more dcids invalid",
643 4: "Reconfig failed - unacceptable parameters"}), ]
644
645
646class ATT_Hdr(Packet):
647 name = "ATT header"
648 fields_desc = [XByteField("opcode", None), ]
649
650
651class ATT_Handle(Packet):
652 name = "ATT Short Handle"
653 fields_desc = [XLEShortField("handle", 0),
654 XLEShortField("value", 0)]
655
656 def extract_padding(self, s):
657 return b'', s
658
659
660class ATT_Handle_UUID128(Packet):
661 name = "ATT Handle (UUID 128)"
662 fields_desc = [XLEShortField("handle", 0),
663 UUIDField("value", None, uuid_fmt=UUIDField.FORMAT_REV)]
664
665 def extract_padding(self, s):
666 return b'', s
667
668
669class ATT_Error_Response(Packet):
670 name = "Error Response"
671 fields_desc = [XByteField("request", 0),
672 LEShortField("handle", 0),
673 ByteEnumField("ecode", 0, _att_error_codes), ]
674
675
676class ATT_Exchange_MTU_Request(Packet):
677 name = "Exchange MTU Request"
678 fields_desc = [LEShortField("mtu", 0), ]
679
680
681class ATT_Exchange_MTU_Response(Packet):
682 name = "Exchange MTU Response"
683 fields_desc = [LEShortField("mtu", 0), ]
684
685
686class ATT_Find_Information_Request(Packet):
687 name = "Find Information Request"
688 fields_desc = [XLEShortField("start", 0x0000),
689 XLEShortField("end", 0xffff), ]
690
691
692class ATT_Find_Information_Response(Packet):
693 name = "Find Information Response"
694 fields_desc = [
695 XByteField("format", 1),
696 MultipleTypeField(
697 [
698 (PacketListField("handles", [], ATT_Handle),
699 lambda pkt: pkt.format == 1),
700 (PacketListField("handles", [], ATT_Handle_UUID128),
701 lambda pkt: pkt.format == 2),
702 ],
703 StrFixedLenField("handles", "", length=0)
704 )
705 ]
706
707
708class ATT_Find_By_Type_Value_Request(Packet):
709 name = "Find By Type Value Request"
710 fields_desc = [XLEShortField("start", 0x0001),
711 XLEShortField("end", 0xffff),
712 XLEShortField("uuid", None),
713 StrField("data", ""), ]
714
715
716class ATT_Find_By_Type_Value_Response(Packet):
717 name = "Find By Type Value Response"
718 fields_desc = [PacketListField("handles", [], ATT_Handle)]
719
720
721class ATT_Read_By_Type_Request_128bit(Packet):
722 name = "Read By Type Request"
723 fields_desc = [XLEShortField("start", 0x0001),
724 XLEShortField("end", 0xffff),
725 XLELongField("uuid1", None),
726 XLELongField("uuid2", None)]
727
728 @classmethod
729 def dispatch_hook(cls, _pkt=None, *args, **kargs):
730 if _pkt and len(_pkt) == 6:
731 return ATT_Read_By_Type_Request
732 return ATT_Read_By_Type_Request_128bit
733
734
735class ATT_Read_By_Type_Request(Packet):
736 name = "Read By Type Request"
737 fields_desc = [XLEShortField("start", 0x0001),
738 XLEShortField("end", 0xffff),
739 XLEShortField("uuid", None)]
740
741
742class ATT_Handle_Variable(Packet):
743 fields_desc = [XLEShortField("handle", 0),
744 XStrLenField(
745 "value", 0,
746 length_from=lambda pkt: pkt and pkt.parent.len - 2 or 0)]
747
748 def extract_padding(self, s):
749 return b"", s
750
751
752class ATT_Read_By_Type_Response(Packet):
753 name = "Read By Type Response"
754 fields_desc = [ByteField("len", 4),
755 PacketListField("handles", [], ATT_Handle_Variable)]
756
757
758class ATT_Read_Request(Packet):
759 name = "Read Request"
760 fields_desc = [XLEShortField("gatt_handle", 0), ]
761
762
763class ATT_Read_Response(Packet):
764 name = "Read Response"
765 fields_desc = [StrField("value", "")]
766
767
768class ATT_Read_Multiple_Request(Packet):
769 name = "Read Multiple Request"
770 fields_desc = [FieldListField("handles", [], XLEShortField("", 0))]
771
772
773class ATT_Read_Multiple_Response(Packet):
774 name = "Read Multiple Response"
775 fields_desc = [StrField("values", "")]
776
777
778class ATT_Read_By_Group_Type_Request(Packet):
779 name = "Read By Group Type Request"
780 fields_desc = [XLEShortField("start", 0),
781 XLEShortField("end", 0xffff),
782 XLEShortField("uuid", 0), ]
783
784
785class ATT_Group_Handle_Variable(Packet):
786 fields_desc = [XLEShortField("handle", 0),
787 XLEShortField("group_end_handle", 0),
788 XStrLenField(
789 "value", 0,
790 length_from=lambda pkt: pkt and pkt.parent.len - 4 or 0)]
791
792 def extract_padding(self, s):
793 return b"", s
794
795
796class ATT_Read_By_Group_Type_Response(Packet):
797 name = "Read By Group Type Response"
798 fields_desc = [ByteField("len", 4),
799 PacketListField("handles", [], ATT_Group_Handle_Variable)]
800
801
802class ATT_Write_Request(Packet):
803 name = "Write Request"
804 fields_desc = [XLEShortField("gatt_handle", 0),
805 StrField("data", ""), ]
806
807
808class ATT_Write_Command(Packet):
809 name = "Write Request"
810 fields_desc = [XLEShortField("gatt_handle", 0),
811 StrField("data", ""), ]
812
813
814class ATT_Write_Response(Packet):
815 name = "Write Response"
816
817
818class ATT_Prepare_Write_Request(Packet):
819 name = "Prepare Write Request"
820 fields_desc = [
821 XLEShortField("gatt_handle", 0),
822 LEShortField("offset", 0),
823 StrField("data", "")
824 ]
825
826
827class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request):
828 name = "Prepare Write Response"
829
830
831class ATT_Handle_Value_Notification(Packet):
832 name = "Handle Value Notification"
833 fields_desc = [XLEShortField("gatt_handle", 0),
834 StrField("value", ""), ]
835
836
837class ATT_Execute_Write_Request(Packet):
838 name = "Execute Write Request"
839 fields_desc = [
840 ByteEnumField("flags", 1, {
841 0: "Cancel all prepared writes",
842 1: "Immediately write all pending prepared values",
843 }),
844 ]
845
846
847class ATT_Execute_Write_Response(Packet):
848 name = "Execute Write Response"
849
850
851class ATT_Read_Multiple_Variable_Request(Packet):
852 name = "Read Multiple Variable Request"
853 fields_desc = [FieldListField("handles", [], XLEShortField("", 0))]
854
855
856class ATT_Length_Value_Tuple(Packet):
857 fields_desc = [LEFieldLenField("len", None, length_of="value"),
858 XStrLenField("value", "", length_from=lambda pkt: pkt.len)]
859
860 def extract_padding(self, s):
861 return b"", s
862
863
864class ATT_Read_Multiple_Variable_Response(Packet):
865 name = "Read Multiple Variable Response"
866 fields_desc = [PacketListField("values", [], ATT_Length_Value_Tuple)]
867
868
869class ATT_Handle_Length_Value_Tuple(Packet):
870 fields_desc = [XLEShortField("handle", 0),
871 LEFieldLenField("len", None, length_of="value"),
872 XStrLenField("value", "", length_from=lambda pkt: pkt.len)]
873
874 def extract_padding(self, s):
875 return b"", s
876
877
878class ATT_Multiple_Handle_Value_Notification(Packet):
879 name = "Multiple Handle Value Notification"
880 fields_desc = [PacketListField("handles", [], ATT_Handle_Length_Value_Tuple)]
881
882
883class ATT_Read_Blob_Request(Packet):
884 name = "Read Blob Request"
885 fields_desc = [
886 XLEShortField("gatt_handle", 0),
887 LEShortField("offset", 0)
888 ]
889
890
891class ATT_Read_Blob_Response(Packet):
892 name = "Read Blob Response"
893 fields_desc = [
894 StrField("value", "")
895 ]
896
897
898class ATT_Handle_Value_Indication(Packet):
899 name = "Handle Value Indication"
900 fields_desc = [
901 XLEShortField("gatt_handle", 0),
902 StrField("value", ""),
903 ]
904
905
906class ATT_Handle_Value_Confirmation(Packet):
907 name = "Handle Value Confirmation"
908
909
910class ATT_Signed_Write_Command(Packet):
911 name = "Signed Write Command"
912
913 fields_desc = [XLEShortField("handle", 0),
914 StrLenField("value", "",
915 length_from=lambda pkt: len(pkt.original) - 14),
916 LEIntField("sign_counter", 0),
917 StrFixedLenField("signature", b'\x00' * 8, 8), ]
918
919
920class SM_Hdr(Packet):
921 name = "SM header"
922 fields_desc = [ByteField("sm_command", None)]
923
924
925class SM_Pairing_Request(Packet):
926 name = "Pairing Request"
927 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501
928 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501
929 BitField("authentication", 0, 8),
930 ByteField("max_key_size", 16),
931 ByteField("initiator_key_distribution", 0),
932 ByteField("responder_key_distribution", 0), ]
933
934
935class SM_Pairing_Response(Packet):
936 name = "Pairing Response"
937 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501
938 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501
939 BitField("authentication", 0, 8),
940 ByteField("max_key_size", 16),
941 ByteField("initiator_key_distribution", 0),
942 ByteField("responder_key_distribution", 0), ]
943
944
945class SM_Confirm(Packet):
946 name = "Pairing Confirm"
947 fields_desc = [StrFixedLenField("confirm", b'\x00' * 16, 16)]
948
949
950class SM_Random(Packet):
951 name = "Pairing Random"
952 fields_desc = [StrFixedLenField("random", b'\x00' * 16, 16)]
953
954
955class SM_Failed(Packet):
956 name = "Pairing Failed"
957 fields_desc = [XByteField("reason", 0)]
958
959
960class SM_Encryption_Information(Packet):
961 name = "Encryption Information"
962 fields_desc = [StrFixedLenField("ltk", b"\x00" * 16, 16), ]
963
964
965class SM_Master_Identification(Packet):
966 name = "Master Identification"
967 fields_desc = [XLEShortField("ediv", 0),
968 StrFixedLenField("rand", b'\x00' * 8, 8), ]
969
970
971class SM_Identity_Information(Packet):
972 name = "Identity Information"
973 fields_desc = [StrFixedLenField("irk", b'\x00' * 16, 16), ]
974
975
976class SM_Identity_Address_Information(Packet):
977 name = "Identity Address Information"
978 fields_desc = [ByteEnumField("addr_type", 0, {0: "public"}),
979 LEMACField("bd_addr", None), ]
980 deprecated_fields = {
981 "atype": ("addr_type", "2.7.0"),
982 "address": ("bd_addr", "2.7.0"),
983 "addr": ("bd_addr", "2.8.0"),
984 }
985
986
987class SM_Signing_Information(Packet):
988 name = "Signing Information"
989 fields_desc = [StrFixedLenField("csrk", b'\x00' * 16, 16), ]
990
991
992class SM_Security_Request(Packet):
993 name = "Security Request"
994 fields_desc = [BitField("auth_req", 0, 8), ]
995
996
997class SM_Public_Key(Packet):
998 name = "Public Key"
999 fields_desc = [StrFixedLenField("key_x", b'\x00' * 32, 32),
1000 StrFixedLenField("key_y", b'\x00' * 32, 32), ]
1001
1002
1003class SM_DHKey_Check(Packet):
1004 name = "DHKey Check"
1005 fields_desc = [StrFixedLenField("dhkey_check", b'\x00' * 16, 16), ]
1006
1007
1008class SM_Keypress_Notification(Packet):
1009 name = "Keypress Notification"
1010 fields_desc = [ByteEnumField("notification_type", 0, {
1011 0: "Passkey entry started",
1012 1: "Passkey digit entered",
1013 2: "Passkey digit erased",
1014 3: "Passkey cleared",
1015 4: "Passkey entry completed",
1016 })]
1017
1018
1019class EIR_Hdr(Packet):
1020 name = "EIR Header"
1021 fields_desc = [
1022 LenField("len", None, fmt="B", adjust=lambda x: x + 1), # Add bytes mark # noqa: E501
1023 # https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
1024 ByteEnumField("type", 0, {
1025 0x01: "flags",
1026 0x02: "incomplete_list_16_bit_svc_uuids",
1027 0x03: "complete_list_16_bit_svc_uuids",
1028 0x04: "incomplete_list_32_bit_svc_uuids",
1029 0x05: "complete_list_32_bit_svc_uuids",
1030 0x06: "incomplete_list_128_bit_svc_uuids",
1031 0x07: "complete_list_128_bit_svc_uuids",
1032 0x08: "shortened_local_name",
1033 0x09: "complete_local_name",
1034 0x0a: "tx_power_level",
1035 0x0d: "class_of_device",
1036 0x0e: "simple_pairing_hash",
1037 0x0f: "simple_pairing_rand",
1038
1039 0x10: "sec_mgr_tk",
1040 0x11: "sec_mgr_oob_flags",
1041 0x12: "slave_conn_intvl_range",
1042 0x14: "list_16_bit_svc_sollication_uuids",
1043 0x15: "list_128_bit_svc_sollication_uuids",
1044 0x16: "svc_data_16_bit_uuid",
1045 0x17: "pub_target_addr",
1046 0x18: "rand_target_addr",
1047 0x19: "appearance",
1048 0x1a: "adv_intvl",
1049 0x1b: "le_addr",
1050 0x1c: "le_role",
1051 0x1d: "simple_pairing_hash_256",
1052 0x1e: "simple_pairing_rand_256",
1053 0x1f: "list_32_bit_svc_sollication_uuids",
1054
1055 0x20: "svc_data_32_bit_uuid",
1056 0x21: "svc_data_128_bit_uuid",
1057 0x22: "sec_conn_confirm",
1058 0x23: "sec_conn_rand",
1059 0x24: "uri",
1060 0x25: "indoor_positioning",
1061 0x26: "transport_discovery",
1062 0x27: "le_supported_features",
1063 0x28: "channel_map_update",
1064 0x29: "mesh_pb_adv",
1065 0x2a: "mesh_message",
1066 0x2b: "mesh_beacon",
1067
1068 0x30: "broadcast_name",
1069
1070 0x3d: "3d_information",
1071
1072 0xff: "mfg_specific_data",
1073 }),
1074 ]
1075
1076 def mysummary(self):
1077 return self.sprintf("EIR %type%")
1078
1079 def guess_payload_class(self, payload):
1080 if self.len == 0:
1081 # For Extended_Inquiry_Response, stop when len=0
1082 return conf.padding_layer
1083 return super(EIR_Hdr, self).guess_payload_class(payload)
1084
1085
1086class EIR_Element(Packet):
1087 name = "EIR Element"
1088
1089 def extract_padding(self, s):
1090 # Needed to end each EIR_Element packet and make PacketListField work.
1091 return b'', s
1092
1093 @staticmethod
1094 def length_from(pkt):
1095 if not pkt.underlayer:
1096 warning("Missing an upper-layer")
1097 return 0
1098 # 'type' byte is included in the length, so subtract 1:
1099 return pkt.underlayer.len - 1
1100
1101
1102class EIR_Raw(EIR_Element):
1103 name = "EIR Raw"
1104 fields_desc = [
1105 StrLenField("data", "", length_from=EIR_Element.length_from)
1106 ]
1107
1108
1109class EIR_Flags(EIR_Element):
1110 name = "Flags"
1111 fields_desc = [
1112 FlagsField("flags", 0x2, 8,
1113 ["limited_disc_mode", "general_disc_mode",
1114 "br_edr_not_supported", "simul_le_br_edr_ctrl",
1115 "simul_le_br_edr_host"] + 3 * ["reserved"])
1116 ]
1117
1118
1119class EIR_CompleteList16BitServiceUUIDs(EIR_Element):
1120 name = "Complete list of 16-bit service UUIDs"
1121 fields_desc = [
1122 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1123 FieldListField("svc_uuids", None, XLEShortField("uuid", 0),
1124 length_from=EIR_Element.length_from)
1125 ]
1126
1127
1128class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs):
1129 name = "Incomplete list of 16-bit service UUIDs"
1130
1131
1132class EIR_CompleteList32BitServiceUUIDs(EIR_Element):
1133 name = 'Complete list of 32-bit service UUIDs'
1134 fields_desc = [
1135 # https://www.bluetooth.com/specifications/assigned-numbers
1136 FieldListField('svc_uuids', None, XLEIntField('uuid', 0),
1137 length_from=EIR_Element.length_from)
1138 ]
1139
1140
1141class EIR_IncompleteList32BitServiceUUIDs(EIR_CompleteList32BitServiceUUIDs):
1142 name = 'Incomplete list of 32-bit service UUIDs'
1143
1144
1145class EIR_CompleteList128BitServiceUUIDs(EIR_Element):
1146 name = "Complete list of 128-bit service UUIDs"
1147 fields_desc = [
1148 FieldListField("svc_uuids", None,
1149 UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV),
1150 length_from=EIR_Element.length_from)
1151 ]
1152
1153
1154class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs):
1155 name = "Incomplete list of 128-bit service UUIDs"
1156
1157
1158class EIR_CompleteLocalName(EIR_Element):
1159 name = "Complete Local Name"
1160 fields_desc = [
1161 StrLenField("local_name", "", length_from=EIR_Element.length_from)
1162 ]
1163
1164
1165class EIR_ShortenedLocalName(EIR_CompleteLocalName):
1166 name = "Shortened Local Name"
1167
1168
1169class EIR_TX_Power_Level(EIR_Element):
1170 name = "TX Power Level"
1171 fields_desc = [SignedByteField("level", 0)]
1172
1173
1174class EIR_ClassOfDevice(EIR_Element):
1175 name = 'Class of device'
1176 fields_desc = [
1177 FlagsField('major_service_classes', 0, 11, [
1178 'limited_discoverable_mode',
1179 'le_audio',
1180 'reserved',
1181 'positioning',
1182 'networking',
1183 'rendering',
1184 'capturing',
1185 'object_transfer',
1186 'audio',
1187 'telephony',
1188 'information'
1189 ], tot_size=-3),
1190 BitEnumField('major_device_class', 0, 5, {
1191 0x00: 'miscellaneous',
1192 0x01: 'computer',
1193 0x02: 'phone',
1194 0x03: 'lan',
1195 0x04: 'audio_video',
1196 0x05: 'peripheral',
1197 0x06: 'imaging',
1198 0x07: 'wearable',
1199 0x08: 'toy',
1200 0x09: 'health',
1201 0x1f: 'uncategorized'
1202 }),
1203 BitField('minor_device_class', 0, 6),
1204 BitField('fixed', 0, 2, end_tot_size=-3)
1205 ]
1206
1207
1208class EIR_SecureSimplePairingHashC192(EIR_Element):
1209 name = 'Secure Simple Pairing Hash C-192'
1210 fields_desc = [NBytesField('hash', 0, 16)]
1211
1212
1213class EIR_SecureSimplePairingRandomizerR192(EIR_Element):
1214 name = 'Secure Simple Pairing Randomizer R-192'
1215 fields_desc = [NBytesField('randomizer', 0, 16)]
1216
1217
1218class EIR_SecurityManagerOOBFlags(EIR_Element):
1219 name = 'Security Manager Out of Band Flags'
1220 fields_desc = [
1221 BitField('oob_flags_field', 0, 1),
1222 BitField('le_supported', 0, 1),
1223 BitField('previously_used', 0, 1),
1224 BitField('address_type', 0, 1),
1225 BitField('reserved', 0, 4)
1226 ]
1227
1228
1229class EIR_PeripheralConnectionIntervalRange(EIR_Element):
1230 name = 'Peripheral Connection Interval Range'
1231 fields_desc = [
1232 LEShortField('conn_interval_min', 0xFFFF),
1233 LEShortField('conn_interval_max', 0xFFFF)
1234 ]
1235
1236
1237class EIR_Manufacturer_Specific_Data(EIR_Element):
1238 name = "EIR Manufacturer Specific Data"
1239 deprecated_fields = {
1240 "company_id": ("company_identifier", "2.6.2"),
1241 }
1242 fields_desc = [
1243 # https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
1244 LEShortEnumField("company_identifier", None,
1245 BLUETOOTH_CORE_COMPANY_IDENTIFIERS),
1246 ]
1247
1248 registered_magic_payloads = {}
1249
1250 @classmethod
1251 def register_magic_payload(cls, payload_cls, magic_check=None):
1252 """
1253 Registers a payload type that uses magic data.
1254
1255 Traditional payloads require registration of a Bluetooth Company ID
1256 (requires company membership of the Bluetooth SIG), or a Bluetooth
1257 Short UUID (requires a once-off payment).
1258
1259 There are alternatives which don't require registration (such as
1260 128-bit UUIDs), but the biggest consumer of energy in a beacon is the
1261 radio -- so the energy consumption of a beacon is proportional to the
1262 number of bytes in a beacon frame.
1263
1264 Some beacon formats side-step this issue by using the Company ID of
1265 their beacon hardware manufacturer, and adding a "magic data sequence"
1266 at the start of the Manufacturer Specific Data field.
1267
1268 Examples of this are AltBeacon and GeoBeacon.
1269
1270 For an example of this method in use, see ``scapy.contrib.altbeacon``.
1271
1272 :param Type[scapy.packet.Packet] payload_cls:
1273 A reference to a Packet subclass to register as a payload.
1274 :param Callable[[bytes], bool] magic_check:
1275 (optional) callable to use to if a payload should be associated
1276 with this type. If not supplied, ``payload_cls.magic_check`` is
1277 used instead.
1278 :raises TypeError: If ``magic_check`` is not specified,
1279 and ``payload_cls.magic_check`` is not implemented.
1280 """
1281 if magic_check is None:
1282 if hasattr(payload_cls, "magic_check"):
1283 magic_check = payload_cls.magic_check
1284 else:
1285 raise TypeError("magic_check not specified, and {} has no "
1286 "attribute magic_check".format(payload_cls))
1287
1288 cls.registered_magic_payloads[payload_cls] = magic_check
1289
1290 def default_payload_class(self, payload):
1291 for cls, check in (
1292 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items()
1293 ):
1294 if check(payload):
1295 return cls
1296
1297 return Packet.default_payload_class(self, payload)
1298
1299 def extract_padding(self, s):
1300 # Needed to end each EIR_Element packet and make PacketListField work.
1301 plen = EIR_Element.length_from(self) - 2
1302 return s[:plen], s[plen:]
1303
1304
1305class EIR_Device_ID(EIR_Element):
1306 name = "Device ID"
1307 fields_desc = [
1308 XLEShortField("vendor_id_source", 0),
1309 XLEShortField("vendor_id", 0),
1310 XLEShortField("product_id", 0),
1311 XLEShortField("version", 0),
1312 ]
1313
1314
1315class EIR_ServiceSolicitation16BitUUID(EIR_Element):
1316 name = "EIR Service Solicitation - 16-bit UUID"
1317 fields_desc = [
1318 XLEShortField("svc_uuid", None)
1319 ]
1320
1321 def extract_padding(self, s):
1322 # Needed to end each EIR_Element packet and make PacketListField work.
1323 plen = EIR_Element.length_from(self) - 2
1324 return s[:plen], s[plen:]
1325
1326
1327class EIR_ServiceSolicitation128BitUUID(EIR_Element):
1328 name = "EIR Service Solicitation - 128-bit UUID"
1329 fields_desc = [
1330 UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV)
1331 ]
1332
1333 def extract_padding(self, s):
1334 # Needed to end each EIR_Element packet and make PacketListField work.
1335 plen = EIR_Element.length_from(self) - 2
1336 return s[:plen], s[plen:]
1337
1338
1339class EIR_ServiceData16BitUUID(EIR_Element):
1340 name = "EIR Service Data - 16-bit UUID"
1341 fields_desc = [
1342 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1343 XLEShortField("svc_uuid", None),
1344 ]
1345
1346 def extract_padding(self, s):
1347 # Needed to end each EIR_Element packet and make PacketListField work.
1348 plen = EIR_Element.length_from(self) - 2
1349 return s[:plen], s[plen:]
1350
1351
1352class EIR_PublicTargetAddress(EIR_Element):
1353 name = "Public Target Address"
1354 fields_desc = [
1355 LEMACField('bd_addr', None)
1356 ]
1357
1358
1359class EIR_RandomTargetAddress(EIR_Element):
1360 name = "Random Target Address"
1361 fields_desc = [
1362 LEMACField('bd_addr', None)
1363 ]
1364
1365
1366class EIR_AdvertisingInterval(EIR_Element):
1367 name = "Advertising Interval"
1368 fields_desc = [
1369 MultipleTypeField(
1370 [
1371 (ByteField("advertising_interval", 0),
1372 lambda p: p.underlayer.len - 1 == 1),
1373 (LEShortField("advertising_interval", 0),
1374 lambda p: p.underlayer.len - 1 == 2),
1375 (LEThreeBytesField("advertising_interval", 0),
1376 lambda p: p.underlayer.len - 1 == 3),
1377 (LEIntField("advertising_interval", 0),
1378 lambda p: p.underlayer.len - 1 == 4),
1379 ],
1380 LEShortField("advertising_interval", 0)
1381 )
1382 ]
1383
1384
1385class EIR_LEBluetoothDeviceAddress(EIR_Element):
1386 name = "LE Bluetooth Device Address"
1387 fields_desc = [
1388 XBitField('reserved', 0, 7, tot_size=-1),
1389 BitEnumField('addr_type', 0, 1, end_tot_size=-1, enum={
1390 0x0: 'Public',
1391 0x1: 'Random'
1392 }),
1393 LEMACField('bd_addr', None)
1394 ]
1395
1396
1397class EIR_LERole(EIR_Element):
1398 name = "LE Role"
1399 fields_desc = [
1400 ByteEnumField("role", 0, {
1401 0: "Only Peripheral Role supported",
1402 1: "Only Central Role supported",
1403 2: "Peripheral and Central Role supported, "
1404 "Peripheral Role preferred for connection establishment",
1405 3: "Peripheral and Central Role supported, "
1406 "Central Role preferred for connection establishment",
1407 }),
1408 ]
1409
1410
1411class EIR_BroadcastName(EIR_Element):
1412 name = "Broadcast Name"
1413 fields_desc = [
1414 StrLenField("broadcast_name", "",
1415 length_from=EIR_Element.length_from)
1416 ]
1417
1418
1419class EIR_3DInformation(EIR_Element):
1420 name = "3D Information"
1421 fields_desc = [
1422 BitField("factory_test_mode", 0, 1, tot_size=-1),
1423 BitField("reserved", 0, 4),
1424 BitField("send_battery_level_on_startup", 0, 1),
1425 BitField("battery_level_reporting", 0, 1),
1426 BitField("association_notification", 0, 1, end_tot_size=-1),
1427 ByteField("path_loss_threshold", 0),
1428 ]
1429
1430
1431class EIR_Appearance(EIR_Element):
1432 name = "EIR_Appearance"
1433 fields_desc = [
1434 BitEnumField('category', 0, 10, tot_size=-2, enum={
1435 0x000: 'Unknown',
1436 0x001: 'Phone',
1437 0x002: 'Computer',
1438 0x003: 'Watch',
1439 0x004: 'Clock',
1440 0x005: 'Display',
1441 0x006: 'Remote Control',
1442 0x007: 'Eyeglasses',
1443 0x008: 'Tag',
1444 0x009: 'Keyring',
1445 0x00A: 'Media Player',
1446 0x00B: 'Barcode Scanner',
1447 0x00C: 'Thermometer',
1448 0x00D: 'Heart Rate Sensor',
1449 0x00E: 'Blood Pressure',
1450 0x00F: 'Human Interface Device',
1451 0x010: 'Glucose Meter',
1452 0x011: 'Running Walking Sensor',
1453 0x012: 'Cycling',
1454 0x013: 'Control Device',
1455 0x014: 'Network Device',
1456 0x015: 'Sensor',
1457 0x016: 'Light Fixtures',
1458 0x017: 'Fan',
1459 0x018: 'HVAC',
1460 0x019: 'Air Conditioning',
1461 0x01A: 'Humidifier',
1462 0x01B: 'Heating',
1463 0x01C: 'Access Control',
1464 0x01D: 'Motorized Device',
1465 0x01E: 'Power Device',
1466 0x01F: 'Light Source',
1467 0x020: 'Window Covering',
1468 0x021: 'Audio Sink',
1469 0x022: 'Audio Source',
1470 0x023: 'Motorized Vehicle',
1471 0x024: 'Domestic Appliance',
1472 0x025: 'Wearable Audio Device',
1473 0x026: 'Aircraft',
1474 0x027: 'AV Equipment',
1475 0x028: 'Display Equipment',
1476 0x029: 'Hearing aid',
1477 0x02A: 'Gaming',
1478 0x02B: 'Signage',
1479 0x031: 'Pulse Oximeter',
1480 0x032: 'Weight Scale',
1481 0x033: 'Personal Mobility Device',
1482 0x034: 'Continuous Glucose Monitor',
1483 0x035: 'Insulin Pump',
1484 0x036: 'Medication Delivery',
1485 0x037: 'Spirometer',
1486 0x051: 'Outdoor Sports Activity'
1487 }),
1488 XBitField('subcategory', 0, 6, end_tot_size=-2)
1489 ]
1490
1491 @property
1492 def appearance(self):
1493 return (self.category << 6) + self.subcategory
1494
1495
1496class EIR_ServiceData32BitUUID(EIR_Element):
1497 name = 'EIR Service Data - 32-bit UUID'
1498 fields_desc = [
1499 XLEIntField('svc_uuid', 0),
1500 ]
1501
1502 def extract_padding(self, s):
1503 # Needed to end each EIR_Element packet and make PacketListField work.
1504 plen = EIR_Element.length_from(self) - 4
1505 return s[:plen], s[plen:]
1506
1507
1508class EIR_ServiceData128BitUUID(EIR_Element):
1509 name = 'EIR Service Data - 128-bit UUID'
1510 fields_desc = [
1511 UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV)
1512 ]
1513
1514 def extract_padding(self, s):
1515 # Needed to end each EIR_Element packet and make PacketListField work.
1516 plen = EIR_Element.length_from(self) - 16
1517 return s[:plen], s[plen:]
1518
1519
1520class EIR_URI(EIR_Element):
1521 name = 'EIR URI'
1522 fields_desc = [
1523 ByteEnumField('scheme', 0, {
1524 0x01: '',
1525 0x02: 'aaa:',
1526 0x03: 'aaas:',
1527 0x04: 'about:',
1528 0x05: 'acap:',
1529 0x06: 'acct:',
1530 0x07: 'cap:',
1531 0x08: 'cid:',
1532 0x09: 'coap:',
1533 0x0A: 'coaps:',
1534 0x0B: 'crid:',
1535 0x0C: 'data:',
1536 0x0D: 'dav:',
1537 0x0E: 'dict:',
1538 0x0F: 'dns:',
1539 0x10: 'file:',
1540 0x11: 'ftp:',
1541 0x12: 'geo:',
1542 0x13: 'go:',
1543 0x14: 'gopher:',
1544 0x15: 'h323:',
1545 0x16: 'http:',
1546 0x17: 'https:',
1547 0x18: 'iax:',
1548 0x19: 'icap:',
1549 0x1A: 'im:',
1550 0x1B: 'imap:',
1551 0x1C: 'info:',
1552 0x1D: 'ipp:',
1553 0x1E: 'ipps:',
1554 0x1F: 'iris:',
1555 0x20: 'iris.beep:',
1556 0x21: 'iris.xpc:',
1557 0x22: 'iris.xpcs:',
1558 0x23: 'iris.lwz:',
1559 0x24: 'jabber:',
1560 0x25: 'ldap:',
1561 0x26: 'mailto:',
1562 0x27: 'mid:',
1563 0x28: 'msrp:',
1564 0x29: 'msrps:',
1565 0x2A: 'mtqp:',
1566 0x2B: 'mupdate:',
1567 0x2C: 'news:',
1568 0x2D: 'nfs:',
1569 0x2E: 'ni:',
1570 0x2F: 'nih:',
1571 0x30: 'nntp:',
1572 0x31: 'opaquelocktoken:',
1573 0x32: 'pop:',
1574 0x33: 'pres:',
1575 0x34: 'reload:',
1576 0x35: 'rtsp:',
1577 0x36: 'rtsps:',
1578 0x37: 'rtspu:',
1579 0x38: 'service:',
1580 0x39: 'session:',
1581 0x3A: 'shttp:',
1582 0x3B: 'sieve:',
1583 0x3C: 'sip:',
1584 0x3D: 'sips:',
1585 0x3E: 'sms:',
1586 0x3F: 'snmp:',
1587 0x40: 'soap.beep:',
1588 0x41: 'soap.beeps:',
1589 0x42: 'stun:',
1590 0x43: 'stuns:',
1591 0x44: 'tag:',
1592 0x45: 'tel:',
1593 0x46: 'telnet:',
1594 0x47: 'tftp:',
1595 0x48: 'thismessage:',
1596 0x49: 'tn3270:',
1597 0x4A: 'tip:',
1598 0x4B: 'turn:',
1599 0x4C: 'turns:',
1600 0x4D: 'tv:',
1601 0x4E: 'urn:',
1602 0x4F: 'vemmi:',
1603 0x50: 'ws:',
1604 0x51: 'wss:',
1605 0x52: 'xcon:',
1606 0x53: 'xconuserid:',
1607 0x54: 'xmlrpc.beep:',
1608 0x55: 'xmlrpc.beeps:',
1609 0x56: 'xmpp:',
1610 0x57: 'z39.50r:',
1611 0x58: 'z39.50s:',
1612 0x59: 'acr:',
1613 0x5A: 'adiumxtra:',
1614 0x5B: 'afp:',
1615 0x5C: 'afs:',
1616 0x5D: 'aim:',
1617 0x5E: 'apt:',
1618 0x5F: 'attachment:',
1619 0x60: 'aw:',
1620 0x61: 'barion:',
1621 0x62: 'beshare:',
1622 0x63: 'bitcoin:',
1623 0x64: 'bolo:',
1624 0x65: 'callto:',
1625 0x66: 'chrome:',
1626 0x67: 'chromeextension:',
1627 0x68: 'comeventbriteattendee:',
1628 0x69: 'content:',
1629 0x6A: 'cvs:',
1630 0x6B: 'dlnaplaysingle:',
1631 0x6C: 'dlnaplaycontainer:',
1632 0x6D: 'dtn:',
1633 0x6E: 'dvb:',
1634 0x6F: 'ed2k:',
1635 0x70: 'facetime:',
1636 0x71: 'feed:',
1637 0x72: 'feedready:',
1638 0x73: 'finger:',
1639 0x74: 'fish:',
1640 0x75: 'gg:',
1641 0x76: 'git:',
1642 0x77: 'gizmoproject:',
1643 0x78: 'gtalk:',
1644 0x79: 'ham:',
1645 0x7A: 'hcp:',
1646 0x7B: 'icon:',
1647 0x7C: 'ipn:',
1648 0x7D: 'irc:',
1649 0x7E: 'irc6:',
1650 0x7F: 'ircs:',
1651 0x80: 'itms:',
1652 0x81: 'jar:',
1653 0x82: 'jms:',
1654 0x83: 'keyparc:',
1655 0x84: 'lastfm:',
1656 0x85: 'ldaps:',
1657 0x86: 'magnet:',
1658 0x87: 'maps:',
1659 0x88: 'market:',
1660 0x89: 'message:',
1661 0x8A: 'mms:',
1662 0x8B: 'mshelp:',
1663 0x8C: 'mssettingspower:',
1664 0x8D: 'msnim:',
1665 0x8E: 'mumble:',
1666 0x8F: 'mvn:',
1667 0x90: 'notes:',
1668 0x91: 'oid:',
1669 0x92: 'palm:',
1670 0x93: 'paparazzi:',
1671 0x94: 'pkcs11:',
1672 0x95: 'platform:',
1673 0x96: 'proxy:',
1674 0x97: 'psyc:',
1675 0x98: 'query:',
1676 0x99: 'res:',
1677 0x9A: 'resource:',
1678 0x9B: 'rmi:',
1679 0x9C: 'rsync:',
1680 0x9D: 'rtmfp:',
1681 0x9E: 'rtmp:',
1682 0x9F: 'secondlife:',
1683 0xA0: 'sftp:',
1684 0xA1: 'sgn:',
1685 0xA2: 'skype:',
1686 0xA3: 'smb:',
1687 0xA4: 'smtp:',
1688 0xA5: 'soldat:',
1689 0xA6: 'spotify:',
1690 0xA7: 'ssh:',
1691 0xA8: 'steam:',
1692 0xA9: 'submit:',
1693 0xAA: 'svn:',
1694 0xAB: 'teamspeak:',
1695 0xAC: 'teliaeid:',
1696 0xAD: 'things:',
1697 0xAE: 'udp:',
1698 0xAF: 'unreal:',
1699 0xB0: 'ut2004:',
1700 0xB1: 'ventrilo:',
1701 0xB2: 'viewsource:',
1702 0xB3: 'webcal:',
1703 0xB4: 'wtai:',
1704 0xB5: 'wyciwyg:',
1705 0xB6: 'xfire:',
1706 0xB7: 'xri:',
1707 0xB8: 'ymsgr:',
1708 0xB9: 'example:',
1709 0xBA: 'mssettingscloudstorage:'
1710 }),
1711 StrLenField('uri_hier_part', None, length_from=EIR_Element.length_from)
1712 ]
1713
1714 @property
1715 def uri(self):
1716 return EIR_URI.scheme.i2s[self.scheme] + self.uri_hier_part.decode('utf-8')
1717
1718
1719class HCI_Command_Hdr(Packet):
1720 name = "HCI Command header"
1721 fields_desc = [XBitField("ogf", 0, 6, tot_size=-2),
1722 XBitField("ocf", 0, 10, end_tot_size=-2),
1723 LenField("len", None, fmt="B"), ]
1724
1725 def answers(self, other):
1726 return False
1727
1728 @property
1729 def opcode(self):
1730 return (self.ogf << 10) + self.ocf
1731
1732 def post_build(self, p, pay):
1733 p += pay
1734 if self.len is None:
1735 p = p[:2] + struct.pack("B", len(pay)) + p[3:]
1736 return p
1737
1738
1739# BUETOOTH CORE SPECIFICATION 5.4 | Vol 3, Part C
1740# 8 EXTENDED INQUIRY RESPONSE
1741
1742class HCI_Extended_Inquiry_Response(Packet):
1743 fields_desc = [
1744 PadField(
1745 PacketListField(
1746 "eir_data", [],
1747 next_cls_cb=lambda *args: (
1748 (not args[2] or args[2].len != 0) and EIR_Hdr or conf.raw_layer
1749 )
1750 ),
1751 align=31, padwith=b"\0",
1752 ),
1753 ]
1754
1755
1756# BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
1757# 7 HCI COMMANDS AND EVENTS
1758# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
1759
1760class HCI_Cmd_Inquiry(Packet):
1761 """
1762 7.1.1 Inquiry command
1763 """
1764 name = "HCI_Inquiry"
1765 fields_desc = [XLE3BytesField("lap", 0x9E8B33),
1766 ByteField("inquiry_length", 0),
1767 ByteField("num_responses", 0)]
1768
1769
1770class HCI_Cmd_Inquiry_Cancel(Packet):
1771 """
1772 7.1.2 Inquiry Cancel command
1773 """
1774 name = "HCI_Inquiry_Cancel"
1775
1776
1777class HCI_Cmd_Periodic_Inquiry_Mode(Packet):
1778 """
1779 7.1.3 Periodic Inquiry Mode command
1780 """
1781 name = "HCI_Periodic_Inquiry_Mode"
1782 fields_desc = [LEShortField("max_period_length", 0x0003),
1783 LEShortField("min_period_length", 0x0002),
1784 XLE3BytesField("lap", 0x9E8B33),
1785 ByteField("inquiry_length", 0),
1786 ByteField("num_responses", 0)]
1787
1788
1789class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet):
1790 """
1791 7.1.4 Exit Periodic Inquiry Mode command
1792 """
1793 name = "HCI_Exit_Periodic_Inquiry_Mode"
1794
1795
1796class HCI_Cmd_Create_Connection(Packet):
1797 """
1798 7.1.5 Create Connection command
1799 """
1800 name = "HCI_Create_Connection"
1801 fields_desc = [LEMACField("bd_addr", None),
1802 LEShortField("packet_type", 0xcc18),
1803 ByteField("page_scan_repetition_mode", 0x02),
1804 ByteField("reserved", 0x0),
1805 LEShortField("clock_offset", 0x0),
1806 ByteField("allow_role_switch", 0x1), ]
1807
1808
1809class HCI_Cmd_Disconnect(Packet):
1810 """
1811 7.1.6 Disconnect command
1812 """
1813 name = "HCI_Disconnect"
1814 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
1815 fields_desc = [XLEShortField("connection_handle", 0),
1816 ByteField("reason", 0x13), ]
1817
1818
1819class HCI_Cmd_Create_Connection_Cancel(Packet):
1820 """
1821 7.1.7 Create Connection Cancel command
1822 """
1823 name = "HCI_Create_Connection_Cancel"
1824 fields_desc = [LEMACField("bd_addr", None), ]
1825
1826
1827class HCI_Cmd_Accept_Connection_Request(Packet):
1828 """
1829 7.1.8 Accept Connection Request command
1830 """
1831 name = "HCI_Accept_Connection_Request"
1832 fields_desc = [LEMACField("bd_addr", None),
1833 ByteField("role", 0x1), ]
1834
1835
1836class HCI_Cmd_Reject_Connection_Response(Packet):
1837 """
1838 7.1.9 Reject Connection Request command
1839 """
1840 name = "HCI_Reject_Connection_Response"
1841 fields_desc = [LEMACField("bd_addr", None),
1842 ByteField("reason", 0x1), ]
1843
1844
1845class HCI_Cmd_Link_Key_Request_Reply(Packet):
1846 """
1847 7.1.10 Link Key Request Reply command
1848 """
1849 name = "HCI_Link_Key_Request_Reply"
1850 fields_desc = [LEMACField("bd_addr", None),
1851 NBytesField("link_key", None, 16), ]
1852
1853
1854class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet):
1855 """
1856 7.1.11 Link Key Request Negative Reply command
1857 """
1858 name = "HCI_Link_Key_Request_Negative_Reply"
1859 fields_desc = [LEMACField("bd_addr", None), ]
1860
1861
1862class HCI_Cmd_PIN_Code_Request_Reply(Packet):
1863 """
1864 7.1.12 PIN Code Request Reply command
1865 """
1866 name = "HCI_PIN_Code_Request_Reply"
1867 fields_desc = [LEMACField("bd_addr", None),
1868 ByteField("pin_code_length", 7),
1869 NBytesField("pin_code", b"\x00" * 16, sz=16), ]
1870
1871
1872class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet):
1873 """
1874 7.1.13 PIN Code Request Negative Reply command
1875 """
1876 name = "HCI_PIN_Code_Request_Negative_Reply"
1877 fields_desc = [LEMACField("bd_addr", None), ]
1878
1879
1880class HCI_Cmd_Change_Connection_Packet_Type(Packet):
1881 """
1882 7.1.14 Change Connection Packet Type command
1883 """
1884 name = "HCI_Cmd_Change_Connection_Packet_Type"
1885 fields_desc = [XLEShortField("connection_handle", None),
1886 LEShortField("packet_type", 0), ]
1887
1888
1889class HCI_Cmd_Authentication_Requested(Packet):
1890 """
1891 7.1.15 Authentication Requested command
1892 """
1893 name = "HCI_Authentication_Requested"
1894 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
1895 fields_desc = [LEShortField("connection_handle", 0)]
1896
1897
1898class HCI_Cmd_Set_Connection_Encryption(Packet):
1899 """
1900 7.1.16 Set Connection Encryption command
1901 """
1902 name = "HCI_Set_Connection_Encryption"
1903 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
1904 fields_desc = [LEShortField("connection_handle", 0),
1905 ByteField("encryption_enable", 0)]
1906
1907
1908class HCI_Cmd_Change_Connection_Link_Key(Packet):
1909 """
1910 7.1.17 Change Connection Link Key command
1911 """
1912 name = "HCI_Change_Connection_Link_Key"
1913 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
1914 fields_desc = [LEShortField("connection_handle", 0), ]
1915
1916
1917class HCI_Cmd_Link_Key_Selection(Packet):
1918 """
1919 7.1.18 Change Connection Link Key command
1920 """
1921 name = "HCI_Cmd_Link_Key_Selection"
1922 fields_desc = [ByteEnumField("handle", 0, {0: "Use semi-permanent Link Keys",
1923 1: "Use Temporary Link Key", }), ]
1924
1925
1926class HCI_Cmd_Remote_Name_Request(Packet):
1927 """
1928 7.1.19 Remote Name Request command
1929 """
1930 name = "HCI_Remote_Name_Request"
1931 fields_desc = [LEMACField("bd_addr", None),
1932 ByteField("page_scan_repetition_mode", 0x02),
1933 ByteField("reserved", 0x0),
1934 LEShortField("clock_offset", 0x0), ]
1935
1936
1937class HCI_Cmd_Remote_Name_Request_Cancel(Packet):
1938 """
1939 7.1.20 Remote Name Request Cancel command
1940 """
1941 name = "HCI_Remote_Name_Request_Cancel"
1942 fields_desc = [LEMACField("bd_addr", None), ]
1943
1944
1945class HCI_Cmd_Read_Remote_Supported_Features(Packet):
1946 """
1947 7.1.21 Read Remote Supported Features command
1948 """
1949 name = "HCI_Read_Remote_Supported_Features"
1950 fields_desc = [LEShortField("connection_handle", None), ]
1951
1952
1953class HCI_Cmd_Read_Remote_Extended_Features(Packet):
1954 """
1955 7.1.22 Read Remote Extended Features command
1956 """
1957 name = "HCI_Read_Remote_Supported_Features"
1958 fields_desc = [LEShortField("connection_handle", None),
1959 ByteField("page_number", None), ]
1960
1961
1962class HCI_Cmd_IO_Capability_Request_Reply(Packet):
1963 """
1964 7.1.29 IO Capability Request Reply command
1965 """
1966 name = "HCI_Read_Remote_Supported_Features"
1967 fields_desc = [LEMACField("bd_addr", None),
1968 ByteEnumField("io_capability", None, {0x00: "DisplayOnly",
1969 0x01: "DisplayYesNo",
1970 0x02: "KeyboardOnly",
1971 0x03: "NoInputNoOutput", }),
1972 ByteEnumField("oob_data_present", None, {0x00: "Not Present",
1973 0x01: "P-192",
1974 0x02: "P-256",
1975 0x03: "P-192 + P-256", }),
1976 ByteEnumField("authentication_requirement", None,
1977 {0x00: "MITM Not Required",
1978 0x01: "MITM Required, No Bonding",
1979 0x02: "MITM Not Required + Dedicated Pairing",
1980 0x03: "MITM Required + Dedicated Pairing",
1981 0x04: "MITM Not Required, General Bonding",
1982 0x05: "MITM Required + General Bonding"}), ]
1983
1984
1985class HCI_Cmd_User_Confirmation_Request_Reply(Packet):
1986 """
1987 7.1.30 User Confirmation Request Reply command
1988 """
1989 name = "HCI_User_Confirmation_Request_Reply"
1990 fields_desc = [LEMACField("bd_addr", None), ]
1991
1992
1993class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet):
1994 """
1995 7.1.31 User Confirmation Request Negative Reply command
1996 """
1997 name = "HCI_User_Confirmation_Request_Negative_Reply"
1998 fields_desc = [LEMACField("bd_addr", None), ]
1999
2000
2001class HCI_Cmd_User_Passkey_Request_Reply(Packet):
2002 """
2003 7.1.32 User Passkey Request Reply command
2004 """
2005 name = "HCI_User_Passkey_Request_Reply"
2006 fields_desc = [LEMACField("bd_addr", None),
2007 LEIntField("numeric_value", None), ]
2008
2009
2010class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet):
2011 """
2012 7.1.33 User Passkey Request Negative Reply command
2013 """
2014 name = "HCI_User_Passkey_Request_Negative_Reply"
2015 fields_desc = [LEMACField("bd_addr", None), ]
2016
2017
2018class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet):
2019 """
2020 7.1.34 Remote OOB Data Request Reply command
2021 """
2022 name = "HCI_Remote_OOB_Data_Request_Reply"
2023 fields_desc = [LEMACField("bd_addr", None),
2024 NBytesField("C", b"\x00" * 16, sz=16),
2025 NBytesField("R", b"\x00" * 16, sz=16), ]
2026
2027
2028class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet):
2029 """
2030 7.1.35 Remote OOB Data Request Negative Reply command
2031 """
2032 name = "HCI_Remote_OOB_Data_Request_Negative_Reply"
2033 fields_desc = [LEMACField("bd_addr", None), ]
2034
2035
2036# 7.2 Link Policy commands, the OGF is defined as 0x02
2037
2038class HCI_Cmd_Hold_Mode(Packet):
2039 name = "HCI_Hold_Mode"
2040 fields_desc = [LEShortField("connection_handle", 0),
2041 LEShortField("hold_mode_max_interval", 0x0002),
2042 LEShortField("hold_mode_min_interval", 0x0002), ]
2043
2044
2045# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
2046
2047class HCI_Cmd_Set_Event_Mask(Packet):
2048 """
2049 7.3.1 Set Event Mask command
2050 """
2051 name = "HCI_Set_Event_Mask"
2052 fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501
2053
2054
2055class HCI_Cmd_Reset(Packet):
2056 """
2057 7.3.2 Reset command
2058 """
2059 name = "HCI_Reset"
2060
2061
2062class HCI_Cmd_Set_Event_Filter(Packet):
2063 """
2064 7.3.3 Set Event Filter command
2065 """
2066 name = "HCI_Set_Event_Filter"
2067 fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ]
2068
2069
2070class HCI_Cmd_Write_Local_Name(Packet):
2071 """
2072 7.3.11 Write Local Name command
2073 """
2074 name = "HCI_Write_Local_Name"
2075 fields_desc = [StrFixedLenField('name', '', length=248)]
2076
2077
2078class HCI_Cmd_Read_Local_Name(Packet):
2079 """
2080 7.3.12 Read Local Name command
2081 """
2082 name = "HCI_Read_Local_Name"
2083
2084
2085class HCI_Cmd_Write_Connect_Accept_Timeout(Packet):
2086 name = "HCI_Write_Connection_Accept_Timeout"
2087 fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec
2088
2089
2090class HCI_Cmd_Write_Extended_Inquiry_Response(Packet):
2091 name = "HCI_Write_Extended_Inquiry_Response"
2092 fields_desc = [ByteField("fec_required", 0),
2093 HCI_Extended_Inquiry_Response]
2094
2095
2096class HCI_Cmd_Read_LE_Host_Support(Packet):
2097 name = "HCI_Read_LE_Host_Support"
2098
2099
2100class HCI_Cmd_Write_LE_Host_Support(Packet):
2101 name = "HCI_Write_LE_Host_Support"
2102 fields_desc = [ByteField("supported", 1),
2103 ByteField("unused", 1), ]
2104
2105
2106# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
2107
2108class HCI_Cmd_Read_Local_Version_Information(Packet):
2109 """
2110 7.4.1 Read Local Version Information command
2111 """
2112 name = "HCI_Read_Local_Version_Information"
2113
2114
2115class HCI_Cmd_Read_Local_Extended_Features(Packet):
2116 """
2117 7.4.4 Read Local Extended Features command
2118 """
2119 name = "HCI_Read_Local_Extended_Features"
2120 fields_desc = [ByteField("page_number", 0)]
2121
2122
2123class HCI_Cmd_Read_BD_Addr(Packet):
2124 """
2125 7.4.6 Read BD_ADDR command
2126 """
2127 name = "HCI_Read_BD_ADDR"
2128
2129
2130# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
2131
2132class HCI_Cmd_Read_Link_Quality(Packet):
2133 name = "HCI_Read_Link_Quality"
2134 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2135 fields_desc = [LEShortField("connection_handle", 0)]
2136
2137
2138class HCI_Cmd_Read_RSSI(Packet):
2139 name = "HCI_Read_RSSI"
2140 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2141 fields_desc = [LEShortField("connection_handle", 0)]
2142
2143
2144# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
2145
2146class HCI_Cmd_Read_Loopback_Mode(Packet):
2147 name = "HCI_Read_Loopback_Mode"
2148
2149
2150class HCI_Cmd_Write_Loopback_Mode(Packet):
2151 name = "HCI_Write_Loopback_Mode"
2152 fields_desc = [ByteEnumField("loopback_mode", 0,
2153 {0: "no loopback",
2154 1: "enable local loopback",
2155 2: "enable remote loopback"})]
2156
2157
2158# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
2159
2160class HCI_Cmd_LE_Set_Event_Mask(Packet):
2161 name = 'HCI_LE_Set_Event_Mask'
2162 fields_desc = [StrFixedLenField('mask', b'\xff\xff\xff\xff\xff\x1f\x00\x00', 8)]
2163
2164
2165class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet):
2166 name = "HCI_LE_Read_Buffer_Size [v1]"
2167
2168
2169class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet):
2170 name = "HCI_LE_Read_Buffer_Size [v2]"
2171
2172
2173class HCI_Cmd_LE_Read_Local_Supported_Features(Packet):
2174 name = "HCI_LE_Read_Local_Supported_Features"
2175
2176
2177class HCI_Cmd_LE_Set_Random_Address(Packet):
2178 name = "HCI_LE_Set_Random_Address"
2179 fields_desc = [LEMACField("addr", None)]
2180 deprecated_fields = {"address": ("addr", "2.7.0")}
2181
2182
2183class HCI_Cmd_LE_Set_Advertising_Parameters(Packet):
2184 name = "HCI_LE_Set_Advertising_Parameters"
2185 fields_desc = [LEShortField("interval_min", 0x0800),
2186 LEShortField("interval_max", 0x0800),
2187 ByteEnumField("adv_type", 0, {
2188 0: "ADV_IND",
2189 1: "ADV_DIRECT_IND",
2190 2: "ADV_SCAN_IND",
2191 3: "ADV_NONCONN_IND",
2192 4: "ADV_DIRECT_IND_LOW"}),
2193 ByteEnumField("own_addr_type", 0, {
2194 0: "public",
2195 1: "random"}),
2196 ByteEnumField("peer_addr_type", 0, {
2197 0: "public",
2198 1: "random"}),
2199 LEMACField("peer_addr", None),
2200 ByteField("channel_map", 7),
2201 ByteEnumField("filter_policy", 0, {
2202 0: "all:all",
2203 1: "connect:all scan:whitelist",
2204 2: "connect:whitelist scan:all",
2205 3: "all:whitelist"}), ]
2206 deprecated_fields = {
2207 "oatype": ("own_addr_type", "2.7.0"),
2208 "datype": ("peer_addr_type", "2.7.0"),
2209 "daddr": ("peer_addr", "2.7.0"),
2210 }
2211
2212
2213class HCI_Cmd_LE_Set_Extended_Advertising_Parameters(Packet):
2214 name = 'HCI_LE_Set_Extended_Advertising_Parameters'
2215 fields_desc = [ByteField('handle', 0),
2216 LEShortField('properties', 19),
2217 LEThreeBytesField('pri_interval_min', 160),
2218 LEThreeBytesField('pri_interval_max', 160),
2219 ByteField('pri_channel_map', 7),
2220 ByteEnumField('own_addr_type', 0, {
2221 0: 'public',
2222 1: 'random',
2223 2: 'rpa_pub',
2224 3: 'rpa_rand'}),
2225 ByteEnumField('peer_addr_type', 0, {
2226 0: 'public',
2227 1: 'random',
2228 2: 'rpa_pub',
2229 3: 'rpa_rand'}),
2230 LEMACField('peer_addr', None),
2231 ByteEnumField("filter_policy", 0, {
2232 0: "all:all",
2233 1: "connect:all scan:whitelist",
2234 2: "connect:whitelist scan:all",
2235 3: "all:whitelist"}),
2236 SignedByteField('tx_power', 127),
2237 ByteEnumField('pri_phy', 1, {1: '1M', 3: 'Coded'}),
2238 ByteField('sec_max_skip', 0),
2239 ByteEnumField('sec_phy', 1, {1: '1M', 2: '2M', 3: 'Coded'}),
2240 ByteField('sid', 0),
2241 ByteField('scan_req_notify_enable', 0)]
2242
2243
2244class HCI_Cmd_LE_Set_Advertising_Set_Random_Address(Packet):
2245 name = 'HCI_LE_Set_Advertising_Set_Random_Address'
2246 fields_desc = [ByteField('handle', 0), LEMACField('addr', None)]
2247
2248
2249class HCI_Cmd_LE_Set_Advertising_Data(Packet):
2250 name = "HCI_LE_Set_Advertising_Data"
2251 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
2252 PadField(
2253 PacketListField("data", [], EIR_Hdr,
2254 length_from=lambda pkt: pkt.len),
2255 align=31, padwith=b"\0"), ]
2256
2257
2258class HCI_Cmd_LE_Set_Extended_Advertising_Data(Packet):
2259 name = 'HCI_LE_Set_Extended_Advertising_Data'
2260 fields_desc = [ByteField('handle', 0),
2261 ByteEnumField('operation', 3, {
2262 0: 'intermediate_frag',
2263 1: 'first_frag',
2264 2: 'last_frag',
2265 3: 'complete',
2266 4: 'unchanged_data'}),
2267 ByteEnumField('frag_pref', 1, {0: 'allow_frag', 1: 'no_frag'}),
2268 FieldLenField('len', None, length_of='data', fmt='B'),
2269 PacketListField('data', [], EIR_Hdr, length_from=lambda pkt: pkt.len)] # noqa: E501
2270
2271
2272class HCI_Cmd_LE_Set_Scan_Response_Data(Packet):
2273 name = "HCI_LE_Set_Scan_Response_Data"
2274 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
2275 StrLenField("data", "", length_from=lambda pkt: pkt.len), ]
2276
2277
2278class HCI_Cmd_LE_Set_Advertise_Enable(Packet):
2279 name = "HCI_LE_Set_Advertising_Enable"
2280 fields_desc = [ByteField("enable", 0)]
2281
2282
2283class Extended_Advertise_Set(Packet):
2284 name = 'Extended Advertising Set'
2285 fields_desc = [ByteField('handle', 0),
2286 LEShortField('duration', 0),
2287 ByteField('max_events', 0)]
2288
2289 def extract_padding(self, s):
2290 return b'', s
2291
2292
2293class HCI_Cmd_LE_Set_Extended_Advertise_Enable(Packet):
2294 name = 'HCI_LE_Set_Extended_Advertising_Enable'
2295 fields_desc = [ByteEnumField('enable', 1, {0: 'disable', 1: 'enable'}),
2296 FieldLenField('num_sets', None, count_of='sets', fmt='B'),
2297 PacketListField('sets', [], Extended_Advertise_Set, count_from=lambda pkt: pkt.num_sets)] # noqa: E501
2298
2299
2300class HCI_Cmd_LE_Set_Scan_Parameters(Packet):
2301 name = "HCI_LE_Set_Scan_Parameters"
2302 fields_desc = [ByteEnumField("type", 0, {0: "passive", 1: "active"}),
2303 XLEShortField("interval", 16),
2304 XLEShortField("window", 16),
2305 ByteEnumField("addr_type", 0, {
2306 0: "public",
2307 1: "random",
2308 2: "rpa (pub)",
2309 3: "rpa (random)"}),
2310 ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})]
2311 deprecated_fields = {"atype": ("addr_type", "2.7.0")}
2312
2313
2314class HCI_Cmd_LE_Set_Extended_Scan_Parameters(Packet):
2315 name = 'HCI_LE_Set_Extended_Scan_Parameters'
2316 fields_desc = [
2317 ByteEnumField('own_address_type', 0, {
2318 0: 'public',
2319 1: 'random',
2320 2: 'rpa_pub',
2321 3: 'rpa_rand'}),
2322 ByteEnumField('scanning_filter_policy', 0, {
2323 0: 'basic',
2324 1: 'whitelist',
2325 2: 'basic_rpa',
2326 3: 'whitelist_rpa'}),
2327 ByteField('scanning_phys', 1),
2328 ConditionalField(ByteEnumField('scan_type_1m', 1, {
2329 0: 'passive',
2330 1: 'active'}), lambda pkt: pkt.scanning_phys & 1),
2331 ConditionalField(LEShortField('scan_interval_1m', 16),
2332 lambda pkt: pkt.scanning_phys & 1),
2333 ConditionalField(LEShortField('scan_window_1m', 16),
2334 lambda pkt: pkt.scanning_phys & 1),
2335 ConditionalField(ByteEnumField('scan_type_2m', 1, {
2336 0: 'passive',
2337 1: 'active'}), lambda pkt: pkt.scanning_phys & 2),
2338 ConditionalField(LEShortField('scan_interval_2m', 16),
2339 lambda pkt: pkt.scanning_phys & 2),
2340 ConditionalField(LEShortField('scan_window_2m', 16),
2341 lambda pkt: pkt.scanning_phys & 2),
2342 ConditionalField(ByteEnumField('scan_type_coded', 1, {
2343 0: 'passive',
2344 1: 'active'}), lambda pkt: pkt.scanning_phys & 4),
2345 ConditionalField(LEShortField('scan_interval_coded', 16),
2346 lambda pkt: pkt.scanning_phys & 4),
2347 ConditionalField(LEShortField('scan_window_coded', 16),
2348 lambda pkt: pkt.scanning_phys & 4)]
2349
2350
2351class HCI_Cmd_LE_Set_Scan_Enable(Packet):
2352 name = "HCI_LE_Set_Scan_Enable"
2353 fields_desc = [ByteField("enable", 1),
2354 ByteField("filter_dups", 1), ]
2355
2356
2357class HCI_Cmd_LE_Set_Extended_Scan_Enable(Packet):
2358 name = 'HCI_LE_Set_Extended_Scan_Enable'
2359 fields_desc = [ByteEnumField('enable', 1, {0: 'disabled', 1: 'enabled'}),
2360 ByteEnumField('filter_dups', 1, {
2361 0: 'disabled',
2362 1: 'enabled',
2363 2: 'reset_period'}),
2364 LEShortField('duration', 500),
2365 LEShortField('period', 0)]
2366
2367
2368class HCI_Cmd_LE_Create_Connection(Packet):
2369 name = "HCI_LE_Create_Connection"
2370 fields_desc = [LEShortField("interval", 96),
2371 LEShortField("window", 48),
2372 ByteEnumField("filter", 0, {0: "address"}),
2373 ByteEnumField("peer_addr_type", 0, {0: "public", 1: "random"}),
2374 LEMACField("peer_addr", None),
2375 ByteEnumField("own_addr_type", 0, {0: "public", 1: "random"}),
2376 LEShortField("min_interval", 40),
2377 LEShortField("max_interval", 56),
2378 LEShortField("latency", 0),
2379 LEShortField("timeout", 42),
2380 LEShortField("min_ce", 0),
2381 LEShortField("max_ce", 0), ]
2382 deprecated_fields = {
2383 "patype": ("peer_addr_type", "2.7.0"),
2384 "paddr": ("peer_addr", "2.7.0"),
2385 "atype": ("own_addr_type", "2.7.0"),
2386 }
2387
2388
2389class HCI_Cmd_LE_Extended_Create_Connection(Packet):
2390 name = 'HCI_LE_Extended_Create_Connection'
2391 fields_desc = [ByteEnumField('filter_policy', 0, {0: 'peer_addr', 1: 'accept_list'}), # noqa: E501
2392 ByteEnumField('address_type', 0, {
2393 0: 'public',
2394 1: 'random',
2395 2: 'rpa_pub',
2396 3: 'rpa_rand'}),
2397 ByteEnumField('peer_addr_type', 0, {
2398 0: 'public',
2399 1: 'random',
2400 2: 'rpa_pub',
2401 3: 'rpa_rand'}),
2402 LEMACField('peer_addr', None),
2403 ByteField('phys', 1),
2404 ConditionalField(LEShortField('interval_1m', 96),
2405 lambda pkt: pkt.phys & 1),
2406 ConditionalField(LEShortField('window_1m', 96),
2407 lambda pkt: pkt.phys & 1),
2408 ConditionalField(LEShortField('min_interval_1m', 40),
2409 lambda pkt: pkt.phys & 1),
2410 ConditionalField(LEShortField('max_interval_1m', 56),
2411 lambda pkt: pkt.phys & 1),
2412 ConditionalField(LEShortField('latency_1m', 0),
2413 lambda pkt: pkt.phys & 1),
2414 ConditionalField(LEShortField('timeout_1m', 42),
2415 lambda pkt: pkt.phys & 1),
2416 ConditionalField(LEShortField('min_ce_1m', 0),
2417 lambda pkt: pkt.phys & 1),
2418 ConditionalField(LEShortField('max_ce_1m', 0),
2419 lambda pkt: pkt.phys & 1),
2420 ConditionalField(LEShortField('interval_2m', 96),
2421 lambda pkt: pkt.phys & 2),
2422 ConditionalField(LEShortField('window_2m', 96),
2423 lambda pkt: pkt.phys & 2),
2424 ConditionalField(LEShortField('min_interval_2m', 40),
2425 lambda pkt: pkt.phys & 2),
2426 ConditionalField(LEShortField('max_interval_2m', 56),
2427 lambda pkt: pkt.phys & 2),
2428 ConditionalField(LEShortField('latency_2m', 0),
2429 lambda pkt: pkt.phys & 2),
2430 ConditionalField(LEShortField('timeout_2m', 42),
2431 lambda pkt: pkt.phys & 2),
2432 ConditionalField(LEShortField('min_ce_2m', 0),
2433 lambda pkt: pkt.phys & 2),
2434 ConditionalField(LEShortField('max_ce_2m', 0),
2435 lambda pkt: pkt.phys & 2),
2436 ConditionalField(LEShortField('interval_coded', 96),
2437 lambda pkt: pkt.phys & 4),
2438 ConditionalField(LEShortField('window_coded', 96),
2439 lambda pkt: pkt.phys & 4),
2440 ConditionalField(LEShortField('min_interval_coded', 40),
2441 lambda pkt: pkt.phys & 4),
2442 ConditionalField(LEShortField('max_interval_coded', 56),
2443 lambda pkt: pkt.phys & 4),
2444 ConditionalField(LEShortField('latency_coded', 0),
2445 lambda pkt: pkt.phys & 4),
2446 ConditionalField(LEShortField('timeout_coded', 42),
2447 lambda pkt: pkt.phys & 4),
2448 ConditionalField(LEShortField('min_ce_coded', 0),
2449 lambda pkt: pkt.phys & 4),
2450 ConditionalField(LEShortField('max_ce_coded', 0),
2451 lambda pkt: pkt.phys & 4)]
2452
2453
2454class HCI_Cmd_LE_Create_Connection_Cancel(Packet):
2455 name = "HCI_LE_Create_Connection_Cancel"
2456
2457
2458class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet):
2459 name = "HCI_LE_Read_Filter_Accept_List_Size"
2460
2461
2462class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet):
2463 name = "HCI_LE_Clear_Filter_Accept_List"
2464
2465
2466class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet):
2467 name = "HCI_LE_Add_Device_To_Filter_Accept_List"
2468 fields_desc = [ByteEnumField("addr_type", 0, {0: "public",
2469 1: "random",
2470 0xff: "anonymous"}),
2471 LEMACField("addr", None)]
2472
2473
2474class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501
2475 name = "HCI_LE_Remove_Device_From_Filter_Accept_List"
2476
2477
2478class HCI_Cmd_LE_Connection_Update(Packet):
2479 name = "HCI_LE_Connection_Update"
2480 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2481 fields_desc = [XLEShortField("connection_handle", 0),
2482 XLEShortField("min_interval", 0),
2483 XLEShortField("max_interval", 0),
2484 XLEShortField("latency", 0),
2485 XLEShortField("timeout", 0),
2486 LEShortField("min_ce", 0),
2487 LEShortField("max_ce", 0xffff), ]
2488
2489
2490class HCI_Cmd_LE_Read_Remote_Features(Packet):
2491 name = "HCI_LE_Read_Remote_Features"
2492 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2493 fields_desc = [LEShortField("connection_handle", 64)]
2494
2495
2496class HCI_Cmd_LE_Enable_Encryption(Packet):
2497 name = "HCI_LE_Enable_Encryption"
2498 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2499 fields_desc = [LEShortField("connection_handle", 0),
2500 StrFixedLenField("rand", None, 8),
2501 XLEShortField("ediv", 0),
2502 StrFixedLenField("ltk", b'\x00' * 16, 16), ]
2503
2504
2505class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet):
2506 name = "HCI_LE_Long_Term_Key_Request_Reply"
2507 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2508 fields_desc = [LEShortField("connection_handle", 0),
2509 StrFixedLenField("ltk", b'\x00' * 16, 16), ]
2510
2511
2512class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet):
2513 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply"
2514 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2515 fields_desc = [LEShortField("connection_handle", 0), ]
2516
2517
2518class HCI_Event_Hdr(Packet):
2519 name = "HCI Event header"
2520 fields_desc = [XByteField("code", 0),
2521 LenField("len", None, fmt="B"), ]
2522
2523 def answers(self, other):
2524 if HCI_Command_Hdr not in other:
2525 return False
2526
2527 # Delegate answers to event types
2528 return self.payload.answers(other)
2529
2530
2531class HCI_Event_Inquiry_Complete(Packet):
2532 """
2533 7.7.1 Inquiry Complete event
2534 """
2535 name = "HCI_Inquiry_Complete"
2536 fields_desc = [
2537 ByteEnumField('status', 0, _bluetooth_error_codes)
2538 ]
2539
2540
2541class HCI_Event_Inquiry_Result(Packet):
2542 """
2543 7.7.2 Inquiry Result event
2544 """
2545 name = "HCI_Inquiry_Result"
2546 fields_desc = [
2547 ByteField("num_response", 0x00),
2548 FieldListField("bd_addr", None, LEMACField("", None),
2549 count_from=lambda p: p.num_response),
2550 FieldListField("page_scan_repetition_mode", None,
2551 ByteField("page_scan_repetition_mode", 0),
2552 count_from=lambda p: p.num_response),
2553 FieldListField("reserved", None, LEShortField("reserved", 0),
2554 count_from=lambda p: p.num_response),
2555 FieldListField("device_class", None, XLE3BytesField("device_class", 0),
2556 count_from=lambda p: p.num_response),
2557 FieldListField("clock_offset", None, LEShortField("clock_offset", 0),
2558 count_from=lambda p: p.num_response)
2559 ]
2560 deprecated_fields = {"addr": ("bd_addr", "2.8.0")}
2561
2562
2563class HCI_Event_Connection_Complete(Packet):
2564 """
2565 7.7.3 Connection Complete event
2566 """
2567 name = "HCI_Connection_Complete"
2568 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2569 fields_desc = [ByteEnumField('status', 0, _bluetooth_error_codes),
2570 LEShortField("connection_handle", 0x0100),
2571 LEMACField("bd_addr", None),
2572 ByteEnumField("link_type", 0, {0: "SCO connection",
2573 1: "ACL connection", }),
2574 ByteEnumField("encryption_enabled", 0,
2575 {0: "link level encryption disabled",
2576 1: "link level encryption enabled", }), ]
2577
2578
2579class HCI_Event_Connection_Request(Packet):
2580 """
2581 7.7.4 Connection Request event
2582 """
2583 name = "HCI_Connection_Request"
2584 fields_desc = [LEMACField("bd_addr", None),
2585 XLE3BytesField("device_class", 0),
2586 ByteEnumField("link_type", 0, {0: "SCO connection",
2587 1: "ACL connection",
2588 2: "eSCO connection", }), ]
2589
2590
2591class HCI_Event_Disconnection_Complete(Packet):
2592 """
2593 7.7.5 Disconnection Complete event
2594 """
2595 name = "HCI_Disconnection_Complete"
2596 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2597 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
2598 LEShortField("connection_handle", 0),
2599 XByteField("reason", 0), ]
2600
2601
2602class HCI_Event_Remote_Name_Request_Complete(Packet):
2603 """
2604 7.7.7 Remote Name Request Complete event
2605 """
2606 name = "HCI_Remote_Name_Request_Complete"
2607 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
2608 LEMACField("bd_addr", None),
2609 StrFixedLenField("remote_name", b"\x00", 248), ]
2610
2611
2612class HCI_Event_Encryption_Change(Packet):
2613 """
2614 7.7.8 Encryption Change event
2615 """
2616 name = "HCI_Encryption_Change"
2617 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2618 fields_desc = [ByteEnumField("status", 0, {0: "change has occurred"}),
2619 LEShortField("connection_handle", 0),
2620 ByteEnumField("enabled", 0, {0: "OFF", 1: "ON (LE)", 2: "ON (BR/EDR)"}), ] # noqa: E501
2621
2622
2623class HCI_Event_Read_Remote_Supported_Features_Complete(Packet):
2624 """
2625 7.7.11 Read Remote Supported Features Complete event
2626 """
2627 name = "HCI_Read_Remote_Supported_Features_Complete"
2628 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2629 fields_desc = [
2630 ByteEnumField('status', 0, _bluetooth_error_codes),
2631 LEShortField('connection_handle', 0),
2632 FlagsField('lmp_features', 0, -64, _bluetooth_features)
2633 ]
2634
2635
2636class HCI_Event_Remote_Host_Supported_Features_Notification(Packet):
2637 """
2638 7.7.50 Remote Host Supported Features Notification event
2639 """
2640 name = "HCI_Remote_Host_Supported_Features_Notification"
2641 fields_desc = [
2642 LEMACField('bd_addr', None),
2643 XLELongField('host_supported_features', 0)
2644 ]
2645
2646
2647class HCI_Event_Read_Remote_Version_Information_Complete(Packet):
2648 """
2649 7.7.12 Read Remote Version Information Complete event
2650 """
2651 name = "HCI_Read_Remote_Version_Information"
2652 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2653 fields_desc = [
2654 ByteEnumField('status', 0, _bluetooth_error_codes),
2655 LEShortField('connection_handle', 0),
2656 ByteField('version', 0x00),
2657 LEShortField('manufacturer_name', 0x0000),
2658 LEShortField('subversion', 0x0000)
2659 ]
2660
2661
2662class HCI_Event_Command_Complete(Packet):
2663 """
2664 7.7.14 Command Complete event
2665 """
2666 name = "HCI_Command_Complete"
2667 fields_desc = [ByteField("number", 0),
2668 XLEShortField("opcode", 0),
2669 ByteEnumField("status", 0, _bluetooth_error_codes)]
2670
2671 def answers(self, other):
2672 if HCI_Command_Hdr not in other:
2673 return False
2674
2675 return other[HCI_Command_Hdr].opcode == self.opcode
2676
2677
2678class HCI_Event_Command_Status(Packet):
2679 """
2680 7.7.15 Command Status event
2681 """
2682 name = "HCI_Command_Status"
2683 fields_desc = [ByteEnumField("status", 0, {0: "pending"}),
2684 ByteField("number", 0),
2685 XLEShortField("opcode", None), ]
2686
2687 def answers(self, other):
2688 if HCI_Command_Hdr not in other:
2689 return False
2690
2691 return other[HCI_Command_Hdr].opcode == self.opcode
2692
2693
2694class HCI_Event_Number_Of_Completed_Packets(Packet):
2695 """
2696 7.7.19 Number Of Completed Packets event
2697 """
2698 name = "HCI_Number_Of_Completed_Packets"
2699 fields_desc = [ByteField("num_handles", 0),
2700 FieldListField("connection_handle_list", None,
2701 LEShortField("connection_handle", 0),
2702 count_from=lambda p: p.num_handles),
2703 FieldListField("num_completed_packets_list", None,
2704 LEShortField("num_completed_packets", 0),
2705 count_from=lambda p: p.num_handles)]
2706
2707
2708class HCI_Event_Link_Key_Request(Packet):
2709 """
2710 7.7.23 Link Key Request event
2711 """
2712 name = 'HCI_Link_Key_Request'
2713 fields_desc = [
2714 LEMACField('bd_addr', None)
2715 ]
2716
2717
2718class HCI_Event_Inquiry_Result_With_Rssi(Packet):
2719 """
2720 7.7.33 Inquiry Result with RSSI event
2721 """
2722 name = "HCI_Inquiry_Result_with_RSSI"
2723 fields_desc = [
2724 ByteField("num_response", 0x00),
2725 FieldListField("bd_addr", None, LEMACField("", None),
2726 count_from=lambda p: p.num_response),
2727 FieldListField("page_scan_repetition_mode", None, ByteField("", 0),
2728 count_from=lambda p: p.num_response),
2729 FieldListField("reserved", None, LEShortField("", 0),
2730 count_from=lambda p: p.num_response),
2731 FieldListField("device_class", None, XLE3BytesField("", 0),
2732 count_from=lambda p: p.num_response),
2733 FieldListField("clock_offset", None, LEShortField("", 0),
2734 count_from=lambda p: p.num_response),
2735 FieldListField("rssi", None, SignedByteField("", 0),
2736 count_from=lambda p: p.num_response)
2737 ]
2738
2739
2740class HCI_Event_Read_Remote_Extended_Features_Complete(Packet):
2741 """
2742 7.7.34 Read Remote Extended Features Complete event
2743 """
2744 name = "HCI_Read_Remote_Extended_Features_Complete"
2745 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2746 fields_desc = [
2747 ByteEnumField('status', 0, _bluetooth_error_codes),
2748 LEShortField('connection_handle', 0),
2749 ByteField('page', 0x00),
2750 ByteField('max_page', 0x00),
2751 XLELongField('extended_features', 0)
2752 ]
2753
2754
2755class HCI_Event_Extended_Inquiry_Result(Packet):
2756 """
2757 7.7.38 Extended Inquiry Result event
2758 """
2759 name = "HCI_Extended_Inquiry_Result"
2760 fields_desc = [
2761 ByteField('num_response', 0x01),
2762 LEMACField('bd_addr', None),
2763 ByteField('page_scan_repetition_mode', 0x00),
2764 ByteField('reserved', 0x00),
2765 XLE3BytesField('device_class', 0x000000),
2766 LEShortField('clock_offset', 0x0000),
2767 SignedByteField('rssi', 0x00),
2768 HCI_Extended_Inquiry_Response,
2769 ]
2770
2771
2772class HCI_Event_IO_Capability_Response(Packet):
2773 """
2774 7.7.41 IO Capability Response event
2775 """
2776 name = "HCI_IO_Capability_Response"
2777 fields_desc = [
2778 LEMACField('bd_addr', None),
2779 ByteField('io_capability', 0x00),
2780 ByteField('oob_data_present', 0x00),
2781 ByteField('authentication_requirements', 0x00)
2782 ]
2783
2784
2785class HCI_Event_Vendor(Packet):
2786 """
2787 Vendor-Specific Debug event (event code 0xFF).
2788
2789 Bluetooth Core 5.4, Vol 4, Part E, section 5.4.4 reserves 0xFF for
2790 vendor-specific debugging events; the format of the parameters is
2791 vendor-defined, so by default the parameters are exposed as a raw ``data``
2792 byte string.
2793
2794 Several vendors reuse this single event code with incompatible parameter
2795 layouts, so ``code=0xFF`` alone is not enough to pick a dissector and
2796 :func:`~scapy.packet.bind_layers` cannot be used. Instead a vendor
2797 registers a dissector with :meth:`register_handler`, providing a
2798 ``check(body)`` that recognises its own parameter layout (typically a
2799 fixed leading subcode). :meth:`dispatch_hook` then dissects a matching
2800 body with that class, so several vendor contribs coexist. When no check
2801 claims the body, ``HCI_Event_Vendor`` itself is used and the body stays in
2802 ``data``, exactly as before.
2803
2804 Handlers should subclass ``HCI_Event_Vendor`` and set ``match_subclass``,
2805 so that ``HCI_Event_Vendor in pkt`` keeps matching vendor events::
2806
2807 class HCI_Event_Vendor_Foo(HCI_Event_Vendor):
2808 name = "HCI_Vendor_Foo"
2809 match_subclass = True
2810 fields_desc = [XByteField("subcode", 0xa5),
2811 ByteField("value", 0)]
2812
2813 @classmethod
2814 def check(cls, body):
2815 return body[:1] == b"\\xa5"
2816
2817 HCI_Event_Vendor.register_handler(HCI_Event_Vendor_Foo)
2818 """
2819 name = "HCI_Vendor_Specific"
2820 fields_desc = [StrLenField("data", b"",
2821 length_from=lambda pkt: pkt.underlayer.len)]
2822
2823 registered_handlers = {}
2824
2825 @classmethod
2826 def register_handler(cls, handler_cls, check=None):
2827 """
2828 Registers a vendor dissector for the ``code=0xFF`` event body.
2829
2830 This event is shared across vendors with incompatible parameter
2831 layouts, so a contrib cannot simply bind its layer to it. Instead each
2832 vendor handler declares a ``check`` that returns True only for its own
2833 body (typically by testing a fixed leading subcode) and registers
2834 itself here. The first registered check that accepts a body wins, so
2835 checks should be as specific as possible. Re-registering the same
2836 ``handler_cls`` replaces its previous entry, so reloading a contrib is
2837 idempotent.
2838
2839 :param Type[scapy.packet.Packet] handler_cls:
2840 A reference to a Packet subclass to dissect the event body with.
2841 It should subclass ``HCI_Event_Vendor``.
2842 :param Callable[[bytes], bool] check:
2843 (optional) callable used to decide whether a body should be
2844 associated with this handler. If not supplied,
2845 ``handler_cls.check`` is used instead.
2846 :raises TypeError: If ``check`` is not specified,
2847 and ``handler_cls.check`` is not implemented.
2848 """
2849 if check is None:
2850 if hasattr(handler_cls, "check"):
2851 check = handler_cls.check
2852 else:
2853 raise TypeError("check not specified, and {} has no "
2854 "attribute check".format(handler_cls))
2855
2856 cls.registered_handlers[handler_cls] = check
2857
2858 @classmethod
2859 def dispatch_hook(cls, _pkt=None, *args, **kargs):
2860 if _pkt:
2861 for handler_cls, check in cls.registered_handlers.items():
2862 if check(_pkt):
2863 return handler_cls
2864 return cls
2865
2866
2867class HCI_Event_LE_Meta(Packet):
2868 """
2869 7.7.65 LE Meta event
2870 """
2871 name = "HCI_LE_Meta"
2872 fields_desc = [ByteEnumField("event", 0, {
2873 0x01: "connection_complete",
2874 0x02: "advertising_report",
2875 0x03: "connection_update_complete",
2876 0x04: "read_remote_features_page_0_complete",
2877 0x05: "long_term_key_request",
2878 0x06: "remote_connection_parameter_request",
2879 0x07: "data_length_change",
2880 0x08: "read_local_p256_public_key_complete",
2881 0x09: "generate_dhkey_complete",
2882 0x0a: "enhanced_connection_complete_v1",
2883 0x0b: "directed_advertising_report",
2884 0x0c: "phy_update_complete",
2885 0x0d: "extended_advertising_report",
2886 0x29: "enhanced_connection_complete_v2"
2887 }), ]
2888
2889 def answers(self, other):
2890 if not self.payload:
2891 return False
2892
2893 # Delegate answers to payload
2894 return self.payload.answers(other)
2895
2896
2897class HCI_Cmd_Complete_Read_Local_Name(Packet):
2898 """
2899 7.3.12 Read Local Name command complete
2900 """
2901 name = 'Read Local Name command complete'
2902 fields_desc = [StrFixedLenField('local_name', '', length=248)]
2903
2904
2905class HCI_Cmd_Complete_Read_Local_Version_Information(Packet):
2906 """
2907 7.4.1 Read Local Version Information command complete
2908 """
2909 name = 'Read Local Version Information'
2910 fields_desc = [
2911 ByteEnumField('hci_version', 0, _bluetooth_core_specification_versions),
2912 LEShortField('hci_subversion', 0),
2913 ByteEnumField('lmp_version', 0, _bluetooth_core_specification_versions),
2914 LEShortEnumField('company_identifier', 0, BLUETOOTH_CORE_COMPANY_IDENTIFIERS),
2915 LEShortField('lmp_subversion', 0)]
2916
2917
2918class HCI_Cmd_Complete_Read_Local_Extended_Features(Packet):
2919 """
2920 7.4.4 Read Local Extended Features command complete
2921 """
2922 name = 'Read Local Extended Features command complete'
2923 fields_desc = [
2924 ByteField('page', 0x00),
2925 ByteField('max_page', 0x00),
2926 XLELongField('extended_features', 0)
2927 ]
2928
2929
2930class HCI_Cmd_Complete_Read_BD_Addr(Packet):
2931 """
2932 7.4.6 Read BD_ADDR command complete
2933 """
2934 name = "Read BD Addr"
2935 fields_desc = [LEMACField("bd_addr", None), ]
2936 deprecated_fields = {"addr": ("bd_addr", "2.8.0")}
2937
2938
2939class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet):
2940 name = "LE Read White List Size"
2941 fields_desc = [ByteField("status", 0),
2942 ByteField("size", 0), ]
2943
2944
2945class HCI_LE_Meta_Connection_Complete(Packet):
2946 name = "Connection Complete"
2947 fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2948 LEShortField("connection_handle", 0),
2949 ByteEnumField("role", 0, {0: "master"}),
2950 ByteEnumField("peer_addr_type", 0, {0: "public", 1: "random"}),
2951 LEMACField("peer_addr", None),
2952 LEShortField("interval", 54),
2953 LEShortField("latency", 0),
2954 LEShortField("supervision", 42),
2955 XByteField("master_clock_accuracy", 5)]
2956 deprecated_fields = {
2957 "handle": ("connection_handle", "2.8.0"),
2958 "patype": ("peer_addr_type", "2.7.0"),
2959 "paddr": ("peer_addr", "2.7.0"),
2960 "clock_latency": ("master_clock_accuracy", "2.7.0"),
2961 }
2962
2963 def answers(self, other):
2964 if HCI_Cmd_LE_Create_Connection in other:
2965 cmd = other[HCI_Cmd_LE_Create_Connection]
2966 elif HCI_Cmd_LE_Extended_Create_Connection in other:
2967 cmd = other[HCI_Cmd_LE_Extended_Create_Connection]
2968 else:
2969 return False
2970
2971 return (cmd.peer_addr_type == self.peer_addr_type and
2972 cmd.peer_addr == self.peer_addr)
2973
2974
2975class HCI_LE_Meta_Enhanced_Connection_Complete(Packet):
2976 name = 'LE Enhanced Connection Complete'
2977 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
2978 fields_desc = [ByteEnumField('status', 0, {0: 'success'}),
2979 LEShortField('connection_handle', 0),
2980 ByteEnumField('role', 0, {0: 'master', 1: 'slave'}),
2981 ByteEnumField('peer_addr_type', 0, {
2982 0: 'public',
2983 1: 'random',
2984 2: 'public_identity',
2985 3: 'random_identity'}),
2986 LEMACField('peer_addr', None),
2987 LEMACField('local_rpa', None),
2988 LEMACField('peer_rpa', None),
2989 LEShortField('interval', 54),
2990 LEShortField('latency', 0),
2991 LEShortField('supervision', 42),
2992 XByteField('master_clock_accuracy', 5)]
2993
2994 def answers(self, other):
2995 if HCI_Cmd_LE_Create_Connection in other:
2996 cmd = other[HCI_Cmd_LE_Create_Connection]
2997 elif HCI_Cmd_LE_Extended_Create_Connection in other:
2998 cmd = other[HCI_Cmd_LE_Extended_Create_Connection]
2999 else:
3000 return False
3001
3002 return cmd.peer_addr_type == self.peer_addr_type and cmd.peer_addr == self.peer_addr # noqa: E501
3003
3004
3005class HCI_LE_Meta_Connection_Update_Complete(Packet):
3006 name = "Connection Update Complete"
3007 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
3008 fields_desc = [ByteEnumField("status", 0, {0: "success"}),
3009 LEShortField("connection_handle", 0),
3010 LEShortField("interval", 54),
3011 LEShortField("latency", 0),
3012 LEShortField("timeout", 42), ]
3013
3014
3015class HCI_LE_Meta_LE_Read_Remote_Features_Complete(Packet):
3016 name = "LE Read Remote Features Complete"
3017 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
3018 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
3019 LEShortField("connection_handle", 0),
3020 XLELongField("le_features", 0)]
3021
3022
3023class HCI_LE_Meta_Advertising_Report(Packet):
3024 name = "Advertising Report"
3025 fields_desc = [ByteEnumField("type", 0, {0: "conn_und", 4: "scan_rsp"}),
3026 ByteEnumField("addr_type", 0, {0: "public", 1: "random"}),
3027 LEMACField("addr", None),
3028 FieldLenField("len", None, length_of="data", fmt="B"),
3029 PacketListField("data", [], EIR_Hdr,
3030 length_from=lambda pkt: pkt.len),
3031 SignedByteField("rssi", 0)]
3032 deprecated_fields = {"atype": ("addr_type", "2.7.0")}
3033
3034 def extract_padding(self, s):
3035 return '', s
3036
3037
3038class HCI_LE_Meta_Advertising_Reports(Packet):
3039 name = "Advertising Reports"
3040 fields_desc = [FieldLenField("len", None, count_of="reports", fmt="B"),
3041 PacketListField("reports", None,
3042 HCI_LE_Meta_Advertising_Report,
3043 count_from=lambda pkt: pkt.len)]
3044
3045
3046class HCI_LE_Meta_Long_Term_Key_Request(Packet):
3047 name = "Long Term Key Request"
3048 deprecated_fields = {"handle": ("connection_handle", "2.8.0")}
3049 fields_desc = [LEShortField("connection_handle", 0),
3050 StrFixedLenField("rand", None, 8),
3051 XLEShortField("ediv", 0), ]
3052
3053
3054class HCI_LE_Meta_Extended_Advertising_Report(Packet):
3055 name = "Extended Advertising Report"
3056 fields_desc = [
3057 BitField("reserved0", 0, 1),
3058 BitEnumField("data_status", 0, 2, {
3059 0b00: "complete",
3060 0b01: "incomplete",
3061 0b10: "incomplete_truncated",
3062 0b11: "reserved"
3063 }),
3064 BitField("legacy", 0, 1),
3065 BitField("scan_response", 0, 1),
3066 BitField("directed", 0, 1),
3067 BitField("scannable", 0, 1),
3068 BitField("connectable", 0, 1),
3069 ByteField("reserved", 0),
3070 ByteEnumField("addr_type", 0, {
3071 0x00: "public_device_address",
3072 0x01: "random_device_address",
3073 0x02: "public_identity_address",
3074 0x03: "random_identity_address",
3075 0xff: "anonymous"
3076 }),
3077 LEMACField('addr', None),
3078 ByteEnumField("primary_phy", 0, {
3079 0x01: "le_1m",
3080 0x03: "le_coded_s8",
3081 0x04: "le_coded_s2"
3082 }),
3083 ByteEnumField("secondary_phy", 0, {
3084 0x01: "le_1m",
3085 0x02: "le_2m",
3086 0x03: "le_coded_s8",
3087 0x04: "le_coded_s2"
3088 }),
3089 ByteField("advertising_sid", 0xff),
3090 ByteField("tx_power", 0x7f),
3091 SignedByteField("rssi", 0x00),
3092 LEShortField("periodic_advertising_interval", 0x0000),
3093 ByteEnumField("direct_addr_type", 0, {
3094 0x00: "public_device_address",
3095 0x01: "non_resolvable_private_address",
3096 0x02: "resolvable_private_address_resolved_0",
3097 0x03: "resolvable_private_address_resolved_1",
3098 0xfe: "resolvable_private_address_unable_resolve"}),
3099 LEMACField("direct_addr", None),
3100 FieldLenField("data_length", None, length_of="data", fmt="B"),
3101 PacketListField("data", [], EIR_Hdr,
3102 length_from=lambda pkt: pkt.data_length),
3103 ]
3104 deprecated_fields = {
3105 "address_type": ("addr_type", "2.7.0"),
3106 "address": ("addr", "2.7.0"),
3107 "direct_address_type": ("direct_addr_type", "2.7.0"),
3108 "direct_address": ("direct_addr", "2.7.0"),
3109 }
3110
3111 def extract_padding(self, s):
3112 return '', s
3113
3114
3115class HCI_LE_Meta_Extended_Advertising_Reports(Packet):
3116 name = "Extended Advertising Reports"
3117 fields_desc = [FieldLenField("num_reports", None, count_of="reports", fmt="B"),
3118 PacketListField("reports", None,
3119 HCI_LE_Meta_Extended_Advertising_Report,
3120 count_from=lambda pkt: pkt.num_reports)]
3121
3122
3123bind_layers(HCI_PHDR_Hdr, HCI_Hdr)
3124
3125bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1)
3126bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2)
3127bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4)
3128bind_layers(HCI_Hdr, conf.raw_layer,)
3129
3130conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr)
3131conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr)
3132
3133
3134# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
3135bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry, ogf=0x01, ocf=0x0001)
3136bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry_Cancel, ogf=0x01, ocf=0x0002)
3137bind_layers(HCI_Command_Hdr, HCI_Cmd_Periodic_Inquiry_Mode, ogf=0x01, ocf=0x0003)
3138bind_layers(HCI_Command_Hdr, HCI_Cmd_Exit_Peiodic_Inquiry_Mode, ogf=0x01, ocf=0x0004)
3139bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, ogf=0x01, ocf=0x0005)
3140bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, ogf=0x01, ocf=0x0006)
3141bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection_Cancel, ogf=0x01, ocf=0x0008)
3142bind_layers(HCI_Command_Hdr, HCI_Cmd_Accept_Connection_Request, ogf=0x01, ocf=0x0009)
3143bind_layers(HCI_Command_Hdr, HCI_Cmd_Reject_Connection_Response, ogf=0x01, ocf=0x000a)
3144bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b)
3145bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply,
3146 ogf=0x01, ocf=0x000c)
3147bind_layers(HCI_Command_Hdr, HCI_Cmd_PIN_Code_Request_Reply, ogf=0x01, ocf=0x000d)
3148bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type,
3149 ogf=0x01, ocf=0x000f)
3150bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, ogf=0x01, ocf=0x0011)
3151bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, ogf=0x01, ocf=0x0013)
3152bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Link_Key, ogf=0x01, ocf=0x0017)
3153bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019)
3154bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request_Cancel, ogf=0x01, ocf=0x001a)
3155bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features,
3156 ogf=0x01, ocf=0x001b)
3157bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features,
3158 ogf=0x01, ocf=0x001c)
3159bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b)
3160bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply,
3161 ogf=0x01, ocf=0x002c)
3162bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply,
3163 ogf=0x01, ocf=0x002d)
3164bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Reply, ogf=0x01, ocf=0x002e)
3165bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply,
3166 ogf=0x01, ocf=0x002f)
3167bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply,
3168 ogf=0x01, ocf=0x0030)
3169bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply,
3170 ogf=0x01, ocf=0x0033)
3171
3172# 7.2 Link Policy commands, the OGF is defined as 0x02
3173bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001)
3174
3175# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
3176bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, ogf=0x03, ocf=0x0001)
3177bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, ogf=0x03, ocf=0x0003)
3178bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, ogf=0x03, ocf=0x0005)
3179bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, ogf=0x03, ocf=0x0013)
3180bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Name, ogf=0x03, ocf=0x0014)
3181bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Connect_Accept_Timeout, ogf=0x03, ocf=0x0016)
3182bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, ogf=0x03, ocf=0x0052) # noqa: E501
3183bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_LE_Host_Support, ogf=0x03, ocf=0x006c)
3184bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_LE_Host_Support, ogf=0x03, ocf=0x006d)
3185
3186# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
3187bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Version_Information, ogf=0x04, ocf=0x0001) # noqa: E501
3188bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Extended_Features, ogf=0x04, ocf=0x0004)
3189bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, ogf=0x04, ocf=0x0009)
3190
3191# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
3192bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Link_Quality, ogf=0x05, ocf=0x0003)
3193bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_RSSI, ogf=0x05, ocf=0x0005)
3194
3195# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
3196bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Loopback_Mode, ogf=0x06, ocf=0x0001)
3197bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Loopback_Mode, ogf=0x06, ocf=0x0002)
3198
3199# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
3200bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Event_Mask, ogf=0x08, ocf=0x0001)
3201bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V1, ogf=0x08, ocf=0x0002)
3202bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V2, ogf=0x08, ocf=0x0060)
3203bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features,
3204 ogf=0x08, ocf=0x0003)
3205bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, ogf=0x08, ocf=0x0005)
3206bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, ogf=0x08, ocf=0x0006) # noqa: E501
3207bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Set_Random_Address, ogf=0x08, ocf=0x0035) # noqa: E501
3208bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Advertising_Parameters, ogf=0x08, ocf=0x0036) # noqa: E501
3209bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, ogf=0x08, ocf=0x0008)
3210bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Advertising_Data, ogf=0x08, ocf=0x0037) # noqa: E501
3211bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, ogf=0x08, ocf=0x0009)
3212bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, ogf=0x08, ocf=0x000a)
3213bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Advertise_Enable, ogf=0x08, ocf=0x0039) # noqa: E501
3214bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, ogf=0x08, ocf=0x000b)
3215bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Scan_Parameters, ogf=0x08, ocf=0x0041) # noqa: E501
3216bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, ogf=0x08, ocf=0x000c)
3217bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Extended_Scan_Enable, ogf=0x08, ocf=0x0042)
3218bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, ogf=0x08, ocf=0x000d)
3219bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Extended_Create_Connection, ogf=0x08, ocf=0x0043) # noqa: E501
3220bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, ogf=0x08, ocf=0x000e) # noqa: E501
3221bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size,
3222 ogf=0x08, ocf=0x000f)
3223bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_Filter_Accept_List, ogf=0x08, ocf=0x0010)
3224bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_Filter_Accept_List, ogf=0x08, ocf=0x0011) # noqa: E501
3225bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List, ogf=0x08, ocf=0x0012) # noqa: E501
3226bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, ogf=0x08, ocf=0x0013)
3227bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Features, ogf=0x08, ocf=0x0016) # noqa: E501
3228bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Enable_Encryption, ogf=0x08, ocf=0x0019) # noqa: E501
3229bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, ogf=0x08, ocf=0x001a) # noqa: E501
3230bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, ogf=0x08, ocf=0x001b) # noqa: E501
3231
3232# 7.7 EVENTS
3233bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Complete, code=0x01)
3234bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result, code=0x02)
3235bind_layers(HCI_Event_Hdr, HCI_Event_Connection_Complete, code=0x03)
3236bind_layers(HCI_Event_Hdr, HCI_Event_Connection_Request, code=0x04)
3237bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x05)
3238bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Name_Request_Complete, code=0x07)
3239bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x08)
3240bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Supported_Features_Complete, code=0x0b)
3241bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Version_Information_Complete, code=0x0c) # noqa: E501
3242bind_layers(HCI_Event_Hdr, HCI_Event_Command_Complete, code=0x0e)
3243bind_layers(HCI_Event_Hdr, HCI_Event_Command_Status, code=0x0f)
3244bind_layers(HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13)
3245bind_layers(HCI_Event_Hdr, HCI_Event_Link_Key_Request, code=0x17)
3246bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result_With_Rssi, code=0x22)
3247bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Extended_Features_Complete, code=0x23)
3248bind_layers(HCI_Event_Hdr, HCI_Event_Extended_Inquiry_Result, code=0x2f)
3249bind_layers(HCI_Event_Hdr, HCI_Event_IO_Capability_Response, code=0x32)
3250bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Host_Supported_Features_Notification, code=0x3d) # noqa: E501
3251bind_layers(HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e)
3252bind_layers(HCI_Event_Hdr, HCI_Event_Vendor, code=0xff)
3253
3254bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Name, opcode=0x0c14) # noqa: E501
3255bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Version_Information, opcode=0x1001) # noqa: E501
3256bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Extended_Features, opcode=0x1004) # noqa: E501
3257bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009) # noqa: E501
3258bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_LE_Read_White_List_Size, opcode=0x200f) # noqa: E501
3259
3260bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=0x01)
3261bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Enhanced_Connection_Complete, event=0x0a)
3262bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=0x02)
3263bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=0x03)
3264bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_LE_Read_Remote_Features_Complete, event=0x04) # noqa: E501
3265bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=0x05)
3266bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Extended_Advertising_Reports, event=0x0d)
3267
3268bind_layers(EIR_Hdr, EIR_Flags, type=0x01)
3269bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02)
3270bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03)
3271bind_layers(EIR_Hdr, EIR_IncompleteList32BitServiceUUIDs, type=0x04)
3272bind_layers(EIR_Hdr, EIR_CompleteList32BitServiceUUIDs, type=0x05)
3273bind_layers(EIR_Hdr, EIR_IncompleteList128BitServiceUUIDs, type=0x06)
3274bind_layers(EIR_Hdr, EIR_CompleteList128BitServiceUUIDs, type=0x07)
3275bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08)
3276bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09)
3277bind_layers(EIR_Hdr, EIR_Device_ID, type=0x10)
3278bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a)
3279bind_layers(EIR_Hdr, EIR_ClassOfDevice, type=0x0d)
3280bind_layers(EIR_Hdr, EIR_SecureSimplePairingHashC192, type=0x0e)
3281bind_layers(EIR_Hdr, EIR_SecureSimplePairingRandomizerR192, type=0x0f)
3282bind_layers(EIR_Hdr, EIR_SecurityManagerOOBFlags, type=0x11)
3283bind_layers(EIR_Hdr, EIR_PeripheralConnectionIntervalRange, type=0x12)
3284bind_layers(EIR_Hdr, EIR_ServiceSolicitation16BitUUID, type=0x14)
3285bind_layers(EIR_Hdr, EIR_ServiceSolicitation128BitUUID, type=0x15)
3286bind_layers(EIR_Hdr, EIR_ServiceData16BitUUID, type=0x16)
3287bind_layers(EIR_Hdr, EIR_PublicTargetAddress, type=0x17)
3288bind_layers(EIR_Hdr, EIR_RandomTargetAddress, type=0x18)
3289bind_layers(EIR_Hdr, EIR_Appearance, type=0x19)
3290bind_layers(EIR_Hdr, EIR_AdvertisingInterval, type=0x1a)
3291bind_layers(EIR_Hdr, EIR_LEBluetoothDeviceAddress, type=0x1b)
3292bind_layers(EIR_Hdr, EIR_LERole, type=0x1c)
3293bind_layers(EIR_Hdr, EIR_ServiceData32BitUUID, type=0x20)
3294bind_layers(EIR_Hdr, EIR_ServiceData128BitUUID, type=0x21)
3295bind_layers(EIR_Hdr, EIR_URI, type=0x24)
3296bind_layers(EIR_Hdr, EIR_BroadcastName, type=0x30)
3297bind_layers(EIR_Hdr, EIR_3DInformation, type=0x3d)
3298bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff)
3299bind_layers(EIR_Hdr, EIR_Raw)
3300
3301bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,)
3302bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
3303bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=5) # LE L2CAP Signaling Channel
3304bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
3305bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
3306bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
3307bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
3308bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
3309bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
3310bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
3311bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8)
3312bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9)
3313bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
3314bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
3315bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12)
3316bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13)
3317bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14)
3318bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15)
3319bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16)
3320bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17)
3321bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18)
3322bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19)
3323bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20)
3324bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21)
3325bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22)
3326bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23)
3327bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24)
3328bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25)
3329bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26)
3330bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4)
3331bind_layers(ATT_Hdr, ATT_Error_Response, opcode=0x1)
3332bind_layers(ATT_Hdr, ATT_Exchange_MTU_Request, opcode=0x2)
3333bind_layers(ATT_Hdr, ATT_Exchange_MTU_Response, opcode=0x3)
3334bind_layers(ATT_Hdr, ATT_Find_Information_Request, opcode=0x4)
3335bind_layers(ATT_Hdr, ATT_Find_Information_Response, opcode=0x5)
3336bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Request, opcode=0x6)
3337bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Response, opcode=0x7)
3338bind_layers(ATT_Hdr, ATT_Read_By_Type_Request_128bit, opcode=0x8)
3339bind_layers(ATT_Hdr, ATT_Read_By_Type_Request, opcode=0x8)
3340bind_layers(ATT_Hdr, ATT_Read_By_Type_Response, opcode=0x9)
3341bind_layers(ATT_Hdr, ATT_Read_Request, opcode=0xa)
3342bind_layers(ATT_Hdr, ATT_Read_Response, opcode=0xb)
3343bind_layers(ATT_Hdr, ATT_Read_Blob_Request, opcode=0xc)
3344bind_layers(ATT_Hdr, ATT_Read_Blob_Response, opcode=0xd)
3345bind_layers(ATT_Hdr, ATT_Read_Multiple_Request, opcode=0xe)
3346bind_layers(ATT_Hdr, ATT_Read_Multiple_Response, opcode=0xf)
3347bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Request, opcode=0x10)
3348bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Response, opcode=0x11)
3349bind_layers(ATT_Hdr, ATT_Write_Request, opcode=0x12)
3350bind_layers(ATT_Hdr, ATT_Write_Response, opcode=0x13)
3351bind_layers(ATT_Hdr, ATT_Prepare_Write_Request, opcode=0x16)
3352bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17)
3353bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18)
3354bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19)
3355bind_layers(ATT_Hdr, ATT_Read_Multiple_Variable_Request, opcode=0x20)
3356bind_layers(ATT_Hdr, ATT_Read_Multiple_Variable_Response, opcode=0x21)
3357bind_layers(ATT_Hdr, ATT_Multiple_Handle_Value_Notification, opcode=0x23)
3358bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52)
3359bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b)
3360bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d)
3361bind_layers(ATT_Hdr, ATT_Handle_Value_Confirmation, opcode=0x1e)
3362bind_layers(ATT_Hdr, ATT_Signed_Write_Command, opcode=0xd2)
3363bind_layers(L2CAP_Hdr, SM_Hdr, cid=6)
3364bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=0x01)
3365bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=0x02)
3366bind_layers(SM_Hdr, SM_Confirm, sm_command=0x03)
3367bind_layers(SM_Hdr, SM_Random, sm_command=0x04)
3368bind_layers(SM_Hdr, SM_Failed, sm_command=0x05)
3369bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=0x06)
3370bind_layers(SM_Hdr, SM_Master_Identification, sm_command=0x07)
3371bind_layers(SM_Hdr, SM_Identity_Information, sm_command=0x08)
3372bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=0x09)
3373bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a)
3374bind_layers(SM_Hdr, SM_Security_Request, sm_command=0x0b)
3375bind_layers(SM_Hdr, SM_Public_Key, sm_command=0x0c)
3376bind_layers(SM_Hdr, SM_DHKey_Check, sm_command=0x0d)
3377bind_layers(SM_Hdr, SM_Keypress_Notification, sm_command=0x0e)
3378
3379
3380###############
3381# HCI Monitor #
3382###############
3383
3384
3385# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L27
3386class HCI_Mon_Hdr(Packet):
3387 name = 'Bluetooth Linux Monitor Transport Header'
3388 fields_desc = [
3389 LEShortEnumField('opcode', None, {
3390 0: "New index",
3391 1: "Delete index",
3392 2: "Command pkt",
3393 3: "Event pkt",
3394 4: "ACL TX pkt",
3395 5: "ACL RX pkt",
3396 6: "SCO TX pkt",
3397 7: "SCO RX pkt",
3398 8: "Open index",
3399 9: "Close index",
3400 10: "Index info",
3401 11: "Vendor diag",
3402 12: "System note",
3403 13: "User logging",
3404 14: "Ctrl open",
3405 15: "Ctrl close",
3406 16: "Ctrl command",
3407 17: "Ctrl event",
3408 18: "ISO TX pkt",
3409 19: "ISO RX pkt",
3410 }),
3411 LEShortField('adapter_id', None),
3412 LEShortField('len', None)
3413 ]
3414
3415
3416# https://www.tcpdump.org/linktypes/LINKTYPE_BLUETOOTH_LINUX_MONITOR.html
3417class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr):
3418 name = 'Bluetooth Linux Monitor Transport Pcap Header'
3419 fields_desc = [
3420 ShortField('adapter_id', None),
3421 ShortField('opcode', None)
3422 ]
3423
3424
3425class HCI_Mon_New_Index(Packet):
3426 name = 'Bluetooth Linux Monitor Transport New Index Packet'
3427 fields_desc = [
3428 ByteEnumField('bus', 0, {
3429 0x00: "BR/EDR",
3430 0x01: "AMP"
3431 }),
3432 ByteEnumField('type', 0, {
3433 0x00: "Virtual",
3434 0x01: "USB",
3435 0x02: "PC Card",
3436 0x03: "UART",
3437 0x04: "RS232",
3438 0x05: "PCI",
3439 0x06: "SDIO"
3440 }),
3441 LEMACField('addr', None),
3442 StrFixedLenField('devname', None, 8)
3443 ]
3444
3445
3446class HCI_Mon_Index_Info(Packet):
3447 name = 'Bluetooth Linux Monitor Transport Index Info Packet'
3448 fields_desc = [
3449 LEMACField('addr', None),
3450 XLEShortField('manufacturer', None)
3451 ]
3452
3453
3454class HCI_Mon_System_Note(Packet):
3455 name = 'Bluetooth Linux Monitor Transport System Note Packet'
3456 fields_desc = [
3457 StrNullField('note', None)
3458 ]
3459
3460
3461# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L34
3462bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0)
3463bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2)
3464bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3)
3465bind_layers(HCI_Mon_Hdr, HCI_ACL_Hdr, opcode=5)
3466bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10)
3467bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12)
3468
3469conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr)
3470
3471
3472###########
3473# Helpers #
3474###########
3475
3476class LowEnergyBeaconHelper:
3477 """
3478 Helpers for building packets for Bluetooth Low Energy Beacons.
3479
3480 Implementers provide a :meth:`build_eir` implementation.
3481
3482 This is designed to be used as a mix-in -- see
3483 ``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples.
3484 """
3485
3486 # Basic flags that should be used by most beacons.
3487 base_eir = [EIR_Hdr() / EIR_Flags(flags=[
3488 "general_disc_mode", "br_edr_not_supported"]), ]
3489
3490 def build_eir(self):
3491 """
3492 Builds a list of EIR messages to wrap this frame.
3493
3494 Users of this helper must implement this method.
3495
3496 :return: List of HCI_Hdr with payloads that describe this beacon type
3497 :rtype: list[scapy.bluetooth.HCI_Hdr]
3498 """
3499 raise NotImplementedError("build_eir")
3500
3501 def build_advertising_report(self):
3502 """
3503 Builds a HCI_LE_Meta_Advertising_Report containing this frame.
3504
3505 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report
3506 """
3507
3508 return HCI_LE_Meta_Advertising_Report(
3509 type=0, # Undirected
3510 addr_type=1, # Random address
3511 data=self.build_eir()
3512 )
3513
3514 def build_set_advertising_data(self):
3515 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame.
3516
3517 This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers.
3518
3519 :rtype: scapy.bluetooth.HCI_Hdr
3520 """
3521
3522 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data(
3523 data=self.build_eir()
3524 )
3525
3526
3527###########
3528# Sockets #
3529###########
3530
3531class BluetoothSocketError(BaseException):
3532 pass
3533
3534
3535class BluetoothCommandError(BaseException):
3536 pass
3537
3538
3539class BluetoothL2CAPSocket(SuperSocket):
3540 desc = "read/write packets on a connected L2CAP socket"
3541
3542 def __init__(self, bt_address):
3543 if WINDOWS:
3544 warning("Not available on Windows")
3545 return
3546 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
3547 socket.BTPROTO_L2CAP)
3548 s.connect((bt_address, 0))
3549 self.ins = self.outs = s
3550
3551 def recv(self, x=MTU):
3552 return L2CAP_CmdHdr(self.ins.recv(x))
3553
3554
3555class BluetoothRFCommSocket(BluetoothL2CAPSocket):
3556 """read/write packets on a connected RFCOMM socket"""
3557
3558 def __init__(self, bt_address, port=0):
3559 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
3560 socket.BTPROTO_RFCOMM)
3561 s.connect((bt_address, port))
3562 self.ins = self.outs = s
3563
3564
3565class BluetoothHCISocket(SuperSocket):
3566 desc = "read/write on a BlueTooth HCI socket"
3567
3568 def __init__(self, iface=0x10000, type=None):
3569 if WINDOWS:
3570 warning("Not available on Windows")
3571 return
3572 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) # noqa: E501
3573 s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR, 1)
3574 s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP, 1)
3575 s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff, 0xffffffff, 0xffffffff, 0)) # type mask, event mask, event mask, opcode # noqa: E501
3576 s.bind((iface,))
3577 self.ins = self.outs = s
3578# s.connect((peer,0))
3579
3580 def recv(self, x=MTU):
3581 return HCI_Hdr(self.ins.recv(x))
3582
3583
3584if ctypes is not None:
3585 class sockaddr_hci(ctypes.Structure):
3586 _fields_ = [
3587 ("sin_family", ctypes.c_ushort),
3588 ("hci_dev", ctypes.c_ushort),
3589 ("hci_channel", ctypes.c_ushort),
3590 ]
3591else:
3592 class sockaddr_hci(object):
3593 pass
3594
3595
3596class _BluetoothLibcSocket(SuperSocket):
3597 def __init__(self, socket_domain, socket_type, socket_protocol, sock_address):
3598 # type: (int, int, int, sockaddr_hci) -> None
3599 if WINDOWS:
3600 warning("Not available on Windows")
3601 return
3602 # Python socket and bind implementations do not allow us to pass down
3603 # the correct parameters. We must call libc functions directly via
3604 # ctypes.
3605 if ctypes is None:
3606 raise Scapy_Exception("ctypes is not available")
3607 sockaddr_hcip = ctypes.POINTER(sockaddr_hci)
3608 from ctypes.util import find_library
3609 libc = ctypes.cdll.LoadLibrary(find_library("c"))
3610
3611 socket_c = libc.socket
3612 socket_c.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int)
3613 socket_c.restype = ctypes.c_int
3614
3615 bind = libc.bind
3616 bind.argtypes = (ctypes.c_int,
3617 ctypes.POINTER(sockaddr_hci),
3618 ctypes.c_int)
3619 bind.restype = ctypes.c_int
3620
3621 # Socket
3622 s = socket_c(socket_domain, socket_type, socket_protocol)
3623 if s < 0:
3624 raise BluetoothSocketError(
3625 f"Unable to open socket({socket_domain}, {socket_type}, "
3626 f"{socket_protocol})")
3627
3628 # Bind
3629 r = bind(s, sockaddr_hcip(sock_address), sizeof(sock_address))
3630 if r != 0:
3631 raise BluetoothSocketError("Unable to bind")
3632
3633 self.hci_fd = s
3634 self.ins = self.outs = socket.fromfd(
3635 s, socket_domain, socket_type, socket_protocol)
3636
3637 def readable(self, timeout=0):
3638 (ins, _, _) = select.select([self.ins], [], [], timeout)
3639 return len(ins) > 0
3640
3641 def flush(self):
3642 while self.readable():
3643 self.recv()
3644
3645 def close(self):
3646 if self.closed:
3647 return
3648
3649 # Properly close socket so we can free the device
3650 from ctypes.util import find_library
3651 libc = ctypes.cdll.LoadLibrary(find_library("c"))
3652
3653 close = libc.close
3654 close.restype = ctypes.c_int
3655 self.closed = True
3656 if hasattr(self, "outs"):
3657 if not hasattr(self, "ins") or self.ins != self.outs:
3658 if self.outs and (WINDOWS or self.outs.fileno() != -1):
3659 close(self.outs.fileno())
3660 if hasattr(self, "ins"):
3661 if self.ins and (WINDOWS or self.ins.fileno() != -1):
3662 close(self.ins.fileno())
3663 if hasattr(self, "hci_fd"):
3664 close(self.hci_fd)
3665
3666
3667class BluetoothUserSocket(_BluetoothLibcSocket):
3668 desc = "read/write H4 over a Bluetooth user channel"
3669
3670 def __init__(self, adapter_index=0):
3671 sa = sockaddr_hci()
3672 sa.sin_family = socket.AF_BLUETOOTH
3673 sa.hci_dev = adapter_index
3674 sa.hci_channel = HCI_CHANNEL_USER
3675 super().__init__(
3676 socket_domain=socket.AF_BLUETOOTH,
3677 socket_type=socket.SOCK_RAW,
3678 socket_protocol=socket.BTPROTO_HCI,
3679 sock_address=sa)
3680
3681 def send_command(self, cmd):
3682 opcode = cmd[HCI_Command_Hdr].opcode
3683 self.send(cmd)
3684 while True:
3685 r = self.recv()
3686 if r.type == 0x04 and r.code in (0xe, 0xf) and r.opcode == opcode:
3687 if hasattr(r, 'status') and r.status != 0:
3688 raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status)) # noqa: E501
3689 return r
3690
3691 def recv(self, x=MTU):
3692 return HCI_Hdr(self.ins.recv(x))
3693
3694
3695class BluetoothMonitorSocket(_BluetoothLibcSocket):
3696 desc = "Read/write over a Bluetooth monitor channel"
3697
3698 def __init__(self):
3699 sa = sockaddr_hci()
3700 sa.sin_family = socket.AF_BLUETOOTH
3701 sa.hci_dev = HCI_DEV_NONE
3702 sa.hci_channel = HCI_CHANNEL_MONITOR
3703 super().__init__(
3704 socket_domain=socket.AF_BLUETOOTH,
3705 socket_type=socket.SOCK_RAW,
3706 socket_protocol=socket.BTPROTO_HCI,
3707 sock_address=sa)
3708
3709 def recv(self, x=MTU):
3710 return HCI_Mon_Hdr(self.ins.recv(x))
3711
3712
3713conf.BTsocket = BluetoothRFCommSocket
3714
3715# Bluetooth
3716
3717
3718@conf.commands.register
3719def srbt(bt_address, pkts, inter=0.1, *args, **kargs):
3720 """send and receive using a bluetooth socket"""
3721 if "port" in kargs:
3722 s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port"))
3723 else:
3724 s = conf.BTsocket(bt_address=bt_address)
3725 a, b = sndrcv(s, pkts, inter=inter, *args, **kargs)
3726 s.close()
3727 return a, b
3728
3729
3730@conf.commands.register
3731def srbt1(bt_address, pkts, *args, **kargs):
3732 """send and receive 1 packet using a bluetooth socket"""
3733 a, b = srbt(bt_address, pkts, *args, **kargs)
3734 if len(a) > 0:
3735 return a[0][1]