// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Copied from:
// https://github.com/google/rootcanal/blob/2b57c6bb3598babd99b07126e093fb6811637a47/packets/hci_packets.pdl
little_endian_packets

custom_field Address : 48 "hci/"

enum Enable : 8 {
  DISABLED = 0x00,
  ENABLED = 0x01,
}

// HCI ACL Packets

enum PacketBoundaryFlag : 2 {
  FIRST_NON_AUTOMATICALLY_FLUSHABLE = 0,
  CONTINUING_FRAGMENT = 1,
  FIRST_AUTOMATICALLY_FLUSHABLE = 2,
}

enum BroadcastFlag : 2 {
  POINT_TO_POINT = 0,
  ACTIVE_PERIPHERAL_BROADCAST = 1,
}

packet Acl {
  handle : 12,
  packet_boundary_flag : PacketBoundaryFlag,
  broadcast_flag : BroadcastFlag,
  _size_(_payload_) : 16,
  _payload_,
}

// HCI SCO Packets

enum PacketStatusFlag : 2 {
  CORRECTLY_RECEIVED = 0,
  POSSIBLY_INCOMPLETE = 1,
  NO_DATA_RECEIVED = 2,
  PARTIALLY_LOST = 3,
}

packet Sco {
  handle : 12,
  packet_status_flag : PacketStatusFlag,
  _reserved_ : 2, // BroadcastFlag
  _size_(data) : 8,
  data : 8[],
}

// HCI Command Packets

enum OpCode : 16 {
  NONE = 0x0000,

  // LINK_CONTROL
  INQUIRY = 0x0401,
  INQUIRY_CANCEL = 0x0402,
  PERIODIC_INQUIRY_MODE = 0x0403,
  EXIT_PERIODIC_INQUIRY_MODE = 0x0404,
  CREATE_CONNECTION = 0x0405,
  DISCONNECT = 0x0406,
  ADD_SCO_CONNECTION = 0x0407,
  CREATE_CONNECTION_CANCEL = 0x0408,
  ACCEPT_CONNECTION_REQUEST = 0x0409,
  REJECT_CONNECTION_REQUEST = 0x040A,
  LINK_KEY_REQUEST_REPLY = 0x040B,
  LINK_KEY_REQUEST_NEGATIVE_REPLY = 0x040C,
  PIN_CODE_REQUEST_REPLY = 0x040D,
  PIN_CODE_REQUEST_NEGATIVE_REPLY = 0x040E,
  CHANGE_CONNECTION_PACKET_TYPE = 0x040F,
  AUTHENTICATION_REQUESTED = 0x0411,
  SET_CONNECTION_ENCRYPTION = 0x0413,
  CHANGE_CONNECTION_LINK_KEY = 0x0415,
  CENTRAL_LINK_KEY = 0x0417,
  REMOTE_NAME_REQUEST = 0x0419,
  REMOTE_NAME_REQUEST_CANCEL = 0x041A,
  READ_REMOTE_SUPPORTED_FEATURES = 0x041B,
  READ_REMOTE_EXTENDED_FEATURES = 0x041C,
  READ_REMOTE_VERSION_INFORMATION = 0x041D,
  READ_CLOCK_OFFSET = 0x041F,
  READ_LMP_HANDLE = 0x0420,
  SETUP_SYNCHRONOUS_CONNECTION = 0x0428,
  ACCEPT_SYNCHRONOUS_CONNECTION = 0x0429,
  REJECT_SYNCHRONOUS_CONNECTION = 0x042A,
  IO_CAPABILITY_REQUEST_REPLY = 0x042B,
  USER_CONFIRMATION_REQUEST_REPLY = 0x042C,
  USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 0x042D,
  USER_PASSKEY_REQUEST_REPLY = 0x042E,
  USER_PASSKEY_REQUEST_NEGATIVE_REPLY = 0x042F,
  REMOTE_OOB_DATA_REQUEST_REPLY = 0x0430,
  REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 0x0433,
  IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 0x0434,
  ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = 0x043D,
  ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = 0x043E,
  TRUNCATED_PAGE = 0x043F,
  TRUNCATED_PAGE_CANCEL = 0x0440,
  SET_CONNECTIONLESS_PERIPHERAL_BROADCAST = 0x0441,
  SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE = 0x0442,
  START_SYNCHRONIZATION_TRAIN = 0x0443,
  RECEIVE_SYNCHRONIZATION_TRAIN = 0x0444,
  REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY = 0x0445,

  // LINK_POLICY
  HOLD_MODE = 0x0801,
  SNIFF_MODE = 0x0803,
  EXIT_SNIFF_MODE = 0x0804,
  QOS_SETUP = 0x0807,
  ROLE_DISCOVERY = 0x0809,
  SWITCH_ROLE = 0x080B,
  READ_LINK_POLICY_SETTINGS = 0x080C,
  WRITE_LINK_POLICY_SETTINGS = 0x080D,
  READ_DEFAULT_LINK_POLICY_SETTINGS = 0x080E,
  WRITE_DEFAULT_LINK_POLICY_SETTINGS = 0x080F,
  FLOW_SPECIFICATION = 0x0810,
  SNIFF_SUBRATING = 0x0811,

  // CONTROLLER_AND_BASEBAND
  SET_EVENT_MASK = 0x0C01,
  RESET = 0x0C03,
  SET_EVENT_FILTER = 0x0C05,
  FLUSH = 0x0C08,
  READ_PIN_TYPE = 0x0C09,
  WRITE_PIN_TYPE = 0x0C0A,
  READ_STORED_LINK_KEY = 0x0C0D,
  WRITE_STORED_LINK_KEY = 0x0C11,
  DELETE_STORED_LINK_KEY = 0x0C12,
  WRITE_LOCAL_NAME = 0x0C13,
  READ_LOCAL_NAME = 0x0C14,
  READ_CONNECTION_ACCEPT_TIMEOUT = 0x0C15,
  WRITE_CONNECTION_ACCEPT_TIMEOUT = 0x0C16,
  READ_PAGE_TIMEOUT = 0x0C17,
  WRITE_PAGE_TIMEOUT = 0x0C18,
  READ_SCAN_ENABLE = 0x0C19,
  WRITE_SCAN_ENABLE = 0x0C1A,
  READ_PAGE_SCAN_ACTIVITY = 0x0C1B,
  WRITE_PAGE_SCAN_ACTIVITY = 0x0C1C,
  READ_INQUIRY_SCAN_ACTIVITY = 0x0C1D,
  WRITE_INQUIRY_SCAN_ACTIVITY = 0x0C1E,
  READ_AUTHENTICATION_ENABLE = 0x0C1F,
  WRITE_AUTHENTICATION_ENABLE = 0x0C20,
  READ_CLASS_OF_DEVICE = 0x0C23,
  WRITE_CLASS_OF_DEVICE = 0x0C24,
  READ_VOICE_SETTING = 0x0C25,
  WRITE_VOICE_SETTING = 0x0C26,
  READ_AUTOMATIC_FLUSH_TIMEOUT = 0x0C27,
  WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x0C28,
  READ_NUM_BROADCAST_RETRANSMITS = 0x0C29,
  WRITE_NUM_BROADCAST_RETRANSMITS = 0x0C2A,
  READ_HOLD_MODE_ACTIVITY = 0x0C2B,
  WRITE_HOLD_MODE_ACTIVITY = 0x0C2C,
  READ_TRANSMIT_POWER_LEVEL = 0x0C2D,
  READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 0x0C2E,
  WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 0x0C2F,
  SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 0x0C31,
  HOST_BUFFER_SIZE = 0x0C33,
  HOST_NUMBER_OF_COMPLETED_PACKETS = 0x0C35,
  READ_LINK_SUPERVISION_TIMEOUT = 0x0C36,
  WRITE_LINK_SUPERVISION_TIMEOUT = 0x0C37,
  READ_NUMBER_OF_SUPPORTED_IAC = 0x0C38,
  READ_CURRENT_IAC_LAP = 0x0C39,
  WRITE_CURRENT_IAC_LAP = 0x0C3A,
  SET_AFH_HOST_CHANNEL_CLASSIFICATION = 0x0C3F,
  READ_INQUIRY_SCAN_TYPE = 0x0C42,
  WRITE_INQUIRY_SCAN_TYPE = 0x0C43,
  READ_INQUIRY_MODE = 0x0C44,
  WRITE_INQUIRY_MODE = 0x0C45,
  READ_PAGE_SCAN_TYPE = 0x0C46,
  WRITE_PAGE_SCAN_TYPE = 0x0C47,
  READ_AFH_CHANNEL_ASSESSMENT_MODE = 0x0C48,
  WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 0x0C49,
  READ_EXTENDED_INQUIRY_RESPONSE = 0x0C51,
  WRITE_EXTENDED_INQUIRY_RESPONSE = 0x0C52,
  REFRESH_ENCRYPTION_KEY = 0x0C53,
  READ_SIMPLE_PAIRING_MODE = 0x0C55,
  WRITE_SIMPLE_PAIRING_MODE = 0x0C56,
  READ_LOCAL_OOB_DATA = 0x0C57,
  READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 0x0C58,
  WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 0x0C59,
  READ_DEFAULT_ERRONEOUS_DATA_REPORTING = 0x0C5A,
  WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING = 0x0C5B,
  ENHANCED_FLUSH = 0x0C5F,
  SEND_KEYPRESS_NOTIFICATION = 0x0C60,
  SET_EVENT_MASK_PAGE_2 = 0x0C63,
  READ_FLOW_CONTROL_MODE = 0x0C66,
  WRITE_FLOW_CONTROL_MODE = 0x0C67,
  READ_ENHANCED_TRANSMIT_POWER_LEVEL = 0x0C68,
  READ_LE_HOST_SUPPORT = 0x0C6C,
  WRITE_LE_HOST_SUPPORT = 0x0C6D,
  SET_MWS_CHANNEL_PARAMETERS = 0x0C6E,
  SET_EXTERNAL_FRAME_CONFIGURATION = 0x0C6F,
  SET_MWS_SIGNALING = 0x0C70,
  SET_MWS_TRANSPORT_LAYER = 0x0C71,
  SET_MWS_SCAN_FREQUENCY_TABLE = 0x0C72,
  SET_MWS_PATTERN_CONFIGURATION = 0x0C73,
  SET_RESERVED_LT_ADDR = 0x0C74,
  DELETE_RESERVED_LT_ADDR = 0x0C75,
  SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA = 0x0C76,
  READ_SYNCHRONIZATION_TRAIN_PARAMETERS = 0x0C77,
  WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS = 0x0C78,
  READ_SECURE_CONNECTIONS_HOST_SUPPORT = 0x0C79,
  WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = 0x0C7A,
  READ_AUTHENTICATED_PAYLOAD_TIMEOUT = 0x0C7B,
  WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT = 0x0C7C,
  READ_LOCAL_OOB_EXTENDED_DATA = 0x0C7D,
  READ_EXTENDED_PAGE_TIMEOUT = 0x0C7E,
  WRITE_EXTENDED_PAGE_TIMEOUT = 0x0C7F,
  READ_EXTENDED_INQUIRY_LENGTH = 0x0C80,
  WRITE_EXTENDED_INQUIRY_LENGTH = 0x0C81,
  SET_ECOSYSTEM_BASE_INTERVAL = 0x0C82,
  CONFIGURE_DATA_PATH = 0x0C83,
  SET_MIN_ENCRYPTION_KEY_SIZE = 0x0C84,

  // INFORMATIONAL_PARAMETERS
  READ_LOCAL_VERSION_INFORMATION = 0x1001,
  READ_LOCAL_SUPPORTED_COMMANDS = 0x1002,
  READ_LOCAL_SUPPORTED_FEATURES = 0x1003,
  READ_LOCAL_EXTENDED_FEATURES = 0x1004,
  READ_BUFFER_SIZE = 0x1005,
  READ_BD_ADDR = 0x1009,
  READ_DATA_BLOCK_SIZE = 0x100A,
  READ_LOCAL_SUPPORTED_CODECS_V1 = 0x100B,
  READ_LOCAL_SIMPLE_PAIRING_OPTIONS = 0x100C,
  READ_LOCAL_SUPPORTED_CODECS_V2 = 0x100D,
  READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES = 0x100E,
  READ_LOCAL_SUPPORTED_CONTROLLER_DELAY = 0x100F,

  // STATUS_PARAMETERS
  READ_FAILED_CONTACT_COUNTER = 0x1401,
  RESET_FAILED_CONTACT_COUNTER = 0x1402,
  READ_LINK_QUALITY = 0x1403,
  READ_RSSI = 0x1405,
  READ_AFH_CHANNEL_MAP = 0x1406,
  READ_CLOCK = 0x1407,
  READ_ENCRYPTION_KEY_SIZE = 0x1408,
  GET_MWS_TRANSPORT_LAYER_CONFIGURATION = 0x140C,
  SET_TRIGGERED_CLOCK_CAPTURE = 0x140D,

  // TESTING
  READ_LOOPBACK_MODE = 0x1801,
  WRITE_LOOPBACK_MODE = 0x1802,
  ENABLE_DEVICE_UNDER_TEST_MODE = 0x1803,
  WRITE_SIMPLE_PAIRING_DEBUG_MODE = 0x1804,
  WRITE_SECURE_CONNECTIONS_TEST_MODE = 0x180A,

  // LE_CONTROLLER
  LE_SET_EVENT_MASK = 0x2001,
  LE_READ_BUFFER_SIZE_V1 = 0x2002,
  LE_READ_LOCAL_SUPPORTED_FEATURES = 0x2003,
  LE_SET_RANDOM_ADDRESS = 0x2005,
  LE_SET_ADVERTISING_PARAMETERS = 0x2006,
  LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER = 0x2007,
  LE_SET_ADVERTISING_DATA = 0x2008,
  LE_SET_SCAN_RESPONSE_DATA = 0x2009,
  LE_SET_ADVERTISING_ENABLE = 0x200A,
  LE_SET_SCAN_PARAMETERS = 0x200B,
  LE_SET_SCAN_ENABLE = 0x200C,
  LE_CREATE_CONNECTION = 0x200D,
  LE_CREATE_CONNECTION_CANCEL = 0x200E,
  LE_READ_FILTER_ACCEPT_LIST_SIZE = 0x200F,
  LE_CLEAR_FILTER_ACCEPT_LIST = 0x2010,
  LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST = 0x2011,
  LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST = 0x2012,
  LE_CONNECTION_UPDATE = 0x2013,
  LE_SET_HOST_CHANNEL_CLASSIFICATION = 0x2014,
  LE_READ_CHANNEL_MAP = 0x2015,
  LE_READ_REMOTE_FEATURES = 0x2016,
  LE_ENCRYPT = 0x2017,
  LE_RAND = 0x2018,
  LE_START_ENCRYPTION = 0x2019,
  LE_LONG_TERM_KEY_REQUEST_REPLY = 0x201A,
  LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = 0x201B,
  LE_READ_SUPPORTED_STATES = 0x201C,
  LE_RECEIVER_TEST_V1 = 0x201D,
  LE_TRANSMITTER_TEST_V1 = 0x201E,
  LE_TEST_END = 0x201F,
  LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = 0x2020,
  LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = 0x2021,
  LE_SET_DATA_LENGTH = 0x2022,
  LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = 0x2023,
  LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = 0x2024,
  LE_READ_LOCAL_P_256_PUBLIC_KEY = 0x2025,
  LE_GENERATE_DHKEY_V1 = 0x2026,
  LE_ADD_DEVICE_TO_RESOLVING_LIST = 0x2027,
  LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = 0x2028,
  LE_CLEAR_RESOLVING_LIST = 0x2029,
  LE_READ_RESOLVING_LIST_SIZE = 0x202A,
  LE_READ_PEER_RESOLVABLE_ADDRESS = 0x202B,
  LE_READ_LOCAL_RESOLVABLE_ADDRESS = 0x202C,
  LE_SET_ADDRESS_RESOLUTION_ENABLE = 0x202D,
  LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = 0x202E,
  LE_READ_MAXIMUM_DATA_LENGTH = 0x202F,
  LE_READ_PHY = 0x2030,
  LE_SET_DEFAULT_PHY = 0x2031,
  LE_SET_PHY = 0x2032,
  LE_RECEIVER_TEST_V2 = 0x2033,
  LE_TRANSMITTER_TEST_V2 = 0x2034,
  LE_SET_ADVERTISING_SET_RANDOM_ADDRESS = 0x2035,
  LE_SET_EXTENDED_ADVERTISING_PARAMETERS = 0x2036,
  LE_SET_EXTENDED_ADVERTISING_DATA = 0x2037,
  LE_SET_EXTENDED_SCAN_RESPONSE_DATA = 0x2038,
  LE_SET_EXTENDED_ADVERTISING_ENABLE = 0x2039,
  LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 0x203A,
  LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 0x203B,
  LE_REMOVE_ADVERTISING_SET = 0x203C,
  LE_CLEAR_ADVERTISING_SETS = 0x203D,
  LE_SET_PERIODIC_ADVERTISING_PARAMETERS = 0x203E,
  LE_SET_PERIODIC_ADVERTISING_DATA = 0x203F,
  LE_SET_PERIODIC_ADVERTISING_ENABLE = 0x2040,
  LE_SET_EXTENDED_SCAN_PARAMETERS = 0x2041,
  LE_SET_EXTENDED_SCAN_ENABLE = 0x2042,
  LE_EXTENDED_CREATE_CONNECTION = 0x2043,
  LE_PERIODIC_ADVERTISING_CREATE_SYNC = 0x2044,
  LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 0x2045,
  LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 0x2046,
  LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST = 0x2047,
  LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST = 0x2048,
  LE_CLEAR_PERIODIC_ADVERTISER_LIST = 0x2049,
  LE_READ_PERIODIC_ADVERTISER_LIST_SIZE = 0x204A,
  LE_READ_TRANSMIT_POWER = 0x204B,
  LE_READ_RF_PATH_COMPENSATION_POWER = 0x204C,
  LE_WRITE_RF_PATH_COMPENSATION_POWER = 0x204D,
  LE_SET_PRIVACY_MODE = 0x204E,
  LE_RECEIVER_TEST_V3 = 0x204F,
  LE_TRANSMITTER_TEST_V3 = 0x2050,
  LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS = 0x2051,
  LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE = 0x2052,
  LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE = 0x2053,
  LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS = 0x2054,
  LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS = 0x2055,
  LE_CONNECTION_CTE_REQUEST_ENABLE = 0x2056,
  LE_CONNECTION_CTE_RESPONSE_ENABLE = 0x2057,
  LE_READ_ANTENNA_INFORMATION = 0x2058,
  LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE = 0x2059,
  LE_PERIODIC_ADVERTISING_SYNC_TRANSFER = 0x205A,
  LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER = 0x205B,
  LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 0x205C,
  LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 0x205D,
  LE_GENERATE_DHKEY_V2 = 0x205E,
  LE_MODIFY_SLEEP_CLOCK_ACCURACY = 0x205F,
  LE_READ_BUFFER_SIZE_V2 = 0x2060,
  LE_READ_ISO_TX_SYNC = 0x2061,
  LE_SET_CIG_PARAMETERS = 0x2062,
  LE_SET_CIG_PARAMETERS_TEST = 0x2063,
  LE_CREATE_CIS = 0x2064,
  LE_REMOVE_CIG = 0x2065,
  LE_ACCEPT_CIS_REQUEST = 0x2066,
  LE_REJECT_CIS_REQUEST = 0x2067,
  LE_CREATE_BIG = 0x2068,
  LE_CREATE_BIG_TEST = 0x2069,
  LE_TERMINATE_BIG = 0x206A,
  LE_BIG_CREATE_SYNC = 0x206B,
  LE_BIG_TERMINATE_SYNC = 0x206C,
  LE_REQUEST_PEER_SCA = 0x206D,
  LE_SETUP_ISO_DATA_PATH = 0x206E,
  LE_REMOVE_ISO_DATA_PATH = 0x206F,
  LE_ISO_TRANSMIT_TEST = 0x2070,
  LE_ISO_RECEIVE_TEST = 0x2071,
  LE_ISO_READ_TEST_COUNTERS = 0x2072,
  LE_ISO_TEST_END = 0x2073,
  LE_SET_HOST_FEATURE = 0x2074,
  LE_READ_ISO_LINK_QUALITY = 0x2075,
  LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL = 0x2076,
  LE_READ_REMOTE_TRANSMIT_POWER_LEVEL = 0x2077,
  LE_SET_PATH_LOSS_REPORTING_PARAMETERS = 0x2078,
  LE_SET_PATH_LOSS_REPORTING_ENABLE = 0x2079,
  LE_SET_TRANSMIT_POWER_REPORTING_ENABLE = 0x207A,
  LE_TRANSMITTER_TEST_V4 = 0x207B,
  LE_SET_DATA_RELATED_ADDRESS_CHANGES = 0x207C,
  LE_SET_DEFAULT_SUBRATE = 0x207D,
  LE_SUBRATE_REQUEST = 0x207E,

  // VENDOR_SPECIFIC
  // MSFT_OPCODE_xxxx below is needed for the tests.
  MSFT_OPCODE_INTEL = 0xFC1E,
  LE_GET_VENDOR_CAPABILITIES = 0xFD53,
  LE_BATCH_SCAN = 0xFD56,
  LE_APCF = 0xFD57,
  LE_GET_CONTROLLER_ACTIVITY_ENERGY_INFO = 0xFD59,
  LE_EX_SET_SCAN_PARAMETERS = 0xFD5A,
  GET_CONTROLLER_DEBUG_INFO = 0xFD5B,
  // MSFT_OPCODE_xxxx below are needed for the tests.
  MSFT_OPCODE_MEDIATEK = 0xFD30,
  MSFT_OPCODE_QUALCOMM = 0xFD70,
}

// For mapping Local Supported Commands command
// Value = Octet * 10 + bit
enum OpCodeIndex : 16 {
  INQUIRY = 0,
  INQUIRY_CANCEL = 1,
  PERIODIC_INQUIRY_MODE = 2,
  EXIT_PERIODIC_INQUIRY_MODE = 3,
  CREATE_CONNECTION = 4,
  DISCONNECT = 5,
  ADD_SCO_CONNECTION = 6,
  CREATE_CONNECTION_CANCEL = 7,
  ACCEPT_CONNECTION_REQUEST = 10,
  REJECT_CONNECTION_REQUEST = 11,
  LINK_KEY_REQUEST_REPLY = 12,
  LINK_KEY_REQUEST_NEGATIVE_REPLY = 13,
  PIN_CODE_REQUEST_REPLY = 14,
  PIN_CODE_REQUEST_NEGATIVE_REPLY = 15,
  CHANGE_CONNECTION_PACKET_TYPE = 16,
  AUTHENTICATION_REQUESTED = 17,
  SET_CONNECTION_ENCRYPTION = 20,
  CHANGE_CONNECTION_LINK_KEY = 21,
  CENTRAL_LINK_KEY = 22,
  REMOTE_NAME_REQUEST = 23,
  REMOTE_NAME_REQUEST_CANCEL = 24,
  READ_REMOTE_SUPPORTED_FEATURES = 25,
  READ_REMOTE_EXTENDED_FEATURES = 26,
  READ_REMOTE_VERSION_INFORMATION = 27,
  READ_CLOCK_OFFSET = 30,
  READ_LMP_HANDLE = 31,
  HOLD_MODE = 41,
  SNIFF_MODE = 42,
  EXIT_SNIFF_MODE = 43,
  QOS_SETUP = 46,
  ROLE_DISCOVERY = 47,
  SWITCH_ROLE = 50,
  READ_LINK_POLICY_SETTINGS = 51,
  WRITE_LINK_POLICY_SETTINGS = 52,
  READ_DEFAULT_LINK_POLICY_SETTINGS = 53,
  WRITE_DEFAULT_LINK_POLICY_SETTINGS = 54,
  FLOW_SPECIFICATION = 55,
  SET_EVENT_MASK = 56,
  RESET = 57,
  SET_EVENT_FILTER = 60,
  FLUSH = 61,
  READ_PIN_TYPE = 62,
  WRITE_PIN_TYPE = 63,
  READ_STORED_LINK_KEY = 65,
  WRITE_STORED_LINK_KEY = 66,
  DELETE_STORED_LINK_KEY = 67,
  WRITE_LOCAL_NAME = 70,
  READ_LOCAL_NAME = 71,
  READ_CONNECTION_ACCEPT_TIMEOUT = 72,
  WRITE_CONNECTION_ACCEPT_TIMEOUT = 73,
  READ_PAGE_TIMEOUT = 74,
  WRITE_PAGE_TIMEOUT = 75,
  READ_SCAN_ENABLE = 76,
  WRITE_SCAN_ENABLE = 77,
  READ_PAGE_SCAN_ACTIVITY = 80,
  WRITE_PAGE_SCAN_ACTIVITY = 81,
  READ_INQUIRY_SCAN_ACTIVITY = 82,
  WRITE_INQUIRY_SCAN_ACTIVITY = 83,
  READ_AUTHENTICATION_ENABLE = 84,
  WRITE_AUTHENTICATION_ENABLE = 85,
  READ_CLASS_OF_DEVICE = 90,
  WRITE_CLASS_OF_DEVICE = 91,
  READ_VOICE_SETTING = 92,
  WRITE_VOICE_SETTING = 93,
  READ_AUTOMATIC_FLUSH_TIMEOUT = 94,
  WRITE_AUTOMATIC_FLUSH_TIMEOUT = 95,
  READ_NUM_BROADCAST_RETRANSMITS = 96,
  WRITE_NUM_BROADCAST_RETRANSMITS = 97,
  READ_HOLD_MODE_ACTIVITY = 100,
  WRITE_HOLD_MODE_ACTIVITY = 101,
  READ_TRANSMIT_POWER_LEVEL = 102,
  READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 103,
  WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 104,
  SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 105,
  HOST_BUFFER_SIZE = 106,
  HOST_NUMBER_OF_COMPLETED_PACKETS = 107,
  READ_LINK_SUPERVISION_TIMEOUT = 110,
  WRITE_LINK_SUPERVISION_TIMEOUT = 111,
  READ_NUMBER_OF_SUPPORTED_IAC = 112,
  READ_CURRENT_IAC_LAP = 113,
  WRITE_CURRENT_IAC_LAP = 114,
  SET_AFH_HOST_CHANNEL_CLASSIFICATION = 121,
  READ_INQUIRY_SCAN_TYPE = 124,
  WRITE_INQUIRY_SCAN_TYPE = 125,
  READ_INQUIRY_MODE = 126,
  WRITE_INQUIRY_MODE = 127,
  READ_PAGE_SCAN_TYPE = 130,
  WRITE_PAGE_SCAN_TYPE = 131,
  READ_AFH_CHANNEL_ASSESSMENT_MODE = 132,
  WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 133,
  READ_LOCAL_VERSION_INFORMATION = 143,
  READ_LOCAL_SUPPORTED_FEATURES = 145,
  READ_LOCAL_EXTENDED_FEATURES = 146,
  READ_BUFFER_SIZE = 147,
  READ_BD_ADDR = 151,
  READ_FAILED_CONTACT_COUNTER = 152,
  RESET_FAILED_CONTACT_COUNTER = 153,
  READ_LINK_QUALITY = 154,
  READ_RSSI = 155,
  READ_AFH_CHANNEL_MAP = 156,
  READ_CLOCK = 157,
  READ_LOOPBACK_MODE = 160,
  WRITE_LOOPBACK_MODE = 161,
  ENABLE_DEVICE_UNDER_TEST_MODE = 162,
  SETUP_SYNCHRONOUS_CONNECTION = 163,
  ACCEPT_SYNCHRONOUS_CONNECTION = 164,
  REJECT_SYNCHRONOUS_CONNECTION = 165,
  READ_EXTENDED_INQUIRY_RESPONSE = 170,
  WRITE_EXTENDED_INQUIRY_RESPONSE = 171,
  REFRESH_ENCRYPTION_KEY = 172,
  SNIFF_SUBRATING = 174,
  READ_SIMPLE_PAIRING_MODE = 175,
  WRITE_SIMPLE_PAIRING_MODE = 176,
  READ_LOCAL_OOB_DATA = 177,
  READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 180,
  WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 181,
  READ_DEFAULT_ERRONEOUS_DATA_REPORTING = 182,
  WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING = 183,
  IO_CAPABILITY_REQUEST_REPLY = 187,
  USER_CONFIRMATION_REQUEST_REPLY = 190,
  USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 191,
  USER_PASSKEY_REQUEST_REPLY = 192,
  USER_PASSKEY_REQUEST_NEGATIVE_REPLY = 193,
  REMOTE_OOB_DATA_REQUEST_REPLY = 194,
  WRITE_SIMPLE_PAIRING_DEBUG_MODE = 195,
  ENHANCED_FLUSH = 196,
  REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 197,
  SEND_KEYPRESS_NOTIFICATION = 202,
  IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 203,
  READ_ENCRYPTION_KEY_SIZE = 204,
  SET_EVENT_MASK_PAGE_2 = 222,
  READ_FLOW_CONTROL_MODE = 230,
  WRITE_FLOW_CONTROL_MODE = 231,
  READ_DATA_BLOCK_SIZE = 232,
  READ_ENHANCED_TRANSMIT_POWER_LEVEL = 240,
  READ_LE_HOST_SUPPORT = 245,
  WRITE_LE_HOST_SUPPORT = 246,
  LE_SET_EVENT_MASK = 250,
  LE_READ_BUFFER_SIZE_V1 = 251,
  LE_READ_LOCAL_SUPPORTED_FEATURES = 252,
  LE_SET_RANDOM_ADDRESS = 254,
  LE_SET_ADVERTISING_PARAMETERS = 255,
  LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER = 256,
  LE_SET_ADVERTISING_DATA = 257,
  LE_SET_SCAN_RESPONSE_DATA = 260,
  LE_SET_ADVERTISING_ENABLE = 261,
  LE_SET_SCAN_PARAMETERS = 262,
  LE_SET_SCAN_ENABLE = 263,
  LE_CREATE_CONNECTION = 264,
  LE_CREATE_CONNECTION_CANCEL = 265,
  LE_READ_FILTER_ACCEPT_LIST_SIZE = 266,
  LE_CLEAR_FILTER_ACCEPT_LIST = 267,
  LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST = 270,
  LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST = 271,
  LE_CONNECTION_UPDATE = 272,
  LE_SET_HOST_CHANNEL_CLASSIFICATION = 273,
  LE_READ_CHANNEL_MAP = 274,
  LE_READ_REMOTE_FEATURES = 275,
  LE_ENCRYPT = 276,
  LE_RAND = 277,
  LE_START_ENCRYPTION = 280,
  LE_LONG_TERM_KEY_REQUEST_REPLY = 281,
  LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = 282,
  LE_READ_SUPPORTED_STATES = 283,
  LE_RECEIVER_TEST_V1 = 284,
  LE_TRANSMITTER_TEST_V1 = 285,
  LE_TEST_END = 286,
  ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = 293,
  ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = 294,
  READ_LOCAL_SUPPORTED_CODECS_V1 = 295,
  SET_MWS_CHANNEL_PARAMETERS = 296,
  SET_EXTERNAL_FRAME_CONFIGURATION = 297,
  SET_MWS_SIGNALING = 300,
  SET_MWS_TRANSPORT_LAYER = 301,
  SET_MWS_SCAN_FREQUENCY_TABLE = 302,
  GET_MWS_TRANSPORT_LAYER_CONFIGURATION = 303,
  SET_MWS_PATTERN_CONFIGURATION = 304,
  SET_TRIGGERED_CLOCK_CAPTURE = 305,
  TRUNCATED_PAGE = 306,
  TRUNCATED_PAGE_CANCEL = 307,
  SET_CONNECTIONLESS_PERIPHERAL_BROADCAST = 310,
  SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE = 311,
  START_SYNCHRONIZATION_TRAIN = 312,
  RECEIVE_SYNCHRONIZATION_TRAIN = 313,
  SET_RESERVED_LT_ADDR = 314,
  DELETE_RESERVED_LT_ADDR = 315,
  SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA = 316,
  READ_SYNCHRONIZATION_TRAIN_PARAMETERS = 317,
  WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS = 320,
  REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY = 321,
  READ_SECURE_CONNECTIONS_HOST_SUPPORT = 322,
  WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = 323,
  READ_AUTHENTICATED_PAYLOAD_TIMEOUT = 324,
  WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT = 325,
  READ_LOCAL_OOB_EXTENDED_DATA = 326,
  WRITE_SECURE_CONNECTIONS_TEST_MODE = 327,
  READ_EXTENDED_PAGE_TIMEOUT = 330,
  WRITE_EXTENDED_PAGE_TIMEOUT = 331,
  READ_EXTENDED_INQUIRY_LENGTH = 332,
  WRITE_EXTENDED_INQUIRY_LENGTH = 333,
  LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = 334,
  LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = 335,
  LE_SET_DATA_LENGTH = 336,
  LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = 337,
  LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = 340,
  LE_READ_LOCAL_P_256_PUBLIC_KEY = 341,
  LE_GENERATE_DHKEY_V1 = 342,
  LE_ADD_DEVICE_TO_RESOLVING_LIST = 343,
  LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = 344,
  LE_CLEAR_RESOLVING_LIST = 345,
  LE_READ_RESOLVING_LIST_SIZE = 346,
  LE_READ_PEER_RESOLVABLE_ADDRESS = 347,
  LE_READ_LOCAL_RESOLVABLE_ADDRESS = 350,
  LE_SET_ADDRESS_RESOLUTION_ENABLE = 351,
  LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = 352,
  LE_READ_MAXIMUM_DATA_LENGTH = 353,
  LE_READ_PHY = 354,
  LE_SET_DEFAULT_PHY = 355,
  LE_SET_PHY = 356,
  LE_RECEIVER_TEST_V2 = 357,
  LE_TRANSMITTER_TEST_V2 = 360,
  LE_SET_ADVERTISING_SET_RANDOM_ADDRESS = 361,
  LE_SET_EXTENDED_ADVERTISING_PARAMETERS = 362,
  LE_SET_EXTENDED_ADVERTISING_DATA = 363,
  LE_SET_EXTENDED_SCAN_RESPONSE_DATA = 364,
  LE_SET_EXTENDED_ADVERTISING_ENABLE = 365,
  LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 366,
  LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 367,
  LE_REMOVE_ADVERTISING_SET = 370,
  LE_CLEAR_ADVERTISING_SETS = 371,
  LE_SET_PERIODIC_ADVERTISING_PARAMETERS = 372,
  LE_SET_PERIODIC_ADVERTISING_DATA = 373,
  LE_SET_PERIODIC_ADVERTISING_ENABLE = 374,
  LE_SET_EXTENDED_SCAN_PARAMETERS = 375,
  LE_SET_EXTENDED_SCAN_ENABLE = 376,
  LE_EXTENDED_CREATE_CONNECTION = 377,
  LE_PERIODIC_ADVERTISING_CREATE_SYNC = 380,
  LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 381,
  LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 382,
  LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST = 383,
  LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST = 384,
  LE_CLEAR_PERIODIC_ADVERTISER_LIST = 385,
  LE_READ_PERIODIC_ADVERTISER_LIST_SIZE = 386,
  LE_READ_TRANSMIT_POWER = 387,
  LE_READ_RF_PATH_COMPENSATION_POWER = 390,
  LE_WRITE_RF_PATH_COMPENSATION_POWER = 391,
  LE_SET_PRIVACY_MODE = 392,
  LE_RECEIVER_TEST_V3 = 393,
  LE_TRANSMITTER_TEST_V3 = 394,
  LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS = 395,
  LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE = 396,
  LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE = 397,
  LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS = 400,
  LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS = 401,
  LE_CONNECTION_CTE_REQUEST_ENABLE = 402,
  LE_CONNECTION_CTE_RESPONSE_ENABLE = 403,
  LE_READ_ANTENNA_INFORMATION = 404,
  LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE = 405,
  LE_PERIODIC_ADVERTISING_SYNC_TRANSFER = 406,
  LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER = 407,
  LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 410,
  LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 411,
  LE_GENERATE_DHKEY_V2 = 412,
  READ_LOCAL_SIMPLE_PAIRING_OPTIONS = 413,
  LE_MODIFY_SLEEP_CLOCK_ACCURACY = 414,
  LE_READ_BUFFER_SIZE_V2 = 415,
  LE_READ_ISO_TX_SYNC = 416,
  LE_SET_CIG_PARAMETERS = 417,
  LE_SET_CIG_PARAMETERS_TEST = 420,
  LE_CREATE_CIS = 421,
  LE_REMOVE_CIG = 422,
  LE_ACCEPT_CIS_REQUEST = 423,
  LE_REJECT_CIS_REQUEST = 424,
  LE_CREATE_BIG = 425,
  LE_CREATE_BIG_TEST = 426,
  LE_TERMINATE_BIG = 427,
  LE_BIG_CREATE_SYNC = 430,
  LE_BIG_TERMINATE_SYNC = 431,
  LE_REQUEST_PEER_SCA = 432,
  LE_SETUP_ISO_DATA_PATH = 433,
  LE_REMOVE_ISO_DATA_PATH = 434,
  LE_ISO_TRANSMIT_TEST = 435,
  LE_ISO_RECEIVE_TEST = 436,
  LE_ISO_READ_TEST_COUNTERS = 437,
  LE_ISO_TEST_END = 440,
  LE_SET_HOST_FEATURE = 441,
  LE_READ_ISO_LINK_QUALITY = 442,
  LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL = 443,
  LE_READ_REMOTE_TRANSMIT_POWER_LEVEL = 444,
  LE_SET_PATH_LOSS_REPORTING_PARAMETERS = 445,
  LE_SET_PATH_LOSS_REPORTING_ENABLE = 446,
  LE_SET_TRANSMIT_POWER_REPORTING_ENABLE = 447,
  LE_TRANSMITTER_TEST_V4 = 450,
  SET_ECOSYSTEM_BASE_INTERVAL = 451,
  READ_LOCAL_SUPPORTED_CODECS_V2 = 452,
  READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES = 453,
  READ_LOCAL_SUPPORTED_CONTROLLER_DELAY = 454,
  CONFIGURE_DATA_PATH = 455,
  LE_SET_DATA_RELATED_ADDRESS_CHANGES = 456,
  SET_MIN_ENCRYPTION_KEY_SIZE = 457,
  LE_SET_DEFAULT_SUBRATE = 460,
  LE_SUBRATE_REQUEST = 461,
}

packet Command {
  op_code : OpCode,
  _size_(_payload_) : 8,
  _payload_,
}

// HCI Event Packets

enum EventCode : 8 {
  INQUIRY_COMPLETE = 0x01,
  INQUIRY_RESULT = 0x02,
  CONNECTION_COMPLETE = 0x03,
  CONNECTION_REQUEST = 0x04,
  DISCONNECTION_COMPLETE = 0x05,
  AUTHENTICATION_COMPLETE = 0x06,
  REMOTE_NAME_REQUEST_COMPLETE = 0x07,
  ENCRYPTION_CHANGE = 0x08,
  CHANGE_CONNECTION_LINK_KEY_COMPLETE = 0x09,
  CENTRAL_LINK_KEY_COMPLETE = 0x0A,
  READ_REMOTE_SUPPORTED_FEATURES_COMPLETE = 0x0B,
  READ_REMOTE_VERSION_INFORMATION_COMPLETE = 0x0C,
  QOS_SETUP_COMPLETE = 0x0D,
  COMMAND_COMPLETE = 0x0E,
  COMMAND_STATUS = 0x0F,
  HARDWARE_ERROR = 0x10,
  FLUSH_OCCURRED = 0x11,
  ROLE_CHANGE = 0x12,
  NUMBER_OF_COMPLETED_PACKETS = 0x13,
  MODE_CHANGE = 0x14,
  RETURN_LINK_KEYS = 0x15,
  PIN_CODE_REQUEST = 0x16,
  LINK_KEY_REQUEST = 0x17,
  LINK_KEY_NOTIFICATION = 0x18,
  LOOPBACK_COMMAND = 0x19,
  DATA_BUFFER_OVERFLOW = 0x1A,
  MAX_SLOTS_CHANGE = 0x1B,
  READ_CLOCK_OFFSET_COMPLETE = 0x1C,
  CONNECTION_PACKET_TYPE_CHANGED = 0x1D,
  QOS_VIOLATION = 0x1E,
  PAGE_SCAN_REPETITION_MODE_CHANGE = 0x20,
  FLOW_SPECIFICATION_COMPLETE = 0x21,
  INQUIRY_RESULT_WITH_RSSI = 0x22,
  READ_REMOTE_EXTENDED_FEATURES_COMPLETE = 0x23,
  SYNCHRONOUS_CONNECTION_COMPLETE = 0x2C,
  SYNCHRONOUS_CONNECTION_CHANGED = 0x2D,
  SNIFF_SUBRATING = 0x2E,
  EXTENDED_INQUIRY_RESULT = 0x2F,
  ENCRYPTION_KEY_REFRESH_COMPLETE = 0x30,
  IO_CAPABILITY_REQUEST = 0x31,
  IO_CAPABILITY_RESPONSE = 0x32,
  USER_CONFIRMATION_REQUEST = 0x33,
  USER_PASSKEY_REQUEST = 0x34,
  REMOTE_OOB_DATA_REQUEST = 0x35,
  SIMPLE_PAIRING_COMPLETE = 0x36,
  LINK_SUPERVISION_TIMEOUT_CHANGED = 0x38,
  ENHANCED_FLUSH_COMPLETE = 0x39,
  USER_PASSKEY_NOTIFICATION = 0x3B,
  KEYPRESS_NOTIFICATION = 0x3C,
  REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION = 0x3D,
  LE_META_EVENT = 0x3e,
  NUMBER_OF_COMPLETED_DATA_BLOCKS = 0x48,
  VENDOR_SPECIFIC = 0xFF,
}

// LE events
enum SubeventCode : 8 {
  CONNECTION_COMPLETE = 0x01,
  ADVERTISING_REPORT = 0x02,
  CONNECTION_UPDATE_COMPLETE = 0x03,
  READ_REMOTE_FEATURES_COMPLETE = 0x04,
  LONG_TERM_KEY_REQUEST = 0x05,
  REMOTE_CONNECTION_PARAMETER_REQUEST = 0x06,
  DATA_LENGTH_CHANGE = 0x07,
  READ_LOCAL_P256_PUBLIC_KEY_COMPLETE = 0x08,
  GENERATE_DHKEY_COMPLETE = 0x09,
  ENHANCED_CONNECTION_COMPLETE = 0x0a,
  DIRECTED_ADVERTISING_REPORT = 0x0b,
  PHY_UPDATE_COMPLETE = 0x0c,
  EXTENDED_ADVERTISING_REPORT = 0x0D,
  PERIODIC_ADVERTISING_SYNC_ESTABLISHED = 0x0E,
  PERIODIC_ADVERTISING_REPORT = 0x0F,
  PERIODIC_ADVERTISING_SYNC_LOST = 0x10,
  SCAN_TIMEOUT = 0x11,
  ADVERTISING_SET_TERMINATED = 0x12,
  SCAN_REQUEST_RECEIVED = 0x13,
  CHANNEL_SELECTION_ALGORITHM = 0x14,
  CONNECTIONLESS_IQ_REPORT = 0x15,
  CONNECTION_IQ_REPORT = 0x16,
  CTE_REQUEST_FAILED = 0x17,
  PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED = 0x18,
  CIS_ESTABLISHED = 0x19,
  CIS_REQUEST = 0x1A,
  CREATE_BIG_COMPLETE = 0x1B,
  TERMINATE_BIG_COMPLETE = 0x1C,
  BIG_SYNC_ESTABLISHED = 0x1D,
  BIG_SYNC_LOST = 0x1E,
  REQUEST_PEER_SCA_COMPLETE = 0x1F,
  PATH_LOSS_THRESHOLD = 0x20,
  TRANSMIT_POWER_REPORTING = 0x21,
  BIG_INFO_ADVERTISING_REPORT = 0x22,
  LE_SUBRATE_CHANGE = 0x23,
}

// Vendor specific events
enum VseSubeventCode : 8 {
  STORAGE_THRESHOLD_BREACH = 0x54,
  LE_MULTI_ADVERTISING_STATE_CHANGE = 0x55,
  LE_ADVERTISEMENT_TRACKING = 0x56,
  CONTROLLER_DEBUG_INFO = 0x57,
  BLUETOOTH_QUALITY_REPORT = 0x58,
}

packet Event {
  event_code : EventCode,
  _size_(_payload_) : 8,
  _payload_,
}

// Common definitions for commands and events

enum FeatureFlag : 1 {
  UNSUPPORTED = 0,
  SUPPORTED = 1,
}

enum ErrorCode: 8 {
  STATUS_UNKNOWN = 0xFF,
  SUCCESS = 0x00,
  UNKNOWN_HCI_COMMAND = 0x01,
  UNKNOWN_CONNECTION = 0x02,
  HARDWARE_FAILURE = 0x03,
  PAGE_TIMEOUT = 0x04,
  AUTHENTICATION_FAILURE = 0x05,
  PIN_OR_KEY_MISSING = 0x06,
  MEMORY_CAPACITY_EXCEEDED = 0x07,
  CONNECTION_TIMEOUT = 0x08,
  CONNECTION_LIMIT_EXCEEDED = 0x09,
  SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED = 0x0A,
  CONNECTION_ALREADY_EXISTS = 0x0B,
  COMMAND_DISALLOWED = 0x0C,
  CONNECTION_REJECTED_LIMITED_RESOURCES = 0x0D,
  CONNECTION_REJECTED_SECURITY_REASONS = 0x0E,
  CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR = 0x0F,
  CONNECTION_ACCEPT_TIMEOUT = 0x10,
  UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE = 0x11,
  INVALID_HCI_COMMAND_PARAMETERS = 0x12,
  REMOTE_USER_TERMINATED_CONNECTION = 0x13,
  REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES = 0x14,
  REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF = 0x15,
  CONNECTION_TERMINATED_BY_LOCAL_HOST = 0x16,
  REPEATED_ATTEMPTS = 0x17,
  PAIRING_NOT_ALLOWED = 0x18,
  UNKNOWN_LMP_PDU = 0x19,
  UNSUPPORTED_REMOTE_OR_LMP_FEATURE = 0x1A,
  SCO_OFFSET_REJECTED = 0x1B,
  SCO_INTERVAL_REJECTED = 0x1C,
  SCO_AIR_MODE_REJECTED = 0x1D,
  INVALID_LMP_OR_LL_PARAMETERS = 0x1E,
  UNSPECIFIED_ERROR = 0x1F,
  UNSUPPORTED_LMP_OR_LL_PARAMETER = 0x20,
  ROLE_CHANGE_NOT_ALLOWED = 0x21,
  TRANSACTION_RESPONSE_TIMEOUT = 0x22,
  LINK_LAYER_COLLISION = 0x23,
  ENCRYPTION_MODE_NOT_ACCEPTABLE = 0x25,
  ROLE_SWITCH_FAILED = 0x35,
  HOST_BUSY = 0x38,
  CONTROLLER_BUSY = 0x3A,
  ADVERTISING_TIMEOUT = 0x3C,
  CONNECTION_FAILED_ESTABLISHMENT = 0x3E,
  UNKNOWN_ADVERTISING_IDENTIFIER = 0x42,
  LIMIT_REACHED = 0x43,
  OPERATION_CANCELLED_BY_HOST = 0x44,
  PACKET_TOO_LONG = 0x45,
}

// Events that are defined with their respective commands

packet CommandComplete : Event (event_code = COMMAND_COMPLETE) {
  num_hci_command_packets : 8,
  command_op_code : OpCode,
  _payload_,
}

packet CommandStatus : Event (event_code = COMMAND_STATUS) {
  status : ErrorCode, // SUCCESS means PENDING
  num_hci_command_packets : 8,
  command_op_code : OpCode,
  _payload_,
}

packet VendorSpecificEvent : Event (event_code = VENDOR_SPECIFIC) {
  subevent_code : VseSubeventCode,
  _payload_,
}

  // Credits
packet NoCommandComplete : CommandComplete (command_op_code = NONE) {
}

struct Lap { // Lower Address Part
  lap : 6,
  _reserved_ : 2,
  _fixed_ = 0x9e8b : 16,
}

  // LINK_CONTROL
packet Inquiry : Command (op_code = INQUIRY) {
  lap : Lap,
  inquiry_length : 8, // 0x1 - 0x30 (times 1.28s)
  num_responses : 8, // 0x00 unlimited
}

test Inquiry {
  "\x01\x04\x05\x33\x8b\x9e\xaa\xbb",
}

packet InquiryStatus : CommandStatus (command_op_code = INQUIRY) {
}

test InquiryStatus {
  "\x0f\x04\x00\x01\x01\x04",
}

packet InquiryCancel : Command (op_code = INQUIRY_CANCEL) {
}

test InquiryCancel {
  "\x02\x04\x00",
}

packet InquiryCancelComplete : CommandComplete (command_op_code = INQUIRY_CANCEL) {
  status : ErrorCode,
}

test InquiryCancelComplete {
  "\x0e\x04\x01\x02\x04\x00",
}

packet PeriodicInquiryMode : Command (op_code = PERIODIC_INQUIRY_MODE) {
  max_period_length : 16, // Range 0x0003 to 0xffff (times 1.28s)
  min_period_length : 16, // Range 0x0002 to 0xfffe (times 1.28s)
  lap : Lap,
  inquiry_length : 8, // 0x1 - 0x30 (times 1.28s)
  num_responses : 8, // 0x00 unlimited
}

test PeriodicInquiryMode {
  "\x03\x04\x09\x12\x34\x56\x78\x11\x8b\x9e\x9a\xbc",
}

packet PeriodicInquiryModeComplete : CommandComplete (command_op_code = PERIODIC_INQUIRY_MODE) {
  status : ErrorCode,
}

test PeriodicInquiryModeComplete {
  "\x0e\x04\x01\x03\x04\x00",
}

packet ExitPeriodicInquiryMode : Command (op_code = EXIT_PERIODIC_INQUIRY_MODE) {
}

test ExitPeriodicInquiryMode {
  "\x04\x04\x00",
}

packet ExitPeriodicInquiryModeComplete : CommandComplete (command_op_code = EXIT_PERIODIC_INQUIRY_MODE) {
  status : ErrorCode,
}

test ExitPeriodicInquiryModeComplete {
  "\x0e\x04\x01\x04\x04\x00",
}

enum PageScanRepetitionMode : 8 {
  R0 = 0x00,
  R1 = 0x01,
  R2 = 0x02,
}

enum ClockOffsetValid : 1 {
  INVALID = 0,
  VALID = 1,
}

enum CreateConnectionRoleSwitch : 8 {
  REMAIN_CENTRAL = 0x00,
  ALLOW_ROLE_SWITCH = 0x01,
}

packet CreateConnection : Command (op_code = CREATE_CONNECTION) {
  bd_addr : Address,
  packet_type : 16,
  page_scan_repetition_mode : PageScanRepetitionMode,
  _reserved_ : 8,
  clock_offset : 15,
  clock_offset_valid : ClockOffsetValid,
  allow_role_switch : CreateConnectionRoleSwitch,
}

packet CreateConnectionStatus : CommandStatus (command_op_code = CREATE_CONNECTION) {
}

enum DisconnectReason : 8 {
  AUTHENTICATION_FAILURE = 0x05,
  REMOTE_USER_TERMINATED_CONNECTION = 0x13,
  REMOTE_DEVICE_TERMINATED_CONNECTION_LOW_RESOURCES = 0x14,
  REMOTE_DEVICE_TERMINATED_CONNECTION_POWER_OFF = 0x15,
  UNSUPPORTED_REMOTE_FEATURE = 0x1A,
  PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29,
  UNACCEPTABLE_CONNECTION_PARAMETERS = 0x3B,
}

packet Disconnect : Command (op_code = DISCONNECT) {
  connection_handle : 12,
  _reserved_ : 4,
  reason : DisconnectReason,
}

packet DisconnectStatus : CommandStatus (command_op_code = DISCONNECT) {
}

packet AddScoConnection : Command (op_code = ADD_SCO_CONNECTION) {
  connection_handle : 12,
  _reserved_ : 4,
  packet_type : 16,
}

packet AddScoConnectionStatus : CommandStatus (command_op_code = ADD_SCO_CONNECTION) {
}

packet CreateConnectionCancel : Command (op_code = CREATE_CONNECTION_CANCEL) {
  bd_addr : Address,
}

packet CreateConnectionCancelComplete : CommandComplete (command_op_code = CREATE_CONNECTION_CANCEL) {
  status : ErrorCode,
  bd_addr : Address,
}

enum AcceptConnectionRequestRole : 8 {
  BECOME_CENTRAL = 0x00,
  REMAIN_PERIPHERAL = 0x01,
}

packet AcceptConnectionRequest : Command (op_code = ACCEPT_CONNECTION_REQUEST) {
  bd_addr : Address,
  role : AcceptConnectionRequestRole,
}

packet AcceptConnectionRequestStatus : CommandStatus (command_op_code = ACCEPT_CONNECTION_REQUEST) {
}

enum RejectConnectionReason : 8 {
  LIMITED_RESOURCES = 0x0D,
  SECURITY_REASONS = 0x0E,
  UNACCEPTABLE_BD_ADDR = 0x0F,
}

packet RejectConnectionRequest : Command (op_code = REJECT_CONNECTION_REQUEST) {
  bd_addr : Address,
  reason : RejectConnectionReason,
}

packet RejectConnectionRequestStatus : CommandStatus (command_op_code = REJECT_CONNECTION_REQUEST) {
}

packet LinkKeyRequestReply : Command (op_code = LINK_KEY_REQUEST_REPLY) {
  bd_addr : Address,
  link_key : 8[16],
}

packet LinkKeyRequestReplyComplete : CommandComplete (command_op_code = LINK_KEY_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet LinkKeyRequestNegativeReply : Command (op_code = LINK_KEY_REQUEST_NEGATIVE_REPLY) {
  bd_addr : Address,
}

packet LinkKeyRequestNegativeReplyComplete : CommandComplete (command_op_code = LINK_KEY_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet PinCodeRequestReply : Command (op_code = PIN_CODE_REQUEST_REPLY) {
  bd_addr : Address,
  pin_code_length : 5, // 0x01 - 0x10
  _reserved_ : 3,
  pin_code : 8[16], // string parameter, first octet first
}

packet PinCodeRequestReplyComplete : CommandComplete (command_op_code = PIN_CODE_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet PinCodeRequestNegativeReply : Command (op_code = PIN_CODE_REQUEST_NEGATIVE_REPLY) {
  bd_addr : Address,
}

packet PinCodeRequestNegativeReplyComplete : CommandComplete (command_op_code = PIN_CODE_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet ChangeConnectionPacketType : Command (op_code = CHANGE_CONNECTION_PACKET_TYPE) {
  connection_handle : 12,
  _reserved_ : 4,
  packet_type : 16,
}

packet ChangeConnectionPacketTypeStatus : CommandStatus (command_op_code = CHANGE_CONNECTION_PACKET_TYPE) {
}

packet AuthenticationRequested : Command (op_code = AUTHENTICATION_REQUESTED) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet AuthenticationRequestedStatus : CommandStatus (command_op_code = AUTHENTICATION_REQUESTED) {
}

packet SetConnectionEncryption : Command (op_code = SET_CONNECTION_ENCRYPTION) {
  connection_handle : 12,
  _reserved_ : 4,
  encryption_enable : Enable,
}

packet SetConnectionEncryptionStatus : CommandStatus (command_op_code = SET_CONNECTION_ENCRYPTION) {
}

packet ChangeConnectionLinkKey : Command (op_code = CHANGE_CONNECTION_LINK_KEY) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ChangeConnectionLinkKeyStatus : CommandStatus (command_op_code = CHANGE_CONNECTION_LINK_KEY) {
}

enum KeyFlag : 8 {
  SEMI_PERMANENT = 0x00,
  TEMPORARY = 0x01,
}

packet CentralLinkKey : Command (op_code = CENTRAL_LINK_KEY) {
  key_flag : KeyFlag,
}

packet CentralLinkKeyStatus : CommandStatus (command_op_code = CENTRAL_LINK_KEY) {
}

packet RemoteNameRequest : Command (op_code = REMOTE_NAME_REQUEST) {
  bd_addr : Address,
  page_scan_repetition_mode : PageScanRepetitionMode,
  _reserved_ : 8,
  clock_offset : 15,
  clock_offset_valid : ClockOffsetValid,
}

packet RemoteNameRequestStatus : CommandStatus (command_op_code = REMOTE_NAME_REQUEST) {
}

packet RemoteNameRequestCancel : Command (op_code = REMOTE_NAME_REQUEST_CANCEL) {
  bd_addr : Address,
}

packet RemoteNameRequestCancelComplete : CommandComplete (command_op_code = REMOTE_NAME_REQUEST_CANCEL) {
  status : ErrorCode,
  bd_addr : Address,
}

packet ReadRemoteSupportedFeatures : Command (op_code = READ_REMOTE_SUPPORTED_FEATURES) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadRemoteSupportedFeaturesStatus : CommandStatus (command_op_code = READ_REMOTE_SUPPORTED_FEATURES) {
}

packet ReadRemoteExtendedFeatures : Command (op_code = READ_REMOTE_EXTENDED_FEATURES) {
  connection_handle : 12,
  _reserved_ : 4,
  page_number : 8,
}

packet ReadRemoteExtendedFeaturesStatus : CommandStatus (command_op_code = READ_REMOTE_EXTENDED_FEATURES) {
}

packet ReadRemoteVersionInformation : Command (op_code = READ_REMOTE_VERSION_INFORMATION) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadRemoteVersionInformationStatus : CommandStatus (command_op_code = READ_REMOTE_VERSION_INFORMATION) {
}

packet ReadClockOffset : Command (op_code = READ_CLOCK_OFFSET) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadClockOffsetStatus : CommandStatus (command_op_code = READ_CLOCK_OFFSET) {
}

packet ReadLmpHandle : Command (op_code = READ_LMP_HANDLE) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadLmpHandleComplete : CommandComplete (command_op_code = READ_LMP_HANDLE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  lmp_handle : 8,
  _reserved_ : 32,
}

enum SynchronousPacketTypeBits : 16 {
  HV1_ALLOWED = 0x0001,
  HV2_ALLOWED = 0x0002,
  HV3_ALLOWED = 0x0004,
  EV3_ALLOWED = 0x0008,
  EV4_ALLOWED = 0x0010,
  EV5_ALLOWED = 0x0020,
  NO_2_EV3_ALLOWED = 0x0040,
  NO_3_EV3_ALLOWED = 0x0080,
  NO_2_EV5_ALLOWED = 0x0100,
  NO_3_EV5_ALLOWED = 0x0200,
}

enum RetransmissionEffort : 8 {
  NO_RETRANSMISSION = 0x00,
  OPTIMIZED_FOR_POWER = 0x01,
  OPTIMIZED_FOR_LINK_QUALITY = 0x02,
  DO_NOT_CARE = 0xFF,
}

packet SetupSynchronousConnection : Command (op_code = SETUP_SYNCHRONOUS_CONNECTION) {
  connection_handle : 12,
  _reserved_ : 4,
  transmit_bandwidth : 32,
  receive_bandwidth : 32,
  max_latency : 16, // 0-3 reserved, 0xFFFF = don't care
  voice_setting : 10,
  _reserved_ : 6,
  retransmission_effort : RetransmissionEffort,
  packet_type : 16, // See SynchronousPacketTypeBits
}

packet SetupSynchronousConnectionStatus : CommandStatus (command_op_code = SETUP_SYNCHRONOUS_CONNECTION) {
}

packet AcceptSynchronousConnection : Command (op_code = ACCEPT_SYNCHRONOUS_CONNECTION) {
  bd_addr : Address,
  transmit_bandwidth : 32,
  receive_bandwidth : 32,
  max_latency : 16, // 0-3 reserved, 0xFFFF = don't care
  voice_setting : 10,
  _reserved_ : 6,
  retransmission_effort : RetransmissionEffort,
  packet_type : 16, // See SynchronousPacketTypeBits
}

packet AcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ACCEPT_SYNCHRONOUS_CONNECTION) {
}

packet RejectSynchronousConnection : Command (op_code = REJECT_SYNCHRONOUS_CONNECTION) {
  bd_addr : Address,
  reason : RejectConnectionReason,
}

packet RejectSynchronousConnectionStatus : CommandStatus (command_op_code = REJECT_SYNCHRONOUS_CONNECTION) {
}

enum IoCapability : 8 {
  DISPLAY_ONLY = 0x00,
  DISPLAY_YES_NO = 0x01,
  KEYBOARD_ONLY = 0x02,
  NO_INPUT_NO_OUTPUT = 0x03,
}

enum OobDataPresent : 8 {
  NOT_PRESENT = 0x00,
  P_192_PRESENT = 0x01,
  P_256_PRESENT = 0x02,
  P_192_AND_256_PRESENT = 0x03,
}

enum AuthenticationRequirements : 8 {
  NO_BONDING = 0x00,
  NO_BONDING_MITM_PROTECTION = 0x01,
  DEDICATED_BONDING = 0x02,
  DEDICATED_BONDING_MITM_PROTECTION = 0x03,
  GENERAL_BONDING = 0x04,
  GENERAL_BONDING_MITM_PROTECTION = 0x05,
}

packet IoCapabilityRequestReply : Command (op_code = IO_CAPABILITY_REQUEST_REPLY) {
  bd_addr : Address,
  io_capability : IoCapability,
  oob_present : OobDataPresent,
  authentication_requirements : AuthenticationRequirements,
}

packet IoCapabilityRequestReplyComplete : CommandComplete (command_op_code = IO_CAPABILITY_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet UserConfirmationRequestReply : Command (op_code = USER_CONFIRMATION_REQUEST_REPLY) {
  bd_addr : Address,
}

packet UserConfirmationRequestReplyComplete : CommandComplete (command_op_code = USER_CONFIRMATION_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet UserConfirmationRequestNegativeReply : Command (op_code = USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY) {
  bd_addr : Address,
}

packet UserConfirmationRequestNegativeReplyComplete : CommandComplete (command_op_code = USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet UserPasskeyRequestReply : Command (op_code = USER_PASSKEY_REQUEST_REPLY) {
  bd_addr : Address,
  numeric_value : 32, // 000000-999999 decimal or 0x0-0xF423F
}

packet UserPasskeyRequestReplyComplete : CommandComplete (command_op_code = USER_PASSKEY_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet UserPasskeyRequestNegativeReply : Command (op_code = USER_PASSKEY_REQUEST_NEGATIVE_REPLY) {
  bd_addr : Address,
}

packet UserPasskeyRequestNegativeReplyComplete : CommandComplete (command_op_code = USER_PASSKEY_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet RemoteOobDataRequestReply : Command (op_code = REMOTE_OOB_DATA_REQUEST_REPLY) {
  bd_addr : Address,
  c : 8[16],
  r : 8[16],
}

packet RemoteOobDataRequestReplyComplete : CommandComplete (command_op_code = REMOTE_OOB_DATA_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet RemoteOobDataRequestNegativeReply : Command (op_code = REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY) {
  bd_addr : Address,
}

packet RemoteOobDataRequestNegativeReplyComplete : CommandComplete (command_op_code = REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

packet IoCapabilityRequestNegativeReply : Command (op_code = IO_CAPABILITY_REQUEST_NEGATIVE_REPLY) {
  bd_addr : Address,
  reason : ErrorCode,
}

packet IoCapabilityRequestNegativeReplyComplete : CommandComplete (command_op_code = IO_CAPABILITY_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}

enum ScoCodingFormatValues : 8 {
  ULAW_LONG = 0x00,
  ALAW_LONG = 0x01,
  CVSD = 0x02,
  TRANSPARENT = 0x03,
  LINEAR_PCM = 0x04,
  MSBC = 0x05,
  LC3 = 0x06,
  VENDOR_SPECIFIC = 0xFF,
}

struct ScoCodingFormat {
  coding_format : ScoCodingFormatValues,
  company_id : 16,
  vendor_specific_codec_id : 16,
}

enum ScoPcmDataFormat : 8 {
  NOT_USED = 0x00,
  ONES_COMPLEMENT = 0x01,
  TWOS_COMPLEMENT = 0x02,
  SIGN_MAGNITUDE = 0x03,
  UNSIGNED = 0x04,
}

enum ScoDataPath : 8 {
  HCI = 0x00,
  // 0x01 to 0xFE are Logical_Channel_Number.
  // The meaning of the logical channels will be vendor specific.
  // In GD and legacy Android Bluetooth stack, we use channel 0x01 for hardware
  // offloaded SCO encoding
  GD_PCM = 0x01,
  AUDIO_TEST_MODE = 0xFF,
}

packet EnhancedSetupSynchronousConnection : Command (op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) {
  connection_handle: 12,
  _reserved_ : 4,
  // Next two items
  // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second.
  // [0xFFFFFFFF]: Don't care
  transmit_bandwidth : 32,
  receive_bandwidth : 32,
  transmit_coding_format : ScoCodingFormat,
  receive_coding_format : ScoCodingFormat,
  // Next two items
  // [0x0001, 0xFFFF]: the actual size of the over-the-air encoded frame in
  //                   octets.
  transmit_codec_frame_size : 16,
  receive_codec_frame_size : 16,
  // Next two items
  // Host to Controller nominal data rate in octets per second.
  input_bandwidth : 32,
  output_bandwidth : 32,
  input_coding_format : ScoCodingFormat,
  output_coding_format : ScoCodingFormat,
  // Next two items
  // Size, in bits, of the sample or framed data
  input_coded_data_bits : 16,
  output_coded_data_bits : 16,
  input_pcm_data_format : ScoPcmDataFormat,
  output_pcm_data_format : ScoPcmDataFormat,
  // Next two items
  // The number of bit positions within an audio sample that the MSB of the
  // sample is away from starting at the MSB of the data.
  input_pcm_sample_payload_msb_position : 8,
  output_pcm_sample_payload_msb_position : 8,
  input_data_path : ScoDataPath,
  output_data_path : ScoDataPath,
  // Next two items
  // [1, 255] The number of bits in each unit of data received from the Host
  //          over the audio data transport.
  // [0] Not applicable (implied by the choice of audio data transport)
  input_transport_unit_bits : 8,
  output_transport_unit_bits : 8,
  // [0x0004, 0xFFFE]: in milliseconds
  //     Upper limit represent the sum of the synchronous interval and the size
  //     of the eSCO window, where the eSCO window is reserved slots plus the
  //     retransmission window
  // [0xFFFF]: don't care
  max_latency: 16,
  packet_type : 16, // See SynchronousPacketTypeBits
  retransmission_effort : RetransmissionEffort,
}

test EnhancedSetupSynchronousConnection {
  "\x3d\x04\x3b\x02\x00\x40\x1f\x00\x00\x40\x1f\x00\x00\x05\x00\x00\x00\x00\x05\x00\x00\x00\x00\x3c\x00\x3c\x00\x00\x7d\x00\x00\x00\x7d\x00\x00\x04\x00\x00\x00\x00\x04\x00\x00\x00\x00\x10\x00\x10\x00\x02\x02\x00\x00\x01\x01\x00\x00\x0d\x00\x88\x03\x02",
}

packet EnhancedSetupSynchronousConnectionStatus : CommandStatus (command_op_code = ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) {
}

packet EnhancedAcceptSynchronousConnection : Command (op_code = ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION) {
  bd_addr : Address,
  // Next two items
  // [0x00000000, 0xFFFFFFFE] Bandwidth in octets per second.
  // [0xFFFFFFFF]: Don't care
  transmit_bandwidth : 32,
  receive_bandwidth : 32,
  transmit_coding_format : ScoCodingFormat,
  receive_coding_format : ScoCodingFormat,
  // Next two items
  // [0x0001, 0xFFFF]: the actual size of the over-the-air encoded frame in
  //                   octets.
  transmit_codec_frame_size : 16,
  receive_codec_frame_size : 16,
  // Next two items
  // Host to Controller nominal data rate in octets per second.
  input_bandwidth : 32,
  output_bandwidth : 32,
  input_coding_format : ScoCodingFormat,
  output_coding_format : ScoCodingFormat,
  // Next two items
  // Size, in bits, of the sample or framed data
  input_coded_data_bits : 16,
  output_coded_data_bits : 16,
  input_pcm_data_format : ScoPcmDataFormat,
  output_pcm_data_format : ScoPcmDataFormat,
  // Next two items
  // The number of bit positions within an audio sample that the MSB of the
  // sample is away from starting at the MSB of the data.
  input_pcm_sample_payload_msb_position : 8,
  output_pcm_sample_payload_msb_position : 8,
  input_data_path : ScoDataPath,
  output_data_path : ScoDataPath,
  // Next two items
  // [1, 255] The number of bits in each unit of data received from the Host
  //          over the audio data transport.
  // [0] Not applicable (implied by the choice of audio data transport)
  input_transport_unit_bits : 8,
  output_transport_unit_bits : 8,
  // [0x0004, 0xFFFE]: in milliseconds
  //     Upper limit represent the sum of the synchronous interval and the size
  //     of the eSCO window, where the eSCO window is reserved slots plus the
  //     retransmission window
  // [0xFFFF]: don't care
  max_latency : 16,
  packet_type : 16, // See SynchronousPacketTypeBits
  retransmission_effort : RetransmissionEffort,
}

packet EnhancedAcceptSynchronousConnectionStatus : CommandStatus (command_op_code = ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION) {
}

packet RemoteOobExtendedDataRequestReply : Command (op_code = REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY) {
  bd_addr : Address,
  c_192 : 8[16],
  r_192 : 8[16],
  c_256 : 8[16],
  r_256 : 8[16],
}

packet RemoteOobExtendedDataRequestReplyComplete : CommandComplete (command_op_code = REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY) {
  status : ErrorCode,
  bd_addr : Address,
}


  // LINK_POLICY
packet HoldMode : Command (op_code = HOLD_MODE) {
  connection_handle : 12,
  _reserved_ : 4,
  hold_mode_max_interval: 16, // 0x0002-0xFFFE (1.25ms-40.9s)
  hold_mode_min_interval: 16, // 0x0002-0xFFFE (1.25ms-40.9s)
}

packet HoldModeStatus : CommandStatus (command_op_code = HOLD_MODE) {
}


packet SniffMode : Command (op_code = SNIFF_MODE) {
  connection_handle : 12,
  _reserved_ : 4,
  sniff_max_interval: 16, // 0x0002-0xFFFE (1.25ms-40.9s)
  sniff_min_interval: 16, // 0x0002-0xFFFE (1.25ms-40.9s)
  sniff_attempt: 16, // 0x0001-0x7FFF (1.25ms-40.9s)
  sniff_timeout: 16, // 0x0000-0x7FFF (0ms-40.9s)
}

packet SniffModeStatus : CommandStatus (command_op_code = SNIFF_MODE) {
}


packet ExitSniffMode : Command (op_code = EXIT_SNIFF_MODE) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ExitSniffModeStatus : CommandStatus (command_op_code = EXIT_SNIFF_MODE) {
}

enum ServiceType : 8 {
  NO_TRAFFIC = 0x00,
  BEST_EFFORT = 0x01,
  GUARANTEED = 0x02,
}

packet QosSetup : Command (op_code = QOS_SETUP) {
  connection_handle : 12,
  _reserved_ : 4,
  _reserved_ : 8,
  service_type : ServiceType,
  token_rate : 32, // Octets/s
  peak_bandwidth : 32, // Octets/s
  latency : 32, // Octets/s
  delay_variation : 32, // microseconds
}

packet QosSetupStatus : CommandStatus (command_op_code = QOS_SETUP) {
}

packet RoleDiscovery : Command (op_code = ROLE_DISCOVERY) {
  connection_handle : 12,
  _reserved_ : 4,
}

enum Role : 8 {
  CENTRAL = 0x00,
  PERIPHERAL = 0x01,
}

packet RoleDiscoveryComplete : CommandComplete (command_op_code = ROLE_DISCOVERY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  current_role : Role,
}

packet SwitchRole : Command (op_code = SWITCH_ROLE) {
  bd_addr : Address,
  role : Role,
}

packet SwitchRoleStatus : CommandStatus (command_op_code = SWITCH_ROLE) {
}


packet ReadLinkPolicySettings : Command (op_code = READ_LINK_POLICY_SETTINGS) {
  connection_handle : 12,
  _reserved_ : 4,
}

enum LinkPolicy : 16 {
  ENABLE_ROLE_SWITCH = 0x01,
  ENABLE_HOLD_MODE = 0x02,
  ENABLE_SNIFF_MODE = 0x04,
  ENABLE_PARK_MODE = 0x08, // deprecated after 5.0
}

packet ReadLinkPolicySettingsComplete : CommandComplete (command_op_code = READ_LINK_POLICY_SETTINGS) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  link_policy_settings : 16,
}

packet WriteLinkPolicySettings : Command (op_code = WRITE_LINK_POLICY_SETTINGS) {
  connection_handle : 12,
  _reserved_ : 4,
  link_policy_settings : 16,
}

packet WriteLinkPolicySettingsComplete : CommandComplete (command_op_code = WRITE_LINK_POLICY_SETTINGS) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadDefaultLinkPolicySettings : Command (op_code = READ_DEFAULT_LINK_POLICY_SETTINGS) {
}

packet ReadDefaultLinkPolicySettingsComplete : CommandComplete (command_op_code = READ_DEFAULT_LINK_POLICY_SETTINGS) {
  status : ErrorCode,
  default_link_policy_settings : 16,
}

packet WriteDefaultLinkPolicySettings : Command (op_code = WRITE_DEFAULT_LINK_POLICY_SETTINGS) {
  default_link_policy_settings : 16,
}

packet WriteDefaultLinkPolicySettingsComplete : CommandComplete (command_op_code = WRITE_DEFAULT_LINK_POLICY_SETTINGS) {
  status : ErrorCode,
}

enum FlowDirection : 8 {
  OUTGOING_FLOW = 0x00,
  INCOMING_FLOW = 0x01,
}

packet FlowSpecification : Command (op_code = FLOW_SPECIFICATION) {
  connection_handle : 12,
  _reserved_ : 4,
  _reserved_ : 8,
  flow_direction : FlowDirection,
  service_type : ServiceType,
  token_rate : 32, // Octets/s
  token_bucket_size : 32,
  peak_bandwidth : 32, // Octets/s
  access_latency : 32, // Octets/s
}

packet FlowSpecificationStatus : CommandStatus (command_op_code = FLOW_SPECIFICATION) {
}

packet SniffSubrating : Command (op_code = SNIFF_SUBRATING) {
  connection_handle : 12,
  _reserved_ : 4,
  maximum_latency : 16,  // 0x0002-0xFFFE (1.25ms-40.9s)
  minimum_remote_timeout : 16, // 0x0000-0xFFFE (0-40.9s)
  minimum_local_timeout: 16, // 0x0000-0xFFFE (0-40.9s)
}

packet SniffSubratingComplete : CommandComplete (command_op_code = SNIFF_SUBRATING) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

  // CONTROLLER_AND_BASEBAND
packet SetEventMask : Command (op_code = SET_EVENT_MASK) {
  event_mask : 64,
}

packet SetEventMaskComplete : CommandComplete (command_op_code = SET_EVENT_MASK) {
  status : ErrorCode,
}

packet Reset : Command (op_code = RESET) {
}

test Reset {
  "\x03\x0c\x00",
}

packet ResetComplete : CommandComplete (command_op_code = RESET) {
  status : ErrorCode,
}

test ResetComplete {
  "\x0e\x04\x01\x03\x0c\x00",
  "\x0e\x04\x01\x03\x0c\x01", // unknown command
}

enum FilterType : 8 {
  CLEAR_ALL_FILTERS = 0x00,
  INQUIRY_RESULT = 0x01,
  CONNECTION_SETUP = 0x02,
}

packet SetEventFilter : Command (op_code = SET_EVENT_FILTER) {
  filter_type : FilterType,
  _body_,
}

packet SetEventFilterComplete : CommandComplete (command_op_code = SET_EVENT_FILTER) {
  status : ErrorCode,
}

packet SetEventFilterClearAll : SetEventFilter (filter_type = CLEAR_ALL_FILTERS) {
}

enum FilterConditionType : 8 {
  ALL_DEVICES = 0x00,
  CLASS_OF_DEVICE = 0x01,
  ADDRESS = 0x02,
}

packet SetEventFilterInquiryResult : SetEventFilter (filter_type = INQUIRY_RESULT) {
  filter_condition_type : FilterConditionType,
  _body_,
}

packet SetEventFilterInquiryResultAllDevices : SetEventFilterInquiryResult (filter_condition_type = ALL_DEVICES) {
}

packet SetEventFilterInquiryResultClassOfDevice : SetEventFilterInquiryResult (filter_condition_type = CLASS_OF_DEVICE) {
  class_of_device : 24,
  class_of_device_mask : 24,
}

packet SetEventFilterInquiryResultAddress : SetEventFilterInquiryResult (filter_condition_type = ADDRESS) {
  address : Address,
}

packet SetEventFilterConnectionSetup : SetEventFilter (filter_type = CONNECTION_SETUP) {
  filter_condition_type : FilterConditionType,
  _body_,
}

enum AutoAcceptFlag : 8 {
  AUTO_ACCEPT_OFF = 0x01,
  AUTO_ACCEPT_ON_ROLE_SWITCH_DISABLED = 0x02,
  AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED = 0x03,
}

packet SetEventFilterConnectionSetupAllDevices : SetEventFilterConnectionSetup (filter_condition_type = ALL_DEVICES) {
  auto_accept_flag : AutoAcceptFlag,
}

packet SetEventFilterConnectionSetupClassOfDevice : SetEventFilterConnectionSetup (filter_condition_type = CLASS_OF_DEVICE) {
  class_of_device : 24,
  class_of_device_mask : 24,
  auto_accept_flag : AutoAcceptFlag,
}

packet SetEventFilterConnectionSetupAddress : SetEventFilterConnectionSetup (filter_condition_type = ADDRESS) {
  address : Address,
  auto_accept_flag : AutoAcceptFlag,
}

packet Flush : Command (op_code = FLUSH) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet FlushComplete : CommandComplete (command_op_code = FLUSH) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

enum PinType : 8 {
  VARIABLE = 0,
  FIXED = 1,
}

packet ReadPinType : Command (op_code = READ_PIN_TYPE) {
}

packet ReadPinTypeComplete : CommandComplete (command_op_code = READ_PIN_TYPE) {
  status : ErrorCode,
  pin_type : PinType,
}

packet WritePinType : Command (op_code = WRITE_PIN_TYPE) {
  pin_type : PinType,
}

packet WritePinTypeComplete : CommandComplete (command_op_code = WRITE_PIN_TYPE) {
  status : ErrorCode,
}

enum ReadStoredLinkKeyReadAllFlag : 8 {
  SPECIFIED_BD_ADDR = 0x00,
  ALL = 0x01,
}

packet ReadStoredLinkKey : Command (op_code = READ_STORED_LINK_KEY) {
  bd_addr : Address,
  read_all_flag : ReadStoredLinkKeyReadAllFlag,
}

packet ReadStoredLinkKeyComplete : CommandComplete (command_op_code = READ_STORED_LINK_KEY) {
  status : ErrorCode,
  max_num_keys : 16,
  num_keys_read : 16,
}

struct KeyAndAddress {
  address : Address,
  link_key : 8[16],
}

packet WriteStoredLinkKey : Command (op_code = WRITE_STORED_LINK_KEY) {
  _count_(keys_to_write) : 8, // 0x01-0x0B
  keys_to_write : KeyAndAddress[],
}

packet WriteStoredLinkKeyComplete : CommandComplete (command_op_code = WRITE_STORED_LINK_KEY) {
  status : ErrorCode,
  num_keys_written : 8,
}

enum DeleteStoredLinkKeyDeleteAllFlag : 8 {
  SPECIFIED_BD_ADDR = 0x00,
  ALL = 0x01,
}

packet DeleteStoredLinkKey : Command (op_code = DELETE_STORED_LINK_KEY) {
  bd_addr : Address,
  delete_all_flag : DeleteStoredLinkKeyDeleteAllFlag,
}

packet DeleteStoredLinkKeyComplete : CommandComplete (command_op_code = DELETE_STORED_LINK_KEY) {
  status : ErrorCode,
  num_keys_deleted : 16,
}

packet WriteLocalName : Command (op_code = WRITE_LOCAL_NAME) {
  local_name : 8[248], // Null-terminated UTF-8 encoded name
}

packet WriteLocalNameComplete : CommandComplete (command_op_code = WRITE_LOCAL_NAME) {
  status : ErrorCode,
}

packet ReadLocalName : Command (op_code = READ_LOCAL_NAME) {
}

packet ReadLocalNameComplete : CommandComplete (command_op_code = READ_LOCAL_NAME) {
  status : ErrorCode,
  local_name : 8[248], // Null-terminated UTF-8 encoded name
}

packet ReadConnectionAcceptTimeout : Command (op_code = READ_CONNECTION_ACCEPT_TIMEOUT) {
}

packet ReadConnectionAcceptTimeoutComplete : CommandComplete (command_op_code = READ_CONNECTION_ACCEPT_TIMEOUT) {
  status : ErrorCode,
  conn_accept_timeout : 16, // 0x0001 to 0xB540 (N * 0.625 ms) 0.625 ms to 29 s
}

packet WriteConnectionAcceptTimeout : Command (op_code = WRITE_CONNECTION_ACCEPT_TIMEOUT) {
  conn_accept_timeout : 16, // 0x0001 to 0xB540 (N * 0.625 ms) 0.625 ms to 29 s, Default 0x1FA0, 5.06s
}

packet WriteConnectionAcceptTimeoutComplete : CommandComplete (command_op_code = WRITE_CONNECTION_ACCEPT_TIMEOUT) {
  status : ErrorCode,
}

packet ReadPageTimeout : Command (op_code = READ_PAGE_TIMEOUT) {
}

test ReadPageTimeout {
  "\x17\x0c\x00",
}

packet ReadPageTimeoutComplete : CommandComplete (command_op_code = READ_PAGE_TIMEOUT) {
  status : ErrorCode,
  page_timeout : 16,
}

test ReadPageTimeoutComplete {
  "\x0e\x06\x01\x17\x0c\x00\x11\x22",
}

packet WritePageTimeout : Command (op_code = WRITE_PAGE_TIMEOUT) {
  page_timeout : 16,
}

test WritePageTimeout {
  "\x18\x0c\x02\x00\x20",
}

packet WritePageTimeoutComplete : CommandComplete (command_op_code = WRITE_PAGE_TIMEOUT) {
  status : ErrorCode,
}

test WritePageTimeoutComplete {
  "\x0e\x04\x01\x18\x0c\x00",
}

enum ScanEnable : 8 {
  NO_SCANS = 0x00,
  INQUIRY_SCAN_ONLY = 0x01,
  PAGE_SCAN_ONLY = 0x02,
  INQUIRY_AND_PAGE_SCAN = 0x03,
}

packet ReadScanEnable : Command (op_code = READ_SCAN_ENABLE) {
}

packet ReadScanEnableComplete : CommandComplete (command_op_code = READ_SCAN_ENABLE) {
  status : ErrorCode,
  scan_enable : ScanEnable,
}

packet WriteScanEnable : Command (op_code = WRITE_SCAN_ENABLE) {
  scan_enable : ScanEnable,
}

packet WriteScanEnableComplete : CommandComplete (command_op_code = WRITE_SCAN_ENABLE) {
  status : ErrorCode,
}

packet ReadPageScanActivity : Command (op_code = READ_PAGE_SCAN_ACTIVITY) {
}

packet ReadPageScanActivityComplete : CommandComplete (command_op_code = READ_PAGE_SCAN_ACTIVITY) {
  status : ErrorCode,
  page_scan_interval : 16, // Range: 0x0012 to 0x1000; only even values are valid * 0x625 ms
  page_scan_window : 16, // 0x0011 to PageScanInterval
}

packet WritePageScanActivity : Command (op_code = WRITE_PAGE_SCAN_ACTIVITY) {
  page_scan_interval : 16, // Range: 0x0012 to 0x1000; only even values are valid * 0x625 ms
  page_scan_window : 16, // 0x0011 to PageScanInterval
}

packet WritePageScanActivityComplete : CommandComplete (command_op_code = WRITE_PAGE_SCAN_ACTIVITY) {
  status : ErrorCode,
}

packet ReadInquiryScanActivity : Command (op_code = READ_INQUIRY_SCAN_ACTIVITY) {
}

test ReadInquiryScanActivity {
  "\x1d\x0c\x00",
}

packet ReadInquiryScanActivityComplete : CommandComplete (command_op_code = READ_INQUIRY_SCAN_ACTIVITY) {
  status : ErrorCode,
  inquiry_scan_interval : 16, // Range: 0x0012 to 0x1000; only even values are valid * 0x625 ms
  inquiry_scan_window : 16, // Range: 0x0011 to 0x1000
}

test ReadInquiryScanActivityComplete {
  "\x0e\x08\x01\x1d\x0c\x00\xaa\xbb\xcc\xdd",
}

packet WriteInquiryScanActivity : Command (op_code = WRITE_INQUIRY_SCAN_ACTIVITY) {
  inquiry_scan_interval : 16, // Range: 0x0012 to 0x1000; only even values are valid * 0x625 ms
  inquiry_scan_window : 16, // Range: 0x0011 to 0x1000
}

test WriteInquiryScanActivity {
  "\x1e\x0c\x04\x00\x08\x12\x00",
}

packet WriteInquiryScanActivityComplete : CommandComplete (command_op_code = WRITE_INQUIRY_SCAN_ACTIVITY) {
  status : ErrorCode,
}

test WriteInquiryScanActivityComplete {
  "\x0e\x04\x01\x1e\x0c\x00",
}

enum AuthenticationEnable : 8 {
  NOT_REQUIRED = 0x00,
  REQUIRED = 0x01,
}

packet ReadAuthenticationEnable : Command (op_code = READ_AUTHENTICATION_ENABLE) {
}

packet ReadAuthenticationEnableComplete : CommandComplete (command_op_code = READ_AUTHENTICATION_ENABLE) {
  status : ErrorCode,
  authentication_enable : AuthenticationEnable,
}

packet WriteAuthenticationEnable : Command (op_code = WRITE_AUTHENTICATION_ENABLE) {
  authentication_enable : AuthenticationEnable,
}

packet WriteAuthenticationEnableComplete : CommandComplete (command_op_code = WRITE_AUTHENTICATION_ENABLE) {
  status : ErrorCode,
}

packet ReadClassOfDevice : Command (op_code = READ_CLASS_OF_DEVICE) {
}

packet ReadClassOfDeviceComplete : CommandComplete (command_op_code = READ_CLASS_OF_DEVICE) {
  status : ErrorCode,
  class_of_device : 24,
}

packet WriteClassOfDevice : Command (op_code = WRITE_CLASS_OF_DEVICE) {
  class_of_device : 24,
}

packet WriteClassOfDeviceComplete : CommandComplete (command_op_code = WRITE_CLASS_OF_DEVICE) {
  status : ErrorCode,
}

packet ReadVoiceSetting : Command (op_code = READ_VOICE_SETTING) {
}

packet ReadVoiceSettingComplete : CommandComplete (command_op_code = READ_VOICE_SETTING) {
  status : ErrorCode,
  voice_setting : 10,
  _reserved_ : 6,
}

packet WriteVoiceSetting : Command (op_code = WRITE_VOICE_SETTING) {
  voice_setting : 10,
  _reserved_ : 6,
}

packet WriteVoiceSettingComplete : CommandComplete (command_op_code = WRITE_VOICE_SETTING) {
  status : ErrorCode,
}

packet ReadAutomaticFlushTimeout : Command (op_code = READ_AUTOMATIC_FLUSH_TIMEOUT) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadAutomaticFlushTimeoutComplete : CommandComplete (command_op_code = READ_AUTOMATIC_FLUSH_TIMEOUT) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  flush_timeout : 16,
}

packet WriteAutomaticFlushTimeout : Command (op_code = WRITE_AUTOMATIC_FLUSH_TIMEOUT) {
  connection_handle : 12,
  _reserved_ : 4,
  flush_timeout : 16, // 0x0000-0x07FF Default 0x0000 (No Automatic Flush)
}

packet WriteAutomaticFlushTimeoutComplete : CommandComplete (command_op_code = WRITE_AUTOMATIC_FLUSH_TIMEOUT) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadNumBroadcastRetransmits : Command (op_code = READ_NUM_BROADCAST_RETRANSMITS) {
}

packet ReadNumBroadcastRetransmitsComplete : CommandComplete (command_op_code = READ_NUM_BROADCAST_RETRANSMITS) {
  status : ErrorCode,
  num_broadcast_retransmissions : 8,
}

packet WriteNumBroadcastRetransmits : Command (op_code = WRITE_NUM_BROADCAST_RETRANSMITS) {
  num_broadcast_retransmissions : 8,
}

packet WriteNumBroadcastRetransmitsComplete : CommandComplete (command_op_code = WRITE_NUM_BROADCAST_RETRANSMITS) {
  status : ErrorCode,
}

enum HoldModeActivity : 8 {
  MAINTAIN_CURRENT_POWER_STATE = 0x00,
  SUSPEND_PAGE_SCAN = 0x01,
  SUSPEND_INQUIRY_SCAN = 0x02,
  SUSPEND_PERIODIC_INQUIRY = 0x03,
}

packet ReadHoldModeActivity : Command (op_code = READ_HOLD_MODE_ACTIVITY) {
}

packet ReadHoldModeActivityComplete : CommandComplete (command_op_code = READ_HOLD_MODE_ACTIVITY) {
  status : ErrorCode,
  hold_mode_activity : HoldModeActivity,
}

packet WriteHoldModeActivity : Command (op_code = WRITE_HOLD_MODE_ACTIVITY) {
  hold_mode_activity : HoldModeActivity,
}

packet WriteHoldModeActivityComplete : CommandComplete (command_op_code = WRITE_HOLD_MODE_ACTIVITY) {
  status : ErrorCode,
}

enum TransmitPowerLevelType : 8 {
  CURRENT = 0x00,
  MAXIMUM = 0x01,
}

packet ReadTransmitPowerLevel : Command (op_code = READ_TRANSMIT_POWER_LEVEL) {
  connection_handle : 12,
  _reserved_ : 4,
  transmit_power_level_type : TransmitPowerLevelType,
}

packet ReadTransmitPowerLevelComplete : CommandComplete (command_op_code = READ_TRANSMIT_POWER_LEVEL) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  transmit_power_level : 8,
}

packet ReadSynchronousFlowControlEnable : Command (op_code = READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE) {
}

packet ReadSynchronousFlowControlEnableComplete : CommandComplete (command_op_code = READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE) {
  status : ErrorCode,
  enable : Enable,
}

packet WriteSynchronousFlowControlEnable : Command (op_code = WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE) {
  enable : Enable,
}

packet WriteSynchronousFlowControlEnableComplete : CommandComplete (command_op_code = WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE) {
  status : ErrorCode,
}

packet SetControllerToHostFlowControl : Command (op_code = SET_CONTROLLER_TO_HOST_FLOW_CONTROL) {
  acl : 1,
  synchronous : 1,
  _reserved_ : 6,
}

packet SetControllerToHostFlowControlComplete : CommandComplete (command_op_code = SET_CONTROLLER_TO_HOST_FLOW_CONTROL) {
  status : ErrorCode,
}

packet HostBufferSize : Command (op_code = HOST_BUFFER_SIZE) {
  host_acl_data_packet_length : 16,
  host_synchronous_data_packet_length : 8,
  host_total_num_acl_data_packets : 16,
  host_total_num_synchronous_data_packets : 16,
}

test HostBufferSize {
  "\x33\x0c\x07\x9b\x06\xff\x14\x00\x0a\x00",
}

packet HostBufferSizeComplete : CommandComplete (command_op_code = HOST_BUFFER_SIZE) {
  status : ErrorCode,
}

test HostBufferSizeComplete {
  "\x0e\x04\x01\x33\x0c\x00",
}

struct CompletedPackets {
  connection_handle : 12,
  _reserved_ : 4,
  host_num_of_completed_packets : 16,
}

packet HostNumCompletedPackets : Command (op_code = HOST_NUMBER_OF_COMPLETED_PACKETS) {
  _count_(completed_packets) : 8,
  completed_packets : CompletedPackets[],
}

packet HostNumCompletedPacketsError : CommandComplete (command_op_code = HOST_NUMBER_OF_COMPLETED_PACKETS) {
  error_code : ErrorCode,
}

packet ReadLinkSupervisionTimeout : Command (op_code = READ_LINK_SUPERVISION_TIMEOUT) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadLinkSupervisionTimeoutComplete : CommandComplete (command_op_code = READ_LINK_SUPERVISION_TIMEOUT) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  link_supervision_timeout : 16, // 0x001-0xFFFF (0.625ms-40.9s)
}

packet WriteLinkSupervisionTimeout : Command (op_code = WRITE_LINK_SUPERVISION_TIMEOUT) {
  connection_handle : 12,
  _reserved_ : 4,
  link_supervision_timeout : 16, // 0x001-0xFFFF (0.625ms-40.9s)
}

packet WriteLinkSupervisionTimeoutComplete : CommandComplete (command_op_code = WRITE_LINK_SUPERVISION_TIMEOUT) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadNumberOfSupportedIac : Command (op_code = READ_NUMBER_OF_SUPPORTED_IAC) {
}

test ReadNumberOfSupportedIac {
  "\x38\x0c\x00",
}

packet ReadNumberOfSupportedIacComplete : CommandComplete (command_op_code = READ_NUMBER_OF_SUPPORTED_IAC) {
  status : ErrorCode,
  num_support_iac : 8,
}

test ReadNumberOfSupportedIacComplete {
  "\x0e\x05\x01\x38\x0c\x00\x99",
}

packet ReadCurrentIacLap : Command (op_code = READ_CURRENT_IAC_LAP) {
}

test ReadCurrentIacLap {
  "\x39\x0c\x00",
}

packet ReadCurrentIacLapComplete : CommandComplete (command_op_code = READ_CURRENT_IAC_LAP) {
  status : ErrorCode,
  _count_(laps_to_read) : 8,
  laps_to_read : Lap[],
}

test ReadCurrentIacLapComplete {
  "\x0e\x0b\x01\x39\x0c\x00\x02\x11\x8b\x9e\x22\x8b\x9e",
}

packet WriteCurrentIacLap : Command (op_code = WRITE_CURRENT_IAC_LAP) {
  _count_(laps_to_write) : 8,
  laps_to_write : Lap[],
}

test WriteCurrentIacLap {
  "\x3a\x0c\x07\x02\x11\x8b\x9e\x22\x8b\x9e",
}

packet WriteCurrentIacLapComplete : CommandComplete (command_op_code = WRITE_CURRENT_IAC_LAP) {
  status : ErrorCode,
}

test WriteCurrentIacLapComplete {
  "\x0e\x04\x01\x3a\x0c\x00",
}

packet SetAfhHostChannelClassification : Command (op_code = SET_AFH_HOST_CHANNEL_CLASSIFICATION) {
  afh_host_channel_classification : 8[10],
}

packet SetAfhHostChannelClassificationComplete : CommandComplete (command_op_code = SET_AFH_HOST_CHANNEL_CLASSIFICATION) {
  status : ErrorCode,
}

enum InquiryScanType : 8 {
  STANDARD = 0x00,
  INTERLACED = 0x01,
}

packet ReadInquiryScanType : Command (op_code = READ_INQUIRY_SCAN_TYPE) {
}

packet ReadInquiryScanTypeComplete : CommandComplete (command_op_code = READ_INQUIRY_SCAN_TYPE) {
  status : ErrorCode,
  inquiry_scan_type : InquiryScanType,
}

packet WriteInquiryScanType : Command (op_code = WRITE_INQUIRY_SCAN_TYPE) {
  inquiry_scan_type : InquiryScanType,
}

packet WriteInquiryScanTypeComplete : CommandComplete (command_op_code = WRITE_INQUIRY_SCAN_TYPE) {
  status : ErrorCode,
}

enum InquiryMode : 8 {
  STANDARD = 0x00,
  RSSI = 0x01,
  RSSI_OR_EXTENDED = 0x02,
}

packet ReadInquiryMode : Command (op_code = READ_INQUIRY_MODE) {
}

packet ReadInquiryModeComplete : CommandComplete (command_op_code = READ_INQUIRY_MODE) {
  status : ErrorCode,
  inquiry_mode : InquiryMode,
}

packet WriteInquiryMode : Command (op_code = WRITE_INQUIRY_MODE) {
  inquiry_mode : InquiryMode,
}

packet WriteInquiryModeComplete : CommandComplete (command_op_code = WRITE_INQUIRY_MODE) {
  status : ErrorCode,
}

enum PageScanType : 8 {
  STANDARD = 0x00,
  INTERLACED = 0x01,
}

packet ReadPageScanType : Command (op_code = READ_PAGE_SCAN_TYPE) {
}

packet ReadPageScanTypeComplete : CommandComplete (command_op_code = READ_PAGE_SCAN_TYPE) {
  status : ErrorCode,
  page_scan_type : PageScanType,
}

packet WritePageScanType : Command (op_code = WRITE_PAGE_SCAN_TYPE) {
  page_scan_type : PageScanType,
}

packet WritePageScanTypeComplete : CommandComplete (command_op_code = WRITE_PAGE_SCAN_TYPE) {
  status : ErrorCode,
}

packet ReadAfhChannelAssessmentMode : Command (op_code = READ_AFH_CHANNEL_ASSESSMENT_MODE) {
}

packet ReadAfhChannelAssessmentModeComplete : CommandComplete (command_op_code = READ_AFH_CHANNEL_ASSESSMENT_MODE) {
  status : ErrorCode,
  controller_channel_assessment : Enable,
}

packet WriteAfhChannelAssessmentMode : Command (op_code = WRITE_AFH_CHANNEL_ASSESSMENT_MODE) {
  controller_channel_assessment : Enable,
}

packet WriteAfhChannelAssessmentModeComplete : CommandComplete (command_op_code = WRITE_AFH_CHANNEL_ASSESSMENT_MODE) {
  status : ErrorCode,
}

enum FecRequired : 8 {
  NOT_REQUIRED = 0x00,
  REQUIRED = 0x01,
}

packet ReadExtendedInquiryResponse : Command (op_code = READ_EXTENDED_INQUIRY_RESPONSE) {
}

packet ReadExtendedInquiryResponseComplete : CommandComplete (command_op_code = READ_EXTENDED_INQUIRY_RESPONSE) {
  status : ErrorCode,
  fec_required : FecRequired,
  extended_inquiry_response : 8[240],
}

packet WriteExtendedInquiryResponse : Command (op_code = WRITE_EXTENDED_INQUIRY_RESPONSE) {
  fec_required : FecRequired,
  extended_inquiry_response : 8[240],
}

packet WriteExtendedInquiryResponseComplete : CommandComplete (command_op_code = WRITE_EXTENDED_INQUIRY_RESPONSE) {
  status : ErrorCode,
}

packet RefreshEncryptionKey : Command (op_code = REFRESH_ENCRYPTION_KEY) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet RefreshEncryptionKeyStatus : CommandStatus (command_op_code = REFRESH_ENCRYPTION_KEY) {
}

packet ReadSimplePairingMode : Command (op_code = READ_SIMPLE_PAIRING_MODE) {
}

packet ReadSimplePairingModeComplete : CommandComplete (command_op_code = READ_SIMPLE_PAIRING_MODE) {
  status : ErrorCode,
  simple_pairing_mode : Enable,
}

packet WriteSimplePairingMode : Command (op_code = WRITE_SIMPLE_PAIRING_MODE) {
  simple_pairing_mode : Enable,
}

test WriteSimplePairingMode {
  "\x56\x0c\x01\x01",
}

packet WriteSimplePairingModeComplete : CommandComplete (command_op_code = WRITE_SIMPLE_PAIRING_MODE) {
  status : ErrorCode,
}

test WriteSimplePairingModeComplete {
  "\x0e\x04\x01\x56\x0c\x00",
}

packet ReadLocalOobData : Command (op_code = READ_LOCAL_OOB_DATA) {
}

packet ReadLocalOobDataComplete : CommandComplete (command_op_code = READ_LOCAL_OOB_DATA) {
  status : ErrorCode,
  c : 8[16],
  r : 8[16],
}

packet ReadInquiryResponseTransmitPowerLevel : Command (op_code = READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL) {
}

packet ReadInquiryResponseTransmitPowerLevelComplete : CommandComplete (command_op_code = READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL) {
  status : ErrorCode,
  tx_power : 8, // (-70dBm to 20dBm)
}

packet WriteInquiryTransmitPowerLevel : Command (op_code = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL) {
  tx_power : 8,
}

packet WriteInquiryResponseTransmitPowerLevelComplete : CommandComplete (command_op_code = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL) {
  status : ErrorCode,
}

enum KeypressNotificationType : 8 {
  ENTRY_STARTED = 0,
  DIGIT_ENTERED = 1,
  DIGIT_ERASED = 2,
  CLEARED = 3,
  ENTRY_COMPLETED = 4,
}

packet SendKeypressNotification : Command (op_code = SEND_KEYPRESS_NOTIFICATION) {
  bd_addr : Address,
  notification_type : KeypressNotificationType,
}

packet SendKeypressNotificationComplete : CommandComplete (command_op_code = SEND_KEYPRESS_NOTIFICATION) {
  status : ErrorCode,
  bd_addr : Address,
}

packet SetEventMaskPage2 : Command (op_code = SET_EVENT_MASK_PAGE_2) {
  event_mask_page_2: 64,
}

packet SetEventMaskPage2Complete : CommandComplete (command_op_code = SET_EVENT_MASK_PAGE_2) {
  status: ErrorCode,
}

packet ReadEnhancedTransmitPowerLevel : Command (op_code = READ_ENHANCED_TRANSMIT_POWER_LEVEL) {
  connection_handle : 12,
  _reserved_ : 4,
  transmit_power_level_type : TransmitPowerLevelType,
}

packet ReadEnhancedTransmitPowerLevelComplete : CommandComplete (command_op_code = READ_ENHANCED_TRANSMIT_POWER_LEVEL) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  tx_power_level_gfsk : 8,
  tx_power_level_dqpsk : 8,
  tx_power_level_8dpsk : 8,
}

packet ReadLeHostSupport : Command (op_code = READ_LE_HOST_SUPPORT) {
}

packet ReadLeHostSupportComplete : CommandComplete (command_op_code = READ_LE_HOST_SUPPORT) {
  status : ErrorCode,
  le_supported_host : Enable,
  _reserved_ : 8, // simultaneous_le_host reserved since 4.1
}

packet WriteLeHostSupport : Command (op_code = WRITE_LE_HOST_SUPPORT) {
  le_supported_host : Enable,
  simultaneous_le_host : Enable,  // According to the spec, this should be 0x00 since 4.1
}

test WriteLeHostSupport {
  "\x6d\x0c\x02\x01\x01",
}

packet WriteLeHostSupportComplete : CommandComplete (command_op_code = WRITE_LE_HOST_SUPPORT) {
  status : ErrorCode,
}

test WriteLeHostSupportComplete {
  "\x0e\x04\x01\x6d\x0c\x00",
}

packet ReadSecureConnectionsHostSupport : Command (op_code = READ_SECURE_CONNECTIONS_HOST_SUPPORT) {
}

packet ReadSecureConnectionsHostSupportComplete : CommandComplete (command_op_code = READ_SECURE_CONNECTIONS_HOST_SUPPORT) {
  status : ErrorCode,
  secure_connections_host_support : Enable,
}

packet WriteSecureConnectionsHostSupport : Command (op_code = WRITE_SECURE_CONNECTIONS_HOST_SUPPORT) {
  secure_connections_host_support : Enable,
}

test WriteSecureConnectionsHostSupport {
  "\x7a\x0c\x01\x01",
}

packet WriteSecureConnectionsHostSupportComplete : CommandComplete (command_op_code = WRITE_SECURE_CONNECTIONS_HOST_SUPPORT) {
  status : ErrorCode,
}

test WriteSecureConnectionsHostSupportComplete {
  "\x0e\x04\x01\x7a\x0c\x00",
}

packet ReadLocalOobExtendedData : Command (op_code = READ_LOCAL_OOB_EXTENDED_DATA) {
}

packet ReadLocalOobExtendedDataComplete : CommandComplete (command_op_code = READ_LOCAL_OOB_EXTENDED_DATA) {
  status : ErrorCode,
  c_192 : 8[16],
  r_192 : 8[16],
  c_256 : 8[16],
  r_256 : 8[16],
}

packet SetEcosystemBaseInterval : Command (op_code = SET_ECOSYSTEM_BASE_INTERVAL) {
  interval : 16,
}

packet SetEcosystemBaseIntervalComplete : CommandComplete (command_op_code = SET_ECOSYSTEM_BASE_INTERVAL) {
  status : ErrorCode,
}

enum DataPathDirection : 8 {
  INPUT = 0,
  OUTPUT = 1,
}

packet ConfigureDataPath : Command (op_code = CONFIGURE_DATA_PATH) {
  data_path_direction : DataPathDirection,
  data_path_id : 8,
  _size_(vendor_specific_config) : 8,
  vendor_specific_config : 8[],
}

packet ConfigureDataPathComplete : CommandComplete (command_op_code = CONFIGURE_DATA_PATH) {
  status : ErrorCode,
}

packet SetMinEncryptionKeySize : Command (op_code = SET_MIN_ENCRYPTION_KEY_SIZE) {
  min_encryption_key_size : 8,
}

packet SetMinEncryptionKeySizeComplete : CommandComplete (command_op_code = SET_MIN_ENCRYPTION_KEY_SIZE) {
  status : ErrorCode,
}


  // INFORMATIONAL_PARAMETERS
packet ReadLocalVersionInformation : Command (op_code = READ_LOCAL_VERSION_INFORMATION) {
}

test ReadLocalVersionInformation {
  "\x01\x10\x00",
}

enum HciVersion : 8 {
  V_1_0B = 0x00,
  V_1_1 = 0x01,
  V_1_2 = 0x02,
  V_2_0 = 0x03, //  + EDR
  V_2_1 = 0x04, //  + EDR
  V_3_0 = 0x05, //  + HS
  V_4_0 = 0x06,
  V_4_1 = 0x07,
  V_4_2 = 0x08,
  V_5_0 = 0x09,
  V_5_1 = 0x0a,
  V_5_2 = 0x0b,
  V_5_3 = 0x0c,
  V_5_4 = 0x0d,
}

enum LmpVersion : 8 {
  V_1_0B = 0x00, // withdrawn
  V_1_1 = 0x01, // withdrawn
  V_1_2 = 0x02, // withdrawn
  V_2_0 = 0x03, //  + EDR
  V_2_1 = 0x04, //  + EDR
  V_3_0 = 0x05, //  + HS
  V_4_0 = 0x06,
  V_4_1 = 0x07,
  V_4_2 = 0x08,
  V_5_0 = 0x09,
  V_5_1 = 0x0a,
  V_5_2 = 0x0b,
  V_5_3 = 0x0c,
  V_5_4 = 0x0d,
}

struct LocalVersionInformation {
  hci_version : HciVersion,
  hci_revision : 16,
  lmp_version : LmpVersion,
  manufacturer_name : 16,
  lmp_subversion : 16,
}

packet ReadLocalVersionInformationComplete : CommandComplete (command_op_code = READ_LOCAL_VERSION_INFORMATION) {
  status : ErrorCode,
  local_version_information : LocalVersionInformation,
}

test ReadLocalVersionInformationComplete {
  "\x0e\x0c\x01\x01\x10\x00\x09\x00\x00\x09\x1d\x00\xbe\x02",
}

packet ReadLocalSupportedCommands : Command (op_code = READ_LOCAL_SUPPORTED_COMMANDS) {
}

test ReadLocalSupportedCommands {
  "\x02\x10\x00",
}

packet ReadLocalSupportedCommandsComplete : CommandComplete (command_op_code = READ_LOCAL_SUPPORTED_COMMANDS) {
  status : ErrorCode,
  supported_commands : 8[64],
}

test ReadLocalSupportedCommandsComplete {
  "\x0e\x44\x01\x02\x10\x00\xff\xff\xff\x03\xce\xff\xef\xff\xff\xff\xff\x7f\xf2\x0f\xe8\xfe\x3f\xf7\x83\xff\x1c\x00\x00\x00\x61\xff\xff\xff\x7f\xbe\x20\xf5\xff\xf0\xff\xff\xff\xff\xff\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
}

packet ReadLocalSupportedFeatures : Command (op_code = READ_LOCAL_SUPPORTED_FEATURES) {
}

packet ReadLocalSupportedFeaturesComplete : CommandComplete (command_op_code = READ_LOCAL_SUPPORTED_FEATURES) {
  status : ErrorCode,
  lmp_features : 64,
}

packet ReadLocalExtendedFeatures : Command (op_code = READ_LOCAL_EXTENDED_FEATURES) {
  page_number : 8,
}

test ReadLocalExtendedFeatures {
  "\x04\x10\x01\x00",
  "\x04\x10\x01\x01",
  "\x04\x10\x01\x02",
}

enum LMPFeaturesPage0Bits: 64 {
  // Byte 0
  LMP_3_SLOT_PACKETS = 0x01,
  LMP_5_SLOT_PACKETS = 0x02,
  ENCRYPTION         = 0x04,
  SLOT_OFFSET        = 0x08,
  TIMING_ACCURACY    = 0x10,
  ROLE_SWITCH        = 0x20,
  HOLD_MODE          = 0x40,
  SNIFF_MODE         = 0x80,

  // Byte 1
  POWER_CONTROL_REQUESTS           = 0x0200,
  CHANNEL_QUALITY_DRIVEN_DATA_RATE = 0x0400,
  SCO_LINK                         = 0x0800,
  HV2_PACKETS                      = 0x1000,
  HV3_PACKETS                      = 0x2000,
  M_LAW_LOG_SYNCHRONOUS_DATA       = 0x4000,
  A_LAW_LOG_SYNCHRONOUS_DATA       = 0x8000,

  // Byte 2
  CVSD_SYNCHRONOUS_DATA                  = 0x010000,
  PAGING_PARAMETER_NEGOTIATION           = 0x020000,
  POWER_CONTROL                          = 0x040000,
  TRANSPARENT_SYNCHRONOUS_DATA           = 0x080000,
  FLOW_CONTROL_LAG_LEAST_SIGNIFICANT_BIT = 0x100000,
  FLOW_CONTROL_LAG_MIDDLE_BIT            = 0x200000,
  FLOW_CONTROL_LAG_MOST_SIGNIFICANT_BIT  = 0x400000,
  BROADCAST_ENCRYPTION                   = 0x800000,

  // Byte 3
  ENHANCED_DATA_RATE_ACL_2_MB_S_MODE = 0x02000000,
  ENHANCED_DATA_RATE_ACL_3_MB_S_MODE = 0x04000000,
  ENHANCED_INQUIRY_SCAN              = 0x08000000,
  INTERLACED_INQUIRY_SCAN            = 0x10000000,
  INTERLACED_PAGE_SCAN               = 0x20000000,
  RSSI_WITH_INQUIRY_RESULTS          = 0x40000000,
  EXTENDED_SCO_LINK                  = 0x80000000,

  // Byte 4
  EV4_PACKETS                               = 0x0100000000,
  EV5_PACKETS                               = 0x0200000000,
  AFH_CAPABLE_PERIPHERAL                    = 0x0800000000,
  AFH_CLASSIFICATION_PERIPHERAL             = 0x1000000000,
  BR_EDR_NOT_SUPPORTED                      = 0x2000000000,
  LE_SUPPORTED_CONTROLLER                   = 0x4000000000,
  LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS = 0x8000000000,

  // Byte 5
  LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS  = 0x010000000000,
  SNIFF_SUBRATING                            = 0x020000000000,
  PAUSE_ENCRYPTION                           = 0x040000000000,
  AFH_CAPABLE_CENTRAL                        = 0x080000000000,
  AFH_CLASSIFICATION_CENTRAL                 = 0x100000000000,
  ENHANCED_DATA_RATE_ESCO_2_MB_S_MODE        = 0x200000000000,
  ENHANCED_DATA_RATE_ESCO_3_MB_S_MODE        = 0x400000000000,
  LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS = 0x800000000000,

  // Byte 6
  EXTENDED_INQUIRY_RESPONSE          = 0x01000000000000,
  SIMULTANEOUS_LE_AND_BR_CONTROLLER  = 0x02000000000000,
  SECURE_SIMPLE_PAIRING_CONTROLLER   = 0x08000000000000,
  ENCAPSULATED_PDU                   = 0x10000000000000,
  ERRONEOUS_DATA_REPORTING           = 0x20000000000000,
  NON_FLUSHABLE_PACKET_BOUNDARY_FLAG = 0x40000000000000,

  // Byte 7
  HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT = 0x0100000000000000,
  VARIABLE_INQUIRY_TX_POWER_LEVEL            = 0x0200000000000000,
  ENHANCED_POWER_CONTROL                     = 0x0400000000000000,
  EXTENDED_FEATURES                          = 0x8000000000000000,
}

enum LMPFeaturesPage1Bits: 64 {
  // Byte 0
  SECURE_SIMPLE_PAIRING_HOST_SUPPORT = 0x01,
  LE_SUPPORTED_HOST                  = 0x02,
  SIMULTANEOUS_LE_AND_BR_HOST        = 0x04,
  SECURE_CONNECTIONS_HOST_SUPPORT    = 0x08,
}

enum LMPFeaturesPage2Bits: 64 {
  // Byte 0
  CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION = 0x01,
  CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION    = 0x02,
  SYNCHRONIZATION_TRAIN                                     = 0x04,
  SYNCHRONIZATION_SCAN                                      = 0x08,
  HCI_INQUIRY_RESPONSE_NOTIFICATION_EVENT                   = 0x10,
  GENERALIZED_INTERLACED_SCAN                               = 0x20,
  COARSE_CLOCK_ADJUSTMENT                                   = 0x40,

  // Byte 1
  SECURE_CONNECTIONS_CONTROLLER_SUPPORT = 0x0100,
  PING                                  = 0x0200,
  SLOT_AVAILABILITY_MASK                = 0x0400,
  TRAIN_NUDGING                         = 0x0800,
}

packet ReadLocalExtendedFeaturesComplete : CommandComplete (command_op_code = READ_LOCAL_EXTENDED_FEATURES) {
  status : ErrorCode,
  page_number : 8,
  maximum_page_number : 8,
  extended_lmp_features : 64,
}

test ReadLocalExtendedFeaturesComplete {
  "\x0e\x0e\x01\x04\x10\x00\x00\x02\xff\xfe\x8f\xfe\xd8\x3f\x5b\x87",
  "\x0e\x0e\x01\x04\x10\x00\x01\x02\x07\x00\x00\x00\x00\x00\x00\x00",
  "\x0e\x0e\x01\x04\x10\x00\x02\x02\x45\x03\x00\x00\x00\x00\x00\x00",
}

packet ReadBufferSize : Command (op_code = READ_BUFFER_SIZE) {
}

test ReadBufferSize {
  "\x05\x10\x00",
}

packet ReadBufferSizeComplete : CommandComplete (command_op_code = READ_BUFFER_SIZE) {
  status : ErrorCode,
  acl_data_packet_length : 16,
  synchronous_data_packet_length : 8,
  total_num_acl_data_packets : 16,
  total_num_synchronous_data_packets : 16,
}

test ReadBufferSizeComplete {
  "\x0e\x0b\x01\x05\x10\x00\x00\x04\x3c\x07\x00\x08\x00",
}

packet ReadBdAddr : Command (op_code = READ_BD_ADDR) {
}

test ReadBdAddr {
  "\x09\x10\x00",
}

packet ReadBdAddrComplete : CommandComplete (command_op_code = READ_BD_ADDR) {
  status : ErrorCode,
  bd_addr : Address,
}

test ReadBdAddrComplete {
  "\x0e\x0a\x01\x09\x10\x00\x14\x8e\x61\x5f\x36\x88",
}

packet ReadDataBlockSize : Command (op_code = READ_DATA_BLOCK_SIZE) {
}

packet ReadDataBlockSizeComplete : CommandComplete (command_op_code = READ_DATA_BLOCK_SIZE) {
  status : ErrorCode,
  max_acl_data_packet_length : 16,
  data_block_length : 16,
  total_num_data_blocks : 16,
}

packet ReadLocalSupportedCodecsV1 : Command (op_code = READ_LOCAL_SUPPORTED_CODECS_V1) {
}

packet ReadLocalSupportedCodecsV1Complete : CommandComplete (command_op_code = READ_LOCAL_SUPPORTED_CODECS_V1) {
  status : ErrorCode,
  _count_(supported_codecs) : 8,
  supported_codecs : 8[],
  _count_(vendor_specific_codecs) : 8,
  vendor_specific_codecs : 32[],
}

packet ReadLocalSupportedCodecsV2 : Command (op_code = READ_LOCAL_SUPPORTED_CODECS_V2) {
}

group CodecTransport {
  br_edr : 1,
  br_edr_sco_and_esco : 1,
  le_cis : 1,
  le_bis : 1,
  _reserved_ : 4,
}

struct CodecConfiguration {
  codec_id : 8,
  CodecTransport,
}

struct VendorCodecConfiguration {
  company_id : 16,
  codec_vendor_id : 16,
  CodecTransport,
}

packet ReadLocalSupportedCodecsV2Complete : CommandComplete (command_op_code = READ_LOCAL_SUPPORTED_CODECS_V2) {
  status : ErrorCode,
  _count_(supported_codecs) : 8,
  supported_codecs : CodecConfiguration[],
  _count_(vendor_specific_codecs) : 8,
  vendor_specific_codecs : VendorCodecConfiguration[],
}

packet ReadLocalSupportedCodecCapabilities : Command (op_code = READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES) {
  codec_id : 8,
  company_id : 16,
  codec_vendor_id : 16,
  CodecTransport,
  direction : DataPathDirection,
}

struct CodecCapability {
  _size_(capability) : 8,
  capability : 8[],
}

packet ReadLocalSupportedCodecCapabilitiesComplete : CommandComplete (command_op_code = READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES) {
  status : ErrorCode,
  _count_(codec_capabilities) : 8,
  codec_capabilities : CodecCapability[],
}

packet ReadLocalSupportedControllerDelay : Command (op_code = READ_LOCAL_SUPPORTED_CONTROLLER_DELAY) {
  codec_id : 8,
  company_id : 16,
  codec_vendor_id : 16,
  CodecTransport,
  direction : DataPathDirection,
  _size_(codec_configuration) : 8,
  codec_configuration : 8[],
}

packet ReadLocalSupportedControllerDelayComplete : CommandComplete (command_op_code = READ_LOCAL_SUPPORTED_CONTROLLER_DELAY) {
  status : ErrorCode,
  min_controller_delay : 24,
  max_controller_delay : 24,
}


  // STATUS_PARAMETERS
packet ReadFailedContactCounter : Command (op_code = READ_FAILED_CONTACT_COUNTER) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadFailedContactCounterComplete : CommandComplete (command_op_code = READ_FAILED_CONTACT_COUNTER) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  failed_contact_counter : 16,
}

packet ResetFailedContactCounter : Command (op_code = RESET_FAILED_CONTACT_COUNTER) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ResetFailedContactCounterComplete : CommandComplete (command_op_code = RESET_FAILED_CONTACT_COUNTER) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadLinkQuality : Command (op_code = READ_LINK_QUALITY) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadLinkQualityComplete : CommandComplete (command_op_code = READ_LINK_QUALITY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  link_quality : 8,
}

packet ReadRssi : Command (op_code = READ_RSSI) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadRssiComplete : CommandComplete (command_op_code = READ_RSSI) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  rssi : 8,
}

packet ReadAfhChannelMap : Command (op_code = READ_AFH_CHANNEL_MAP) {
  connection_handle : 12,
  _reserved_ : 4,
}

enum AfhMode : 8 {
  AFH_DISABLED = 0x00,
  AFH_ENABLED = 0x01,
}

packet ReadAfhChannelMapComplete : CommandComplete (command_op_code = READ_AFH_CHANNEL_MAP) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  afh_mode : AfhMode,
  afh_channel_map : 8[10],
}


enum WhichClock : 8 {
  LOCAL = 0x00,
  PICONET = 0x01,
}

packet ReadClock : Command (op_code = READ_CLOCK) {
  connection_handle : 12,
  _reserved_ : 4,
  which_clock : WhichClock,
}

packet ReadClockComplete : CommandComplete (command_op_code = READ_CLOCK) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  clock : 28,
  _reserved_ : 4,
  accuracy : 16,
}

packet ReadEncryptionKeySize : Command (op_code = READ_ENCRYPTION_KEY_SIZE) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet ReadEncryptionKeySizeComplete : CommandComplete (command_op_code = READ_ENCRYPTION_KEY_SIZE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  key_size : 8,
}

  // TESTING
enum LoopbackMode : 8 {
  NO_LOOPBACK = 0x00,
  ENABLE_LOCAL = 0x01,
  ENABLE_REMOTE = 0x02,
}

packet ReadLoopbackMode : Command (op_code = READ_LOOPBACK_MODE) {
}

packet ReadLoopbackModeComplete : CommandComplete (command_op_code = READ_LOOPBACK_MODE) {
  status : ErrorCode,
  loopback_mode : LoopbackMode,
}

packet WriteLoopbackMode : Command (op_code = WRITE_LOOPBACK_MODE) {
  loopback_mode : LoopbackMode,
}

packet WriteLoopbackModeComplete : CommandComplete (command_op_code = WRITE_LOOPBACK_MODE) {
  status : ErrorCode,
}

packet EnableDeviceUnderTestMode : Command (op_code = ENABLE_DEVICE_UNDER_TEST_MODE) {
}

packet EnableDeviceUnderTestModeComplete : CommandComplete (command_op_code = ENABLE_DEVICE_UNDER_TEST_MODE) {
  status : ErrorCode,
}

packet WriteSimplePairingDebugMode : Command (op_code = WRITE_SIMPLE_PAIRING_DEBUG_MODE) {
  simple_pairing_debug_mode : Enable,
}

packet WriteSimplePairingDebugModeComplete : CommandComplete (command_op_code = WRITE_SIMPLE_PAIRING_DEBUG_MODE) {
  status : ErrorCode,
}

packet WriteSecureConnectionsTestMode : Command (op_code = WRITE_SECURE_CONNECTIONS_TEST_MODE) {
  connection_handle : 12,
  _reserved_ : 4,
  dm1_aclu_mode : Enable,
  esco_loopback_mode : Enable,
}

packet WriteSecureConnectionsTestModeComplete : CommandComplete (command_op_code = WRITE_SECURE_CONNECTIONS_TEST_MODE) {
  status : ErrorCode,
}

  // LE_CONTROLLER
packet LeSetEventMask : Command (op_code = LE_SET_EVENT_MASK) {
  le_event_mask : 64,
}

packet LeSetEventMaskComplete : CommandComplete (command_op_code = LE_SET_EVENT_MASK) {
  status : ErrorCode,
}

packet LeReadBufferSizeV1 : Command (op_code = LE_READ_BUFFER_SIZE_V1) {
}

struct LeBufferSize {
  le_data_packet_length : 16,
  total_num_le_packets : 8,
}

test LeReadBufferSizeV1 {
  "\x02\x20\x00",
}

packet LeReadBufferSizeV1Complete : CommandComplete (command_op_code = LE_READ_BUFFER_SIZE_V1) {
  status : ErrorCode,
  le_buffer_size : LeBufferSize,
}

test LeReadBufferSizeV1Complete {
  "\x0e\x07\x01\x02\x20\x00\xfb\x00\x10",
}

enum LLFeaturesBits : 64 {
  // Byte 0
  LE_ENCRYPTION                                 = 0x0000000000000001,
  CONNECTION_PARAMETERS_REQUEST_PROCEDURE       = 0x0000000000000002,
  EXTENDED_REJECT_INDICATION                    = 0x0000000000000004,
  PERIPHERAL_INITIATED_FEATURES_EXCHANGE        = 0x0000000000000008,
  LE_PING                                       = 0x0000000000000010,
  LE_DATA_PACKET_LENGTH_EXTENSION               = 0x0000000000000020,
  LL_PRIVACY                                    = 0x0000000000000040,
  EXTENDED_SCANNER_FILTER_POLICIES              = 0x0000000000000080,

  // Byte 1
  LE_2M_PHY                                     = 0x0000000000000100,
  STABLE_MODULATION_INDEX_TRANSMITTER           = 0x0000000000000200,
  STABLE_MODULATION_INDEX_RECEIVER              = 0x0000000000000400,
  LE_CODED_PHY                                  = 0x0000000000000800,
  LE_EXTENDED_ADVERTISING                       = 0x0000000000001000,
  LE_PERIODIC_ADVERTISING                       = 0x0000000000002000,
  CHANNEL_SELECTION_ALGORITHM_2                 = 0x0000000000004000,
  LE_POWER_CLASS_1                              = 0x0000000000008000,

  // Byte 2
  MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE     = 0x0000000000010000,
  CONNECTION_CTE_REQUEST                        = 0x0000000000020000,
  CONNECTION_CTE_RESPONSE                       = 0x0000000000040000,
  CONNECTIONLESS_CTE_TRANSMITTER                = 0x0000000000080000,
  CONNECTIONLESS_CTE_RECEIVER                   = 0x0000000000100000,
  ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION     = 0x0000000000200000,
  ANTENNA_SWITCHING_DURING_CTE_RECEPTION        = 0x0000000000400000,
  RECEIVING_CONSTANT_TONE_EXTENSIONS            = 0x0000000000800000,

  // Byte 3
  PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER     = 0x0000000001000000,
  PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT  = 0x0000000002000000,
  SLEEP_CLOCK_ACCURACY_UPDATES                  = 0x0000000004000000,
  REMOTE_PUBLIC_KEY_VALIDATION                  = 0x0000000008000000,
  CONNECTED_ISOCHRONOUS_STREAM_CENTRAL          = 0x0000000010000000,
  CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL       = 0x0000000020000000,
  ISOCHRONOUS_BROADCASTER                       = 0x0000000040000000,
  SYNCHRONIZED_RECEIVER                         = 0x0000000080000000,

  // Byte 4
  CONNECTED_ISOCHRONOUS_STREAM_HOST_SUPPORT     = 0x0000000100000000,
  LE_POWER_CONTROL_REQUEST                      = 0x0000000200000000,
  LE_POWER_CONTROL_REQUEST_BIS                  = 0x0000000400000000,
  LE_PATH_LOSS_MONITORING                       = 0x0000000800000000,
  PERIODIC_ADVERTISING_ADI_SUPPORT              = 0x0000001000000000,
  CONNECTION_SUBRATING                          = 0x0000002000000000,
  CONNECTION_SUBRATING_HOST_SUPPORT             = 0x0000004000000000,
  CHANNEL_CLASSIFICATION                        = 0x0000008000000000,
}

packet LeReadLocalSupportedFeatures : Command (op_code = LE_READ_LOCAL_SUPPORTED_FEATURES) {
}

packet LeReadLocalSupportedFeaturesComplete : CommandComplete (command_op_code = LE_READ_LOCAL_SUPPORTED_FEATURES) {
  status : ErrorCode,
  le_features : 64,
}

packet LeSetRandomAddress : Command (op_code = LE_SET_RANDOM_ADDRESS) {
  random_address : Address,
}

packet LeSetRandomAddressComplete : CommandComplete (command_op_code = LE_SET_RANDOM_ADDRESS) {
  status : ErrorCode,
}

enum AdvertisingFilterPolicy : 2 {
  ALL_DEVICES = 0, // Default
  LISTED_SCAN = 1,
  LISTED_CONNECT = 2,
  LISTED_SCAN_AND_CONNECT = 3,
}

enum PeerAddressType : 8 {
  PUBLIC_DEVICE_OR_IDENTITY_ADDRESS = 0x00,
  RANDOM_DEVICE_OR_IDENTITY_ADDRESS = 0x01,
}

enum AdvertisingType : 8 {
  ADV_IND = 0x00,
  ADV_DIRECT_IND_HIGH = 0x01,
  ADV_SCAN_IND = 0x02,
  ADV_NONCONN_IND = 0x03,
  ADV_DIRECT_IND_LOW = 0x04,
}

enum AddressType : 8 {
  PUBLIC_DEVICE_ADDRESS = 0x00,
  RANDOM_DEVICE_ADDRESS = 0x01,
  PUBLIC_IDENTITY_ADDRESS = 0x02,
  RANDOM_IDENTITY_ADDRESS = 0x03,
}

enum OwnAddressType : 8 {
  PUBLIC_DEVICE_ADDRESS = 0x00,
  RANDOM_DEVICE_ADDRESS = 0x01,
  RESOLVABLE_OR_PUBLIC_ADDRESS = 0x02,
  RESOLVABLE_OR_RANDOM_ADDRESS = 0x03,
}

packet LeSetAdvertisingParameters : Command (op_code = LE_SET_ADVERTISING_PARAMETERS) {
  advertising_interval_min : 16,
  advertising_interval_max : 16,
  advertising_type : AdvertisingType,
  own_address_type : OwnAddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  advertising_channel_map : 8,
  advertising_filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
}

packet LeSetAdvertisingParametersComplete : CommandComplete (command_op_code = LE_SET_ADVERTISING_PARAMETERS) {
  status : ErrorCode,
}

packet LeReadAdvertisingPhysicalChannelTxPower : Command (op_code = LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) {
}

packet LeReadAdvertisingPhysicalChannelTxPowerComplete : CommandComplete (command_op_code = LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) {
  status : ErrorCode,
  transmit_power_level : 8, // (-127dBm to 20dBm) Accuracy: +/-4dB
}

packet LeSetAdvertisingData : Command (op_code = LE_SET_ADVERTISING_DATA) {
  _size_(advertising_data) : 8,
  advertising_data : 8[],
  _padding_[31], // Zero padding to 31 bytes of advertising_data
}

packet LeSetAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_ADVERTISING_DATA) {
  status : ErrorCode,
}

packet LeSetScanResponseData : Command (op_code = LE_SET_SCAN_RESPONSE_DATA) {
  _size_(advertising_data) : 8,
  advertising_data : 8[],
  _padding_[31], // Zero padding to 31 bytes of advertising_data
}

packet LeSetScanResponseDataComplete : CommandComplete (command_op_code = LE_SET_SCAN_RESPONSE_DATA) {
  status : ErrorCode,
}

packet LeSetAdvertisingEnable : Command (op_code = LE_SET_ADVERTISING_ENABLE) {
  advertising_enable : Enable, // Default DISABLED
}

packet LeSetAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_ADVERTISING_ENABLE) {
  status : ErrorCode,
}

enum LeScanType : 8 {
  PASSIVE = 0x00, // Default
  ACTIVE = 0x01,
}

enum LeScanningFilterPolicy : 8 {
  ACCEPT_ALL = 0x00, // Default
  FILTER_ACCEPT_LIST_ONLY = 0x01,
  CHECK_INITIATORS_IDENTITY = 0x02,
  FILTER_ACCEPT_LIST_AND_INITIATORS_IDENTITY = 0x03,
}

packet LeSetScanParameters : Command (op_code = LE_SET_SCAN_PARAMETERS) {
  le_scan_type : LeScanType,
  le_scan_interval : 16, // 0x0004-0x4000 Default 0x10 (10ms)
  le_scan_window : 16, // Default 0x10 (10ms)
  own_address_type : OwnAddressType,
  scanning_filter_policy : LeScanningFilterPolicy,
}

test LeSetScanParameters {
  "\x0b\x20\x07\x01\x12\x00\x12\x00\x01\x00",
}

packet LeSetScanParametersComplete : CommandComplete (command_op_code = LE_SET_SCAN_PARAMETERS) {
  status : ErrorCode,
}

packet LeSetScanEnable : Command (op_code = LE_SET_SCAN_ENABLE) {
  le_scan_enable : Enable,
  filter_duplicates : Enable,
}

test LeSetScanEnable {
  "\x0c\x20\x02\x01\x00",
}

packet LeSetScanEnableComplete : CommandComplete (command_op_code = LE_SET_SCAN_ENABLE) {
  status : ErrorCode,
}

enum InitiatorFilterPolicy : 8 {
  USE_PEER_ADDRESS = 0x00,
  USE_FILTER_ACCEPT_LIST = 0x01,
}

packet LeCreateConnection : Command (op_code = LE_CREATE_CONNECTION) {
  le_scan_interval : 16, // 0x0004-0x4000
  le_scan_window : 16, // < = LeScanInterval
  initiator_filter_policy : InitiatorFilterPolicy,
  peer_address_type : AddressType,
  peer_address : Address,
  own_address_type : OwnAddressType,
  connection_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  connection_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  max_latency : 16, // 0x0006-0x01F3
  supervision_timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
  min_ce_length : 16, // 0.625ms
  max_ce_length : 16, // 0.625ms
}

packet LeCreateConnectionStatus : CommandStatus (command_op_code = LE_CREATE_CONNECTION) {
}

packet LeCreateConnectionCancel : Command (op_code = LE_CREATE_CONNECTION_CANCEL) {
}

packet LeCreateConnectionCancelComplete : CommandComplete (command_op_code = LE_CREATE_CONNECTION_CANCEL) {
  status : ErrorCode,
}

packet LeReadFilterAcceptListSize : Command (op_code = LE_READ_FILTER_ACCEPT_LIST_SIZE) {
}

test LeReadFilterAcceptListSize {
  "\x0f\x20\x00",
}

packet LeReadFilterAcceptListSizeComplete : CommandComplete (command_op_code = LE_READ_FILTER_ACCEPT_LIST_SIZE) {
  status : ErrorCode,
  filter_accept_list_size : 8,
}

test LeReadFilterAcceptListSizeComplete {
  "\x0e\x05\x01\x0f\x20\x00\x80",
}

packet LeClearFilterAcceptList : Command (op_code = LE_CLEAR_FILTER_ACCEPT_LIST) {
}

packet LeClearFilterAcceptListComplete : CommandComplete (command_op_code = LE_CLEAR_FILTER_ACCEPT_LIST) {
  status : ErrorCode,
}

enum FilterAcceptListAddressType : 8 {
  PUBLIC = 0x00,
  RANDOM = 0x01,
  ANONYMOUS_ADVERTISERS = 0xFF,
}

packet LeAddDeviceToFilterAcceptList : Command (op_code = LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST) {
  address_type : FilterAcceptListAddressType,
  address : Address,
}

packet LeAddDeviceToFilterAcceptListComplete : CommandComplete (command_op_code = LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST) {
  status : ErrorCode,
}

packet LeRemoveDeviceFromFilterAcceptList : Command (op_code = LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST) {
  address_type : FilterAcceptListAddressType,
  address : Address,
}

packet LeRemoveDeviceFromFilterAcceptListComplete : CommandComplete (command_op_code = LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST) {
  status : ErrorCode,
}

packet LeConnectionUpdate : Command (op_code = LE_CONNECTION_UPDATE) {
  connection_handle : 12,
  _reserved_ : 4,
  connection_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  connection_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  max_latency : 16, // 0x0006-0x01F3
  supervision_timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
  min_ce_length : 16, // 0.625ms
  max_ce_length : 16, // 0.625ms
}

packet LeConnectionUpdateStatus : CommandStatus (command_op_code = LE_CONNECTION_UPDATE) {
}

packet LeSetHostChannelClassification : Command (op_code = LE_SET_HOST_CHANNEL_CLASSIFICATION) {
  channel_map : 8[5],
}

packet LeSetHostChannelClassificationComplete : CommandComplete (command_op_code = LE_SET_HOST_CHANNEL_CLASSIFICATION) {
  status : ErrorCode,
}

packet LeReadChannelMap : Command (op_code = LE_READ_CHANNEL_MAP) {
}

packet LeReadChannelMapComplete : CommandComplete (command_op_code = LE_READ_CHANNEL_MAP) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  channel_map : 8[5],
}

packet LeReadRemoteFeatures : Command (op_code = LE_READ_REMOTE_FEATURES) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeReadRemoteFeaturesStatus : CommandStatus (command_op_code = LE_READ_REMOTE_FEATURES) {
}

packet LeEncrypt : Command (op_code = LE_ENCRYPT) {
  key : 8[16],
  plaintext_data : 8[16],
}

packet LeEncryptComplete : CommandComplete (command_op_code = LE_ENCRYPT) {
  status : ErrorCode,
  encrypted_data : 8[16],
}

packet LeRand : Command (op_code = LE_RAND) {
}

packet LeRandComplete : CommandComplete (command_op_code = LE_RAND) {
  status : ErrorCode,
  random_number : 64,
}

packet LeStartEncryption : Command (op_code = LE_START_ENCRYPTION) {
  connection_handle: 16,
  rand: 8[8],
  ediv: 16,
  ltk: 8[16],
}

packet LeStartEncryptionStatus : CommandStatus (command_op_code = LE_START_ENCRYPTION) {
}

packet LeLongTermKeyRequestReply : Command (op_code = LE_LONG_TERM_KEY_REQUEST_REPLY) {
  connection_handle: 16,
  long_term_key: 8[16],
}

packet LeLongTermKeyRequestReplyComplete : CommandComplete (command_op_code = LE_LONG_TERM_KEY_REQUEST_REPLY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeLongTermKeyRequestNegativeReply : Command (op_code = LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeLongTermKeyRequestNegativeReplyComplete : CommandComplete (command_op_code = LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeReadSupportedStates : Command (op_code = LE_READ_SUPPORTED_STATES) {
}

packet LeReadSupportedStatesComplete : CommandComplete (command_op_code = LE_READ_SUPPORTED_STATES) {
  status : ErrorCode,
  le_states : 64,
}

packet LeReceiverTest : Command (op_code = LE_RECEIVER_TEST_V1) {
  rx_channel : 8,
}

packet LeReceiverTestComplete : CommandComplete (command_op_code = LE_RECEIVER_TEST_V1) {
  status : ErrorCode,
}

enum LeTestPayload : 8 {
  PRBS9 = 0x00,
  REPEATED_F0 = 0x01,
  REPEATED_AA = 0x02,
  PRBS15 = 0x03,
  REPEATED_FF = 0x04,
  REPEATED_00 = 0x05,
  REPEATED_0F = 0x06,
  REPEATED_55 = 0x07,
}

packet LeTransmitterTest : Command (op_code = LE_TRANSMITTER_TEST_V1) {
  tx_channel : 8,
  test_data_length : 8,
  packet_payload : LeTestPayload,
}

packet LeTransmitterTestComplete : CommandComplete (command_op_code = LE_TRANSMITTER_TEST_V1) {
  status : ErrorCode,
}

packet LeTestEnd : Command (op_code = LE_TEST_END) {
}

packet LeTestEndComplete : CommandComplete (command_op_code = LE_TEST_END) {
  status : ErrorCode,
}

packet LeRemoteConnectionParameterRequestReply : Command (op_code = LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY) {
  connection_handle : 12,
  _reserved_ : 4,
  interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  latency : 16, // 0x0006-0x01F3
  timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
  minimum_ce_length : 16, // 0.625ms
  maximum_ce_length : 16, // 0.625ms
}

packet LeRemoteConnectionParameterRequestReplyComplete : CommandComplete (command_op_code = LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeRemoteConnectionParameterRequestNegativeReply : Command (op_code = LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY) {
  connection_handle : 12,
  _reserved_ : 4,
  reason : ErrorCode,
}

packet LeRemoteConnectionParameterRequestNegativeReplyComplete : CommandComplete (command_op_code = LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeSetDataLength : Command (op_code = LE_SET_DATA_LENGTH) {
  connection_handle : 12,
  _reserved_ : 4,
  tx_octets : 16, // payload octets per single PDU 0x1B to 0x00FB
  tx_time : 16, // microseconds used to transmit a single PDU 0x0148 to 0x4290
}

packet LeSetDataLengthComplete : CommandComplete (command_op_code = LE_SET_DATA_LENGTH) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeReadSuggestedDefaultDataLength : Command (op_code = LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH) {
}

packet LeReadSuggestedDefaultDataLengthComplete : CommandComplete (command_op_code = LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH) {
  status : ErrorCode,
  tx_octets : 16, // payload octets per single PDU 0x1B to 0x00FB
  tx_time : 16, // microseconds used to transmit a single PDU 0x0148 to 0x4290
}

packet LeWriteSuggestedDefaultDataLength : Command (op_code = LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH) {
  tx_octets : 16, // payload octets per single PDU 0x1B to 0x00FB
  tx_time : 16, // microseconds used to transmit a single PDU 0x0148 to 0x4290
}

packet LeWriteSuggestedDefaultDataLengthComplete : CommandComplete (command_op_code = LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH) {
  status : ErrorCode,
}

packet LeReadLocalP256PublicKeyCommand : Command (op_code = LE_READ_LOCAL_P_256_PUBLIC_KEY) {
}

packet LeReadLocalP256PublicKeyCommandStatus : CommandStatus (command_op_code = LE_READ_LOCAL_P_256_PUBLIC_KEY) {
}

packet LeGenerateDhkeyV1Command : Command (op_code = LE_GENERATE_DHKEY_V1) {
  remote_p_256_public_key : 8[64],
}

packet LeGenerateDhkeyV1CommandStatus : CommandStatus (command_op_code = LE_GENERATE_DHKEY_V1) {
}

packet LeAddDeviceToResolvingList : Command (op_code = LE_ADD_DEVICE_TO_RESOLVING_LIST) {
  peer_identity_address_type : PeerAddressType,
  peer_identity_address : Address,
  peer_irk : 8[16],
  local_irk : 8[16],
}

packet LeAddDeviceToResolvingListComplete : CommandComplete (command_op_code = LE_ADD_DEVICE_TO_RESOLVING_LIST) {
  status : ErrorCode,
}

packet LeRemoveDeviceFromResolvingList : Command (op_code = LE_REMOVE_DEVICE_FROM_RESOLVING_LIST) {
  peer_identity_address_type : PeerAddressType,
  peer_identity_address : Address,
}

packet LeRemoveDeviceFromResolvingListComplete : CommandComplete (command_op_code = LE_REMOVE_DEVICE_FROM_RESOLVING_LIST) {
  status : ErrorCode,
}

packet LeClearResolvingList : Command (op_code = LE_CLEAR_RESOLVING_LIST) {
}

packet LeClearResolvingListComplete : CommandComplete (command_op_code = LE_CLEAR_RESOLVING_LIST) {
  status : ErrorCode,
}

packet LeReadResolvingListSize : Command (op_code = LE_READ_RESOLVING_LIST_SIZE) {
}

packet LeReadResolvingListSizeComplete : CommandComplete (command_op_code = LE_READ_RESOLVING_LIST_SIZE) {
  status : ErrorCode,
  resolving_list_size : 8,
}

packet LeReadPeerResolvableAddress : Command (op_code = LE_READ_PEER_RESOLVABLE_ADDRESS) {
  peer_identity_address_type : PeerAddressType,
  peer_identity_address : Address,
}

packet LeReadPeerResolvableAddressComplete : CommandComplete (command_op_code = LE_READ_PEER_RESOLVABLE_ADDRESS) {
  status : ErrorCode,
  peer_resolvable_address : Address,
}

packet LeReadLocalResolvableAddress : Command (op_code = LE_READ_LOCAL_RESOLVABLE_ADDRESS) {
  peer_identity_address_type : PeerAddressType,
  peer_identity_address : Address,
}

packet LeReadLocalResolvableAddressComplete : CommandComplete (command_op_code = LE_READ_LOCAL_RESOLVABLE_ADDRESS) {
  status : ErrorCode,
  local_resolvable_address : Address,
}

packet LeSetAddressResolutionEnable : Command (op_code = LE_SET_ADDRESS_RESOLUTION_ENABLE) {
  address_resolution_enable : Enable,
}

packet LeSetAddressResolutionEnableComplete : CommandComplete (command_op_code = LE_SET_ADDRESS_RESOLUTION_ENABLE) {
  status : ErrorCode,
}

packet LeSetResolvablePrivateAddressTimeout : Command (op_code = LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT) {
  rpa_timeout : 16, // RPA_Timeout measured in seconds 0x0001 to 0xA1B8 1s to 11.5 hours
}

packet LeSetResolvablePrivateAddressTimeoutComplete : CommandComplete (command_op_code = LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT) {
  status : ErrorCode,
}

packet LeReadMaximumDataLength : Command (op_code = LE_READ_MAXIMUM_DATA_LENGTH) {
}

struct LeMaximumDataLength {
  supported_max_tx_octets : 16,
  supported_max_tx_time: 16,
  supported_max_rx_octets : 16,
  supported_max_rx_time: 16,
}

packet LeReadMaximumDataLengthComplete : CommandComplete (command_op_code = LE_READ_MAXIMUM_DATA_LENGTH) {
  status : ErrorCode,
  le_maximum_data_length : LeMaximumDataLength,
}

packet LeReadPhy : Command (op_code = LE_READ_PHY) {
  connection_handle : 12,
  _reserved_ : 4,
}

enum PhyType : 8 {
  LE_1M = 0x01,
  LE_2M = 0x02,
  LE_CODED = 0x03,
}

packet LeReadPhyComplete : CommandComplete (command_op_code = LE_READ_PHY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  tx_phy : PhyType,
  rx_phy : PhyType,
}

packet LeSetDefaultPhy : Command (op_code = LE_SET_DEFAULT_PHY) {
  all_phys_no_transmit_preference : 1,
  all_phys_no_receive_preference : 1,
  _reserved_ : 6,
  tx_phys : 3,
  _reserved_ : 5,
  rx_phys : 3,
  _reserved_ : 5,
}

packet LeSetDefaultPhyComplete : CommandComplete (command_op_code = LE_SET_DEFAULT_PHY) {
  status : ErrorCode,
}

enum PhyOptions : 8 {
  NO_PREFERENCE = 0x00,
  S_2 = 0x01,
  S_8 = 0x02,
}

packet LeSetPhy : Command (op_code = LE_SET_PHY) {
  connection_handle : 12,
  _reserved_ : 4,
  all_phys_no_transmit_preference : 1,
  all_phys_no_receive_preference : 1,
  _reserved_ : 6,
  tx_phys : 3,
  _reserved_ : 5,
  rx_phys : 3,
  _reserved_ : 5,
  phy_options : PhyOptions,
}

packet LeSetPhyStatus : CommandStatus (command_op_code = LE_SET_PHY) {
}

enum ModulationIndex : 8 {
  STANDARD = 0x00,
  STABLE = 0x01,
}

packet LeEnhancedReceiverTest : Command (op_code = LE_RECEIVER_TEST_V2) {
  rx_channel : 8,
  phy : PhyType,
  modulation_index : ModulationIndex,
}

packet LeEnhancedReceiverTestComplete : CommandComplete (command_op_code = LE_RECEIVER_TEST_V2) {
  status : ErrorCode,
}

packet LeEnhancedTransmitterTest : Command (op_code = LE_TRANSMITTER_TEST_V2) {
  tx_channel : 8,
  test_data_length : 8,
  packet_payload : LeTestPayload,
  phy : PhyType,
}

packet LeEnhancedTransmitterTestComplete : CommandComplete (command_op_code = LE_TRANSMITTER_TEST_V2) {
  status : ErrorCode,
}

packet LeSetAdvertisingSetRandomAddress : Command (op_code = LE_SET_ADVERTISING_SET_RANDOM_ADDRESS) {
  advertising_handle : 8,
  random_address : Address,
}

test LeSetAdvertisingSetRandomAddress {
  "\x35\x20\x07\x00\x77\x58\xeb\xd3\x1c\x6e",
}

packet LeSetAdvertisingSetRandomAddressComplete : CommandComplete (command_op_code = LE_SET_ADVERTISING_SET_RANDOM_ADDRESS) {
  status : ErrorCode,
}

test LeSetAdvertisingSetRandomAddressComplete {
  "\x0e\x04\x01\x35\x20\x00",
}

// The lower 4 bits of the advertising event properties
enum LegacyAdvertisingEventProperties : 4 {
  ADV_IND = 0x3,
  ADV_DIRECT_IND_LOW = 0x5,
  ADV_DIRECT_IND_HIGH = 0xD,
  ADV_SCAN_IND = 0x2,
  ADV_NONCONN_IND = 0,
}

enum PrimaryPhyType : 8 {
  LE_1M = 0x01,
  LE_CODED = 0x03,
}

enum SecondaryPhyType : 8 {
  NO_PACKETS = 0x00,
  LE_1M = 0x01,
  LE_2M = 0x02,
  LE_CODED = 0x03,
}

packet LeSetExtendedAdvertisingParametersLegacy : Command (op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
  advertising_handle : 8,
  legacy_advertising_event_properties : LegacyAdvertisingEventProperties,
  _fixed_ = 0x1 : 1, // legacy bit set
  _reserved_ : 11, // advertising_event_properties reserved bits
  primary_advertising_interval_min : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_interval_max : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_channel_map : 3,  // bit 0 - Channel 37, bit 1 - 38, bit 2 - 39
  _reserved_ : 5,
  own_address_type : OwnAddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  advertising_filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
  advertising_tx_power : 8, // -127 to +20, 0x7F - no preference
  _fixed_ = 0x1 : 8, // PrimaryPhyType LE_1M
  _reserved_ : 8, // secondary_advertising_max_skip
  _fixed_ = 0x1 : 8, // secondary_advertising_phy LE_1M
  advertising_sid : 8, // SID subfield from the ADI field of the PDU
  scan_request_notification_enable : Enable,
}

test LeSetExtendedAdvertisingParametersLegacy {
  "\x36\x20\x19\x00\x13\x00\x90\x01\x00\xc2\x01\x00\x07\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x01\x00\x01\x01\x00",
  "\x36\x20\x19\x01\x13\x00\x90\x01\x00\xc2\x01\x00\x07\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x01\x00\x01\x01\x00",
}

struct AdvertisingEventProperties {
  connectable : 1,
  scannable : 1,
  directed : 1,
  high_duty_cycle : 1,
  legacy : 1,
  anonymous : 1,
  tx_power : 1,
  _reserved_ : 9,
}

packet LeSetExtendedAdvertisingParameters : Command (op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
  advertising_handle : 8,
  advertising_event_properties : AdvertisingEventProperties,
  primary_advertising_interval_min : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_interval_max : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
  primary_advertising_channel_map : 3,  // bit 0 - Channel 37, bit 1 - 38, bit 2 - 39
  _reserved_ : 5,
  own_address_type : OwnAddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  advertising_filter_policy : AdvertisingFilterPolicy,
  _reserved_ : 6,
  advertising_tx_power : 8, // -127 to +20, 0x7F - no preference
  primary_advertising_phy : PrimaryPhyType,
  secondary_advertising_max_skip : 8, // 1 to 255, 0x00 - AUX_ADV_IND sent before next advertising event
  secondary_advertising_phy : SecondaryPhyType,
  advertising_sid : 8, // SID subfield from the ADI field of the PDU
  scan_request_notification_enable : Enable,
}

packet LeSetExtendedAdvertisingParametersComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
  status : ErrorCode,
  selected_tx_power : 8, // -127 to +20
}

enum Operation : 3 {
  INTERMEDIATE_FRAGMENT = 0,
  FIRST_FRAGMENT = 1,
  LAST_FRAGMENT = 2,
  COMPLETE_ADVERTISEMENT = 3,
  UNCHANGED_DATA = 4,
}

enum FragmentPreference : 1 {
  CONTROLLER_MAY_FRAGMENT = 0,
  CONTROLLER_SHOULD_NOT = 1,
}

packet LeSetExtendedAdvertisingData : Command (op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  fragment_preference : FragmentPreference,
  _reserved_ : 7,
  _size_(advertising_data) : 8,
  advertising_data : 8[],
}

test LeSetExtendedAdvertisingData {
  "\x37\x20\x12\x00\x03\x01\x0e\x02\x01\x02\x0a\x09\x50\x69\x78\x65\x6c\x20\x33\x20\x58",
}

packet LeSetExtendedAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
  status : ErrorCode,
}

test LeSetExtendedAdvertisingDataComplete {
  "\x0e\x04\x01\x37\x20\x00",
}

packet LeSetExtendedScanResponseData : Command (op_code = LE_SET_EXTENDED_SCAN_RESPONSE_DATA) {
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  fragment_preference : FragmentPreference,
  _reserved_ : 7,
  _size_(scan_response_data) : 8,
  scan_response_data : 8[],
}

packet LeSetExtendedScanResponseDataComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_SCAN_RESPONSE_DATA) {
  status : ErrorCode,
}

packet LeSetExtendedAdvertisingEnableDisableAll : Command (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  _fixed_ = 0x00 : 8, // Enable::DISABLED
  _fixed_ = 0x00 : 8, // Disable all sets
}

struct EnabledSet {
  advertising_handle : 8,
  duration : 16,
  max_extended_advertising_events : 8,
}

struct DisabledSet {
  advertising_handle : 8,
  _fixed_ = 0x00 : 16, // duration
  _fixed_ = 0x00 : 8, // max_extended_advertising_events
}

packet LeSetExtendedAdvertisingDisable : Command (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  _fixed_ = 0x00 : 8, // Enable::DISABLED
  _count_(disabled_sets) : 8,
  disabled_sets : DisabledSet[],
}

packet LeSetExtendedAdvertisingEnable : Command (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  enable : Enable,
  _count_(enabled_sets) : 8,
  enabled_sets : EnabledSet[],
}

test LeSetExtendedAdvertisingEnable {
  "\x39\x20\x06\x01\x01\x01\x00\x00\x00",
}

test LeSetExtendedAdvertisingDisable {
  "\x39\x20\x06\x00\x01\x01\x00\x00\x00",
}

packet LeSetExtendedAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
  status : ErrorCode,
}

test LeSetExtendedAdvertisingEnableComplete {
  "\x0e\x04\x01\x39\x20\x00",
}

packet LeReadMaximumAdvertisingDataLength : Command (op_code = LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) {
}

packet LeReadMaximumAdvertisingDataLengthComplete : CommandComplete (command_op_code = LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) {
  status : ErrorCode,
  maximum_advertising_data_length : 16,
}

packet LeReadNumberOfSupportedAdvertisingSets : Command (op_code = LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS) {
}

packet LeReadNumberOfSupportedAdvertisingSetsComplete : CommandComplete (command_op_code = LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS) {
  status : ErrorCode,
  number_supported_advertising_sets : 8,
}

packet LeRemoveAdvertisingSet : Command (op_code = LE_REMOVE_ADVERTISING_SET) {
  advertising_handle : 8,
}

test LeRemoveAdvertisingSet {
  "\x3c\x20\x01\x01",
}

packet LeRemoveAdvertisingSetComplete : CommandComplete (command_op_code = LE_REMOVE_ADVERTISING_SET) {
  status : ErrorCode,
}

test LeRemoveAdvertisingSetComplete {
  "\x0e\x04\x01\x3c\x20\x00",
}

packet LeClearAdvertisingSets : Command (op_code = LE_CLEAR_ADVERTISING_SETS) {
}

packet LeClearAdvertisingSetsComplete : CommandComplete (command_op_code = LE_CLEAR_ADVERTISING_SETS) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingParameters : Command (op_code = LE_SET_PERIODIC_ADVERTISING_PARAMETERS) {
  advertising_handle : 8,
  periodic_advertising_interval_min : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
  periodic_advertising_interval_max : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
  _reserved_ : 6,
  include_tx_power : 1,
  _reserved_ : 9,
}

packet LeSetPeriodicAdvertisingParametersComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_PARAMETERS) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingData : Command (op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
  advertising_handle : 8,
  operation : Operation,
  _reserved_ : 5,
  _size_(advertising_data) : 8,
  advertising_data : 8[],
}

packet LeSetPeriodicAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingEnable : Command (op_code = LE_SET_PERIODIC_ADVERTISING_ENABLE) {
  enable : 1,
  include_adi: 1,
  _reserved_: 6,
  advertising_handle : 8,
}

packet LeSetPeriodicAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_ENABLE) {
  status : ErrorCode,
}

struct ScanningPhyParameters {
  le_scan_type : LeScanType,
  le_scan_interval : 16, // 0x0004-0xFFFF Default 0x10 (10ms)
  le_scan_window : 16, // 0x004-0xFFFF Default 0x10 (10ms)
}

packet LeSetExtendedScanParameters : Command (op_code = LE_SET_EXTENDED_SCAN_PARAMETERS) {
  own_address_type : OwnAddressType,
  scanning_filter_policy : LeScanningFilterPolicy,
  scanning_phys : 8,
  scanning_phy_parameters : ScanningPhyParameters[],
}

test LeSetExtendedScanParameters {
  "\x41\x20\x08\x01\x00\x01\x01\x12\x00\x12\x00",
  "\x41\x20\x08\x01\x00\x01\x01\x99\x19\x99\x19",
}

packet LeSetExtendedScanParametersComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_SCAN_PARAMETERS) {
  status : ErrorCode,
}

test LeSetExtendedScanParametersComplete {
  "\x0e\x04\x01\x41\x20\x00",
}

enum FilterDuplicates : 8 {
  DISABLED = 0,
  ENABLED = 1,
  RESET_EACH_PERIOD = 2,
}

packet LeSetExtendedScanEnable : Command (op_code = LE_SET_EXTENDED_SCAN_ENABLE) {
  enable : Enable,
  filter_duplicates : FilterDuplicates,
  duration : 16, // 0 - Scan continuously,  N * 10 ms
  period : 16, // 0 - Scan continuously,  N * 1.28 sec
}

test LeSetExtendedScanEnable {
  "\x42\x20\x06\x01\x00\x00\x00\x00\x00",
  "\x42\x20\x06\x00\x01\x00\x00\x00\x00",
}

packet LeSetExtendedScanEnableComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_SCAN_ENABLE) {
  status : ErrorCode,
}

test LeSetExtendedScanEnableComplete {
  "\x0e\x04\x01\x42\x20\x00",
}

struct InitiatingPhyParameters {
  scan_interval : 16, // 0x0004-0xFFFF
  scan_window : 16, // < = LeScanInterval
  connection_interval_min : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  connection_interval_max : 16, // 0x0006-0x0C80 (7.5ms to 4s)
  max_latency : 16, // 0x0006-0x01F3
  supervision_timeout : 16, // 0x00A to 0x0C80 (100ms to 32s)
  min_ce_length : 16, // 0.625ms
  max_ce_length : 16, // 0.625ms
}

packet LeExtendedCreateConnection : Command (op_code = LE_EXTENDED_CREATE_CONNECTION) {
  initiator_filter_policy : InitiatorFilterPolicy,
  own_address_type : OwnAddressType,
  peer_address_type : PeerAddressType,
  peer_address : Address,
  initiating_phys : 8,
  initiating_phy_parameters : InitiatingPhyParameters[],
}

test LeExtendedCreateConnection {
  "\x43\x20\x2a\x01\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x08\x30\x00\x18\x00\x28\x00\x00\x00\xf4\x01\x00\x00\x00\x00\x00\x08\x30\x00\x18\x00\x28\x00\x00\x00\xf4\x01\x00\x00\x00\x00",
}

packet LeExtendedCreateConnectionStatus : CommandStatus (command_op_code = LE_EXTENDED_CREATE_CONNECTION) {
}

enum PeriodicSyncCteType : 8 {
  AVOID_AOA_CONSTANT_TONE_EXTENSION = 0x01,
  AVOID_AOD_CONSTANT_TONE_EXTENSION_WITH_ONE_US_SLOTS = 0x02,
  AVOID_AOD_CONSTANT_TONE_EXTENSION_WITH_TWO_US_SLOTS = 0x04,
  AVOID_TYPE_THREE_CONSTANT_TONE_EXTENSION = 0x08,
  AVOID_NO_CONSTANT_TONE_EXTENSION = 0x10,
}

struct PeriodicAdvertisingOptions {
  use_periodic_advertiser_list: 1,
  disable_reporting: 1,
  enable_duplicate_filtering: 1,
  _reserved_: 5,
}

enum AdvertiserAddressType : 8 {
  PUBLIC_DEVICE_OR_IDENTITY_ADDRESS = 0x00,
  RANDOM_DEVICE_OR_IDENTITY_ADDRESS = 0x01,
}

packet LePeriodicAdvertisingCreateSync : Command (op_code = LE_PERIODIC_ADVERTISING_CREATE_SYNC) {
  options : PeriodicAdvertisingOptions,
  advertising_sid : 8,
  advertiser_address_type : AdvertiserAddressType,
  advertiser_address : Address,
  skip : 16,
  sync_timeout : 16,
  sync_cte_type : 8,
}

packet LePeriodicAdvertisingCreateSyncStatus : CommandStatus (command_op_code = LE_PERIODIC_ADVERTISING_CREATE_SYNC) {
}

packet LePeriodicAdvertisingCreateSyncCancel : Command (op_code = LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL) {
}

packet LePeriodicAdvertisingCreateSyncCancelComplete : CommandComplete (command_op_code = LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL) {
  status : ErrorCode,
}

packet LePeriodicAdvertisingTerminateSync : Command (op_code = LE_PERIODIC_ADVERTISING_TERMINATE_SYNC) {
  sync_handle : 12,
  _reserved_ : 4,
}

packet LePeriodicAdvertisingTerminateSyncComplete : CommandComplete (command_op_code = LE_PERIODIC_ADVERTISING_TERMINATE_SYNC) {
  status : ErrorCode,
}

packet LeAddDeviceToPeriodicAdvertiserList : Command (op_code = LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST) {
  advertiser_address_type : AdvertiserAddressType,
  advertiser_address : Address,
  advertising_sid : 8,
}

packet LeAddDeviceToPeriodicAdvertiserListComplete : CommandComplete (command_op_code = LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST) {
  status : ErrorCode,
}

packet LeRemoveDeviceFromPeriodicAdvertiserList : Command (op_code = LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST) {
  advertiser_address_type : AdvertiserAddressType,
  advertiser_address : Address,
  advertising_sid : 8,
}

packet LeRemoveDeviceFromPeriodicAdvertiserListComplete : CommandComplete (command_op_code = LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST) {
  status : ErrorCode,
}

packet LeClearPeriodicAdvertiserList : Command (op_code = LE_CLEAR_PERIODIC_ADVERTISER_LIST) {
}

packet LeClearPeriodicAdvertiserListComplete : CommandComplete (command_op_code = LE_CLEAR_PERIODIC_ADVERTISER_LIST) {
  status : ErrorCode,
}

packet LeReadPeriodicAdvertiserListSize : Command (op_code = LE_READ_PERIODIC_ADVERTISER_LIST_SIZE) {
}

packet LeReadPeriodicAdvertiserListSizeComplete : CommandComplete (command_op_code = LE_READ_PERIODIC_ADVERTISER_LIST_SIZE) {
  status : ErrorCode,
  periodic_advertiser_list_size : 8,
}

packet LeReadTransmitPower : Command (op_code = LE_READ_TRANSMIT_POWER) {
}

packet LeReadTransmitPowerComplete : CommandComplete (command_op_code = LE_READ_TRANSMIT_POWER) {
  status : ErrorCode,
  min_tx_power_dbm : 8,
  max_tx_power_dbm : 8,
}

packet LeReadRfPathCompensationPower : Command (op_code = LE_READ_RF_PATH_COMPENSATION_POWER) {
}

packet LeReadRfPathCompensationPowerComplete : CommandComplete (command_op_code = LE_READ_RF_PATH_COMPENSATION_POWER) {
  status : ErrorCode,
  rf_tx_path_compensation_tenths_db : 16,
  rf_rx_path_compensation_tenths_db : 16,
}

packet LeWriteRfPathCompensationPower : Command (op_code = LE_WRITE_RF_PATH_COMPENSATION_POWER) {
  rf_tx_path_compensation_tenths_db : 16,
  rf_rx_path_compensation_tenths_db : 16,
}

packet LeWriteRfPathCompensationPowerComplete : CommandComplete (command_op_code = LE_WRITE_RF_PATH_COMPENSATION_POWER) {
  status : ErrorCode,
}

enum PrivacyMode : 8 {
  NETWORK = 0,
  DEVICE = 1,
}

packet LeSetPrivacyMode : Command (op_code = LE_SET_PRIVACY_MODE) {
  peer_identity_address_type : PeerAddressType,
  peer_identity_address : Address,
  privacy_mode : PrivacyMode,
}

packet LeSetPrivacyModeComplete : CommandComplete (command_op_code = LE_SET_PRIVACY_MODE) {
  status : ErrorCode,
}

packet LeSetPeriodicAdvertisingReceiveEnable : Command (op_code = LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE) {
  sync_handle : 12,
  _reserved_ : 4,
  enable : 8,
}

packet LeSetPeriodicAdvertisingReceiveEnableComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE) {
  status : ErrorCode,
}

packet LePeriodicAdvertisingSyncTransfer : Command (op_code = LE_PERIODIC_ADVERTISING_SYNC_TRANSFER) {
  connection_handle : 12,
  _reserved_ : 4,
  service_data : 16,
  sync_handle: 12,
  _reserved_ : 4,
}

packet LePeriodicAdvertisingSyncTransferComplete : CommandComplete (command_op_code = LE_PERIODIC_ADVERTISING_SYNC_TRANSFER) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LePeriodicAdvertisingSetInfoTransfer : Command (op_code = LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER) {
  connection_handle : 12,
  _reserved_ : 4,
  service_data : 16,
  advertising_handle: 8,
}

packet LePeriodicAdvertisingSetInfoTransferComplete : CommandComplete (command_op_code = LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

enum SyncTransferMode : 8 {
  NO_SYNC = 0,
  SEND_SYNC_RECEIVED_DISABLE_REPORTS = 1,
  SEND_SYNC_RECEIVED_SEND_REPORTS = 2,
}

enum CteType : 8 {
  AOA_CONSTANT_TONE_EXTENSION = 0x00,
  AOD_CONSTANT_TONE_EXTENSION_ONE_US_SLOTS = 0x01,
  AOD_CONSTANT_TONE_EXTENSION_TWO_US_SLOTS = 0x02,
  NO_CONSTANT_TONE_EXTENSION = 0xFF,
}

packet LeSetPeriodicAdvertisingSyncTransferParameters : Command (op_code = LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS) {
  connection_handle : 12,
  _reserved_ : 4,
  mode : SyncTransferMode,
  skip: 16,
  sync_timeout : 16,
  cte_type : CteType,
}

packet LeSetPeriodicAdvertisingSyncTransferParametersComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeSetDefaultPeriodicAdvertisingSyncTransferParameters : Command (op_code = LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS) {
  mode : SyncTransferMode,
  skip: 16,
  sync_timeout : 16,
  cte_type : CteType,
}

packet LeSetDefaultPeriodicAdvertisingSyncTransferParametersComplete : CommandComplete (command_op_code = LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS) {
  status : ErrorCode,
}

enum UseDebugKey : 8 {
  USE_GENERATED_KEY = 0,
  USE_DEBUG_KEY = 1,
}

packet LeGenerateDhkeyCommand : Command (op_code = LE_GENERATE_DHKEY_V2) {
  remote_p_256_public_key : 8[64],
  key_type : UseDebugKey,
}

packet LeGenerateDhkeyCommandStatus : CommandStatus (command_op_code = LE_GENERATE_DHKEY_V2) {
}

enum ScaAction : 8 {
  MORE_ACCURATE_CLOCK = 0,
  LESS_ACCURATE_CLOCK = 1,
}

packet LeModifySleepClockAccuracy : Command (op_code = LE_MODIFY_SLEEP_CLOCK_ACCURACY) {
  action : ScaAction,
}

packet LeModifySleepClockAccuracyComplete : CommandComplete (command_op_code = LE_MODIFY_SLEEP_CLOCK_ACCURACY) {
  status : ErrorCode,
}

packet LeReadBufferSizeV2 : Command (op_code = LE_READ_BUFFER_SIZE_V2) {
}

packet LeReadBufferSizeV2Complete : CommandComplete (command_op_code = LE_READ_BUFFER_SIZE_V2) {
  status : ErrorCode,
  le_buffer_size : LeBufferSize,
  iso_buffer_size : LeBufferSize,
}

packet LeReadIsoTxSync : Command (op_code = LE_READ_ISO_TX_SYNC) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeReadIsoTxSyncComplete : CommandComplete (command_op_code = LE_READ_ISO_TX_SYNC) {
  connection_handle : 12,
  _reserved_ : 4,
  packet_sequence_number : 16,
  timestamp : 32,
  time_offset : 24,
}

struct CisParametersConfig {
  cis_id : 8,
  max_sdu_c_to_p : 12,
  _reserved_ : 4,
  max_sdu_p_to_c : 12,
  _reserved_ : 4,
  phy_c_to_p : 3,
  _reserved_ : 5,
  phy_p_to_c : 3,
  _reserved_ : 5,
  rtn_c_to_p : 4,
  _reserved_ : 4,
  rtn_p_to_c : 4,
  _reserved_ : 4,
}

enum Packing : 8 {
  SEQUENTIAL = 0,
  INTERLEAVED = 1,
}

enum ClockAccuracy : 8 {
  PPM_500 = 0x00,
  PPM_250 = 0x01,
  PPM_150 = 0x02,
  PPM_100 = 0x03,
  PPM_75 = 0x04,
  PPM_50 = 0x05,
  PPM_30 = 0x06,
  PPM_20 = 0x07,
}

packet LeSetCigParameters : Command (op_code = LE_SET_CIG_PARAMETERS) {
  cig_id : 8,
  sdu_interval_c_to_p : 24,
  sdu_interval_p_to_c : 24,
  worst_case_sca: ClockAccuracy,
  packing : Packing,
  framing : Enable,
  max_transport_latency_c_to_p : 16,
  max_transport_latency_p_to_c : 16,
  _count_(cis_config) : 8,
  cis_config : CisParametersConfig[],
}

packet LeSetCigParametersComplete : CommandComplete (command_op_code = LE_SET_CIG_PARAMETERS) {
  status : ErrorCode,
  cig_id : 8,
  _count_(connection_handle) : 8,
  connection_handle : 16[],
}

struct LeCisParametersTestConfig {
  cis_id : 8,
  nse : 8,
  max_sdu_c_to_p : 16,
  max_sdu_p_to_c : 16,
  max_pdu_c_to_p : 16,
  max_pdu_p_to_c : 16,
  phy_c_to_p : 8,
  phy_p_to_c : 8,
  bn_c_to_p : 8,
  bn_p_to_c : 8,
}

packet LeSetCigParametersTest : Command (op_code = LE_SET_CIG_PARAMETERS_TEST) {
  cig_id : 8,
  sdu_interval_c_to_p : 24,
  sdu_interval_p_to_c : 24,
  ft_c_to_p : 8,
  ft_p_to_c : 8,
  iso_interval : 16,
  worst_case_sca: ClockAccuracy,
  packing : Packing,
  framing : Enable,
  _count_(cis_config) : 8,
  cis_config : LeCisParametersTestConfig[],
}

packet LeSetCigParametersTestComplete : CommandComplete (command_op_code = LE_SET_CIG_PARAMETERS_TEST) {
  status : ErrorCode,
  cig_id : 8,
  _count_(connection_handle) : 8,
  connection_handle : 16[],
}

struct LeCreateCisConfig {
  cis_connection_handle : 12,
  _reserved_ : 4,
  acl_connection_handle : 12,
  _reserved_ : 4,
}

packet LeCreateCis : Command (op_code = LE_CREATE_CIS) {
  _count_(cis_config) : 8,
  cis_config : LeCreateCisConfig[],
}

packet LeCreateCisStatus : CommandStatus (command_op_code = LE_CREATE_CIS) {
}

packet LeRemoveCig : Command (op_code = LE_REMOVE_CIG) {
  cig_id : 8,
}

packet LeRemoveCigComplete : CommandComplete (command_op_code = LE_REMOVE_CIG) {
  status : ErrorCode,
  cig_id : 8,
}

packet LeAcceptCisRequest : Command (op_code = LE_ACCEPT_CIS_REQUEST) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeAcceptCisRequestStatus : CommandStatus (command_op_code = LE_ACCEPT_CIS_REQUEST) {
}

packet LeRejectCisRequest : Command (op_code = LE_REJECT_CIS_REQUEST) {
  connection_handle : 12,
  _reserved_ : 4,
  reason : ErrorCode,
}

packet LeRejectCisRequestComplete : CommandComplete (command_op_code = LE_REJECT_CIS_REQUEST) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeCreateBig : Command (op_code = LE_CREATE_BIG) {
  big_handle : 8,
  advertising_handle : 8,
  num_bis : 8,
  sdu_interval : 24,
  max_sdu : 16,
  max_transport_latency : 16,
  rtn : 4,
  _reserved_ : 4,
  phy : SecondaryPhyType,
  packing : Packing,
  framing : Enable,
  encryption : Enable,
  broadcast_code: 8[16],
}

packet LeCreateBigStatus : CommandStatus (command_op_code = LE_CREATE_BIG) {
}

packet LeTerminateBig : Command (op_code = LE_TERMINATE_BIG) {
  big_handle : 8,
  reason : ErrorCode,
}

packet LeTerminateBigStatus : CommandStatus (command_op_code = LE_TERMINATE_BIG) {
}

packet LeBigCreateSync : Command (op_code = LE_BIG_CREATE_SYNC) {
  big_handle : 8,
  sync_handle : 12,
  _reserved_ : 4,
  encryption : Enable,
  broadcast_code : 8[16],
  mse : 5,
  _reserved_ : 3,
  big_sync_timeout : 16,
  _count_(bis) : 8,
  bis : 8[],
}

packet LeBigCreateSyncStatus : CommandStatus (command_op_code = LE_BIG_CREATE_SYNC) {
}

packet LeBigTerminateSync : Command (op_code = LE_BIG_TERMINATE_SYNC) {
  big_handle : 8,
}

packet LeBigTerminateSyncComplete : CommandComplete (command_op_code = LE_BIG_TERMINATE_SYNC) {
  status : ErrorCode,
  big_handle : 8,
}

packet LeRequestPeerSca : Command (op_code = LE_REQUEST_PEER_SCA) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeRequestPeerScaStatus : CommandStatus (command_op_code = LE_REQUEST_PEER_SCA) {
}

packet LeSetupIsoDataPath : Command (op_code = LE_SETUP_ISO_DATA_PATH) {
  connection_handle : 12,
  _reserved_ : 4,
  data_path_direction : DataPathDirection,
  data_path_id : 8,
  codec_id : 40,
  controller_delay : 24,
  _count_(codec_configuration) : 8,
  codec_configuration : 8[],
}

packet LeSetupIsoDataPathComplete : CommandComplete (command_op_code = LE_SETUP_ISO_DATA_PATH) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

enum RemoveDataPathDirection : 8 {
  INPUT = 1,
  OUTPUT = 2,
  INPUT_AND_OUTPUT = 3,
}

packet LeRemoveIsoDataPath : Command (op_code = LE_REMOVE_ISO_DATA_PATH) {
  connection_handle : 12,
  _reserved_ : 4,
  remove_data_path_direction : RemoveDataPathDirection,
}

packet LeRemoveIsoDataPathComplete : CommandComplete (command_op_code = LE_REMOVE_ISO_DATA_PATH) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

enum LeHostFeatureBits : 8 {
  CONNECTED_ISO_STREAM_HOST_SUPPORT = 32,
  CONNECTION_SUBRATING_HOST_SUPPORT = 38,
}

packet LeSetHostFeature : Command (op_code = LE_SET_HOST_FEATURE) {
  bit_number : LeHostFeatureBits,
  bit_value:  Enable,
}

packet LeSetHostFeatureComplete : CommandComplete (command_op_code = LE_SET_HOST_FEATURE) {
  status : ErrorCode,
}

packet LeReadIsoLinkQuality : Command (op_code = LE_READ_ISO_LINK_QUALITY) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeReadIsoLinkQualityComplete : CommandComplete (command_op_code = LE_READ_ISO_LINK_QUALITY) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  tx_unacked_packets : 32,
  tx_flushed_packets : 32,
  tx_last_subevent_packets : 32,
  retransmitted_packets : 32,
  crc_error_packets : 32,
  rx_unreceived_packets : 32,
  duplicate_packets : 32,
}

packet LeEnhancedReadTransmitPowerLevel : Command (op_code = LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL) {
  connection_handle : 12,
  _reserved_ : 4,
  phy : 8,
}

enum PhyWithCodedSpecified : 8 {
  LE_1M = 1,
  LE_2M = 2,
  LE_CODED_S_8 = 3,
  LE_CODED_S_2 = 4,
}

packet LeEnhancedReadTransmitPowerLevelComplete : CommandComplete (command_op_code = LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  phy : PhyWithCodedSpecified,
  current_transmit_power_level : 8,
  max_transmit_power_level : 8,
}

packet LeReadRemoteTransmitPowerLevel : Command (op_code = LE_READ_REMOTE_TRANSMIT_POWER_LEVEL) {
  connection_handle : 12,
  _reserved_ : 4,
  phy : 8,
}

packet LeReadRemoteTransmitPowerLevelStatus : CommandStatus (command_op_code = LE_READ_REMOTE_TRANSMIT_POWER_LEVEL) {
}

packet LeSetPathLossReportingParameters : Command (op_code = LE_SET_PATH_LOSS_REPORTING_PARAMETERS) {
  connection_handle : 12,
  _reserved_ : 4,
  high_threshold : 8,
  high_hysteresis : 8,
  low_threshold : 8,
  low_hysteresis : 8,
  min_time_spent : 16,
}

packet LeSetPathLossReportingParametersComplete : CommandComplete (command_op_code = LE_SET_PATH_LOSS_REPORTING_PARAMETERS) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeSetPathLossReportingEnable : Command (op_code = LE_SET_PATH_LOSS_REPORTING_ENABLE) {
  connection_handle : 12,
  _reserved_ : 4,
  enable : 8,
}

packet LeSetPathLossReportingEnableComplete : CommandComplete (command_op_code = LE_SET_PATH_LOSS_REPORTING_ENABLE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeSetTransmitPowerReportingEnable : Command (op_code = LE_SET_TRANSMIT_POWER_REPORTING_ENABLE) {
  connection_handle : 12,
  _reserved_ : 4,
  local_enable : 8,
  remote_enable : 8,
}

packet LeSetTransmitPowerReportingEnableComplete : CommandComplete (command_op_code = LE_SET_TRANSMIT_POWER_REPORTING_ENABLE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet LeSetDataRelatedAddressChanges : Command (op_code = LE_SET_DATA_RELATED_ADDRESS_CHANGES) {
  advertising_handle : 8,
  change_reasons : 8,
}

packet LeSetDataRelatedAddressChangesComplete : CommandComplete (command_op_code = LE_SET_DATA_RELATED_ADDRESS_CHANGES) {
  status : ErrorCode,
}

packet LeSetDefaultSubrate : Command (op_code = LE_SET_DEFAULT_SUBRATE) {
  subrate_min : 9,
  _reserved_ : 7,
  subrate_max : 9,
  _reserved_ : 7,
  max_latency : 9,
  _reserved_ : 7,
  continuation_number : 9,
  _reserved_ : 7,
  supervision_timeout: 12,
  _reserved_ : 4,
}

packet LeSetDefaultSubrateComplete : CommandComplete (command_op_code = LE_SET_DEFAULT_SUBRATE) {
  status : ErrorCode,
}

packet LeSubrateRequest : Command (op_code = LE_SUBRATE_REQUEST) {
  connection_handle : 12,
  _reserved_ : 4,
  subrate_min : 9,
  _reserved_ : 7,
  subrate_max : 9,
  _reserved_ : 7,
  max_latency : 9,
  _reserved_ : 7,
  continuation_number : 9,
  _reserved_ : 7,
  supervision_timeout: 12,
  _reserved_ : 4,
}

packet LeSubrateRequestStatus : CommandStatus (command_op_code = LE_SUBRATE_REQUEST) {
}

// HCI Event Packets

packet InquiryComplete : Event (event_code = INQUIRY_COMPLETE) {
  status : ErrorCode,
}

struct InquiryResponse {
  bd_addr : Address,
  page_scan_repetition_mode : PageScanRepetitionMode,
  _reserved_ : 8,
  _reserved_ : 8,
  class_of_device : 24,
  clock_offset : 15,
  _reserved_ : 1,
}

packet InquiryResult : Event (event_code = INQUIRY_RESULT) {
  _count_(responses) : 8,
  responses : InquiryResponse[],
}

enum LinkType : 8 {
  SCO = 0x00,
  ACL = 0x01,
}

packet ConnectionComplete : Event (event_code = CONNECTION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  bd_addr : Address,
  link_type : LinkType,
  encryption_enabled : Enable,
}

enum ConnectionRequestLinkType : 8 {
  UNKNOWN = 0xFF,
  SCO = 0x00,
  ACL = 0x01,
  ESCO = 0x02,
}

packet ConnectionRequest : Event (event_code = CONNECTION_REQUEST) {
  bd_addr : Address,
  class_of_device : 24,
  link_type : ConnectionRequestLinkType,
}

packet DisconnectionComplete : Event (event_code = DISCONNECTION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  reason : ErrorCode,
}

packet AuthenticationComplete : Event (event_code = AUTHENTICATION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet RemoteNameRequestComplete : Event (event_code = REMOTE_NAME_REQUEST_COMPLETE) {
  status : ErrorCode,
  bd_addr : Address,
  remote_name : 8[248], // UTF-8 encoded user-friendly descriptive name
}

enum EncryptionEnabled : 8 {
  OFF = 0x00,
  ON = 0x01, // E0 for BR/EDR and AES-CCM for LE
  BR_EDR_AES_CCM = 0x02,
}

packet EncryptionChange : Event (event_code = ENCRYPTION_CHANGE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  encryption_enabled : EncryptionEnabled,
}

packet ChangeConnectionLinkKeyComplete : Event (event_code = CHANGE_CONNECTION_LINK_KEY_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet CentralLinkKeyComplete : Event (event_code = CENTRAL_LINK_KEY_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  key_flag : KeyFlag,
}

packet ReadRemoteSupportedFeaturesComplete : Event (event_code = READ_REMOTE_SUPPORTED_FEATURES_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  lmp_features : 64,
}

packet ReadRemoteVersionInformationComplete : Event (event_code = READ_REMOTE_VERSION_INFORMATION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  version : 8,
  manufacturer_name : 16,
  sub_version : 16,
}

packet QosSetupComplete : Event (event_code = QOS_SETUP_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  _reserved_ : 8,
  service_type : ServiceType,
  token_rate : 32, // Octets/s
  peak_bandwidth : 32, // Octets/s
  latency : 32, // Octets/s
  delay_variation : 32, // microseconds
}

// Command Complete and Command Status Events are implemented above Commands.

packet HardwareError : Event (event_code = HARDWARE_ERROR) {
  hardware_code : 8,
}

packet FlushOccurred : Event (event_code = FLUSH_OCCURRED) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet RoleChange : Event (event_code = ROLE_CHANGE) {
  status : ErrorCode,
  bd_addr : Address,
  new_role : Role,
}

packet NumberOfCompletedPackets : Event (event_code = NUMBER_OF_COMPLETED_PACKETS) {
  _count_(completed_packets) : 8,
  completed_packets : CompletedPackets[],
}

enum Mode : 8 {
  ACTIVE = 0x00,
  HOLD = 0x01,
  SNIFF = 0x02,
}

packet ModeChange : Event (event_code = MODE_CHANGE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  current_mode : Mode,
  interval : 16, // 0x002 - 0xFFFE (1.25ms - 40.9s)
}

struct ZeroKeyAndAddress {
  address : Address,
  _fixed_ = 0 : 64,
  _fixed_ = 0 : 64,
}

packet ReturnLinkKeys : Event (event_code = RETURN_LINK_KEYS) {
  _count_(keys) : 8,
  keys : ZeroKeyAndAddress[],
}

packet PinCodeRequest : Event (event_code = PIN_CODE_REQUEST) {
  bd_addr : Address,
}

packet LinkKeyRequest : Event (event_code = LINK_KEY_REQUEST) {
  bd_addr : Address,
}

enum KeyType : 8 {
  COMBINATION = 0x00,
  DEBUG_COMBINATION = 0x03,
  UNAUTHENTICATED_P192 = 0x04,
  AUTHENTICATED_P192 = 0x05,
  CHANGED = 0x06,
  UNAUTHENTICATED_P256 = 0x07,
  AUTHENTICATED_P256 = 0x08,
}

packet LinkKeyNotification : Event (event_code = LINK_KEY_NOTIFICATION) {
  bd_addr : Address,
  link_key : 8[16],
  key_type : KeyType,
}

packet LoopbackCommand : Event (event_code = LOOPBACK_COMMAND) {
  _payload_, // Command packet, truncated if it was longer than 252 bytes
}

packet DataBufferOverflow : Event (event_code = DATA_BUFFER_OVERFLOW) {
  link_type : LinkType,
}

packet MaxSlotsChange : Event (event_code = MAX_SLOTS_CHANGE) {
  connection_handle : 12,
  _reserved_ : 4,
  lmp_max_slots : 8,
}

packet ReadClockOffsetComplete : Event (event_code = READ_CLOCK_OFFSET_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  clock_offset : 15,
  _reserved_ : 1,
}

packet ConnectionPacketTypeChanged : Event (event_code = CONNECTION_PACKET_TYPE_CHANGED) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  packet_type : 16,
}

packet QosViolation : Event (event_code = QOS_VIOLATION) {
  connection_handle : 12,
  _reserved_ : 4,
}

packet PageScanRepetitionModeChange : Event (event_code = PAGE_SCAN_REPETITION_MODE_CHANGE) {
  bd_addr : Address,
  page_scan_repetition_mode : PageScanRepetitionMode,
}

packet FlowSpecificationComplete : Event (event_code = FLOW_SPECIFICATION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  _reserved_ : 8,
  flow_direction : FlowDirection,
  service_type : ServiceType,
  token_rate : 32, // Octets/s
  token_bucket_size : 32,
  peak_bandwidth : 32, // Octets/s
  access_latency : 32, // Octets/s
}

struct InquiryResponseWithRssi {
  address : Address,
  page_scan_repetition_mode : PageScanRepetitionMode,
  _reserved_ : 8,
  class_of_device : 24,
  clock_offset : 15,
  _reserved_ : 1,
  rssi : 8,
}

packet InquiryResultWithRssi : Event (event_code = INQUIRY_RESULT_WITH_RSSI) {
  _count_(responses) : 8,
  responses : InquiryResponseWithRssi[],
}

packet ReadRemoteExtendedFeaturesComplete : Event (event_code = READ_REMOTE_EXTENDED_FEATURES_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  page_number : 8,
  maximum_page_number : 8,
  extended_lmp_features : 64,
}

enum ScoLinkType : 8 {
  SCO = 0x00,
  ESCO = 0x02,
}

enum ScoAirMode : 8 {
  ULAW_LOG = 0x00,
  ALAW_LOG = 0x01,
  CVSD = 0x02,
  TRANSPARENT = 0x03,
}

packet SynchronousConnectionComplete : Event (event_code = SYNCHRONOUS_CONNECTION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
   _reserved_ : 4,
  bd_addr : Address,
  link_type : ScoLinkType,
  // Time between two consecutive eSCO instants measured in slots.
  // eSCO only, Shall be zero for SCO links.
  transmission_interval_slots : 8,
  // The size of the retransmission window measured in slots.
  // eSCO only. Shall be zero for SCO links.
  retransmission_window_slots : 8,
  // Length in bytes of the eSCO payload in the receive direction.
  // eSCO only. Shall be zero for SCO links.
  rx_packet_length : 16,
  // Length in bytes of the eSCO payload in the transmit direction.
  // eSCO only. Shall be zero for SCO links.
  tx_packet_length : 16,
  air_mode : ScoAirMode,
}

test SynchronousConnectionComplete {
  "\x2c\x11\x00\x03\x00\x1d\xdf\xed\x2b\x1a\xf8\x02\x0c\x04\x3c\x00\x3c\x00\x03",
}

packet SynchronousConnectionChanged : Event (event_code = SYNCHRONOUS_CONNECTION_CHANGED) {
  status : ErrorCode,
  connection_handle : 12,
   _reserved_ : 4,
  // Time between two consecutive eSCO instants measured in slots.
  // eSCO only, Shall be zero for SCO links.
  transmission_interval_slots : 8,
  // Time between two consecutive SCO/eSCO instants measured in slots.
  retransmission_window_slots : 8,
  // Length in bytes of the SCO/eSCO payload in the receive direction.
  rx_packet_length : 16,
  // Length in bytes of the SCO/eSCO payload in the transmit direction.
  tx_packet_length : 16,
}

packet SniffSubratingEvent : Event (event_code = SNIFF_SUBRATING) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  maximum_transmit_latency : 16, // 0x000 - 0xFFFE (0s - 40.9s)
  maximum_receive_latency : 16, // 0x000 - 0xFFFE (0s - 40.9s)
  minimum_remote_timeout : 16, // 0x000 - 0xFFFE (0s - 40.9s)
  minimum_local_timeout : 16, // 0x000 - 0xFFFE (0s - 40.9s)
}

packet ExtendedInquiryResult : Event (event_code = EXTENDED_INQUIRY_RESULT) {
  _fixed_ = 0x01 : 8,
  address : Address,
  page_scan_repetition_mode : PageScanRepetitionMode,
  _reserved_ : 8,
  class_of_device : 24,
  clock_offset : 15,
  _reserved_ : 1,
  rssi : 8,
  // Extended inquiry Result is always 255 bytes long;
  // the gap data is padded with zeros as necessary.
  // Refer to BLUETOOTH CORE SPECIFICATION Version 5.2 | Vol 3, Part C Section 8 on page 1340
  extended_inquiry_response : 8[240],
}

packet EncryptionKeyRefreshComplete : Event (event_code = ENCRYPTION_KEY_REFRESH_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
}

packet IoCapabilityRequest : Event (event_code = IO_CAPABILITY_REQUEST) {
  bd_addr : Address,
}

packet IoCapabilityResponse : Event (event_code = IO_CAPABILITY_RESPONSE) {
  bd_addr : Address,
  io_capability : IoCapability,
  oob_data_present : OobDataPresent,
  authentication_requirements : AuthenticationRequirements,
}

packet UserConfirmationRequest : Event (event_code = USER_CONFIRMATION_REQUEST) {
  bd_addr : Address,
  numeric_value : 20, // 0x00000-0xF423F (000000 - 999999)
  _reserved_ : 12,
}

packet UserPasskeyRequest : Event (event_code = USER_PASSKEY_REQUEST) {
  bd_addr : Address,
}

packet RemoteOobDataRequest : Event (event_code = REMOTE_OOB_DATA_REQUEST) {
  bd_addr : Address,
}

packet SimplePairingComplete : Event (event_code = SIMPLE_PAIRING_COMPLETE) {
  status : ErrorCode,
  bd_addr : Address,
}

packet LinkSupervisionTimeoutChanged : Event (event_code = LINK_SUPERVISION_TIMEOUT_CHANGED) {
  connection_handle : 12,
  _reserved_ : 4,
  link_supervision_timeout : 16, // 0x001-0xFFFF (0.625ms-40.9s)
}

enum FlushablePacketType : 8 {
  AUTOMATICALLY_FLUSHABLE_ONLY = 0,
}

packet EnhancedFlush : Command (op_code = ENHANCED_FLUSH) {
  connection_handle : 12,
  _reserved_ : 4,
  packet_type : FlushablePacketType,
}

test EnhancedFlush {
  "\x5f\x0c\x03\x02\x00\x00",
}

packet EnhancedFlushStatus : CommandStatus (command_op_code = ENHANCED_FLUSH) {
}

packet EnhancedFlushComplete : Event (event_code = ENHANCED_FLUSH_COMPLETE) {
  connection_handle : 12,
  _reserved_ : 4,
}

test EnhancedFlushComplete {
  "\x39\x02\x02\x00",
}

packet UserPasskeyNotification : Event (event_code = USER_PASSKEY_NOTIFICATION) {
  bd_addr : Address,
  passkey : 20, // 0x00000-0xF423F (000000 - 999999)
  _reserved_ : 12,
}

packet KeypressNotification : Event (event_code = KEYPRESS_NOTIFICATION) {
  bd_addr : Address,
  notification_type : KeypressNotificationType,
}

packet RemoteHostSupportedFeaturesNotification : Event (event_code = REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION) {
  bd_addr : Address,
  host_supported_features : 64,
}

packet LeMetaEvent : Event (event_code = LE_META_EVENT) {
  subevent_code : SubeventCode,
  _body_,
}

packet NumberOfCompletedDataBlocks : Event (event_code = NUMBER_OF_COMPLETED_DATA_BLOCKS) {
  total_num_data_blocks : 16,
  _payload_, // placeholder (unimplemented)
}

// LE Events
packet LeConnectionComplete : LeMetaEvent (subevent_code = CONNECTION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  role : Role,
  peer_address_type : AddressType,
  peer_address : Address,
  connection_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
  peripheral_latency : 16,
  supervision_timeout : 16,  // 0x000A to 0x0C80 (100ms to 32s)
  central_clock_accuracy : ClockAccuracy,
}

enum AdvertisingEventType : 8 {
  ADV_IND = 0x00,
  ADV_DIRECT_IND = 0x01,
  ADV_SCAN_IND = 0x02,
  ADV_NONCONN_IND = 0x03,
  SCAN_RESPONSE = 0x04,
}

struct LeAdvertisingResponse {
  event_type : AdvertisingEventType,
  address_type : AddressType,
  address : Address,
  _size_(advertising_data) : 8,
  advertising_data : 8[],
  rssi : 8,
}

packet LeAdvertisingReport : LeMetaEvent (subevent_code = ADVERTISING_REPORT) {
  _count_(responses) : 8,
  responses : LeAdvertisingResponse[],
}

packet LeConnectionUpdateComplete : LeMetaEvent (subevent_code = CONNECTION_UPDATE_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  connection_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
  peripheral_latency : 16,  // Number of connection events
  supervision_timeout : 16,  // 0x000A to 0x0C80 (100ms to 32s)
}

packet LeReadRemoteFeaturesComplete : LeMetaEvent (subevent_code = READ_REMOTE_FEATURES_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  le_features : 64,
}

packet LeLongTermKeyRequest : LeMetaEvent (subevent_code = LONG_TERM_KEY_REQUEST) {
  connection_handle : 12,
  _reserved_ : 4,
  random_number : 8[8],
  encrypted_diversifier : 16,
}

packet LeRemoteConnectionParameterRequest : LeMetaEvent (subevent_code = REMOTE_CONNECTION_PARAMETER_REQUEST) {
  connection_handle : 12,
  _reserved_ : 4,
  interval_min : 16, // 0x006 - 0x0C80 (7.5ms - 4s)
  interval_max : 16, // 0x006 - 0x0C80 (7.5ms - 4s)
  latency : 16,  // Number of connection events (0x0000 to 0x01f3 (499)
  timeout : 16,  // 0x000A to 0x0C80 (100ms to 32s)
}

packet LeDataLengthChange : LeMetaEvent (subevent_code = DATA_LENGTH_CHANGE) {
  connection_handle : 12,
  _reserved_ : 4,
  max_tx_octets : 16, // 0x001B - 0x00FB
  max_tx_time : 16, // 0x0148 - 0x4290
  max_rx_octets : 16, // 0x001B - 0x00FB
  max_rx_time : 16, // 0x0148 - 0x4290
}

packet ReadLocalP256PublicKeyComplete : LeMetaEvent (subevent_code = READ_LOCAL_P256_PUBLIC_KEY_COMPLETE) {
  status : ErrorCode,
  local_p_256_public_key : 8[64],
}

packet GenerateDhKeyComplete : LeMetaEvent (subevent_code = GENERATE_DHKEY_COMPLETE) {
  status : ErrorCode,
  dh_key : 8[32],
}

packet LeEnhancedConnectionComplete : LeMetaEvent (subevent_code = ENHANCED_CONNECTION_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  role : Role,
  peer_address_type : AddressType,
  peer_address : Address,
  local_resolvable_private_address : Address,
  peer_resolvable_private_address : Address,
  connection_interval : 16, // 0x006 - 0x0C80 (7.5ms - 4000ms)
  peripheral_latency : 16,
  supervision_timeout : 16,  // 0x000A to 0x0C80 (100ms to 32s)
  central_clock_accuracy : ClockAccuracy,
}

enum DirectAdvertisingAddressType : 8 {
  PUBLIC_DEVICE_ADDRESS = 0x00,
  RANDOM_DEVICE_ADDRESS = 0x01,
  PUBLIC_IDENTITY_ADDRESS = 0x02,
  RANDOM_IDENTITY_ADDRESS = 0x03,
  CONTROLLER_UNABLE_TO_RESOLVE = 0xFE,
  NO_ADDRESS_PROVIDED = 0xFF,
}

enum DirectAdvertisingEventType : 8 {
  ADV_DIRECT_IND = 0x01,
}

enum DirectAddressType : 8 {
  RANDOM_DEVICE_ADDRESS = 0x01,
}

struct LeDirectedAdvertisingResponse {
  event_type : DirectAdvertisingEventType,
  address_type : DirectAdvertisingAddressType,
  address : Address,
  direct_address_type : DirectAddressType,
  direct_address : Address,
  rssi : 8,
}

packet LeDirectedAdvertisingReport : LeMetaEvent (subevent_code = DIRECTED_ADVERTISING_REPORT) {
  _count_(responses) : 8,
  responses : LeDirectedAdvertisingResponse[],
}

packet LePhyUpdateComplete : LeMetaEvent (subevent_code = PHY_UPDATE_COMPLETE) {
    status : ErrorCode,
    connection_handle : 12,
    _reserved_ : 4,
    tx_phy : PhyType,
    rx_phy : PhyType,
}

enum DataStatus : 2 {
  COMPLETE = 0x0,
  CONTINUING = 0x1,
  TRUNCATED = 0x2,
  RESERVED = 0x3,
}

struct LeExtendedAdvertisingResponse {
  connectable : 1,
  scannable : 1,
  directed : 1,
  scan_response : 1,
  legacy : 1,
  data_status : DataStatus,
  _reserved_ : 9,
  address_type : DirectAdvertisingAddressType,
  address : Address,
  primary_phy : PrimaryPhyType,
  secondary_phy : SecondaryPhyType,
  advertising_sid : 8, // SID subfield in the ADI field
  tx_power : 8,
  rssi : 8, // -127 to +20 (0x7F means not available)
  periodic_advertising_interval : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
  direct_address_type : DirectAdvertisingAddressType,
  direct_address : Address,
  _size_(advertising_data) : 8,
  advertising_data: 8[],
}

packet LeExtendedAdvertisingReport : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {
  _count_(responses) : 8,
  responses : LeExtendedAdvertisingResponse[],
}

packet LePeriodicAdvertisingSyncEstablished : LeMetaEvent (subevent_code = PERIODIC_ADVERTISING_SYNC_ESTABLISHED) {
  status : ErrorCode,
  sync_handle : 12,
  _reserved_ : 4,
  advertising_sid : 8,
  advertiser_address_type : AddressType,
  advertiser_address : Address,
  advertiser_phy : SecondaryPhyType,
  periodic_advertising_interval : 16,
  advertiser_clock_accuracy : ClockAccuracy,
}

packet LePeriodicAdvertisingReport : LeMetaEvent (subevent_code = PERIODIC_ADVERTISING_REPORT) {
  sync_handle : 12,
  _reserved_ : 4,
  tx_power : 8,
  rssi : 8,
  cte_type : CteType,
  data_status : DataStatus,
  _reserved_: 6,
  _size_(data) : 8,
  data : 8[],
}

packet LePeriodicAdvertisingSyncLost : LeMetaEvent (subevent_code = PERIODIC_ADVERTISING_SYNC_LOST) {
  sync_handle : 12,
  _reserved_ : 4,
}

packet LeScanTimeout : LeMetaEvent (subevent_code = SCAN_TIMEOUT) {
}

packet LeAdvertisingSetTerminated : LeMetaEvent (subevent_code = ADVERTISING_SET_TERMINATED) {
  status : ErrorCode,
  advertising_handle : 8,
  connection_handle : 12,
  _reserved_ : 4,
  num_completed_extended_advertising_events : 8,
}

packet LeScanRequestReceived : LeMetaEvent (subevent_code = SCAN_REQUEST_RECEIVED) {
  advertising_handle : 8,
  scanner_address_type : AddressType,
  scanner_address : Address,
}

enum ChannelSelectionAlgorithm : 8 {
  ALGORITHM_1 = 0,
  ALGORITHM_2 = 1,
}

packet LeChannelSelectionAlgorithm : LeMetaEvent (subevent_code = CHANNEL_SELECTION_ALGORITHM) {
  connection_handle : 12,
  _reserved_ : 4,
  channel_selection_algorithm : ChannelSelectionAlgorithm,
}

packet LeConnectionlessIqReport : LeMetaEvent (subevent_code = CONNECTIONLESS_IQ_REPORT) {
  _payload_, // placeholder (unimplemented)
}

packet LeConnectionIqReport : LeMetaEvent (subevent_code = CONNECTION_IQ_REPORT) {
  _payload_, // placeholder (unimplemented)
}

packet LeCteRequestFailed : LeMetaEvent (subevent_code = CTE_REQUEST_FAILED) {
  _payload_, // placeholder (unimplemented)
}

packet LePeriodicAdvertisingSyncTransferReceived : LeMetaEvent (subevent_code = PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  service_data : 16,
  sync_handle : 12,
  _reserved_ : 4,
  advertising_sid : 4,
  _reserved_ : 4,
  advertiser_address_type : AddressType,
  advertiser_address : Address,
  advertiser_phy : SecondaryPhyType,
  periodic_advertising_interval : 16,
  advertiser_clock_accuracy : ClockAccuracy,
}

packet LeCisEstablished : LeMetaEvent (subevent_code = CIS_ESTABLISHED) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  cig_sync_delay : 24,
  cis_sync_delay : 24,
  transport_latency_c_to_p : 24,
  transport_latency_p_to_c : 24,
  phy_c_to_p : SecondaryPhyType,
  phy_p_to_c : SecondaryPhyType,
  nse : 8,
  bn_c_to_p : 4,
  _reserved_ : 4,
  bn_p_to_c : 4,
  _reserved_ : 4,
  ft_c_to_p : 8,
  ft_p_to_c : 8,
  max_pdu_c_to_p : 8,
  _reserved_ : 8,
  max_pdu_p_to_c : 8,
  _reserved_ : 8,
  iso_interval : 16,
}

packet LeCisRequest : LeMetaEvent (subevent_code = CIS_REQUEST) {
  acl_connection_handle : 12,
  _reserved_ : 4,
  cis_connection_handle : 12,
  _reserved_ : 4,
  cig_id : 8,
  cis_id : 8,
}

packet LeCreateBigComplete : LeMetaEvent (subevent_code = CREATE_BIG_COMPLETE) {
  status : ErrorCode,
  big_handle : 8,
  big_sync_delay : 24,
  transport_latency_big: 24,
  phy : SecondaryPhyType,
  nse : 8,
  bn : 8,
  pto : 8,
  irc : 8,
  max_pdu : 16,
  iso_interval : 16,
  _size_(connection_handle) : 8,
  connection_handle : 16[],
}

packet LeTerminateBigComplete : LeMetaEvent (subevent_code = TERMINATE_BIG_COMPLETE) {
  big_handle : 8,
  reason : ErrorCode,
}

packet LeBigSyncEstablished : LeMetaEvent (subevent_code = BIG_SYNC_ESTABLISHED) {
  status : ErrorCode,
  big_handle : 8,
  transport_latency_big : 24,
  nse : 8,
  bn : 8,
  pto : 8,
  irc : 8,
  max_pdu : 16,
  iso_interval : 16,
  _size_(connection_handle) : 8,
  connection_handle : 16[],
}

packet LeBigSyncLost : LeMetaEvent (subevent_code = BIG_SYNC_LOST) {
  big_handle : 8,
  reason : ErrorCode,
}

packet LeRequestPeerScaComplete : LeMetaEvent (subevent_code = REQUEST_PEER_SCA_COMPLETE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  peer_clock_accuracy : ClockAccuracy,
}

enum PathLossZone : 8 {
  LOW = 0,
  MID = 1,
  HIGH = 2,
}

packet LePathLossThreshold : LeMetaEvent (subevent_code = PATH_LOSS_THRESHOLD) {
  connection_handle : 12,
  _reserved_ : 4,
  current_path_loss : 8,
  zone_entered : PathLossZone,
}

enum ReportingReason : 8 {
  LOCAL_TRANSMIT_POWER_CHANGED = 0x00,
  REMOTE_TRANSMIT_POWER_CHANGED = 0x01,
  READ_COMMAND_COMPLETE = 0x02,
}

packet LeTransmitPowerReporting : LeMetaEvent (subevent_code = TRANSMIT_POWER_REPORTING) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  reason : ReportingReason,
  phy : 8,
  transmit_power_level : 8,
  transmit_power_level_flag : 8,
  delta : 8,
}

packet LeBigInfoAdvertisingReport : LeMetaEvent (subevent_code = BIG_INFO_ADVERTISING_REPORT) {
  sync_handle : 12,
  _reserved_ : 4,
  num_bis : 8,
  nse : 8,
  iso_interval : 16,
  bn : 8,
  pto : 8,
  irc : 8,
  max_pdu : 16,
  sdu_interval : 24,
  max_sdu : 16,
  phy : SecondaryPhyType,
  framing : Enable,
  encryption : Enable,
}

packet LeSubrateChange : LeMetaEvent (subevent_code = LE_SUBRATE_CHANGE) {
  status : ErrorCode,
  connection_handle : 12,
  _reserved_ : 4,
  subrate_factor : 9,
  _reserved_ : 7,
  peripheral_latency : 9,
  _reserved_ : 7,
  continuation_number : 9,
  _reserved_ : 7,
  supervision_timeout: 12,
  _reserved_ : 4,
}

enum IsoPacketBoundaryFlag : 2 {
  FIRST_FRAGMENT = 0,
  CONTINUATION_FRAGMENT = 1,
  COMPLETE_SDU = 2,
  LAST_FRAGMENT = 3,
}

enum TimeStampFlag : 1 {
  NOT_PRESENT = 0,
  PRESENT = 1,
}

packet Iso {
  connection_handle : 12,
  pb_flag : IsoPacketBoundaryFlag,
  ts_flag : TimeStampFlag,
  _reserved_ : 1,
  _size_(_payload_) : 14,
  _reserved_ : 2,
  _payload_,
}

enum IsoPacketStatusFlag : 2 {
  VALID = 0,
  POSSIBLY_INVALID = 1,
  LOST_DATA = 2,
}

packet IsoWithTimestamp : Iso (ts_flag = PRESENT) {
  time_stamp : 32,
  packet_sequence_number : 16,
  iso_sdu_length : 12,
  _reserved_ : 2,
  packet_status_flag : IsoPacketStatusFlag,
  _payload_,
}

packet IsoWithoutTimestamp : Iso (ts_flag = NOT_PRESENT) {
  packet_sequence_number : 16,
  iso_sdu_length : 12,
  _reserved_ : 2,
  packet_status_flag : IsoPacketStatusFlag,
  _payload_,
}

// https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
enum GapDataType : 8 {
  INVALID = 0x00,
  FLAGS = 0x01,
  INCOMPLETE_LIST_16_BIT_UUIDS = 0x02,
  COMPLETE_LIST_16_BIT_UUIDS = 0x03,
  INCOMPLETE_LIST_32_BIT_UUIDS = 0x04,
  COMPLETE_LIST_32_BIT_UUIDS = 0x05,
  INCOMPLETE_LIST_128_BIT_UUIDS = 0x06,
  COMPLETE_LIST_128_BIT_UUIDS = 0x07,
  SHORTENED_LOCAL_NAME = 0x08,
  COMPLETE_LOCAL_NAME = 0x09,
  TX_POWER_LEVEL = 0x0A,
  CLASS_OF_DEVICE = 0x0D,
  SIMPLE_PAIRING_HASH_C = 0x0E,
  SIMPLE_PAIRING_RANDOMIZER_R = 0x0F,
  DEVICE_ID = 0x10,
  SECURITY_MANAGER_OOB_FLAGS = 0x11,
  SLAVE_CONNECTION_INTERVAL_RANGE = 0x12,
  LIST_16BIT_SERVICE_SOLICITATION_UUIDS = 0x14,
  LIST_128BIT_SERVICE_SOLICITATION_UUIDS = 0x15,
  SERVICE_DATA_16_BIT_UUIDS = 0x16,
  PUBLIC_TARGET_ADDRESS = 0x17,
  RANDOM_TARGET_ADDRESS = 0x18,
  APPEARANCE = 0x19,
  ADVERTISING_INTERVAL = 0x1A,
  LE_BLUETOOTH_DEVICE_ADDRESS = 0x1B,
  LE_ROLE = 0x1C,
  SIMPLE_PAIRING_HASH_C_256 = 0x1D,
  SIMPLE_PAIRING_RANDOMIZER_R_256 = 0x1E,
  LIST_32BIT_SERVICE_SOLICITATION_UUIDS = 0x1F,
  SERVICE_DATA_32_BIT_UUIDS = 0x20,
  SERVICE_DATA_128_BIT_UUIDS = 0x21,
  LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE = 0x22,
  LE_SECURE_CONNECTIONS_RANDOM_VALUE = 0x23,
  URI = 0x24,
  INDOOR_POSITIONING = 0x25,
  TRANSPORT_DISCOVERY_DATA = 0x26,
  LE_SUPPORTED_FEATURES = 0x27,
  CHANNEL_MAP_UPDATE_INDICATION = 0x28,
  MESH_PB_ADV = 0x29,
  MESH_MESSAGE = 0x2A,
  MESH_BEACON = 0x2B,
  BIG_INFO = 0x2C,
  BROADCAST_CODE = 0x2D,
  THREE_D_INFORMATION_DATA = 0x3D,
  MANUFACTURER_SPECIFIC_DATA = 0xFF,
}

// -----------------------------------------------------------------------------
//  LE Get Vendor Capabilities Command
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#vendor-specific-capabilities
// -----------------------------------------------------------------------------

packet LeGetVendorCapabilities : Command (op_code = LE_GET_VENDOR_CAPABILITIES) {
}

test LeGetVendorCapabilities {
  "\x53\xfd\x00",
}

struct BaseVendorCapabilities {
  max_advt_instances: 8,
  offloaded_resolution_of_private_address : 8,
  total_scan_results_storage: 16,
  max_irk_list_sz: 8,
  filtering_support: 8,
  max_filter: 8,
  activity_energy_info_support: 8,
}

packet LeGetVendorCapabilitiesComplete : CommandComplete (command_op_code = LE_GET_VENDOR_CAPABILITIES) {
  status : ErrorCode,
  base_vendor_capabilities : BaseVendorCapabilities,
  _payload_,
}

packet LeGetVendorCapabilitiesComplete095 : LeGetVendorCapabilitiesComplete {
  version_supported: 16,
  total_num_of_advt_tracked: 16,
  extended_scan_support: 8,
  debug_logging_supported: 8,
  _payload_,
}

packet LeGetVendorCapabilitiesComplete096 : LeGetVendorCapabilitiesComplete095 {
  le_address_generation_offloading_support: 8,
  _payload_,
}

packet LeGetVendorCapabilitiesComplete098 : LeGetVendorCapabilitiesComplete096 {
  a2dp_source_offload_capability_mask: 32,
  bluetooth_quality_report_support: 8
}

// -----------------------------------------------------------------------------
//  LE Batch Scan Command
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_batch_scan_command
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#storage-threshold-breach-subevent
// -----------------------------------------------------------------------------

enum BatchScanOpcode : 8 {
  ENABLE = 0x01,
  SET_STORAGE_PARAMETERS = 0x02,
  SET_SCAN_PARAMETERS = 0x03,
  READ_RESULT_PARAMETERS = 0x04,
}

packet LeBatchScan : Command (op_code = LE_BATCH_SCAN) {
  batch_scan_opcode : BatchScanOpcode,
  _body_,
}

packet LeBatchScanComplete : CommandComplete (command_op_code = LE_BATCH_SCAN) {
  status : ErrorCode,
  batch_scan_opcode : BatchScanOpcode,
  _body_,
}

packet LeBatchScanEnable : LeBatchScan (batch_scan_opcode = ENABLE) {
  enable : Enable,
}

packet LeBatchScanEnableComplete : LeBatchScanComplete (batch_scan_opcode = ENABLE) {
}

packet LeBatchScanSetStorageParameters : LeBatchScan (batch_scan_opcode = SET_STORAGE_PARAMETERS) {
  batch_scan_full_max_percentage : 8,
  batch_scan_truncated_max_percentage : 8,
  batch_scan_notify_threshold_percentage : 8,
}

packet LeBatchScanSetStorageParametersComplete : LeBatchScanComplete (batch_scan_opcode = SET_STORAGE_PARAMETERS) {
}

enum BatchScanDiscardRule : 8 {
  OLDEST = 0x00,
  WEAKEST_RSSI = 0x01,
}

packet LeBatchScanSetScanParameters : LeBatchScan (batch_scan_opcode = SET_SCAN_PARAMETERS) {
  truncated_mode_enabled : 1,
  full_mode_enabled : 1,
  _reserved_ : 6,
  duty_cycle_scan_window_slots : 32,
  duty_cycle_scan_interval_slots : 32,
  own_address_type : PeerAddressType,
  batch_scan_discard_rule : BatchScanDiscardRule,
}

packet LeBatchScanSetScanParametersComplete : LeBatchScanComplete (batch_scan_opcode = SET_SCAN_PARAMETERS) {
}

enum BatchScanDataRead : 8 {
  TRUNCATED_MODE_DATA = 0x01,
  FULL_MODE_DATA = 0x02,
}

packet LeBatchScanReadResultParameters : LeBatchScan (batch_scan_opcode = READ_RESULT_PARAMETERS) {
  batch_scan_data_read : BatchScanDataRead,
}

packet LeBatchScanReadResultParametersCompleteRaw : LeBatchScanComplete (batch_scan_opcode = READ_RESULT_PARAMETERS) {
  batch_scan_data_read : BatchScanDataRead,
  num_of_records : 8,
  raw_data : 8[],
}

packet LeBatchScanReadResultParametersComplete : LeBatchScanComplete (batch_scan_opcode = READ_RESULT_PARAMETERS) {
  batch_scan_data_read : BatchScanDataRead,
  _body_,
}

struct TruncatedResult {
  bd_addr : Address,
  address_type : AddressType,
  tx_power : 8,
  rssi : 8,
  timestamp : 16,
}

packet LeBatchScanReadTruncatedResultParametersComplete : LeBatchScanReadResultParametersComplete (batch_scan_data_read = TRUNCATED_MODE_DATA) {
  _count_(results) : 8,
  results : TruncatedResult[],
}

struct FullResult {
  bd_addr : Address,
  address_type : AddressType,
  tx_power : 8,
  rssi : 8,
  timestamp : 16,
  _size_(adv_packet) : 8,
  adv_packet : 8[],
  _size_(scan_response) : 8,
  scan_response : 8[],
}

packet LeBatchScanReadFullResultParametersComplete : LeBatchScanReadResultParametersComplete (batch_scan_data_read = FULL_MODE_DATA) {
  _count_(results) : 8,
  results : FullResult[],
}

packet StorageThresholdBreachEvent : VendorSpecificEvent (subevent_code = STORAGE_THRESHOLD_BREACH) {
}

// -----------------------------------------------------------------------------
//  Advertising Packet Content Filter (APCF) Command.
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#advertising-packet-content-filter
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le-advertisement-tracking-sub-event
// -----------------------------------------------------------------------------

enum ApcfOpcode : 8 {
  ENABLE = 0x00,
  SET_FILTERING_PARAMETERS = 0x01,
  BROADCASTER_ADDRESS = 0x02,
  SERVICE_UUID = 0x03,
  SERVICE_SOLICITATION_UUID = 0x04,
  LOCAL_NAME = 0x05,
  MANUFACTURER_DATA = 0x06,
  SERVICE_DATA = 0x07,
  TRANSPORT_DISCOVERY_SERVICE = 0x08,
  AD_TYPE_FILTER = 0x09,
  READ_EXTENDED_FEATURES = 0xFF,
}

packet LeApcf : Command (op_code = LE_APCF) {
  apcf_opcode : ApcfOpcode,
  _payload_,
}

packet LeApcfComplete : CommandComplete (command_op_code = LE_APCF) {
  status : ErrorCode,
  apcf_opcode : ApcfOpcode,
  _payload_
}

packet LeApcfEnable : LeApcf (apcf_opcode = ENABLE) {
  apcf_enable : Enable,
}

packet LeApcfEnableComplete : LeApcfComplete (apcf_opcode = ENABLE) {
  apcf_enable : Enable,
}

enum ApcfAction : 8 {
  ADD = 0x00,
  DELETE = 0x01,
  CLEAR = 0x02,
}

enum DeliveryMode : 8 {
  IMMEDIATE = 0x00,
  ONFOUND = 0x01,
  BATCHED = 0x02,
}

// Bit mask for the APCF Feature Selection field.
enum ApcfFeatureSelection : 8 {
  BROADCASTER_ADDRESS = 0x00,
  SERVICE_DATA_CHANGE = 0x01,
  SERVICE_UUID = 0x02,
  SERVICE_SOLICITATION_UUID = 0x03,
  LOCAL_NAME = 0x04,
  MANUFACTURER_DATA = 0x05,
  SERVICE_DATA = 0x06,
  TRANSPORT_DISCOVERY_DATA = 0x07,
  AD_TYPE = 0x08,
}

packet LeApcfSetFilteringParameters : LeApcf (apcf_opcode = SET_FILTERING_PARAMETERS) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  apcf_feature_selection : 16,
  apcf_list_logic_type : 16,
  apcf_filter_logic_type : 8,
  rssi_high_thresh : 8,
  delivery_mode : DeliveryMode,
  onfound_timeout : 16,
  onfound_timeout_cnt : 8,
  rssi_low_thresh : 8,
  onlost_timeout : 16,
  num_of_tracking_entries : 16,
}

packet LeApcfSetFilteringParametersComplete : LeApcfComplete (apcf_opcode = SET_FILTERING_PARAMETERS) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

enum ApcfApplicationAddressType : 8 {
  PUBLIC = 0x00,
  RANDOM = 0x01,
  NOT_APPLICABLE = 0x02,
}

packet LeApcfBroadcasterAddress : LeApcf (apcf_opcode = BROADCASTER_ADDRESS) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  apcf_broadcaster_address : Address,
  apcf_application_address_type : ApcfApplicationAddressType,
}

packet LeApcfBroadcasterAddressComplete : LeApcfComplete (apcf_opcode = BROADCASTER_ADDRESS) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfServiceUuid : LeApcf (apcf_opcode = SERVICE_UUID) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  acpf_uuid_data : 8[],
}

packet LeApcfServiceUuidComplete : LeApcfComplete (apcf_opcode = SERVICE_UUID) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfSolicitationUuid : LeApcf (apcf_opcode = SERVICE_SOLICITATION_UUID) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  acpf_uuid_data : 8[],
}

packet LeApcfSolicitationUuidComplete : LeApcfComplete (apcf_opcode = SERVICE_SOLICITATION_UUID) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfLocalName : LeApcf (apcf_opcode = LOCAL_NAME) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  apcf_local_name : 8[],
}

packet LeApcfLocalNameComplete : LeApcfComplete (apcf_opcode = LOCAL_NAME) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfManufacturerData : LeApcf (apcf_opcode = MANUFACTURER_DATA) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  apcf_manufacturer_data : 8[],
}

packet LeApcfManufacturerDataComplete : LeApcfComplete (apcf_opcode = MANUFACTURER_DATA) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfServiceData : LeApcf (apcf_opcode = SERVICE_DATA) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  apcf_service_data : 8[],
}

packet LeApcfServiceDataComplete : LeApcfComplete (apcf_opcode = SERVICE_DATA) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfADType : LeApcf (apcf_opcode = AD_TYPE_FILTER) {
  apcf_action : ApcfAction,
  apcf_filter_index : 8,
  apcf_ad_type_data : 8[],
}

packet LeApcfADTypeComplete : LeApcfComplete (apcf_opcode = AD_TYPE_FILTER) {
  apcf_action : ApcfAction,
  apcf_available_spaces : 8,
}

packet LeApcfReadExtendedFeatures : LeApcf (apcf_opcode = READ_EXTENDED_FEATURES) {
}

test LeApcfReadExtendedFeatures {
  "\x57\xfd\x01\xff",
}

packet LeApcfReadExtendedFeaturesComplete : LeApcfComplete (apcf_opcode = READ_EXTENDED_FEATURES) {
  transport_discovery_data_filter : 1,
  ad_type_filter : 1,
  _reserved_ : 14,
}

test LeApcfReadExtendedFeaturesComplete {
  "\x0e\x07\x01\x57\xfd\x00\xff\x03\x00",
}

enum AdvertiserState : 8 {
  ADVERTISER_FOUND = 0x0,
  ADVERTISER_LOST = 0x1,
}

enum AdvtInfoPresent : 8 {
  ADVT_INFO_PRESENT = 0x0,
  ADVT_INFO_NOT_PRESENT = 0x1,
}

struct AdvtInfo {
  tx_power : 8,
  rssi : 8,
  timestamp : 16,
  _size_(adv_packet) : 8,
  adv_packet : 8[],
  _size_(scan_data_resp) : 8,
  scan_data_resp : 8[],
}

packet LeAdvertisementTrackingEvent : VendorSpecificEvent (subevent_code = LE_ADVERTISEMENT_TRACKING) {
  apcf_filter_index : 8,
  advertiser_state : AdvertiserState,
  advt_info_present : AdvtInfoPresent,
  advertiser_address : Address,
  advertiser_address_type : PeerAddressType,
  advt_info : AdvtInfo[],
}

// -----------------------------------------------------------------------------
//  LE Get Controller Activity Energy Info Command
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le_get_controller_activity_energy_info
// -----------------------------------------------------------------------------

packet LeGetControllerActivityEnergyInfo : Command (op_code = LE_GET_CONTROLLER_ACTIVITY_ENERGY_INFO) {
}

packet LeGetControllerActivityEnergyInfoComplete : CommandComplete (command_op_code = LE_GET_CONTROLLER_ACTIVITY_ENERGY_INFO) {
  status : ErrorCode,
  total_tx_time_ms : 32,
  total_rx_time_ms : 32,
  total_idle_time_ms : 32,
  total_energy_used : 32,
}

// -----------------------------------------------------------------------------
//  LE Extended Set Scan Parameters Command
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#le-extended-set-scan-parameters-command
// -----------------------------------------------------------------------------

enum LeExScanType : 8 {
  PASSIVE = 0x0,
  ACTIVE = 0x1,
}

enum LeExScanFilterPolicy : 8 {
  ACCEPT_ALL = 0x0,
  FILTER_ACCEPT_LIST_ONLY = 0x01,
}

packet LeExSetScanParameters : Command (op_code = LE_EX_SET_SCAN_PARAMETERS) {
  le_ex_scan_type : LeExScanType,
  le_ex_scan_interval : 32,
  le_ex_scan_window : 32,
  own_address_type : OwnAddressType,
  le_ex_scan_filter_policy : LeExScanFilterPolicy,
}

packet LeExSetScanParametersComplete : CommandComplete (command_op_code = LE_EX_SET_SCAN_PARAMETERS) {
  status : ErrorCode,
}

// -----------------------------------------------------------------------------
//  Get Controller Debug Info Command
//  https://source.android.com/docs/core/connect/bluetooth/hci_requirements#get-controller-debug-info-command
// -----------------------------------------------------------------------------

packet GetControllerDebugInfo : Command (op_code = GET_CONTROLLER_DEBUG_INFO) {
}

packet GetControllerDebugInfoComplete : CommandComplete (command_op_code = GET_CONTROLLER_DEBUG_INFO) {
  status : ErrorCode,
}

packet ControllerDebugInfoEvent : VendorSpecificEvent (subevent_code = CONTROLLER_DEBUG_INFO) {
  debug_block_byte_offset_start : 16,
  last_block : 8,
  _size_(debug_data) : 16,
  debug_data : 8[],
}

// -----------------------------------------------------------------------------
//  Microsoft Commands
//  https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/microsoft-defined-bluetooth-hci-commands-and-events
// -----------------------------------------------------------------------------

enum MsftSubcommandOpcode : 8 {
  MSFT_READ_SUPPORTED_FEATURES = 0x00,
  MSFT_MONITOR_RSSI = 0x01,
  MSFT_CANCEL_MONITOR_RSSI = 0x02,
  MSFT_LE_MONITOR_ADV = 0x03,
  MSFT_LE_CANCEL_MONITOR_ADV = 0x04,
  MSFT_LE_SET_ADV_FILTER_ENABLE = 0x05,
  MSFT_READ_ABSOLUTE_RSSI = 0x06,
}

// MSFT Commands do not have a constant opcode, so leave `op_code` undefined.
packet MsftCommand : Command {
  subcommand_opcode: MsftSubcommandOpcode,
  _payload_,
}

packet MsftReadSupportedFeatures : MsftCommand (subcommand_opcode = MSFT_READ_SUPPORTED_FEATURES) {}

enum MsftLeMonitorAdvConditionType : 8 {
  MSFT_CONDITION_TYPE_PATTERNS = 0x01,
  MSFT_CONDITION_TYPE_UUID = 0x02,
  MSFT_CONDITION_TYPE_IRK_RESOLUTION = 0x03,
  MSFT_CONDITION_TYPE_ADDRESS = 0x04,
}

enum MsftLeMonitorAdvConditionUuidType : 8 {
  MSFT_CONDITION_UUID_TYPE_16_BIT = 0x01,
  MSFT_CONDITION_UUID_TYPE_32_BIT = 0x02,
  MSFT_CONDITION_UUID_TYPE_128_BIT = 0x03,
}

packet MsftLeMonitorAdv : MsftCommand (subcommand_opcode = MSFT_LE_MONITOR_ADV) {
  rssi_threshold_high : 8,
  rssi_threshold_low : 8,
  rssi_threshold_low_time_interval : 8,
  rssi_sampling_period : 8,
  condition_type: MsftLeMonitorAdvConditionType,
  _payload_,
}

struct MsftLeMonitorAdvConditionPattern {
  _size_(pattern) : 8, // including one byte for ad_type and one byte for start_of_pattern
  ad_type: 8,
  start_of_pattern: 8,
  pattern: 8[+2],
}

packet MsftLeMonitorAdvConditionPatterns : MsftLeMonitorAdv (condition_type = MSFT_CONDITION_TYPE_PATTERNS) {
  _count_(patterns): 8,
  patterns: MsftLeMonitorAdvConditionPattern[],
}

test MsftLeMonitorAdvConditionPatterns {
  "\x1e\xfc\x0e\x03\x10\x05\x04\xaa\x01\x01\x06\x03\x00\x80\x81\x82\x83", // 1 pattern
  "\x70\xfd\x13\x03\x15\x04\x02\xbb\x01\x02\x04\x03\x00\x80\x81\x06\x0f\x00\x90\x91\x92\x93", // 2 patterns
}

packet MsftLeMonitorAdvConditionUuid : MsftLeMonitorAdv (condition_type = MSFT_CONDITION_TYPE_UUID) {
  uuid_type: MsftLeMonitorAdvConditionUuidType,
  _payload_,
}

packet MsftLeMonitorAdvConditionUuid2 : MsftLeMonitorAdvConditionUuid (uuid_type = MSFT_CONDITION_UUID_TYPE_16_BIT) {
  uuid2: 8[2],
}

test MsftLeMonitorAdvConditionUuid2 {
  "\x1e\xfc\x09\x03\x10\x11\x12\x13\x02\x01\x70\x71", // opcode = fc1e for Intel
  "\x70\xfd\x09\x03\x10\x11\x12\x13\x02\x01\x70\x71", // opcode = fd70 for Qualcomm
}

packet MsftLeMonitorAdvConditionUuid4 : MsftLeMonitorAdvConditionUuid (uuid_type = MSFT_CONDITION_UUID_TYPE_32_BIT) {
  uuid4: 8[4],
}

test MsftLeMonitorAdvConditionUuid4 {
  "\x1e\xfc\x0b\x03\x10\x11\x12\x13\x02\x02\x70\x71\x72\x73",
  "\x70\xfd\x0b\x03\x10\x11\x12\x13\x02\x02\x70\x71\x72\x73",
}

packet MsftLeMonitorAdvConditionUuid16 : MsftLeMonitorAdvConditionUuid (uuid_type = MSFT_CONDITION_UUID_TYPE_128_BIT) {
  uuid16: 8[16],
}

test MsftLeMonitorAdvConditionUuid16 {
  "\x1e\xfc\x17\x03\x10\x11\x12\x13\x02\x03\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
  "\x70\xfd\x17\x03\x10\x11\x12\x13\x02\x03\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f",
}

packet MsftLeCancelMonitorAdv: MsftCommand (subcommand_opcode = MSFT_LE_CANCEL_MONITOR_ADV) {
  monitor_handle: 8,
}

test MsftLeCancelMonitorAdv {
  "\x1e\xfc\x02\x04\x01", // cancel handle 0x01
}

packet MsftLeSetAdvFilterEnable : MsftCommand (subcommand_opcode = MSFT_LE_SET_ADV_FILTER_ENABLE) {
  enable: 8,
}

test MsftLeSetAdvFilterEnable {
  "\x1e\xfc\x02\x05\x01", // disable
  "\x70\xfd\x02\x05\x01", // enable
}

packet MsftCommandComplete : CommandComplete {
  status: ErrorCode,
  subcommand_opcode: MsftSubcommandOpcode,
  _payload_,
}

packet MsftReadSupportedFeaturesCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_READ_SUPPORTED_FEATURES) {
  supported_features: 64,
  _size_(prefix) : 8,
  prefix: 8[],
}

test MsftReadSupportedFeaturesCommandComplete {
  "\x0e\x10\x01\x1e\xfc\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x02\x87\x80", // Msft opcode by Intel
  "\x0e\x12\x01\x70\xfd\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x04\x4d\x53\x46\x54", // Msft opcode by Qualcomm
}

packet MsftLeMonitorAdvCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_LE_MONITOR_ADV) {
  monitor_handle: 8,
}

test MsftLeMonitorAdvCommandComplete {
  "\x0e\x06\x01\x1e\xfc\x00\x03\x05", // succeeded
  "\x0e\x06\x01\x70\xfd\x01\x03\x06", // failed
}

packet MsftLeCancelMonitorAdvCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_LE_CANCEL_MONITOR_ADV) {}

packet MsftLeSetAdvFilterEnableCommandComplete : MsftCommandComplete (subcommand_opcode = MSFT_LE_SET_ADV_FILTER_ENABLE) {}

enum MsftEventCode : 8 {
  MSFT_RSSI_EVENT = 0x01,
  MSFT_LE_MONITOR_DEVICE_EVENT = 0x02,
}

enum MsftEventStatus : 8 {
  MSFT_EVENT_STATUS_SUCCESS = 0x00,
  MSFT_EVENT_STATUS_FAILURE = 0x01,
}

// It is not possible to define MSFT Event packet by deriving `Event` packet
// because it starts with variable-length event prefix which can only be determined
// at run-time (after receiving return of MSFT Read Supported Features).
// Therefore we only define the payload which is located after the event prefix.
packet MsftEventPayload {
  msft_event_code : MsftEventCode,
  _payload_,
}

packet MsftRssiEventPayload : MsftEventPayload (msft_event_code = MSFT_RSSI_EVENT) {
  status: MsftEventStatus,
  connection_handle: 16,
  rssi: 8,
}

test MsftRssiEventPayload {
  "\x01\x00\x01\x10\xf0", // MSFT_RSSI_EVENT succeeded
  "\x01\x01\x02\x02\x08", // MSFT_RSSI_EVENT failed
}

packet MsftLeMonitorDeviceEventPayload : MsftEventPayload (msft_event_code = MSFT_LE_MONITOR_DEVICE_EVENT) {
  address_type: 8,
  bd_addr: Address,
  monitor_handle: 8,
  monitor_state: 8,
}

test MsftLeMonitorDeviceEventPayload {
  "\x02\x01\x00\x01\x02\x03\x04\x05\x10\x00",
  "\x02\x02\xf0\xf1\xf2\xf3\xf4\xf5\xaa\x02",
}