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