• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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