• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Philippe Biondi <phil@secdev.org>
5# Copyright (C) Mike Ryan <mikeryan@lacklustre.net>
6# Copyright (C) Michael Farrell <micolous+git@gmail.com>
7# Copyright (C) Haram Park <freehr94@korea.ac.kr>
8
9"""
10Bluetooth layers, sockets and send/receive functions.
11"""
12
13import ctypes
14import functools
15import socket
16import struct
17import select
18from ctypes import sizeof
19
20from scapy.config import conf
21from scapy.data import (
22    DLT_BLUETOOTH_HCI_H4,
23    DLT_BLUETOOTH_HCI_H4_WITH_PHDR,
24    DLT_BLUETOOTH_LINUX_MONITOR
25)
26from scapy.packet import bind_layers, Packet
27from scapy.fields import (
28    BitField,
29    XBitField,
30    ByteEnumField,
31    ByteField,
32    FieldLenField,
33    FieldListField,
34    FlagsField,
35    IntField,
36    LEShortEnumField,
37    LEShortField,
38    LEIntField,
39    LenField,
40    MultipleTypeField,
41    NBytesField,
42    PacketListField,
43    PadField,
44    ShortField,
45    SignedByteField,
46    StrField,
47    StrFixedLenField,
48    StrLenField,
49    StrNullField,
50    UUIDField,
51    XByteField,
52    XLE3BytesField,
53    XLELongField,
54    XStrLenField,
55    XLEShortField,
56    XLEIntField,
57    LEMACField,
58    BitEnumField,
59)
60from scapy.supersocket import SuperSocket
61from scapy.sendrecv import sndrcv
62from scapy.data import MTU
63from scapy.consts import WINDOWS
64from scapy.error import warning
65
66
67############
68#  Consts  #
69############
70
71# From hci.h
72HCI_CHANNEL_RAW = 0
73HCI_CHANNEL_USER = 1
74HCI_CHANNEL_MONITOR = 2
75HCI_CHANNEL_CONTROL = 3
76HCI_CHANNEL_LOGGING = 4
77
78HCI_DEV_NONE = 0xffff
79
80
81##########
82# Layers #
83##########
84
85# See bluez/lib/hci.h for details
86
87# Transport layers
88
89class HCI_PHDR_Hdr(Packet):
90    name = "HCI PHDR transport layer"
91    fields_desc = [IntField("direction", 0)]
92
93
94# Real layers
95
96_bluetooth_packet_types = {
97    0: "Acknowledgement",
98    1: "Command",
99    2: "ACL Data",
100    3: "Synchronous",
101    4: "Event",
102    5: "Reserve",
103    14: "Vendor",
104    15: "Link Control"
105}
106
107_bluetooth_error_codes = {
108    0x00: "Success",
109    0x01: "Unknown HCI Command",
110    0x02: "Unknown Connection Identifier",
111    0x03: "Hardware Failure",
112    0x04: "Page Timeout",
113    0x05: "Authentication Failure",
114    0x06: "PIN or Key Missing",
115    0x07: "Memory Capacity Exceeded",
116    0x08: "Connection Timeout",
117    0x09: "Connection Limit Exceeded",
118    0x0A: "Synchronous Connection Limit To A Device Exceeded",
119    0x0B: "Connection Already Exists",
120    0x0C: "Command Disallowed",
121    0x0D: "Connection Rejected due to Limited Resources",
122    0x0E: "Connection Rejected Due To Security Reasons",
123    0x0F: "Connection Rejected due to Unacceptable BD_ADDR",
124    0x10: "Connection Accept Timeout Exceeded",
125    0x11: "Unsupported Feature or Parameter Value",
126    0x12: "Invalid HCI Command Parameters",
127    0x13: "Remote User Terminated Connection",
128    0x14: "Remote Device Terminated Connection due to Low Resources",
129    0x15: "Remote Device Terminated Connection due to Power Off",
130    0x16: "Connection Terminated By Local Host",
131    0x17: "Repeated Attempts",
132    0x18: "Pairing Not Allowed",
133    0x19: "Unknown LMP PDU",
134    0x1A: "Unsupported Remote Feature / Unsupported LMP Feature",
135    0x1B: "SCO Offset Rejected",
136    0x1C: "SCO Interval Rejected",
137    0x1D: "SCO Air Mode Rejected",
138    0x1E: "Invalid LMP Parameters / Invalid LL Parameters",
139    0x1F: "Unspecified Error",
140    0x20: "Unsupported LMP Parameter Value / Unsupported LL Parameter Value",
141    0x21: "Role Change Not Allowed",
142    0x22: "LMP Response Timeout / LL Response Timeout",
143    0x23: "LMP Error Transaction Collision / LL Procedure Collision",
144    0x24: "LMP PDU Not Allowed",
145    0x25: "Encryption Mode Not Acceptable",
146    0x26: "Link Key cannot be Changed",
147    0x27: "Requested QoS Not Supported",
148    0x28: "Instant Passed",
149    0x29: "Pairing With Unit Key Not Supported",
150    0x2A: "Different Transaction Collision",
151    0x2B: "Reserved for future use",
152    0x2C: "QoS Unacceptable Parameter",
153    0x2D: "QoS Rejected",
154    0x2E: "Channel Classification Not Supported",
155    0x2F: "Insufficient Security",
156    0x30: "Parameter Out Of Mandatory Range",
157    0x31: "Reserved for future use",
158    0x32: "Role Switch Pending",
159    0x33: "Reserved for future use",
160    0x34: "Reserved Slot Violation",
161    0x35: "Role Switch Failed",
162    0x36: "Extended Inquiry Response Too Large",
163    0x37: "Secure Simple Pairing Not Supported By Host",
164    0x38: "Host Busy - Pairing",
165    0x39: "Connection Rejected due to No Suitable Channel Found",
166    0x3A: "Controller Busy",
167    0x3B: "Unacceptable Connection Parameters",
168    0x3C: "Advertising Timeout",
169    0x3D: "Connection Terminated due to MIC Failure",
170    0x3E: "Connection Failed to be Established / Synchronization Timeout",
171    0x3F: "MAC Connection Failed",
172    0x40: "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock"
173          " Dragging",
174    0x41: "Type0 Submap Not Defined",
175    0x42: "Unknown Advertising Identifier",
176    0x43: "Limit Reached",
177    0x44: "Operation Cancelled by Host",
178    0x45: "Packet Too Long"
179}
180
181_att_error_codes = {
182    0x01: "invalid handle",
183    0x02: "read not permitted",
184    0x03: "write not permitted",
185    0x04: "invalid pdu",
186    0x05: "insufficient auth",
187    0x06: "unsupported req",
188    0x07: "invalid offset",
189    0x08: "insufficient author",
190    0x09: "prepare queue full",
191    0x0a: "attr not found",
192    0x0b: "attr not long",
193    0x0c: "insufficient key size",
194    0x0d: "invalid value size",
195    0x0e: "unlikely",
196    0x0f: "insufficiet encrypt",
197    0x10: "unsupported gpr type",
198    0x11: "insufficient resources",
199}
200
201_bluetooth_features = [
202    '3_slot_packets',
203    '5_slot_packets',
204    'encryption',
205    'slot_offset',
206    'timing_accuracy',
207    'role_switch',
208    'hold_mode',
209    'sniff_mode',
210    'park_mode',
211    'power_control_requests',
212    'channel_quality_driven_data_rate',
213    'sco_link',
214    'hv2_packets',
215    'hv3_packets',
216    'u_law_log_synchronous_data',
217    'a_law_log_synchronous_data',
218    'cvsd_synchronous_data',
219    'paging_parameter_negotiation',
220    'power_control',
221    'transparent_synchronous_data',
222    'flow_control_lag_4_bit0',
223    'flow_control_lag_4_bit1',
224    'flow_control_lag_4_bit2',
225    'broadband_encryption',
226    'cvsd_synchronous_data',
227    'edr_acl_2_mbps_mode',
228    'edr_acl_3_mbps_mode',
229    'enhanced_inquiry_scan',
230    'interlaced_inquiry_scan',
231    'interlaced_page_scan',
232    'rssi_with_inquiry_results',
233    'ev3_packets',
234    'ev4_packets',
235    'ev5_packets',
236    'reserved',
237    'afh_capable_slave',
238    'afh_classification_slave',
239    'br_edr_not_supported',
240    'le_supported_controller',
241    '3_slot_edr_acl_packets',
242    '5_slot_edr_acl_packets',
243    'sniff_subrating',
244    'pause_encryption',
245    'afh_capable_master',
246    'afh_classification_master',
247    'edr_esco_2_mbps_mode',
248    'edr_esco_3_mbps_mode',
249    '3_slot_edr_esco_packets',
250    'extended_inquiry_response',
251    'simultaneous_le_and_br_edr_to_same_device_capable_controller',
252    'reserved2',
253    'secure_simple_pairing',
254    'encapsulated_pdu',
255    'erroneous_data_reporting',
256    'non_flushable_packet_boundary_flag',
257    'reserved3',
258    'link_supervision_timeout_changed_event',
259    'inquiry_tx_power_level',
260    'enhanced_power_control',
261    'reserved4_bit0',
262    'reserved4_bit1',
263    'reserved4_bit2',
264    'reserved4_bit3',
265    'extended_features',
266]
267
268
269class HCI_Hdr(Packet):
270    name = "HCI header"
271    fields_desc = [ByteEnumField("type", 2, _bluetooth_packet_types)]
272
273    def mysummary(self):
274        return self.sprintf("HCI %type%")
275
276
277class HCI_ACL_Hdr(Packet):
278    name = "HCI ACL header"
279    fields_desc = [BitField("BC", 0, 2, tot_size=-2),
280                   BitField("PB", 0, 2),
281                   BitField("handle", 0, 12, end_tot_size=-2),
282                   LEShortField("len", None), ]
283
284    def post_build(self, p, pay):
285        p += pay
286        if self.len is None:
287            p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
288        return p
289
290
291class L2CAP_Hdr(Packet):
292    name = "L2CAP header"
293    fields_desc = [LEShortField("len", None),
294                   LEShortEnumField("cid", 0, {1: "control", 4: "attribute"}), ]  # noqa: E501
295
296    def post_build(self, p, pay):
297        p += pay
298        if self.len is None:
299            p = struct.pack("<H", len(pay)) + p[2:]
300        return p
301
302
303class L2CAP_CmdHdr(Packet):
304    name = "L2CAP command header"
305    fields_desc = [
306        ByteEnumField("code", 8, {1: "rej",
307                                  2: "conn_req",
308                                  3: "conn_resp",
309                                  4: "conf_req",
310                                  5: "conf_resp",
311                                  6: "disconn_req",
312                                  7: "disconn_resp",
313                                  8: "echo_req",
314                                  9: "echo_resp",
315                                  10: "info_req",
316                                  11: "info_resp",
317                                  12: "create_channel_req",
318                                  13: "create_channel_resp",
319                                  14: "move_channel_req",
320                                  15: "move_channel_resp",
321                                  16: "move_channel_confirm_req",
322                                  17: "move_channel_confirm_resp",
323                                  18: "conn_param_update_req",
324                                  19: "conn_param_update_resp",
325                                  20: "LE_credit_based_conn_req",
326                                  21: "LE_credit_based_conn_resp",
327                                  22: "flow_control_credit_ind",
328                                  23: "credit_based_conn_req",
329                                  24: "credit_based_conn_resp",
330                                  25: "credit_based_reconf_req",
331                                  26: "credit_based_reconf_resp"}),
332        ByteField("id", 0),
333        LEShortField("len", None)]
334
335    def post_build(self, p, pay):
336        p += pay
337        if self.len is None:
338            p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
339        return p
340
341    def answers(self, other):
342        if other.id == self.id:
343            if self.code == 1:
344                return 1
345            if other.code in [2, 4, 6, 8, 10, 18] and self.code == other.code + 1:  # noqa: E501
346                if other.code == 8:
347                    return 1
348                return self.payload.answers(other.payload)
349        return 0
350
351
352class L2CAP_ConnReq(Packet):
353    name = "L2CAP Conn Req"
354    fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
355                                               3: "RFCOMM",
356                                               5: "TCS-BIN",
357                                               7: "TCS-BIN-CORDLESS",
358                                               15: "BNEP",
359                                               17: "HID-Control",
360                                               19: "HID-Interrupt",
361                                               21: "UPnP",
362                                               23: "AVCTP-Control",
363                                               25: "AVDTP",
364                                               27: "AVCTP-Browsing",
365                                               29: "UDI_C-Plane",
366                                               31: "ATT",
367                                               33: "3DSP",
368                                               35: "IPSP",
369                                               37: "OTS"}),
370                   LEShortField("scid", 0),
371                   ]
372
373
374class L2CAP_ConnResp(Packet):
375    name = "L2CAP Conn Resp"
376    fields_desc = [LEShortField("dcid", 0),
377                   LEShortField("scid", 0),
378                   LEShortEnumField("result", 0, ["success", "pend", "cr_bad_psm", "cr_sec_block", "cr_no_mem", "reserved", "cr_inval_scid", "cr_scid_in_use"]),  # noqa: E501
379                   LEShortEnumField("status", 0, ["no_info", "authen_pend", "author_pend", "reserved"]),  # noqa: E501
380                   ]
381
382    def answers(self, other):
383        # dcid Resp == scid Req. Therefore compare SCIDs
384        return isinstance(other, L2CAP_ConnReq) and self.scid == other.scid
385
386
387class L2CAP_CmdRej(Packet):
388    name = "L2CAP Command Rej"
389    fields_desc = [LEShortField("reason", 0),
390                   ]
391
392
393class L2CAP_ConfReq(Packet):
394    name = "L2CAP Conf Req"
395    fields_desc = [LEShortField("dcid", 0),
396                   LEShortField("flags", 0),
397                   ]
398
399
400class L2CAP_ConfResp(Packet):
401    name = "L2CAP Conf Resp"
402    fields_desc = [LEShortField("scid", 0),
403                   LEShortField("flags", 0),
404                   LEShortEnumField("result", 0, ["success", "unaccept", "reject", "unknown"]),  # noqa: E501
405                   ]
406
407    def answers(self, other):
408        # Req and Resp contain either the SCID or the DCID.
409        return isinstance(other, L2CAP_ConfReq)
410
411
412class L2CAP_DisconnReq(Packet):
413    name = "L2CAP Disconn Req"
414    fields_desc = [LEShortField("dcid", 0),
415                   LEShortField("scid", 0), ]
416
417
418class L2CAP_DisconnResp(Packet):
419    name = "L2CAP Disconn Resp"
420    fields_desc = [LEShortField("dcid", 0),
421                   LEShortField("scid", 0), ]
422
423    def answers(self, other):
424        return self.scid == other.scid
425
426
427class L2CAP_EchoReq(Packet):
428    name = "L2CAP Echo Req"
429    fields_desc = [StrField("data", ""), ]
430
431
432class L2CAP_EchoResp(Packet):
433    name = "L2CAP Echo Resp"
434    fields_desc = [StrField("data", ""), ]
435
436
437class L2CAP_InfoReq(Packet):
438    name = "L2CAP Info Req"
439    fields_desc = [LEShortEnumField("type", 0, {1: "CL_MTU", 2: "FEAT_MASK"}),
440                   StrField("data", "")
441                   ]
442
443
444class L2CAP_InfoResp(Packet):
445    name = "L2CAP Info Resp"
446    fields_desc = [LEShortField("type", 0),
447                   LEShortEnumField("result", 0, ["success", "not_supp"]),
448                   StrField("data", ""), ]
449
450    def answers(self, other):
451        return self.type == other.type
452
453
454class L2CAP_Create_Channel_Request(Packet):
455    name = "L2CAP Create Channel Request"
456    fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
457                                               3: "RFCOMM",
458                                               5: "TCS-BIN",
459                                               7: "TCS-BIN-CORDLESS",
460                                               15: "BNEP",
461                                               17: "HID-Control",
462                                               19: "HID-Interrupt",
463                                               21: "UPnP",
464                                               23: "AVCTP-Control",
465                                               25: "AVDTP",
466                                               27: "AVCTP-Browsing",
467                                               29: "UDI_C-Plane",
468                                               31: "ATT",
469                                               33: "3DSP",
470                                               35: "IPSP",
471                                               37: "OTS"}),
472                   LEShortField("scid", 0),
473                   ByteField("controller_id", 0), ]
474
475
476class L2CAP_Create_Channel_Response(Packet):
477    name = "L2CAP Create Channel Response"
478    fields_desc = [LEShortField("dcid", 0),
479                   LEShortField("scid", 0),
480                   LEShortEnumField("result", 0, {
481                       0: "Connection successful",
482                       1: "Connection pending",
483                       2: "Connection refused - PSM not supported",
484                       3: "Connection refused - security block",
485                       4: "Connection refused - no resources available",
486                       5: "Connection refused - cont_ID not supported",
487                       6: "Connection refused - invalid scid",
488                       7: "Connection refused - scid already allocated"}),
489                   LEShortEnumField("status", 0, {
490                       0: "No further information available",
491                       1: "Authentication pending",
492                       2: "Authorization pending"}), ]
493
494
495class L2CAP_Move_Channel_Request(Packet):
496    name = "L2CAP Move Channel Request"
497    fields_desc = [LEShortField("icid", 0),
498                   ByteField("dest_controller_id", 0), ]
499
500
501class L2CAP_Move_Channel_Response(Packet):
502    name = "L2CAP Move Channel Response"
503    fields_desc = [LEShortField("icid", 0),
504                   LEShortEnumField("result", 0, {
505                       0: "Move success",
506                       1: "Move pending",
507                       2: "Move refused - Cont_ID not supported",
508                       3: "Move refused - Cont_ID is same as old one",
509                       4: "Move refused - Configuration not supported",
510                       5: "Move refused - Move channel collision",
511                       6: "Move refused - Not allowed to be moved"}), ]
512
513
514class L2CAP_Move_Channel_Confirmation_Request(Packet):
515    name = "L2CAP Move Channel Confirmation Request"
516    fields_desc = [LEShortField("icid", 0),
517                   LEShortEnumField("result", 0, {0: "Move success",
518                                                  1: "Move failure"}), ]
519
520
521class L2CAP_Move_Channel_Confirmation_Response(Packet):
522    name = "L2CAP Move Channel Confirmation Response"
523    fields_desc = [LEShortField("icid", 0), ]
524
525
526class L2CAP_Connection_Parameter_Update_Request(Packet):
527    name = "L2CAP Connection Parameter Update Request"
528    fields_desc = [LEShortField("min_interval", 0),
529                   LEShortField("max_interval", 0),
530                   LEShortField("slave_latency", 0),
531                   LEShortField("timeout_mult", 0), ]
532
533
534class L2CAP_Connection_Parameter_Update_Response(Packet):
535    name = "L2CAP Connection Parameter Update Response"
536    fields_desc = [LEShortField("move_result", 0), ]
537
538
539class L2CAP_LE_Credit_Based_Connection_Request(Packet):
540    name = "L2CAP LE Credit Based Connection Request"
541    fields_desc = [LEShortField("spsm", 0),
542                   LEShortField("scid", 0),
543                   LEShortField("mtu", 0),
544                   LEShortField("mps", 0),
545                   LEShortField("initial_credits", 0), ]
546
547
548class L2CAP_LE_Credit_Based_Connection_Response(Packet):
549    name = "L2CAP LE Credit Based Connection Response"
550    fields_desc = [LEShortField("dcid", 0),
551                   LEShortField("mtu", 0),
552                   LEShortField("mps", 0),
553                   LEShortField("initial_credits", 0),
554                   LEShortEnumField("result", 0, {
555                       0: "Connection successful",
556                       2: "Connection refused - SPSM not supported",
557                       4: "Connection refused - no resources available",
558                       5: "Connection refused - authentication error",
559                       6: "Connection refused - authorization error",
560                       7: "Connection refused - encrypt_key size error",
561                       8: "Connection refused - insufficient encryption",
562                       9: "Connection refused - invalid scid",
563                       10: "Connection refused - scid already allocated",
564                       11: "Connection refused - parameters error"}), ]
565
566
567class L2CAP_Flow_Control_Credit_Ind(Packet):
568    name = "L2CAP Flow Control Credit Ind"
569    fields_desc = [LEShortField("cid", 0),
570                   LEShortField("credits", 0), ]
571
572
573class L2CAP_Credit_Based_Connection_Request(Packet):
574    name = "L2CAP Credit Based Connection Request"
575    fields_desc = [LEShortField("spsm", 0),
576                   LEShortField("mtu", 0),
577                   LEShortField("mps", 0),
578                   LEShortField("initial_credits", 0),
579                   LEShortField("scid", 0), ]
580
581
582class L2CAP_Credit_Based_Connection_Response(Packet):
583    name = "L2CAP Credit Based Connection Response"
584    fields_desc = [LEShortField("mtu", 0),
585                   LEShortField("mps", 0),
586                   LEShortField("initial_credits", 0),
587                   LEShortEnumField("result", 0, {
588                       0: "All connection successful",
589                       2: "All connection refused - SPSM not supported",
590                       4: "Some connections refused - resources error",
591                       5: "All connection refused - authentication error",
592                       6: "All connection refused - authorization error",
593                       7: "All connection refused - encrypt_key size error",
594                       8: "All connection refused - encryption error",
595                       9: "Some connection refused - invalid scid",
596                       10: "Some connection refused - scid already allocated",
597                       11: "All Connection refused - unacceptable parameters",
598                       12: "All connections refused - invalid parameters"}),
599                   LEShortField("dcid", 0), ]
600
601
602class L2CAP_Credit_Based_Reconfigure_Request(Packet):
603    name = "L2CAP Credit Based Reconfigure Request"
604    fields_desc = [LEShortField("mtu", 0),
605                   LEShortField("mps", 0),
606                   LEShortField("dcid", 0), ]
607
608
609class L2CAP_Credit_Based_Reconfigure_Response(Packet):
610    name = "L2CAP Credit Based Reconfigure Response"
611    fields_desc = [LEShortEnumField("result", 0, {
612                   0: "Reconfig successful",
613                   1: "Reconfig failed - MTU size reduction not allowed",
614                   2: "Reconfig failed - MPS size reduction not allowed",
615                   3: "Reconfig failed - one or more dcids invalid",
616                   4: "Reconfig failed - unacceptable parameters"}), ]
617
618
619class ATT_Hdr(Packet):
620    name = "ATT header"
621    fields_desc = [XByteField("opcode", None), ]
622
623
624class ATT_Handle(Packet):
625    name = "ATT Short Handle"
626    fields_desc = [XLEShortField("handle", 0),
627                   XLEShortField("value", 0)]
628
629    def extract_padding(self, s):
630        return b'', s
631
632
633class ATT_Handle_UUID128(Packet):
634    name = "ATT Handle (UUID 128)"
635    fields_desc = [XLEShortField("handle", 0),
636                   UUIDField("value", None, uuid_fmt=UUIDField.FORMAT_REV)]
637
638    def extract_padding(self, s):
639        return b'', s
640
641
642class ATT_Error_Response(Packet):
643    name = "Error Response"
644    fields_desc = [XByteField("request", 0),
645                   LEShortField("handle", 0),
646                   ByteEnumField("ecode", 0, _att_error_codes), ]
647
648
649class ATT_Exchange_MTU_Request(Packet):
650    name = "Exchange MTU Request"
651    fields_desc = [LEShortField("mtu", 0), ]
652
653
654class ATT_Exchange_MTU_Response(Packet):
655    name = "Exchange MTU Response"
656    fields_desc = [LEShortField("mtu", 0), ]
657
658
659class ATT_Find_Information_Request(Packet):
660    name = "Find Information Request"
661    fields_desc = [XLEShortField("start", 0x0000),
662                   XLEShortField("end", 0xffff), ]
663
664
665class ATT_Find_Information_Response(Packet):
666    name = "Find Information Response"
667    fields_desc = [
668        XByteField("format", 1),
669        MultipleTypeField(
670            [
671                (PacketListField("handles", [], ATT_Handle),
672                    lambda pkt: pkt.format == 1),
673                (PacketListField("handles", [], ATT_Handle_UUID128),
674                    lambda pkt: pkt.format == 2),
675            ],
676            StrFixedLenField("handles", "", length=0)
677        )
678    ]
679
680
681class ATT_Find_By_Type_Value_Request(Packet):
682    name = "Find By Type Value Request"
683    fields_desc = [XLEShortField("start", 0x0001),
684                   XLEShortField("end", 0xffff),
685                   XLEShortField("uuid", None),
686                   StrField("data", ""), ]
687
688
689class ATT_Find_By_Type_Value_Response(Packet):
690    name = "Find By Type Value Response"
691    fields_desc = [PacketListField("handles", [], ATT_Handle)]
692
693
694class ATT_Read_By_Type_Request_128bit(Packet):
695    name = "Read By Type Request"
696    fields_desc = [XLEShortField("start", 0x0001),
697                   XLEShortField("end", 0xffff),
698                   XLELongField("uuid1", None),
699                   XLELongField("uuid2", None)]
700
701    @classmethod
702    def dispatch_hook(cls, _pkt=None, *args, **kargs):
703        if _pkt and len(_pkt) == 6:
704            return ATT_Read_By_Type_Request
705        return ATT_Read_By_Type_Request_128bit
706
707
708class ATT_Read_By_Type_Request(Packet):
709    name = "Read By Type Request"
710    fields_desc = [XLEShortField("start", 0x0001),
711                   XLEShortField("end", 0xffff),
712                   XLEShortField("uuid", None)]
713
714
715class ATT_Handle_Variable(Packet):
716    __slots__ = ["val_length"]
717    fields_desc = [XLEShortField("handle", 0),
718                   XStrLenField(
719                       "value", 0,
720                       length_from=lambda pkt: pkt.val_length)]
721
722    def __init__(self, _pkt=b"", val_length=2, **kwargs):
723        self.val_length = val_length
724        Packet.__init__(self, _pkt, **kwargs)
725
726    def extract_padding(self, s):
727        return b"", s
728
729
730class ATT_Read_By_Type_Response(Packet):
731    name = "Read By Type Response"
732    fields_desc = [ByteField("len", 4),
733                   PacketListField(
734                       "handles", [],
735                       next_cls_cb=lambda pkt, *args: (
736                           pkt._next_cls_cb(pkt, *args)
737                       ))]
738
739    @classmethod
740    def _next_cls_cb(cls, pkt, lst, p, remain):
741        if len(remain) >= pkt.len:
742            return functools.partial(
743                ATT_Handle_Variable,
744                val_length=pkt.len - 2
745            )
746        return None
747
748
749class ATT_Read_Request(Packet):
750    name = "Read Request"
751    fields_desc = [XLEShortField("gatt_handle", 0), ]
752
753
754class ATT_Read_Response(Packet):
755    name = "Read Response"
756    fields_desc = [StrField("value", "")]
757
758
759class ATT_Read_Multiple_Request(Packet):
760    name = "Read Multiple Request"
761    fields_desc = [FieldListField("handles", [], XLEShortField("", 0))]
762
763
764class ATT_Read_Multiple_Response(Packet):
765    name = "Read Multiple Response"
766    fields_desc = [StrField("values", "")]
767
768
769class ATT_Read_By_Group_Type_Request(Packet):
770    name = "Read By Group Type Request"
771    fields_desc = [XLEShortField("start", 0),
772                   XLEShortField("end", 0xffff),
773                   XLEShortField("uuid", 0), ]
774
775
776class ATT_Read_By_Group_Type_Response(Packet):
777    name = "Read By Group Type Response"
778    fields_desc = [XByteField("length", 0),
779                   StrField("data", ""), ]
780
781
782class ATT_Write_Request(Packet):
783    name = "Write Request"
784    fields_desc = [XLEShortField("gatt_handle", 0),
785                   StrField("data", ""), ]
786
787
788class ATT_Write_Command(Packet):
789    name = "Write Request"
790    fields_desc = [XLEShortField("gatt_handle", 0),
791                   StrField("data", ""), ]
792
793
794class ATT_Write_Response(Packet):
795    name = "Write Response"
796
797
798class ATT_Prepare_Write_Request(Packet):
799    name = "Prepare Write Request"
800    fields_desc = [
801        XLEShortField("gatt_handle", 0),
802        LEShortField("offset", 0),
803        StrField("data", "")
804    ]
805
806
807class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request):
808    name = "Prepare Write Response"
809
810
811class ATT_Handle_Value_Notification(Packet):
812    name = "Handle Value Notification"
813    fields_desc = [XLEShortField("gatt_handle", 0),
814                   StrField("value", ""), ]
815
816
817class ATT_Execute_Write_Request(Packet):
818    name = "Execute Write Request"
819    fields_desc = [
820        ByteEnumField("flags", 1, {
821            0: "Cancel all prepared writes",
822            1: "Immediately write all pending prepared values",
823        }),
824    ]
825
826
827class ATT_Execute_Write_Response(Packet):
828    name = "Execute Write Response"
829
830
831class ATT_Read_Blob_Request(Packet):
832    name = "Read Blob Request"
833    fields_desc = [
834        XLEShortField("gatt_handle", 0),
835        LEShortField("offset", 0)
836    ]
837
838
839class ATT_Read_Blob_Response(Packet):
840    name = "Read Blob Response"
841    fields_desc = [
842        StrField("value", "")
843    ]
844
845
846class ATT_Handle_Value_Indication(Packet):
847    name = "Handle Value Indication"
848    fields_desc = [
849        XLEShortField("gatt_handle", 0),
850        StrField("value", ""),
851    ]
852
853
854class SM_Hdr(Packet):
855    name = "SM header"
856    fields_desc = [ByteField("sm_command", None)]
857
858
859class SM_Pairing_Request(Packet):
860    name = "Pairing Request"
861    fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}),  # noqa: E501
862                   ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}),  # noqa: E501
863                   BitField("authentication", 0, 8),
864                   ByteField("max_key_size", 16),
865                   ByteField("initiator_key_distribution", 0),
866                   ByteField("responder_key_distribution", 0), ]
867
868
869class SM_Pairing_Response(Packet):
870    name = "Pairing Response"
871    fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}),  # noqa: E501
872                   ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}),  # noqa: E501
873                   BitField("authentication", 0, 8),
874                   ByteField("max_key_size", 16),
875                   ByteField("initiator_key_distribution", 0),
876                   ByteField("responder_key_distribution", 0), ]
877
878
879class SM_Confirm(Packet):
880    name = "Pairing Confirm"
881    fields_desc = [StrFixedLenField("confirm", b'\x00' * 16, 16)]
882
883
884class SM_Random(Packet):
885    name = "Pairing Random"
886    fields_desc = [StrFixedLenField("random", b'\x00' * 16, 16)]
887
888
889class SM_Failed(Packet):
890    name = "Pairing Failed"
891    fields_desc = [XByteField("reason", 0)]
892
893
894class SM_Encryption_Information(Packet):
895    name = "Encryption Information"
896    fields_desc = [StrFixedLenField("ltk", b"\x00" * 16, 16), ]
897
898
899class SM_Master_Identification(Packet):
900    name = "Master Identification"
901    fields_desc = [XLEShortField("ediv", 0),
902                   StrFixedLenField("rand", b'\x00' * 8, 8), ]
903
904
905class SM_Identity_Information(Packet):
906    name = "Identity Information"
907    fields_desc = [StrFixedLenField("irk", b'\x00' * 16, 16), ]
908
909
910class SM_Identity_Address_Information(Packet):
911    name = "Identity Address Information"
912    fields_desc = [ByteEnumField("atype", 0, {0: "public"}),
913                   LEMACField("address", None), ]
914
915
916class SM_Signing_Information(Packet):
917    name = "Signing Information"
918    fields_desc = [StrFixedLenField("csrk", b'\x00' * 16, 16), ]
919
920
921class SM_Public_Key(Packet):
922    name = "Public Key"
923    fields_desc = [StrFixedLenField("key_x", b'\x00' * 32, 32),
924                   StrFixedLenField("key_y", b'\x00' * 32, 32), ]
925
926
927class SM_DHKey_Check(Packet):
928    name = "DHKey Check"
929    fields_desc = [StrFixedLenField("dhkey_check", b'\x00' * 16, 16), ]
930
931
932class EIR_Hdr(Packet):
933    name = "EIR Header"
934    fields_desc = [
935        LenField("len", None, fmt="B", adjust=lambda x: x + 1),  # Add bytes mark  # noqa: E501
936        # https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
937        ByteEnumField("type", 0, {
938            0x01: "flags",
939            0x02: "incomplete_list_16_bit_svc_uuids",
940            0x03: "complete_list_16_bit_svc_uuids",
941            0x04: "incomplete_list_32_bit_svc_uuids",
942            0x05: "complete_list_32_bit_svc_uuids",
943            0x06: "incomplete_list_128_bit_svc_uuids",
944            0x07: "complete_list_128_bit_svc_uuids",
945            0x08: "shortened_local_name",
946            0x09: "complete_local_name",
947            0x0a: "tx_power_level",
948            0x0d: "class_of_device",
949            0x0e: "simple_pairing_hash",
950            0x0f: "simple_pairing_rand",
951
952            0x10: "sec_mgr_tk",
953            0x11: "sec_mgr_oob_flags",
954            0x12: "slave_conn_intvl_range",
955            0x14: "list_16_bit_svc_sollication_uuids",
956            0x15: "list_128_bit_svc_sollication_uuids",
957            0x16: "svc_data_16_bit_uuid",
958            0x17: "pub_target_addr",
959            0x18: "rand_target_addr",
960            0x19: "appearance",
961            0x1a: "adv_intvl",
962            0x1b: "le_addr",
963            0x1c: "le_role",
964            0x1d: "simple_pairing_hash_256",
965            0x1e: "simple_pairing_rand_256",
966            0x1f: "list_32_bit_svc_sollication_uuids",
967
968            0x20: "svc_data_32_bit_uuid",
969            0x21: "svc_data_128_bit_uuid",
970            0x22: "sec_conn_confirm",
971            0x23: "sec_conn_rand",
972            0x24: "uri",
973            0x25: "indoor_positioning",
974            0x26: "transport_discovery",
975            0x27: "le_supported_features",
976            0x28: "channel_map_update",
977            0x29: "mesh_pb_adv",
978            0x2a: "mesh_message",
979            0x2b: "mesh_beacon",
980
981            0x3d: "3d_information",
982
983            0xff: "mfg_specific_data",
984        }),
985    ]
986
987    def mysummary(self):
988        return self.sprintf("EIR %type%")
989
990    def guess_payload_class(self, payload):
991        if self.len == 0:
992            # For Extended_Inquiry_Response, stop when len=0
993            return conf.padding_layer
994        return super(EIR_Hdr, self).guess_payload_class(payload)
995
996
997class EIR_Element(Packet):
998    name = "EIR Element"
999
1000    def extract_padding(self, s):
1001        # Needed to end each EIR_Element packet and make PacketListField work.
1002        return b'', s
1003
1004    @staticmethod
1005    def length_from(pkt):
1006        if not pkt.underlayer:
1007            warning("Missing an upper-layer")
1008            return 0
1009        # 'type' byte is included in the length, so subtract 1:
1010        return pkt.underlayer.len - 1
1011
1012
1013class EIR_Raw(EIR_Element):
1014    name = "EIR Raw"
1015    fields_desc = [
1016        StrLenField("data", "", length_from=EIR_Element.length_from)
1017    ]
1018
1019
1020class EIR_Flags(EIR_Element):
1021    name = "Flags"
1022    fields_desc = [
1023        FlagsField("flags", 0x2, 8,
1024                   ["limited_disc_mode", "general_disc_mode",
1025                    "br_edr_not_supported", "simul_le_br_edr_ctrl",
1026                    "simul_le_br_edr_host"] + 3 * ["reserved"])
1027    ]
1028
1029
1030class EIR_CompleteList16BitServiceUUIDs(EIR_Element):
1031    name = "Complete list of 16-bit service UUIDs"
1032    fields_desc = [
1033        # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1034        FieldListField("svc_uuids", None, XLEShortField("uuid", 0),
1035                       length_from=EIR_Element.length_from)
1036    ]
1037
1038
1039class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs):
1040    name = "Incomplete list of 16-bit service UUIDs"
1041
1042
1043class EIR_CompleteList32BitServiceUUIDs(EIR_Element):
1044    name = 'Complete list of 32-bit service UUIDs'
1045    fields_desc = [
1046        # https://www.bluetooth.com/specifications/assigned-numbers
1047        FieldListField('svc_uuids', None, XLEIntField('uuid', 0),
1048                       length_from=EIR_Element.length_from)
1049    ]
1050
1051
1052class EIR_IncompleteList32BitServiceUUIDs(EIR_CompleteList32BitServiceUUIDs):
1053    name = 'Incomplete list of 32-bit service UUIDs'
1054
1055
1056class EIR_CompleteList128BitServiceUUIDs(EIR_Element):
1057    name = "Complete list of 128-bit service UUIDs"
1058    fields_desc = [
1059        FieldListField("svc_uuids", None,
1060                       UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV),
1061                       length_from=EIR_Element.length_from)
1062    ]
1063
1064
1065class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs):
1066    name = "Incomplete list of 128-bit service UUIDs"
1067
1068
1069class EIR_CompleteLocalName(EIR_Element):
1070    name = "Complete Local Name"
1071    fields_desc = [
1072        StrLenField("local_name", "", length_from=EIR_Element.length_from)
1073    ]
1074
1075
1076class EIR_ShortenedLocalName(EIR_CompleteLocalName):
1077    name = "Shortened Local Name"
1078
1079
1080class EIR_TX_Power_Level(EIR_Element):
1081    name = "TX Power Level"
1082    fields_desc = [SignedByteField("level", 0)]
1083
1084
1085class EIR_ClassOfDevice(EIR_Element):
1086    name = 'Class of device'
1087    fields_desc = [
1088        FlagsField('major_service_classes', 0, 11, [
1089            'limited_discoverable_mode',
1090            'le_audio',
1091            'reserved',
1092            'positioning',
1093            'networking',
1094            'rendering',
1095            'capturing',
1096            'object_transfer',
1097            'audio',
1098            'telephony',
1099            'information'
1100        ], tot_size=-3),
1101        BitEnumField('major_device_class', 0, 5, {
1102            0x00: 'miscellaneous',
1103            0x01: 'computer',
1104            0x02: 'phone',
1105            0x03: 'lan',
1106            0x04: 'audio_video',
1107            0x05: 'peripheral',
1108            0x06: 'imaging',
1109            0x07: 'wearable',
1110            0x08: 'toy',
1111            0x09: 'health',
1112            0x1f: 'uncategorized'
1113        }),
1114        BitField('minor_device_class', 0, 6),
1115        BitField('fixed', 0, 2, end_tot_size=-3)
1116    ]
1117
1118
1119class EIR_SecureSimplePairingHashC192(EIR_Element):
1120    name = 'Secure Simple Pairing Hash C-192'
1121    fields_desc = [NBytesField('hash', 0, 16)]
1122
1123
1124class EIR_SecureSimplePairingRandomizerR192(EIR_Element):
1125    name = 'Secure Simple Pairing Randomizer R-192'
1126    fields_desc = [NBytesField('randomizer', 0, 16)]
1127
1128
1129class EIR_SecurityManagerOOBFlags(EIR_Element):
1130    name = 'Security Manager Out of Band Flags'
1131    fields_desc = [
1132        BitField('oob_flags_field', 0, 1),
1133        BitField('le_supported', 0, 1),
1134        BitField('previously_used', 0, 1),
1135        BitField('address_type', 0, 1),
1136        BitField('reserved', 0, 4)
1137    ]
1138
1139
1140class EIR_PeripheralConnectionIntervalRange(EIR_Element):
1141    name = 'Peripheral Connection Interval Range'
1142    fields_desc = [
1143        LEShortField('conn_interval_min', 0xFFFF),
1144        LEShortField('conn_interval_max', 0xFFFF)
1145    ]
1146
1147
1148class EIR_Manufacturer_Specific_Data(EIR_Element):
1149    name = "EIR Manufacturer Specific Data"
1150    fields_desc = [
1151        # https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
1152        XLEShortField("company_id", None),
1153    ]
1154
1155    registered_magic_payloads = {}
1156
1157    @classmethod
1158    def register_magic_payload(cls, payload_cls, magic_check=None):
1159        """
1160        Registers a payload type that uses magic data.
1161
1162        Traditional payloads require registration of a Bluetooth Company ID
1163        (requires company membership of the Bluetooth SIG), or a Bluetooth
1164        Short UUID (requires a once-off payment).
1165
1166        There are alternatives which don't require registration (such as
1167        128-bit UUIDs), but the biggest consumer of energy in a beacon is the
1168        radio -- so the energy consumption of a beacon is proportional to the
1169        number of bytes in a beacon frame.
1170
1171        Some beacon formats side-step this issue by using the Company ID of
1172        their beacon hardware manufacturer, and adding a "magic data sequence"
1173        at the start of the Manufacturer Specific Data field.
1174
1175        Examples of this are AltBeacon and GeoBeacon.
1176
1177        For an example of this method in use, see ``scapy.contrib.altbeacon``.
1178
1179        :param Type[scapy.packet.Packet] payload_cls:
1180            A reference to a Packet subclass to register as a payload.
1181        :param Callable[[bytes], bool] magic_check:
1182            (optional) callable to use to if a payload should be associated
1183            with this type. If not supplied, ``payload_cls.magic_check`` is
1184            used instead.
1185        :raises TypeError: If ``magic_check`` is not specified,
1186                           and ``payload_cls.magic_check`` is not implemented.
1187        """
1188        if magic_check is None:
1189            if hasattr(payload_cls, "magic_check"):
1190                magic_check = payload_cls.magic_check
1191            else:
1192                raise TypeError("magic_check not specified, and {} has no "
1193                                "attribute magic_check".format(payload_cls))
1194
1195        cls.registered_magic_payloads[payload_cls] = magic_check
1196
1197    def default_payload_class(self, payload):
1198        for cls, check in (
1199            EIR_Manufacturer_Specific_Data.registered_magic_payloads.items()
1200        ):
1201            if check(payload):
1202                return cls
1203
1204        return Packet.default_payload_class(self, payload)
1205
1206    def extract_padding(self, s):
1207        # Needed to end each EIR_Element packet and make PacketListField work.
1208        plen = EIR_Element.length_from(self) - 2
1209        return s[:plen], s[plen:]
1210
1211
1212class EIR_Device_ID(EIR_Element):
1213    name = "Device ID"
1214    fields_desc = [
1215        XLEShortField("vendor_id_source", 0),
1216        XLEShortField("vendor_id", 0),
1217        XLEShortField("product_id", 0),
1218        XLEShortField("version", 0),
1219    ]
1220
1221
1222class EIR_ServiceData16BitUUID(EIR_Element):
1223    name = "EIR Service Data - 16-bit UUID"
1224    fields_desc = [
1225        # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1226        XLEShortField("svc_uuid", None),
1227    ]
1228
1229    def extract_padding(self, s):
1230        # Needed to end each EIR_Element packet and make PacketListField work.
1231        plen = EIR_Element.length_from(self) - 2
1232        return s[:plen], s[plen:]
1233
1234
1235class EIR_ServiceData32BitUUID(EIR_Element):
1236    name = 'EIR Service Data - 32-bit UUID'
1237    fields_desc = [
1238        XLEIntField('svc_uuid', 0),
1239    ]
1240
1241    def extract_padding(self, s):
1242        # Needed to end each EIR_Element packet and make PacketListField work.
1243        plen = EIR_Element.length_from(self) - 4
1244        return s[:plen], s[plen:]
1245
1246
1247class EIR_ServiceData128BitUUID(EIR_Element):
1248    name = 'EIR Service Data - 128-bit UUID'
1249    fields_desc = [
1250        UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV)
1251    ]
1252
1253    def extract_padding(self, s):
1254        # Needed to end each EIR_Element packet and make PacketListField work.
1255        plen = EIR_Element.length_from(self) - 16
1256        return s[:plen], s[plen:]
1257
1258
1259class HCI_Command_Hdr(Packet):
1260    name = "HCI Command header"
1261    fields_desc = [XBitField("ogf", 0, 6, tot_size=-2),
1262                   XBitField("ocf", 0, 10, end_tot_size=-2),
1263                   LenField("len", None, fmt="B"), ]
1264
1265    def answers(self, other):
1266        return False
1267
1268    @property
1269    def opcode(self):
1270        return (self.ogf << 10) + self.ocf
1271
1272    def post_build(self, p, pay):
1273        p += pay
1274        if self.len is None:
1275            p = p[:2] + struct.pack("B", len(pay)) + p[3:]
1276        return p
1277
1278
1279# BUETOOTH CORE SPECIFICATION 5.4 | Vol 3, Part C
1280# 8 EXTENDED INQUIRY RESPONSE
1281
1282class HCI_Extended_Inquiry_Response(Packet):
1283    fields_desc = [
1284        PadField(
1285            PacketListField(
1286                "eir_data", [],
1287                next_cls_cb=lambda *args: (
1288                    (not args[2] or args[2].len != 0) and EIR_Hdr or conf.raw_layer
1289                )
1290            ),
1291            align=31, padwith=b"\0",
1292        ),
1293    ]
1294
1295
1296# BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
1297# 7 HCI COMMANDS AND EVENTS
1298# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
1299
1300class HCI_Cmd_Inquiry(Packet):
1301    """
1302    7.1.1 Inquiry command
1303    """
1304    name = "HCI_Inquiry"
1305    fields_desc = [XLE3BytesField("lap", 0x9E8B33),
1306                   ByteField("inquiry_length", 0),
1307                   ByteField("num_responses", 0)]
1308
1309
1310class HCI_Cmd_Inquiry_Cancel(Packet):
1311    """
1312    7.1.2 Inquiry Cancel command
1313    """
1314    name = "HCI_Inquiry_Cancel"
1315
1316
1317class HCI_Cmd_Periodic_Inquiry_Mode(Packet):
1318    """
1319    7.1.3 Periodic Inquiry Mode command
1320    """
1321    name = "HCI_Periodic_Inquiry_Mode"
1322    fields_desc = [LEShortField("max_period_length", 0x0003),
1323                   LEShortField("min_period_length", 0x0002),
1324                   XLE3BytesField("lap", 0x9E8B33),
1325                   ByteField("inquiry_length", 0),
1326                   ByteField("num_responses", 0)]
1327
1328
1329class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet):
1330    """
1331    7.1.4 Exit Periodic Inquiry Mode command
1332    """
1333    name = "HCI_Exit_Periodic_Inquiry_Mode"
1334
1335
1336class HCI_Cmd_Create_Connection(Packet):
1337    """
1338    7.1.5 Create Connection command
1339    """
1340    name = "HCI_Create_Connection"
1341    fields_desc = [LEMACField("bd_addr", None),
1342                   LEShortField("packet_type", 0xcc18),
1343                   ByteField("page_scan_repetition_mode", 0x02),
1344                   ByteField("reserved", 0x0),
1345                   LEShortField("clock_offset", 0x0),
1346                   ByteField("allow_role_switch", 0x1), ]
1347
1348
1349class HCI_Cmd_Disconnect(Packet):
1350    """
1351    7.1.6 Disconnect command
1352    """
1353    name = "HCI_Disconnect"
1354    fields_desc = [XLEShortField("handle", 0),
1355                   ByteField("reason", 0x13), ]
1356
1357
1358class HCI_Cmd_Create_Connection_Cancel(Packet):
1359    """
1360    7.1.7 Create Connection Cancel command
1361    """
1362    name = "HCI_Create_Connection_Cancel"
1363    fields_desc = [LEMACField("bd_addr", None), ]
1364
1365
1366class HCI_Cmd_Accept_Connection_Request(Packet):
1367    """
1368    7.1.8 Accept Connection Request command
1369    """
1370    name = "HCI_Accept_Connection_Request"
1371    fields_desc = [LEMACField("bd_addr", None),
1372                   ByteField("role", 0x1), ]
1373
1374
1375class HCI_Cmd_Reject_Connection_Response(Packet):
1376    """
1377    7.1.9 Reject Connection Request command
1378    """
1379    name = "HCI_Reject_Connection_Response"
1380    fields_desc = [LEMACField("bd_addr", None),
1381                   ByteField("reason", 0x1), ]
1382
1383
1384class HCI_Cmd_Link_Key_Request_Reply(Packet):
1385    """
1386    7.1.10 Link Key Request Reply command
1387    """
1388    name = "HCI_Link_Key_Request_Reply"
1389    fields_desc = [LEMACField("bd_addr", None),
1390                   NBytesField("link_key", None, 16), ]
1391
1392
1393class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet):
1394    """
1395    7.1.11 Link Key Request Negative Reply command
1396    """
1397    name = "HCI_Link_Key_Request_Negative_Reply"
1398    fields_desc = [LEMACField("bd_addr", None), ]
1399
1400
1401class HCI_Cmd_PIN_Code_Request_Reply(Packet):
1402    """
1403    7.1.12 PIN Code Request Reply command
1404    """
1405    name = "HCI_PIN_Code_Request_Reply"
1406    fields_desc = [LEMACField("bd_addr", None),
1407                   ByteField("pin_code_length", 7),
1408                   NBytesField("pin_code", b"\x00" * 16, sz=16), ]
1409
1410
1411class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet):
1412    """
1413    7.1.13 PIN Code Request Negative Reply command
1414    """
1415    name = "HCI_PIN_Code_Request_Negative_Reply"
1416    fields_desc = [LEMACField("bd_addr", None), ]
1417
1418
1419class HCI_Cmd_Change_Connection_Packet_Type(Packet):
1420    """
1421    7.1.14 Change Connection Packet Type command
1422    """
1423    name = "HCI_Cmd_Change_Connection_Packet_Type"
1424    fields_desc = [XLEShortField("connection_handle", None),
1425                   LEShortField("packet_type", 0), ]
1426
1427
1428class HCI_Cmd_Authentication_Requested(Packet):
1429    """
1430    7.1.15 Authentication Requested command
1431    """
1432    name = "HCI_Authentication_Requested"
1433    fields_desc = [LEShortField("handle", 0)]
1434
1435
1436class HCI_Cmd_Set_Connection_Encryption(Packet):
1437    """
1438    7.1.16 Set Connection Encryption command
1439    """
1440    name = "HCI_Set_Connection_Encryption"
1441    fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)]
1442
1443
1444class HCI_Cmd_Change_Connection_Link_Key(Packet):
1445    """
1446    7.1.17 Change Connection Link Key command
1447    """
1448    name = "HCI_Change_Connection_Link_Key"
1449    fields_desc = [LEShortField("handle", 0), ]
1450
1451
1452class HCI_Cmd_Link_Key_Selection(Packet):
1453    """
1454    7.1.18 Change Connection Link Key command
1455    """
1456    name = "HCI_Cmd_Link_Key_Selection"
1457    fields_desc = [ByteEnumField("handle", 0, {0: "Use semi-permanent Link Keys",
1458                                               1: "Use Temporary Link Key", }), ]
1459
1460
1461class HCI_Cmd_Remote_Name_Request(Packet):
1462    """
1463    7.1.19 Remote Name Request command
1464    """
1465    name = "HCI_Remote_Name_Request"
1466    fields_desc = [LEMACField("bd_addr", None),
1467                   ByteField("page_scan_repetition_mode", 0x02),
1468                   ByteField("reserved", 0x0),
1469                   LEShortField("clock_offset", 0x0), ]
1470
1471
1472class HCI_Cmd_Remote_Name_Request_Cancel(Packet):
1473    """
1474    7.1.20 Remote Name Request Cancel command
1475    """
1476    name = "HCI_Remote_Name_Request_Cancel"
1477    fields_desc = [LEMACField("bd_addr", None), ]
1478
1479
1480class HCI_Cmd_Read_Remote_Supported_Features(Packet):
1481    """
1482    7.1.21 Read Remote Supported Features command
1483    """
1484    name = "HCI_Read_Remote_Supported_Features"
1485    fields_desc = [LEShortField("connection_handle", None), ]
1486
1487
1488class HCI_Cmd_Read_Remote_Extended_Features(Packet):
1489    """
1490    7.1.22 Read Remote Extended Features command
1491    """
1492    name = "HCI_Read_Remote_Supported_Features"
1493    fields_desc = [LEShortField("connection_handle", None),
1494                   ByteField("page_number", None), ]
1495
1496
1497class HCI_Cmd_IO_Capability_Request_Reply(Packet):
1498    """
1499    7.1.29 IO Capability Request Reply command
1500    """
1501    name = "HCI_Read_Remote_Supported_Features"
1502    fields_desc = [LEMACField("bd_addr", None),
1503                   ByteEnumField("io_capability", None, {0x00: "DisplayOnly",
1504                                                         0x01: "DisplayYesNo",
1505                                                         0x02: "KeyboardOnly",
1506                                                         0x03: "NoInputNoOutput", }),
1507                   ByteEnumField("oob_data_present", None, {0x00: "Not Present",
1508                                                            0x01: "P-192",
1509                                                            0x02: "P-256",
1510                                                            0x03: "P-192 + P-256", }),
1511                   ByteEnumField("authentication_requirement", None,
1512                                 {0x00: "MITM Not Required",
1513                                  0x01: "MITM Required, No Bonding",
1514                                  0x02: "MITM Not Required + Dedicated Pairing",
1515                                  0x03: "MITM Required + Dedicated Pairing",
1516                                  0x04: "MITM Not Required, General Bonding",
1517                                  0x05: "MITM Required + General Bonding"}), ]
1518
1519
1520class HCI_Cmd_User_Confirmation_Request_Reply(Packet):
1521    """
1522    7.1.30 User Confirmation Request Reply command
1523    """
1524    name = "HCI_User_Confirmation_Request_Reply"
1525    fields_desc = [LEMACField("bd_addr", None), ]
1526
1527
1528class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet):
1529    """
1530    7.1.31 User Confirmation Request Negative Reply command
1531    """
1532    name = "HCI_User_Confirmation_Request_Negative_Reply"
1533    fields_desc = [LEMACField("bd_addr", None), ]
1534
1535
1536class HCI_Cmd_User_Passkey_Request_Reply(Packet):
1537    """
1538    7.1.32 User Passkey Request Reply command
1539    """
1540    name = "HCI_User_Passkey_Request_Reply"
1541    fields_desc = [LEMACField("bd_addr", None),
1542                   LEIntField("numeric_value", None), ]
1543
1544
1545class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet):
1546    """
1547    7.1.33 User Passkey Request Negative Reply command
1548    """
1549    name = "HCI_User_Passkey_Request_Negative_Reply"
1550    fields_desc = [LEMACField("bd_addr", None), ]
1551
1552
1553class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet):
1554    """
1555    7.1.34 Remote OOB Data Request Reply command
1556    """
1557    name = "HCI_Remote_OOB_Data_Request_Reply"
1558    fields_desc = [LEMACField("bd_addr", None),
1559                   NBytesField("C", b"\x00" * 16, sz=16),
1560                   NBytesField("R", b"\x00" * 16, sz=16), ]
1561
1562
1563class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet):
1564    """
1565    7.1.35 Remote OOB Data Request Negative Reply command
1566    """
1567    name = "HCI_Remote_OOB_Data_Request_Negative_Reply"
1568    fields_desc = [LEMACField("bd_addr", None), ]
1569
1570
1571# 7.2 Link Policy commands, the OGF is defined as 0x02
1572
1573class HCI_Cmd_Hold_Mode(Packet):
1574    name = "HCI_Hold_Mode"
1575    fields_desc = [LEShortField("connection_handle", 0),
1576                   LEShortField("hold_mode_max_interval", 0x0002),
1577                   LEShortField("hold_mode_min_interval", 0x0002), ]
1578
1579
1580# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
1581
1582class HCI_Cmd_Set_Event_Mask(Packet):
1583    """
1584    7.3.1 Set Event Mask command
1585    """
1586    name = "HCI_Set_Event_Mask"
1587    fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)]  # noqa: E501
1588
1589
1590class HCI_Cmd_Reset(Packet):
1591    """
1592    7.3.2 Reset command
1593    """
1594    name = "HCI_Reset"
1595
1596
1597class HCI_Cmd_Set_Event_Filter(Packet):
1598    """
1599    7.3.3 Set Event Filter command
1600    """
1601    name = "HCI_Set_Event_Filter"
1602    fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ]
1603
1604
1605class HCI_Cmd_Write_Local_Name(Packet):
1606    """
1607    7.3.11 Write Local Name command
1608    """
1609    name = "HCI_Write_Local_Name"
1610    fields_desc = [StrFixedLenField('name', '', length=248)]
1611
1612
1613class HCI_Cmd_Read_Local_Name(Packet):
1614    """
1615    7.3.12 Read Local Name command
1616    """
1617    name = "HCI_Read_Local_Name"
1618
1619
1620class HCI_Cmd_Write_Connect_Accept_Timeout(Packet):
1621    name = "HCI_Write_Connection_Accept_Timeout"
1622    fields_desc = [LEShortField("timeout", 32000)]  # 32000 slots is 20000 msec
1623
1624
1625class HCI_Cmd_Write_Extended_Inquiry_Response(Packet):
1626    name = "HCI_Write_Extended_Inquiry_Response"
1627    fields_desc = [ByteField("fec_required", 0),
1628                   HCI_Extended_Inquiry_Response]
1629
1630
1631class HCI_Cmd_Read_LE_Host_Support(Packet):
1632    name = "HCI_Read_LE_Host_Support"
1633
1634
1635class HCI_Cmd_Write_LE_Host_Support(Packet):
1636    name = "HCI_Write_LE_Host_Support"
1637    fields_desc = [ByteField("supported", 1),
1638                   ByteField("unused", 1), ]
1639
1640
1641# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
1642
1643class HCI_Cmd_Read_Local_Version_Information(Packet):
1644    """
1645    7.4.1 Read Local Version Information command
1646    """
1647    name = "HCI_Read_Local_Version_Information"
1648
1649
1650class HCI_Cmd_Read_Local_Extended_Features(Packet):
1651    """
1652    7.4.4 Read Local Extended Features command
1653    """
1654    name = "HCI_Read_Local_Extended_Features"
1655    fields_desc = [ByteField("page_number", 0)]
1656
1657
1658class HCI_Cmd_Read_BD_Addr(Packet):
1659    """
1660    7.4.6 Read BD_ADDR command
1661    """
1662    name = "HCI_Read_BD_ADDR"
1663
1664
1665# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
1666
1667class HCI_Cmd_Read_Link_Quality(Packet):
1668    name = "HCI_Read_Link_Quality"
1669    fields_desc = [LEShortField("handle", 0)]
1670
1671
1672class HCI_Cmd_Read_RSSI(Packet):
1673    name = "HCI_Read_RSSI"
1674    fields_desc = [LEShortField("handle", 0)]
1675
1676
1677# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
1678
1679class HCI_Cmd_Read_Loopback_Mode(Packet):
1680    name = "HCI_Read_Loopback_Mode"
1681
1682
1683class HCI_Cmd_Write_Loopback_Mode(Packet):
1684    name = "HCI_Write_Loopback_Mode"
1685    fields_desc = [ByteEnumField("loopback_mode", 0,
1686                                 {0: "no loopback",
1687                                  1: "enable local loopback",
1688                                  2: "enable remote loopback"})]
1689
1690
1691# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
1692
1693class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet):
1694    name = "HCI_LE_Read_Buffer_Size [v1]"
1695
1696
1697class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet):
1698    name = "HCI_LE_Read_Buffer_Size [v2]"
1699
1700
1701class HCI_Cmd_LE_Read_Local_Supported_Features(Packet):
1702    name = "HCI_LE_Read_Local_Supported_Features"
1703
1704
1705class HCI_Cmd_LE_Set_Random_Address(Packet):
1706    name = "HCI_LE_Set_Random_Address"
1707    fields_desc = [LEMACField("address", None)]
1708
1709
1710class HCI_Cmd_LE_Set_Advertising_Parameters(Packet):
1711    name = "HCI_LE_Set_Advertising_Parameters"
1712    fields_desc = [LEShortField("interval_min", 0x0800),
1713                   LEShortField("interval_max", 0x0800),
1714                   ByteEnumField("adv_type", 0, {0: "ADV_IND", 1: "ADV_DIRECT_IND", 2: "ADV_SCAN_IND", 3: "ADV_NONCONN_IND", 4: "ADV_DIRECT_IND_LOW"}),  # noqa: E501
1715                   ByteEnumField("oatype", 0, {0: "public", 1: "random"}),
1716                   ByteEnumField("datype", 0, {0: "public", 1: "random"}),
1717                   LEMACField("daddr", None),
1718                   ByteField("channel_map", 7),
1719                   ByteEnumField("filter_policy", 0, {0: "all:all", 1: "connect:all scan:whitelist", 2: "connect:whitelist scan:all", 3: "all:whitelist"}), ]  # noqa: E501
1720
1721
1722class HCI_Cmd_LE_Set_Advertising_Data(Packet):
1723    name = "HCI_LE_Set_Advertising_Data"
1724    fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
1725                   PadField(
1726                       PacketListField("data", [], EIR_Hdr,
1727                                       length_from=lambda pkt: pkt.len),
1728                       align=31, padwith=b"\0"), ]
1729
1730
1731class HCI_Cmd_LE_Set_Scan_Response_Data(Packet):
1732    name = "HCI_LE_Set_Scan_Response_Data"
1733    fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
1734                   StrLenField("data", "", length_from=lambda pkt: pkt.len), ]
1735
1736
1737class HCI_Cmd_LE_Set_Advertise_Enable(Packet):
1738    name = "HCI_LE_Set_Advertising_Enable"
1739    fields_desc = [ByteField("enable", 0)]
1740
1741
1742class HCI_Cmd_LE_Set_Scan_Parameters(Packet):
1743    name = "HCI_LE_Set_Scan_Parameters"
1744    fields_desc = [ByteEnumField("type", 0, {0: "passive", 1: "active"}),
1745                   XLEShortField("interval", 16),
1746                   XLEShortField("window", 16),
1747                   ByteEnumField("atype", 0, {0: "public",
1748                                              1: "random",
1749                                              2: "rpa (pub)",
1750                                              3: "rpa (random)"}),
1751                   ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})]
1752
1753
1754class HCI_Cmd_LE_Set_Scan_Enable(Packet):
1755    name = "HCI_LE_Set_Scan_Enable"
1756    fields_desc = [ByteField("enable", 1),
1757                   ByteField("filter_dups", 1), ]
1758
1759
1760class HCI_Cmd_LE_Create_Connection(Packet):
1761    name = "HCI_LE_Create_Connection"
1762    fields_desc = [LEShortField("interval", 96),
1763                   LEShortField("window", 48),
1764                   ByteEnumField("filter", 0, {0: "address"}),
1765                   ByteEnumField("patype", 0, {0: "public", 1: "random"}),
1766                   LEMACField("paddr", None),
1767                   ByteEnumField("atype", 0, {0: "public", 1: "random"}),
1768                   LEShortField("min_interval", 40),
1769                   LEShortField("max_interval", 56),
1770                   LEShortField("latency", 0),
1771                   LEShortField("timeout", 42),
1772                   LEShortField("min_ce", 0),
1773                   LEShortField("max_ce", 0), ]
1774
1775
1776class HCI_Cmd_LE_Create_Connection_Cancel(Packet):
1777    name = "HCI_LE_Create_Connection_Cancel"
1778
1779
1780class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet):
1781    name = "HCI_LE_Read_Filter_Accept_List_Size"
1782
1783
1784class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet):
1785    name = "HCI_LE_Clear_Filter_Accept_List"
1786
1787
1788class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet):
1789    name = "HCI_LE_Add_Device_To_Filter_Accept_List"
1790    fields_desc = [ByteEnumField("address_type", 0, {0: "public",
1791                                                     1: "random",
1792                                                     0xff: "anonymous"}),
1793                   LEMACField("address", None)]
1794
1795
1796class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List):  # noqa: E501
1797    name = "HCI_LE_Remove_Device_From_Filter_Accept_List"
1798
1799
1800class HCI_Cmd_LE_Connection_Update(Packet):
1801    name = "HCI_LE_Connection_Update"
1802    fields_desc = [XLEShortField("handle", 0),
1803                   XLEShortField("min_interval", 0),
1804                   XLEShortField("max_interval", 0),
1805                   XLEShortField("latency", 0),
1806                   XLEShortField("timeout", 0),
1807                   LEShortField("min_ce", 0),
1808                   LEShortField("max_ce", 0xffff), ]
1809
1810
1811class HCI_Cmd_LE_Read_Remote_Features(Packet):
1812    name = "HCI_LE_Read_Remote_Features"
1813    fields_desc = [LEShortField("handle", 64)]
1814
1815
1816class HCI_Cmd_LE_Enable_Encryption(Packet):
1817    name = "HCI_LE_Enable_Encryption"
1818    fields_desc = [LEShortField("handle", 0),
1819                   StrFixedLenField("rand", None, 8),
1820                   XLEShortField("ediv", 0),
1821                   StrFixedLenField("ltk", b'\x00' * 16, 16), ]
1822
1823
1824class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet):
1825    name = "HCI_LE_Long_Term_Key_Request_Reply"
1826    fields_desc = [LEShortField("handle", 0),
1827                   StrFixedLenField("ltk", b'\x00' * 16, 16), ]
1828
1829
1830class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet):
1831    name = "HCI_LE_Long_Term_Key_Request _Negative_Reply"
1832    fields_desc = [LEShortField("handle", 0), ]
1833
1834
1835class HCI_Event_Hdr(Packet):
1836    name = "HCI Event header"
1837    fields_desc = [XByteField("code", 0),
1838                   LenField("len", None, fmt="B"), ]
1839
1840    def answers(self, other):
1841        if HCI_Command_Hdr not in other:
1842            return False
1843
1844        # Delegate answers to event types
1845        return self.payload.answers(other)
1846
1847
1848class HCI_Event_Inquiry_Complete(Packet):
1849    """
1850    7.7.1 Inquiry Complete event
1851    """
1852    name = "HCI_Inquiry_Complete"
1853    fields_desc = [
1854        ByteEnumField('status', 0, _bluetooth_error_codes)
1855    ]
1856
1857
1858class HCI_Event_Inquiry_Result(Packet):
1859    """
1860    7.7.2 Inquiry Result event
1861    """
1862    name = "HCI_Inquiry_Result"
1863    fields_desc = [
1864        ByteField("num_response", 0x00),
1865        FieldListField("addr", None, LEMACField("addr", None),
1866                       count_from=lambda p: p.num_response),
1867        FieldListField("page_scan_repetition_mode", None,
1868                       ByteField("page_scan_repetition_mode", 0),
1869                       count_from=lambda p: p.num_response),
1870        FieldListField("reserved", None, LEShortField("reserved", 0),
1871                       count_from=lambda p: p.num_response),
1872        FieldListField("device_class", None, XLE3BytesField("device_class", 0),
1873                       count_from=lambda p: p.num_response),
1874        FieldListField("clock_offset", None, LEShortField("clock_offset", 0),
1875                       count_from=lambda p: p.num_response)
1876    ]
1877
1878
1879class HCI_Event_Connection_Complete(Packet):
1880    """
1881    7.7.3 Connection Complete event
1882    """
1883    name = "HCI_Connection_Complete"
1884    fields_desc = [ByteEnumField('status', 0, _bluetooth_error_codes),
1885                   LEShortField("handle", 0x0100),
1886                   LEMACField("bd_addr", None),
1887                   ByteEnumField("link_type", 0, {0: "SCO connection",
1888                                                  1: "ACL connection", }),
1889                   ByteEnumField("encryption_enabled", 0,
1890                                 {0: "link level encryption disabled",
1891                                  1: "link level encryption enabled", }), ]
1892
1893
1894class HCI_Event_Disconnection_Complete(Packet):
1895    """
1896    7.7.5 Disconnection Complete event
1897    """
1898    name = "HCI_Disconnection_Complete"
1899    fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
1900                   LEShortField("handle", 0),
1901                   XByteField("reason", 0), ]
1902
1903
1904class HCI_Event_Remote_Name_Request_Complete(Packet):
1905    """
1906    7.7.7 Remote Name Request Complete event
1907    """
1908    name = "HCI_Remote_Name_Request_Complete"
1909    fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
1910                   LEMACField("bd_addr", None),
1911                   StrFixedLenField("remote_name", b"\x00", 248), ]
1912
1913
1914class HCI_Event_Encryption_Change(Packet):
1915    """
1916    7.7.8 Encryption Change event
1917    """
1918    name = "HCI_Encryption_Change"
1919    fields_desc = [ByteEnumField("status", 0, {0: "change has occurred"}),
1920                   LEShortField("handle", 0),
1921                   ByteEnumField("enabled", 0, {0: "OFF", 1: "ON (LE)", 2: "ON (BR/EDR)"}), ]  # noqa: E501
1922
1923
1924class HCI_Event_Read_Remote_Supported_Features_Complete(Packet):
1925    """
1926    7.7.11 Read Remote Supported Features Complete event
1927    """
1928    name = "HCI_Read_Remote_Supported_Features_Complete"
1929    fields_desc = [
1930        ByteEnumField('status', 0, _bluetooth_error_codes),
1931        LEShortField('handle', 0),
1932        FlagsField('lmp_features', 0, -64, _bluetooth_features)
1933    ]
1934
1935
1936class HCI_Event_Read_Remote_Version_Information_Complete(Packet):
1937    """
1938    7.7.12 Read Remote Version Information Complete event
1939    """
1940    name = "HCI_Read_Remote_Version_Information"
1941    fields_desc = [
1942        ByteEnumField('status', 0, _bluetooth_error_codes),
1943        LEShortField('handle', 0),
1944        ByteField('version', 0x00),
1945        LEShortField('manufacturer_name', 0x0000),
1946        LEShortField('subversion', 0x0000)
1947    ]
1948
1949
1950class HCI_Event_Command_Complete(Packet):
1951    """
1952    7.7.14 Command Complete event
1953    """
1954    name = "HCI_Command_Complete"
1955    fields_desc = [ByteField("number", 0),
1956                   XLEShortField("opcode", 0),
1957                   ByteEnumField("status", 0, _bluetooth_error_codes)]
1958
1959    def answers(self, other):
1960        if HCI_Command_Hdr not in other:
1961            return False
1962
1963        return other[HCI_Command_Hdr].opcode == self.opcode
1964
1965
1966class HCI_Event_Command_Status(Packet):
1967    """
1968    7.7.15 Command Status event
1969    """
1970    name = "HCI_Command_Status"
1971    fields_desc = [ByteEnumField("status", 0, {0: "pending"}),
1972                   ByteField("number", 0),
1973                   XLEShortField("opcode", None), ]
1974
1975    def answers(self, other):
1976        if HCI_Command_Hdr not in other:
1977            return False
1978
1979        return other[HCI_Command_Hdr].opcode == self.opcode
1980
1981
1982class HCI_Event_Number_Of_Completed_Packets(Packet):
1983    """
1984    7.7.19 Number Of Completed Packets event
1985    """
1986    name = "HCI_Number_Of_Completed_Packets"
1987    fields_desc = [ByteField("num_handles", 0),
1988                   FieldListField("connection_handle_list", None,
1989                                  LEShortField("connection_handle", 0),
1990                                  count_from=lambda p: p.num_handles),
1991                   FieldListField("num_completed_packets_list", None,
1992                                  LEShortField("num_completed_packets", 0),
1993                                  count_from=lambda p: p.num_handles)]
1994
1995
1996class HCI_Event_Link_Key_Request(Packet):
1997    """
1998    7.7.23 Link Key Request event
1999    """
2000    name = 'HCI_Link_Key_Request'
2001    fields_desc = [
2002        LEMACField('bd_addr', None)
2003    ]
2004
2005
2006class HCI_Event_Inquiry_Result_With_Rssi(Packet):
2007    """
2008    7.7.33 Inquiry Result with RSSI event
2009    """
2010    name = "HCI_Inquiry_Result_with_RSSI"
2011    fields_desc = [
2012        ByteField("num_response", 0x00),
2013        FieldListField("bd_addr", None, LEMACField,
2014                       count_from=lambda p: p.num_response),
2015        FieldListField("page_scan_repetition_mode", None, ByteField,
2016                       count_from=lambda p: p.num_response),
2017        FieldListField("reserved", None, LEShortField,
2018                       count_from=lambda p: p.num_response),
2019        FieldListField("device_class", None, XLE3BytesField,
2020                       count_from=lambda p: p.num_response),
2021        FieldListField("clock_offset", None, LEShortField,
2022                       count_from=lambda p: p.num_response),
2023        FieldListField("rssi", None, SignedByteField,
2024                       count_from=lambda p: p.num_response)
2025    ]
2026
2027
2028class HCI_Event_Read_Remote_Extended_Features_Complete(Packet):
2029    """
2030    7.7.34 Read Remote Extended Features Complete event
2031    """
2032    name = "HCI_Read_Remote_Extended_Features_Complete"
2033    fields_desc = [
2034        ByteEnumField('status', 0, _bluetooth_error_codes),
2035        LEShortField('handle', 0),
2036        ByteField('page', 0x00),
2037        ByteField('max_page', 0x00),
2038        XLELongField('extended_features', 0)
2039    ]
2040
2041
2042class HCI_Event_Extended_Inquiry_Result(Packet):
2043    """
2044    7.7.38 Extended Inquiry Result event
2045    """
2046    name = "HCI_Extended_Inquiry_Result"
2047    fields_desc = [
2048        ByteField('num_response', 0x01),
2049        LEMACField('bd_addr', None),
2050        ByteField('page_scan_repetition_mode', 0x00),
2051        ByteField('reserved', 0x00),
2052        XLE3BytesField('device_class', 0x000000),
2053        LEShortField('clock_offset', 0x0000),
2054        SignedByteField('rssi', 0x00),
2055        HCI_Extended_Inquiry_Response,
2056    ]
2057
2058
2059class HCI_Event_IO_Capability_Response(Packet):
2060    """
2061    7.7.41 IO Capability Response event
2062    """
2063    name = "HCI_IO_Capability_Response"
2064    fields_desc = [
2065        LEMACField('bd_addr', None),
2066        ByteField('io_capability', 0x00),
2067        ByteField('oob_data_present', 0x00),
2068        ByteField('authentication_requirements', 0x00)
2069    ]
2070
2071
2072class HCI_Event_LE_Meta(Packet):
2073    """
2074    7.7.65 LE Meta event
2075    """
2076    name = "HCI_LE_Meta"
2077    fields_desc = [ByteEnumField("event", 0, {
2078                   1: "connection_complete",
2079                   2: "advertising_report",
2080                   3: "connection_update_complete",
2081                   5: "long_term_key_request",
2082                   }), ]
2083
2084    def answers(self, other):
2085        if not self.payload:
2086            return False
2087
2088        # Delegate answers to payload
2089        return self.payload.answers(other)
2090
2091
2092class HCI_Cmd_Complete_Read_Local_Name(Packet):
2093    """
2094    7.3.12 Read Local Name command complete
2095    """
2096    name = 'Read Local Name command complete'
2097    fields_desc = [StrFixedLenField('local_name', '', length=248)]
2098
2099
2100class HCI_Cmd_Complete_Read_Local_Version_Information(Packet):
2101    """
2102    7.4.1 Read Local Version Information command complete
2103    """
2104    name = 'Read Local Version Information'
2105    fields_desc = [
2106        ByteField('hci_version', 0),
2107        LEShortField('hci_subversion', 0),
2108        ByteField('lmp_version', 0),
2109        LEShortField('company_identifier', 0),
2110        LEShortField('lmp_subversion', 0)]
2111
2112
2113class HCI_Cmd_Complete_Read_Local_Extended_Features(Packet):
2114    """
2115    7.4.4 Read Local Extended Features command complete
2116    """
2117    name = 'Read Local Extended Features command complete'
2118    fields_desc = [
2119        ByteField('page', 0x00),
2120        ByteField('max_page', 0x00),
2121        XLELongField('extended_features', 0)
2122    ]
2123
2124
2125class HCI_Cmd_Complete_Read_BD_Addr(Packet):
2126    """
2127    7.4.6 Read BD_ADDR command complete
2128    """
2129    name = "Read BD Addr"
2130    fields_desc = [LEMACField("addr", None), ]
2131
2132
2133class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet):
2134    name = "LE Read White List Size"
2135    fields_desc = [ByteField("status", 0),
2136                   ByteField("size", 0), ]
2137
2138
2139class HCI_LE_Meta_Connection_Complete(Packet):
2140    name = "Connection Complete"
2141    fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2142                   LEShortField("handle", 0),
2143                   ByteEnumField("role", 0, {0: "master"}),
2144                   ByteEnumField("patype", 0, {0: "public", 1: "random"}),
2145                   LEMACField("paddr", None),
2146                   LEShortField("interval", 54),
2147                   LEShortField("latency", 0),
2148                   LEShortField("supervision", 42),
2149                   XByteField("clock_latency", 5), ]
2150
2151    def answers(self, other):
2152        if HCI_Cmd_LE_Create_Connection not in other:
2153            return False
2154
2155        return (other[HCI_Cmd_LE_Create_Connection].patype == self.patype and
2156                other[HCI_Cmd_LE_Create_Connection].paddr == self.paddr)
2157
2158
2159class HCI_LE_Meta_Connection_Update_Complete(Packet):
2160    name = "Connection Update Complete"
2161    fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2162                   LEShortField("handle", 0),
2163                   LEShortField("interval", 54),
2164                   LEShortField("latency", 0),
2165                   LEShortField("timeout", 42), ]
2166
2167
2168class HCI_LE_Meta_Advertising_Report(Packet):
2169    name = "Advertising Report"
2170    fields_desc = [ByteEnumField("type", 0, {0: "conn_und", 4: "scan_rsp"}),
2171                   ByteEnumField("atype", 0, {0: "public", 1: "random"}),
2172                   LEMACField("addr", None),
2173                   FieldLenField("len", None, length_of="data", fmt="B"),
2174                   PacketListField("data", [], EIR_Hdr,
2175                                   length_from=lambda pkt: pkt.len),
2176                   SignedByteField("rssi", 0)]
2177
2178    def extract_padding(self, s):
2179        return '', s
2180
2181
2182class HCI_LE_Meta_Advertising_Reports(Packet):
2183    name = "Advertising Reports"
2184    fields_desc = [FieldLenField("len", None, count_of="reports", fmt="B"),
2185                   PacketListField("reports", None,
2186                                   HCI_LE_Meta_Advertising_Report,
2187                                   count_from=lambda pkt: pkt.len)]
2188
2189
2190class HCI_LE_Meta_Long_Term_Key_Request(Packet):
2191    name = "Long Term Key Request"
2192    fields_desc = [LEShortField("handle", 0),
2193                   StrFixedLenField("rand", None, 8),
2194                   XLEShortField("ediv", 0), ]
2195
2196
2197bind_layers(HCI_PHDR_Hdr, HCI_Hdr)
2198
2199bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1)
2200bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2)
2201bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4)
2202bind_layers(HCI_Hdr, conf.raw_layer,)
2203
2204conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr)
2205conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr)
2206
2207
2208# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
2209bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry, ogf=0x01, ocf=0x0001)
2210bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry_Cancel, ogf=0x01, ocf=0x0002)
2211bind_layers(HCI_Command_Hdr, HCI_Cmd_Periodic_Inquiry_Mode, ogf=0x01, ocf=0x0003)
2212bind_layers(HCI_Command_Hdr, HCI_Cmd_Exit_Peiodic_Inquiry_Mode, ogf=0x01, ocf=0x0004)
2213bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, ogf=0x01, ocf=0x0005)
2214bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, ogf=0x01, ocf=0x0006)
2215bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection_Cancel, ogf=0x01, ocf=0x0008)
2216bind_layers(HCI_Command_Hdr, HCI_Cmd_Accept_Connection_Request, ogf=0x01, ocf=0x0009)
2217bind_layers(HCI_Command_Hdr, HCI_Cmd_Reject_Connection_Response, ogf=0x01, ocf=0x000a)
2218bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b)
2219bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply,
2220            ogf=0x01, ocf=0x000c)
2221bind_layers(HCI_Command_Hdr, HCI_Cmd_PIN_Code_Request_Reply, ogf=0x01, ocf=0x000d)
2222bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type,
2223            ogf=0x01, ocf=0x000f)
2224bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, ogf=0x01, ocf=0x0011)
2225bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, ogf=0x01, ocf=0x0013)
2226bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Link_Key, ogf=0x01, ocf=0x0017)
2227bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019)
2228bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request_Cancel, ogf=0x01, ocf=0x001a)
2229bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features,
2230            ogf=0x01, ocf=0x001b)
2231bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features,
2232            ogf=0x01, ocf=0x001c)
2233bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b)
2234bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply,
2235            ogf=0x01, ocf=0x002c)
2236bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply,
2237            ogf=0x01, ocf=0x002d)
2238bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Reply, ogf=0x01, ocf=0x002e)
2239bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply,
2240            ogf=0x01, ocf=0x002f)
2241bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply,
2242            ogf=0x01, ocf=0x0030)
2243bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply,
2244            ogf=0x01, ocf=0x0033)
2245
2246# 7.2 Link Policy commands, the OGF is defined as 0x02
2247bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001)
2248
2249# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
2250bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, ogf=0x03, ocf=0x0001)
2251bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, ogf=0x03, ocf=0x0003)
2252bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, ogf=0x03, ocf=0x0005)
2253bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, ogf=0x03, ocf=0x0013)
2254bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Name, ogf=0x03, ocf=0x0014)
2255bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Connect_Accept_Timeout, ogf=0x03, ocf=0x0016)
2256bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, ogf=0x03, ocf=0x0052)  # noqa: E501
2257bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_LE_Host_Support, ogf=0x03, ocf=0x006c)
2258bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_LE_Host_Support, ogf=0x03, ocf=0x006d)
2259
2260# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
2261bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Version_Information, ogf=0x04, ocf=0x0001)  # noqa: E501
2262bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Extended_Features, ogf=0x04, ocf=0x0004)
2263bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, ogf=0x04, ocf=0x0009)
2264
2265# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
2266bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Link_Quality, ogf=0x05, ocf=0x0003)
2267bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_RSSI, ogf=0x05, ocf=0x0005)
2268
2269# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
2270bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Loopback_Mode, ogf=0x06, ocf=0x0001)
2271bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Loopback_Mode, ogf=0x06, ocf=0x0002)
2272
2273# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
2274bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V1, ogf=0x08, ocf=0x0002)
2275bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V2, ogf=0x08, ocf=0x0060)
2276bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features,
2277            ogf=0x08, ocf=0x0003)
2278bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, ogf=0x08, ocf=0x0005)
2279bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, ogf=0x08, ocf=0x0006)  # noqa: E501
2280bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, ogf=0x08, ocf=0x0008)
2281bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, ogf=0x08, ocf=0x0009)
2282bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, ogf=0x08, ocf=0x000a)
2283bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, ogf=0x08, ocf=0x000b)
2284bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, ogf=0x08, ocf=0x000c)
2285bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, ogf=0x08, ocf=0x000d)
2286bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, ogf=0x08, ocf=0x000e)  # noqa: E501
2287bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size,
2288            ogf=0x08, ocf=0x000f)
2289bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_Filter_Accept_List, ogf=0x08, ocf=0x0010)
2290bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_Filter_Accept_List, ogf=0x08, ocf=0x0011)  # noqa: E501
2291bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List, ogf=0x08, ocf=0x0012)  # noqa: E501
2292bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, ogf=0x08, ocf=0x0013)
2293bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Features, ogf=0x08, ocf=0x0016)  # noqa: E501
2294bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Enable_Encryption, ogf=0x08, ocf=0x0019)  # noqa: E501
2295bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, ogf=0x08, ocf=0x001a)  # noqa: E501
2296bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, ogf=0x08, ocf=0x001b)  # noqa: E501
2297
2298# 7.7 EVENTS
2299bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Complete, code=0x01)
2300bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result, code=0x02)
2301bind_layers(HCI_Event_Hdr, HCI_Event_Connection_Complete, code=0x03)
2302bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x05)
2303bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Name_Request_Complete, code=0x07)
2304bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x08)
2305bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Supported_Features_Complete, code=0x0b)
2306bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Version_Information_Complete, code=0x0c)  # noqa: E501
2307bind_layers(HCI_Event_Hdr, HCI_Event_Command_Complete, code=0x0e)
2308bind_layers(HCI_Event_Hdr, HCI_Event_Command_Status, code=0x0f)
2309bind_layers(HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13)
2310bind_layers(HCI_Event_Hdr, HCI_Event_Link_Key_Request, code=0x17)
2311bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result_With_Rssi, code=0x22)
2312bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Extended_Features_Complete, code=0x23)
2313bind_layers(HCI_Event_Hdr, HCI_Event_Extended_Inquiry_Result, code=0x2f)
2314bind_layers(HCI_Event_Hdr, HCI_Event_IO_Capability_Response, code=0x32)
2315bind_layers(HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e)
2316
2317bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Name, opcode=0x0c14)  # noqa: E501
2318bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Version_Information, opcode=0x1001)  # noqa: E501
2319bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Extended_Features, opcode=0x1004)  # noqa: E501
2320bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009)  # noqa: E501
2321bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_LE_Read_White_List_Size, opcode=0x200f)  # noqa: E501
2322
2323bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=1)
2324bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=2)
2325bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=3)
2326bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=5)
2327
2328bind_layers(EIR_Hdr, EIR_Flags, type=0x01)
2329bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02)
2330bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03)
2331bind_layers(EIR_Hdr, EIR_IncompleteList32BitServiceUUIDs, type=0x04)
2332bind_layers(EIR_Hdr, EIR_CompleteList32BitServiceUUIDs, type=0x05)
2333bind_layers(EIR_Hdr, EIR_IncompleteList128BitServiceUUIDs, type=0x06)
2334bind_layers(EIR_Hdr, EIR_CompleteList128BitServiceUUIDs, type=0x07)
2335bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08)
2336bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09)
2337bind_layers(EIR_Hdr, EIR_Device_ID, type=0x10)
2338bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a)
2339bind_layers(EIR_Hdr, EIR_ClassOfDevice, type=0x0d)
2340bind_layers(EIR_Hdr, EIR_SecureSimplePairingHashC192, type=0x0e)
2341bind_layers(EIR_Hdr, EIR_SecureSimplePairingRandomizerR192, type=0x0f)
2342bind_layers(EIR_Hdr, EIR_SecurityManagerOOBFlags, type=0x11)
2343bind_layers(EIR_Hdr, EIR_PeripheralConnectionIntervalRange, type=0x12)
2344bind_layers(EIR_Hdr, EIR_ServiceData16BitUUID, type=0x16)
2345bind_layers(EIR_Hdr, EIR_ServiceData32BitUUID, type=0x20)
2346bind_layers(EIR_Hdr, EIR_ServiceData128BitUUID, type=0x21)
2347bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff)
2348bind_layers(EIR_Hdr, EIR_Raw)
2349
2350bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,)
2351bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
2352bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=5)  # LE L2CAP Signaling Channel
2353bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
2354bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
2355bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
2356bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
2357bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
2358bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
2359bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
2360bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8)
2361bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9)
2362bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
2363bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
2364bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12)
2365bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13)
2366bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14)
2367bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15)
2368bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16)
2369bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17)
2370bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18)
2371bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19)
2372bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20)
2373bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21)
2374bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22)
2375bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23)
2376bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24)
2377bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25)
2378bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26)
2379bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4)
2380bind_layers(ATT_Hdr, ATT_Error_Response, opcode=0x1)
2381bind_layers(ATT_Hdr, ATT_Exchange_MTU_Request, opcode=0x2)
2382bind_layers(ATT_Hdr, ATT_Exchange_MTU_Response, opcode=0x3)
2383bind_layers(ATT_Hdr, ATT_Find_Information_Request, opcode=0x4)
2384bind_layers(ATT_Hdr, ATT_Find_Information_Response, opcode=0x5)
2385bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Request, opcode=0x6)
2386bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Response, opcode=0x7)
2387bind_layers(ATT_Hdr, ATT_Read_By_Type_Request_128bit, opcode=0x8)
2388bind_layers(ATT_Hdr, ATT_Read_By_Type_Request, opcode=0x8)
2389bind_layers(ATT_Hdr, ATT_Read_By_Type_Response, opcode=0x9)
2390bind_layers(ATT_Hdr, ATT_Read_Request, opcode=0xa)
2391bind_layers(ATT_Hdr, ATT_Read_Response, opcode=0xb)
2392bind_layers(ATT_Hdr, ATT_Read_Blob_Request, opcode=0xc)
2393bind_layers(ATT_Hdr, ATT_Read_Blob_Response, opcode=0xd)
2394bind_layers(ATT_Hdr, ATT_Read_Multiple_Request, opcode=0xe)
2395bind_layers(ATT_Hdr, ATT_Read_Multiple_Response, opcode=0xf)
2396bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Request, opcode=0x10)
2397bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Response, opcode=0x11)
2398bind_layers(ATT_Hdr, ATT_Write_Request, opcode=0x12)
2399bind_layers(ATT_Hdr, ATT_Write_Response, opcode=0x13)
2400bind_layers(ATT_Hdr, ATT_Prepare_Write_Request, opcode=0x16)
2401bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17)
2402bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18)
2403bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19)
2404bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52)
2405bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b)
2406bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d)
2407bind_layers(L2CAP_Hdr, SM_Hdr, cid=6)
2408bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=1)
2409bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=2)
2410bind_layers(SM_Hdr, SM_Confirm, sm_command=3)
2411bind_layers(SM_Hdr, SM_Random, sm_command=4)
2412bind_layers(SM_Hdr, SM_Failed, sm_command=5)
2413bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=6)
2414bind_layers(SM_Hdr, SM_Master_Identification, sm_command=7)
2415bind_layers(SM_Hdr, SM_Identity_Information, sm_command=8)
2416bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=9)
2417bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a)
2418bind_layers(SM_Hdr, SM_Public_Key, sm_command=0x0c)
2419bind_layers(SM_Hdr, SM_DHKey_Check, sm_command=0x0d)
2420
2421
2422###############
2423# HCI Monitor #
2424###############
2425
2426
2427# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L27
2428class HCI_Mon_Hdr(Packet):
2429    name = 'Bluetooth Linux Monitor Transport Header'
2430    fields_desc = [
2431        LEShortEnumField('opcode', None, {
2432            0: "New index",
2433            1: "Delete index",
2434            2: "Command pkt",
2435            3: "Event pkt",
2436            4: "ACL TX pkt",
2437            5: "ACL RX pkt",
2438            6: "SCO TX pkt",
2439            7: "SCO RX pkt",
2440            8: "Open index",
2441            9: "Close index",
2442            10: "Index info",
2443            11: "Vendor diag",
2444            12: "System note",
2445            13: "User logging",
2446            14: "Ctrl open",
2447            15: "Ctrl close",
2448            16: "Ctrl command",
2449            17: "Ctrl event",
2450            18: "ISO TX pkt",
2451            19: "ISO RX pkt",
2452        }),
2453        LEShortField('adapter_id', None),
2454        LEShortField('len', None)
2455    ]
2456
2457
2458# https://www.tcpdump.org/linktypes/LINKTYPE_BLUETOOTH_LINUX_MONITOR.html
2459class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr):
2460    name = 'Bluetooth Linux Monitor Transport Pcap Header'
2461    fields_desc = [
2462        ShortField('adapter_id', None),
2463        ShortField('opcode', None)
2464    ]
2465
2466
2467class HCI_Mon_New_Index(Packet):
2468    name = 'Bluetooth Linux Monitor Transport New Index Packet'
2469    fields_desc = [
2470        ByteEnumField('bus', 0, {
2471            0x00: "BR/EDR",
2472            0x01: "AMP"
2473        }),
2474        ByteEnumField('type', 0, {
2475            0x00: "Virtual",
2476            0x01: "USB",
2477            0x02: "PC Card",
2478            0x03: "UART",
2479            0x04: "RS232",
2480            0x05: "PCI",
2481            0x06: "SDIO"
2482        }),
2483        LEMACField('addr', None),
2484        StrFixedLenField('devname', None, 8)
2485    ]
2486
2487
2488class HCI_Mon_Index_Info(Packet):
2489    name = 'Bluetooth Linux Monitor Transport Index Info Packet'
2490    fields_desc = [
2491        LEMACField('addr', None),
2492        XLEShortField('manufacturer', None)
2493    ]
2494
2495
2496class HCI_Mon_System_Note(Packet):
2497    name = 'Bluetooth Linux Monitor Transport System Note Packet'
2498    fields_desc = [
2499        StrNullField('note', None)
2500    ]
2501
2502
2503# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L34
2504bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0)
2505bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2)
2506bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3)
2507bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10)
2508bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12)
2509
2510conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr)
2511
2512
2513###########
2514# Helpers #
2515###########
2516
2517class LowEnergyBeaconHelper:
2518    """
2519    Helpers for building packets for Bluetooth Low Energy Beacons.
2520
2521    Implementers provide a :meth:`build_eir` implementation.
2522
2523    This is designed to be used as a mix-in -- see
2524    ``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples.
2525    """
2526
2527    # Basic flags that should be used by most beacons.
2528    base_eir = [EIR_Hdr() / EIR_Flags(flags=[
2529        "general_disc_mode", "br_edr_not_supported"]), ]
2530
2531    def build_eir(self):
2532        """
2533        Builds a list of EIR messages to wrap this frame.
2534
2535        Users of this helper must implement this method.
2536
2537        :return: List of HCI_Hdr with payloads that describe this beacon type
2538        :rtype: list[scapy.bluetooth.HCI_Hdr]
2539        """
2540        raise NotImplementedError("build_eir")
2541
2542    def build_advertising_report(self):
2543        """
2544        Builds a HCI_LE_Meta_Advertising_Report containing this frame.
2545
2546        :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report
2547        """
2548
2549        return HCI_LE_Meta_Advertising_Report(
2550            type=0,   # Undirected
2551            atype=1,  # Random address
2552            data=self.build_eir()
2553        )
2554
2555    def build_set_advertising_data(self):
2556        """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame.
2557
2558        This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers.
2559
2560        :rtype: scapy.bluetooth.HCI_Hdr
2561        """
2562
2563        return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data(
2564            data=self.build_eir()
2565        )
2566
2567
2568###########
2569# Sockets #
2570###########
2571
2572class BluetoothSocketError(BaseException):
2573    pass
2574
2575
2576class BluetoothCommandError(BaseException):
2577    pass
2578
2579
2580class BluetoothL2CAPSocket(SuperSocket):
2581    desc = "read/write packets on a connected L2CAP socket"
2582
2583    def __init__(self, bt_address):
2584        if WINDOWS:
2585            warning("Not available on Windows")
2586            return
2587        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
2588                          socket.BTPROTO_L2CAP)
2589        s.connect((bt_address, 0))
2590        self.ins = self.outs = s
2591
2592    def recv(self, x=MTU):
2593        return L2CAP_CmdHdr(self.ins.recv(x))
2594
2595
2596class BluetoothRFCommSocket(BluetoothL2CAPSocket):
2597    """read/write packets on a connected RFCOMM socket"""
2598
2599    def __init__(self, bt_address, port=0):
2600        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
2601                          socket.BTPROTO_RFCOMM)
2602        s.connect((bt_address, port))
2603        self.ins = self.outs = s
2604
2605
2606class BluetoothHCISocket(SuperSocket):
2607    desc = "read/write on a BlueTooth HCI socket"
2608
2609    def __init__(self, iface=0x10000, type=None):
2610        if WINDOWS:
2611            warning("Not available on Windows")
2612            return
2613        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)  # noqa: E501
2614        s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR, 1)
2615        s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP, 1)
2616        s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff, 0xffffffff, 0xffffffff, 0))  # type mask, event mask, event mask, opcode  # noqa: E501
2617        s.bind((iface,))
2618        self.ins = self.outs = s
2619#        s.connect((peer,0))
2620
2621    def recv(self, x=MTU):
2622        return HCI_Hdr(self.ins.recv(x))
2623
2624
2625class sockaddr_hci(ctypes.Structure):
2626    _fields_ = [
2627        ("sin_family", ctypes.c_ushort),
2628        ("hci_dev", ctypes.c_ushort),
2629        ("hci_channel", ctypes.c_ushort),
2630    ]
2631
2632
2633class _BluetoothLibcSocket(SuperSocket):
2634    def __init__(self, socket_domain, socket_type, socket_protocol, sock_address):
2635        # type: (int, int, int, sockaddr_hci) -> None
2636        if WINDOWS:
2637            warning("Not available on Windows")
2638            return
2639        # Python socket and bind implementations do not allow us to pass down
2640        # the correct parameters. We must call libc functions directly via
2641        # ctypes.
2642        sockaddr_hcip = ctypes.POINTER(sockaddr_hci)
2643        from ctypes.util import find_library
2644        libc = ctypes.cdll.LoadLibrary(find_library("c"))
2645
2646        socket_c = libc.socket
2647        socket_c.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int)
2648        socket_c.restype = ctypes.c_int
2649
2650        bind = libc.bind
2651        bind.argtypes = (ctypes.c_int,
2652                         ctypes.POINTER(sockaddr_hci),
2653                         ctypes.c_int)
2654        bind.restype = ctypes.c_int
2655
2656        # Socket
2657        s = socket_c(socket_domain, socket_type, socket_protocol)
2658        if s < 0:
2659            raise BluetoothSocketError(
2660                f"Unable to open socket({socket_domain}, {socket_type}, "
2661                f"{socket_protocol})")
2662
2663        # Bind
2664        r = bind(s, sockaddr_hcip(sock_address), sizeof(sock_address))
2665        if r != 0:
2666            raise BluetoothSocketError("Unable to bind")
2667
2668        self.hci_fd = s
2669        self.ins = self.outs = socket.fromfd(
2670            s, socket_domain, socket_type, socket_protocol)
2671
2672    def readable(self, timeout=0):
2673        (ins, _, _) = select.select([self.ins], [], [], timeout)
2674        return len(ins) > 0
2675
2676    def flush(self):
2677        while self.readable():
2678            self.recv()
2679
2680    def close(self):
2681        if self.closed:
2682            return
2683
2684        # Properly close socket so we can free the device
2685        from ctypes.util import find_library
2686        libc = ctypes.cdll.LoadLibrary(find_library("c"))
2687
2688        close = libc.close
2689        close.restype = ctypes.c_int
2690        self.closed = True
2691        if hasattr(self, "outs"):
2692            if not hasattr(self, "ins") or self.ins != self.outs:
2693                if self.outs and (WINDOWS or self.outs.fileno() != -1):
2694                    close(self.outs.fileno())
2695        if hasattr(self, "ins"):
2696            if self.ins and (WINDOWS or self.ins.fileno() != -1):
2697                close(self.ins.fileno())
2698        if hasattr(self, "hci_fd"):
2699            close(self.hci_fd)
2700
2701
2702class BluetoothUserSocket(_BluetoothLibcSocket):
2703    desc = "read/write H4 over a Bluetooth user channel"
2704
2705    def __init__(self, adapter_index=0):
2706        sa = sockaddr_hci()
2707        sa.sin_family = socket.AF_BLUETOOTH
2708        sa.hci_dev = adapter_index
2709        sa.hci_channel = HCI_CHANNEL_USER
2710        super().__init__(
2711            socket_domain=socket.AF_BLUETOOTH,
2712            socket_type=socket.SOCK_RAW,
2713            socket_protocol=socket.BTPROTO_HCI,
2714            sock_address=sa)
2715
2716    def send_command(self, cmd):
2717        opcode = cmd.opcode
2718        self.send(cmd)
2719        while True:
2720            r = self.recv()
2721            if r.type == 0x04 and r.code == 0xe and r.opcode == opcode:
2722                if r.status != 0:
2723                    raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status))  # noqa: E501
2724                return r
2725
2726    def recv(self, x=MTU):
2727        return HCI_Hdr(self.ins.recv(x))
2728
2729
2730class BluetoothMonitorSocket(_BluetoothLibcSocket):
2731    desc = "Read/write over a Bluetooth monitor channel"
2732
2733    def __init__(self):
2734        sa = sockaddr_hci()
2735        sa.sin_family = socket.AF_BLUETOOTH
2736        sa.hci_dev = HCI_DEV_NONE
2737        sa.hci_channel = HCI_CHANNEL_MONITOR
2738        super().__init__(
2739            socket_domain=socket.AF_BLUETOOTH,
2740            socket_type=socket.SOCK_RAW,
2741            socket_protocol=socket.BTPROTO_HCI,
2742            sock_address=sa)
2743
2744    def recv(self, x=MTU):
2745        return HCI_Mon_Hdr(self.ins.recv(x))
2746
2747
2748conf.BTsocket = BluetoothRFCommSocket
2749
2750# Bluetooth
2751
2752
2753@conf.commands.register
2754def srbt(bt_address, pkts, inter=0.1, *args, **kargs):
2755    """send and receive using a bluetooth socket"""
2756    if "port" in kargs:
2757        s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port"))
2758    else:
2759        s = conf.BTsocket(bt_address=bt_address)
2760    a, b = sndrcv(s, pkts, inter=inter, *args, **kargs)
2761    s.close()
2762    return a, b
2763
2764
2765@conf.commands.register
2766def srbt1(bt_address, pkts, *args, **kargs):
2767    """send and receive 1 packet using a bluetooth socket"""
2768    a, b = srbt(bt_address, pkts, *args, **kargs)
2769    if len(a) > 0:
2770        return a[0][1]
2771