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
17from blueberry.tests.gd.cert.capture import Capture
18from blueberry.tests.gd.cert.matchers import HciMatchers
19from blueberry.tests.gd.cert.matchers import SecurityMatchers
20from blueberry.facade.security.facade_pb2 import UiMsgType
21import hci_packets as hci
22
23
24class HalCaptures(object):
25
26    @staticmethod
27    def ReadBdAddrCompleteCapture():
28        return Capture(lambda packet: packet.payload[0:5] == b'\x0e\x0a\x01\x09\x10',
29                       lambda packet: hci.Event.parse_all(packet.payload))
30
31    @staticmethod
32    def ConnectionRequestCapture():
33        return Capture(lambda packet: packet.payload[0:2] == b'\x04\x0a',
34                       lambda packet: hci.Event.parse_all(packet.payload))
35
36    @staticmethod
37    def ConnectionCompleteCapture():
38        return Capture(lambda packet: packet.payload[0:3] == b'\x03\x0b\x00',
39                       lambda packet: hci.Event.parse_all(packet.payload))
40
41    @staticmethod
42    def DisconnectionCompleteCapture():
43        return Capture(lambda packet: packet.payload[0:2] == b'\x05\x04',
44                       lambda packet: hci.Event.parse_all(packet.payload))
45
46    @staticmethod
47    def LeConnectionCompleteCapture():
48        return Capture(
49            lambda packet: packet.payload[0] == 0x3e and (packet.payload[2] == 0x01 or packet.payload[2] == 0x0a),
50            lambda packet: hci.Event.parse_all(packet.payload))
51
52
53class HciCaptures(object):
54
55    @staticmethod
56    def ReadLocalOobDataCompleteCapture():
57        return Capture(
58            HciMatchers.CommandComplete(hci.OpCode.READ_LOCAL_OOB_DATA),
59            lambda packet: HciMatchers.ExtractMatchingCommandComplete(packet.payload, hci.OpCode.READ_LOCAL_OOB_DATA))
60
61    @staticmethod
62    def ReadLocalOobExtendedDataCompleteCapture():
63        return Capture(
64            HciMatchers.CommandComplete(hci.OpCode.READ_LOCAL_OOB_EXTENDED_DATA), lambda packet: HciMatchers.
65            ExtractMatchingCommandComplete(packet.payload, hci.OpCode.READ_LOCAL_OOB_EXTENDED_DATA))
66
67    @staticmethod
68    def ReadBdAddrCompleteCapture():
69        return Capture(HciMatchers.CommandComplete(hci.OpCode.READ_BD_ADDR),
70                       lambda packet: hci.Event.parse_all(packet.payload))
71
72    @staticmethod
73    def ConnectionRequestCapture():
74        return Capture(HciMatchers.EventWithCode(hci.EventCode.CONNECTION_REQUEST),
75                       lambda packet: hci.Event.parse_all(packet.payload))
76
77    @staticmethod
78    def ConnectionCompleteCapture():
79        return Capture(HciMatchers.EventWithCode(hci.EventCode.CONNECTION_COMPLETE),
80                       lambda packet: hci.Event.parse_all(packet.payload))
81
82    @staticmethod
83    def DisconnectionCompleteCapture():
84        return Capture(HciMatchers.EventWithCode(hci.EventCode.DISCONNECTION_COMPLETE),
85                       lambda packet: hci.Event.parse_all(packet.payload))
86
87    @staticmethod
88    def LeConnectionCompleteCapture():
89        return Capture(HciMatchers.LeConnectionComplete(),
90                       lambda packet: HciMatchers.ExtractLeConnectionComplete(packet.payload))
91
92    @staticmethod
93    def SimplePairingCompleteCapture():
94        return Capture(HciMatchers.EventWithCode(hci.EventCode.SIMPLE_PAIRING_COMPLETE),
95                       lambda packet: hci.Event.parse_all(packet.payload))
96
97
98class SecurityCaptures(object):
99
100    @staticmethod
101    def DisplayPasskey():
102        return Capture(SecurityMatchers.UiMsg(UiMsgType.DISPLAY_PASSKEY), SecurityCaptures._extract_passkey)
103
104    @staticmethod
105    def _extract_passkey(event):
106        if event is None:
107            return None
108        return event.numeric_value
109