• 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 l2cap_packets
19from bluetooth_packets_python3.l2cap_packets import CommandCode, LeCommandCode
20from blueberry.tests.gd.cert.capture import Capture
21from blueberry.tests.gd.cert.matchers import HciMatchers
22from blueberry.tests.gd.cert.matchers import L2capMatchers
23from blueberry.tests.gd.cert.matchers import SecurityMatchers
24from blueberry.facade.security.facade_pb2 import UiMsgType
25import hci_packets as hci
26
27
28class HalCaptures(object):
29
30    @staticmethod
31    def ReadBdAddrCompleteCapture():
32        return Capture(lambda packet: packet.payload[0:5] == b'\x0e\x0a\x01\x09\x10',
33                       lambda packet: hci.Event.parse_all(packet.payload))
34
35    @staticmethod
36    def ConnectionRequestCapture():
37        return Capture(lambda packet: packet.payload[0:2] == b'\x04\x0a',
38                       lambda packet: hci.Event.parse_all(packet.payload))
39
40    @staticmethod
41    def ConnectionCompleteCapture():
42        return Capture(lambda packet: packet.payload[0:3] == b'\x03\x0b\x00',
43                       lambda packet: hci.Event.parse_all(packet.payload))
44
45    @staticmethod
46    def DisconnectionCompleteCapture():
47        return Capture(lambda packet: packet.payload[0:2] == b'\x05\x04',
48                       lambda packet: hci.Event.parse_all(packet.payload))
49
50    @staticmethod
51    def LeConnectionCompleteCapture():
52        return Capture(
53            lambda packet: packet.payload[0] == 0x3e and (packet.payload[2] == 0x01 or packet.payload[2] == 0x0a),
54            lambda packet: hci.Event.parse_all(packet.payload))
55
56
57class HciCaptures(object):
58
59    @staticmethod
60    def ReadLocalOobDataCompleteCapture():
61        return Capture(
62            HciMatchers.CommandComplete(hci.OpCode.READ_LOCAL_OOB_DATA),
63            lambda packet: HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci.OpCode.READ_LOCAL_OOB_DATA))
64
65    @staticmethod
66    def ReadLocalOobExtendedDataCompleteCapture():
67        return Capture(
68            HciMatchers.CommandComplete(hci.OpCode.READ_LOCAL_OOB_EXTENDED_DATA), lambda packet: HciMatchers.
69            ExtractMatchingCommandComplete(packet.payload, hci.OpCode.READ_LOCAL_OOB_EXTENDED_DATA))
70
71    @staticmethod
72    def ReadBdAddrCompleteCapture():
73        return Capture(HciMatchers.CommandComplete(hci.OpCode.READ_BD_ADDR),
74                       lambda packet: hci.Event.parse_all(packet.payload))
75
76    @staticmethod
77    def ConnectionRequestCapture():
78        return Capture(HciMatchers.EventWithCode(hci.EventCode.CONNECTION_REQUEST),
79                       lambda packet: hci.Event.parse_all(packet.payload))
80
81    @staticmethod
82    def ConnectionCompleteCapture():
83        return Capture(HciMatchers.EventWithCode(hci.EventCode.CONNECTION_COMPLETE),
84                       lambda packet: hci.Event.parse_all(packet.payload))
85
86    @staticmethod
87    def DisconnectionCompleteCapture():
88        return Capture(HciMatchers.EventWithCode(hci.EventCode.DISCONNECTION_COMPLETE),
89                       lambda packet: hci.Event.parse_all(packet.payload))
90
91    @staticmethod
92    def LeConnectionCompleteCapture():
93        return Capture(HciMatchers.LeConnectionComplete(),
94                       lambda packet: HciMatchers.ExtractLeConnectionComplete(packet.payload))
95
96    @staticmethod
97    def SimplePairingCompleteCapture():
98        return Capture(HciMatchers.EventWithCode(hci.EventCode.SIMPLE_PAIRING_COMPLETE),
99                       lambda packet: hci.Event.parse_all(packet.payload))
100
101
102class L2capCaptures(object):
103
104    @staticmethod
105    def ConnectionRequest(psm):
106        return Capture(L2capMatchers.ConnectionRequest(psm), L2capCaptures._extract_connection_request)
107
108    @staticmethod
109    def _extract_connection_request(packet):
110        frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONNECTION_REQUEST)
111        return l2cap_packets.ConnectionRequestView(frame)
112
113    @staticmethod
114    def ConnectionResponse(scid):
115        return Capture(L2capMatchers.ConnectionResponse(scid), L2capCaptures._extract_connection_response)
116
117    @staticmethod
118    def _extract_connection_response(packet):
119        frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONNECTION_RESPONSE)
120        return l2cap_packets.ConnectionResponseView(frame)
121
122    @staticmethod
123    def ConfigurationRequest(cid=None):
124        return Capture(L2capMatchers.ConfigurationRequest(cid), L2capCaptures._extract_configuration_request)
125
126    @staticmethod
127    def _extract_configuration_request(packet):
128        frame = L2capMatchers.control_frame_with_code(packet, CommandCode.CONFIGURATION_REQUEST)
129        return l2cap_packets.ConfigurationRequestView(frame)
130
131    @staticmethod
132    def CreditBasedConnectionRequest(psm):
133        return Capture(L2capMatchers.CreditBasedConnectionRequest(psm),
134                       L2capCaptures._extract_credit_based_connection_request)
135
136    @staticmethod
137    def _extract_credit_based_connection_request(packet):
138        frame = L2capMatchers.le_control_frame_with_code(packet, LeCommandCode.LE_CREDIT_BASED_CONNECTION_REQUEST)
139        return l2cap_packets.LeCreditBasedConnectionRequestView(frame)
140
141    @staticmethod
142    def CreditBasedConnectionResponse():
143        return Capture(L2capMatchers.CreditBasedConnectionResponse(),
144                       L2capCaptures._extract_credit_based_connection_response)
145
146    @staticmethod
147    def _extract_credit_based_connection_response(packet):
148        frame = L2capMatchers.le_control_frame_with_code(packet, LeCommandCode.LE_CREDIT_BASED_CONNECTION_RESPONSE)
149        return l2cap_packets.LeCreditBasedConnectionResponseView(frame)
150
151    @staticmethod
152    def LinkSecurityInterfaceCallbackEvent(type):
153        return Capture(L2capMatchers.LinkSecurityInterfaceCallbackEvent(type), L2capCaptures._extract_address)
154
155    @staticmethod
156    def _extract_address(packet):
157        return packet.address
158
159
160class SecurityCaptures(object):
161
162    @staticmethod
163    def DisplayPasskey():
164        return Capture(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY), SecurityCaptures._extract_passkey)
165
166    @staticmethod
167    def _extract_passkey(event):
168        if event is None:
169            return None
170        return event.numeric_value
171