1#!/usr/bin/env python3 2# 3# Copyright 2020 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import bluetooth_packets_python3 as bt_packets 18from bluetooth_packets_python3 import hci_packets 19from bluetooth_packets_python3 import l2cap_packets 20from bluetooth_packets_python3.l2cap_packets import CommandCode, LeCommandCode 21from cert.capture import Capture 22from cert.matchers import HciMatchers 23from cert.matchers import L2capMatchers 24from cert.matchers import SecurityMatchers 25from security.facade_pb2 import UiMsgType 26 27 28class HalCaptures(object): 29 30 @staticmethod 31 def ReadBdAddrCompleteCapture(): 32 return Capture( 33 lambda packet: packet.payload[0:5] == b'\x0e\x0a\x01\x09\x10', lambda packet: hci_packets.ReadBdAddrCompleteView( 34 hci_packets.CommandCompleteView( 35 hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload)))))) 36 37 @staticmethod 38 def ConnectionRequestCapture(): 39 return Capture( 40 lambda packet: packet.payload[0:2] == b'\x04\x0a', lambda packet: hci_packets.ConnectionRequestView( 41 hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload))))) 42 43 @staticmethod 44 def ConnectionCompleteCapture(): 45 return Capture( 46 lambda packet: packet.payload[0:3] == b'\x03\x0b\x00', lambda packet: hci_packets.ConnectionCompleteView( 47 hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload))))) 48 49 @staticmethod 50 def DisconnectionCompleteCapture(): 51 return Capture( 52 lambda packet: packet.payload[0:2] == b'\x05\x04', lambda packet: hci_packets.DisconnectionCompleteView( 53 hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload))))) 54 55 @staticmethod 56 def LeConnectionCompleteCapture(): 57 return Capture( 58 lambda packet: packet.payload[0] == 0x3e and (packet.payload[2] == 0x01 or packet.payload[2] == 0x0a), 59 lambda packet: hci_packets.LeConnectionCompleteView( 60 hci_packets.LeMetaEventView( 61 hci_packets.EventView(bt_packets.PacketViewLittleEndian(list(packet.payload)))))) 62 63 64class HciCaptures(object): 65 66 @staticmethod 67 def ReadLocalOobDataCompleteCapture(): 68 return Capture( 69 HciMatchers.CommandComplete(hci_packets.OpCode.READ_LOCAL_OOB_DATA), 70 lambda packet: HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci_packets.OpCode.READ_LOCAL_OOB_DATA) 71 ) 72 73 @staticmethod 74 def ReadLocalOobExtendedDataCompleteCapture(): 75 return Capture( 76 HciMatchers.CommandComplete(hci_packets.OpCode.READ_LOCAL_OOB_EXTENDED_DATA), 77 lambda packet: HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci_packets.OpCode.READ_LOCAL_OOB_EXTENDED_DATA) 78 ) 79 80 @staticmethod 81 def ReadBdAddrCompleteCapture(): 82 return Capture( 83 HciMatchers.CommandComplete(hci_packets.OpCode.READ_BD_ADDR), 84 lambda packet: hci_packets.ReadBdAddrCompleteView(HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci_packets.OpCode.READ_BD_ADDR))) 85 86 @staticmethod 87 def ConnectionRequestCapture(): 88 return Capture( 89 HciMatchers.EventWithCode(hci_packets.EventCode.CONNECTION_REQUEST), 90 lambda packet: hci_packets.ConnectionRequestView( 91 HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.CONNECTION_REQUEST))) 92 93 @staticmethod 94 def ConnectionCompleteCapture(): 95 return Capture( 96 HciMatchers.EventWithCode(hci_packets.EventCode.CONNECTION_COMPLETE), 97 lambda packet: hci_packets.ConnectionCompleteView( 98 HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.CONNECTION_COMPLETE))) 99 100 @staticmethod 101 def DisconnectionCompleteCapture(): 102 return Capture( 103 HciMatchers.EventWithCode(hci_packets.EventCode.DISCONNECTION_COMPLETE), 104 lambda packet: hci_packets.DisconnectionCompleteView( 105 HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.DISCONNECTION_COMPLETE))) 106 107 @staticmethod 108 def LeConnectionCompleteCapture(): 109 return Capture(HciMatchers.LeConnectionComplete(), 110 lambda packet: HciMatchers.ExtractLeConnectionComplete(packet.payload)) 111 112 @staticmethod 113 def SimplePairingCompleteCapture(): 114 return Capture(HciMatchers.EventWithCode(hci_packets.EventCode.SIMPLE_PAIRING_COMPLETE), 115 lambda packet: hci_packets.SimplePairingCompleteView( 116 HciMatchers.ExtractEventWithCode(packet.payload, hci_packets.EventCode.SIMPLE_PAIRING_COMPLETE))) 117 118 119class L2capCaptures(object): 120 121 @staticmethod 122 def ConnectionRequest(psm): 123 return Capture(L2capMatchers.ConnectionRequest(psm), L2capCaptures._extract_connection_request) 124 125 @staticmethod 126 def _extract_connection_request(packet): 127 frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONNECTION_REQUEST) 128 return l2cap_packets.ConnectionRequestView(frame) 129 130 @staticmethod 131 def ConnectionResponse(scid): 132 return Capture(L2capMatchers.ConnectionResponse(scid), L2capCaptures._extract_connection_response) 133 134 @staticmethod 135 def _extract_connection_response(packet): 136 frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONNECTION_RESPONSE) 137 return l2cap_packets.ConnectionResponseView(frame) 138 139 @staticmethod 140 def ConfigurationRequest(cid=None): 141 return Capture(L2capMatchers.ConfigurationRequest(cid), L2capCaptures._extract_configuration_request) 142 143 @staticmethod 144 def _extract_configuration_request(packet): 145 frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONFIGURATION_REQUEST) 146 return l2cap_packets.ConfigurationRequestView(frame) 147 148 @staticmethod 149 def CreditBasedConnectionRequest(psm): 150 return Capture( 151 L2capMatchers.CreditBasedConnectionRequest(psm), L2capCaptures._extract_credit_based_connection_request) 152 153 @staticmethod 154 def _extract_credit_based_connection_request(packet): 155 frame = L2capMatchers.le_control_frame_with_code(packet, LeCommandCode.LE_CREDIT_BASED_CONNECTION_REQUEST) 156 return l2cap_packets.LeCreditBasedConnectionRequestView(frame) 157 158 @staticmethod 159 def CreditBasedConnectionResponse(): 160 return Capture(L2capMatchers.CreditBasedConnectionResponse(), 161 L2capCaptures._extract_credit_based_connection_response) 162 163 @staticmethod 164 def _extract_credit_based_connection_response(packet): 165 frame = L2capMatchers.le_control_frame_with_code(packet, LeCommandCode.LE_CREDIT_BASED_CONNECTION_RESPONSE) 166 return l2cap_packets.LeCreditBasedConnectionResponseView(frame) 167 168 @staticmethod 169 def LinkSecurityInterfaceCallbackEvent(type): 170 return Capture(L2capMatchers.LinkSecurityInterfaceCallbackEvent(type), L2capCaptures._extract_address) 171 172 @staticmethod 173 def _extract_address(packet): 174 return packet.address 175 176 177class SecurityCaptures(object): 178 179 @staticmethod 180 def DisplayPasskey(): 181 return Capture(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY), SecurityCaptures._extract_passkey) 182 183 @staticmethod 184 def _extract_passkey(event): 185 if event is None: 186 return None 187 return event.numeric_value 188