1#!/usr/bin/env python3
2#
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# 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, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16"""
17SDP PTS Tests.
18"""
19from acts.test_utils.abstract_devices.bluetooth_device import AndroidBluetoothDevice
20from acts.test_utils.abstract_devices.bluetooth_device import FuchsiaBluetoothDevice
21from acts.test_utils.bt.bt_constants import bt_attribute_values
22from acts.test_utils.bt.bt_constants import sig_uuid_constants
23from acts.test_utils.bt.pts.pts_base_class import PtsBaseClass
24
25import acts.test_utils.bt.pts.fuchsia_pts_ics_lib as f_ics_lib
26import acts.test_utils.bt.pts.fuchsia_pts_ixit_lib as f_ixit_lib
27
28# SDP_RECORD Definition is WIP
29SDP_RECORD = {
30    'service_class_uuids': ["0001"],
31    'protocol_descriptors': [
32        {
33            'protocol':
34            int(sig_uuid_constants['AVDTP'], 16),
35            'params': [
36                {
37                    'data': 0x0103  # to indicate 1.3
38                },
39                {
40                    'data': 0x0105  # to indicate 1.5
41                }
42            ]
43        },
44        {
45            'protocol': int(sig_uuid_constants['SDP'], 16),
46            'params': [{
47                'data': int(sig_uuid_constants['AVDTP'], 16),
48            }]
49        }
50    ],
51    'profile_descriptors': [{
52        'profile_id':
53        int(sig_uuid_constants['AdvancedAudioDistribution'], 16),
54        'major_version':
55        1,
56        'minor_version':
57        3,
58    }],
59    'additional_protocol_descriptors': [{
60        'protocol':
61        int(sig_uuid_constants['L2CAP'], 16),
62        'params': [
63            {
64                'data': int(sig_uuid_constants['AVDTP'], 16),
65            },
66            {
67                'data': int(sig_uuid_constants['AVCTP'], 16),
68            },
69            {
70                'data': int(sig_uuid_constants['GenericAudio'], 16),
71            },
72        ]
73    }],
74    'information': [{
75        'language': "en",
76        'name': "A2DP",
77        'description': "Advanced Audio Distribution Profile",
78        'provider': "Fuchsia"
79    }],
80    'additional_attributes': [{
81        'id': 0x0201,
82        'element': {
83            'data': int(sig_uuid_constants['AVDTP'], 16)
84        }
85    }]
86}
87
88ATTRIBUTES = [
89    bt_attribute_values['ATTR_PROTOCOL_DESCRIPTOR_LIST'],
90    bt_attribute_values['ATTR_SERVICE_CLASS_ID_LIST'],
91    bt_attribute_values['ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST'],
92    bt_attribute_values['ATTR_SERVICE_AVAILABILITY'],
93    bt_attribute_values['ATTR_A2DP_SUPPORTED_FEATURES'],
94]
95
96PROFILE_ID = int(sig_uuid_constants['AudioSource'], 16)
97
98
99class SdpPtsTest(PtsBaseClass):
100
101    def setup_class(self):
102        super().setup_class()
103        self.dut.initialize_bluetooth_controller()
104        # self.dut.set_bluetooth_local_name(self.dut_bluetooth_local_name)
105        local_dut_mac_address = self.dut.get_local_bluetooth_address()
106
107        ics = None
108        ixit = None
109        if isinstance(self.dut, FuchsiaBluetoothDevice):
110            fuchsia_ixit = f_ixit_lib.SDP_IXIT
111            fuchsia_ixit[b'TSPX_bd_addr_iut'] = (b'OCTETSTRING',
112                                                 local_dut_mac_address.replace(
113                                                     ':', '').encode())
114            ics = f_ics_lib.SDP_ICS
115            ixit = fuchsia_ixit
116        elif isinstance(self.dut, AndroidBluetoothDevice):
117            # TODO: Add ICS and IXIT values for Android
118            self.log.warn(
119                "ICS/IXIT values not set for Android, using Fuchsia as default."
120            )
121            fuchsia_ixit = f_ixit_lib.SDP_IXIT
122            fuchsia_ixit[b'TSPX_bd_addr_iut'] = (b'OCTETSTRING',
123                                                 local_dut_mac_address.replace(
124                                                     ':', '').encode())
125            ics = f_ics_lib.SDP_ICS
126            ixit = fuchsia_ixit
127
128        ### PTS SETUP: Required after ICS, IXIT, and profile is setup ###
129        self.pts.set_profile_under_test("SDP")
130        self.pts.set_ics_and_ixit(ics, ixit)
131        self.pts.setup_pts()
132        ### End PTS Setup ###
133
134        self.dut.unbond_all_known_devices()
135        self.dut.set_discoverable(True)
136
137    def setup_test(self):
138        super(SdpPtsTest, self).setup_test()
139        self.dut.sdp_init()
140        self.dut.sdp_add_search(ATTRIBUTES, PROFILE_ID)
141        self.dut.sdp_add_service(SDP_RECORD)
142
143        # Make sure there were no lingering answers due to a failed test.
144        self.pts.extra_answers = []
145
146    def teardown_test(self):
147        super(SdpPtsTest, self).teardown_test()
148        self.dut.sdp_clean_up()
149
150    def teardown_class(self):
151        super(SdpPtsTest, self).teardown_class()
152        self.dut.sdp_clean_up()
153        self.dut.set_discoverable(False)
154
155    # BEGIN SDP TESTCASES #
156
157    @PtsBaseClass.pts_test_wrap
158    def test_sdp_sr_sa_bv_01_c(self):
159        return self.pts.execute_test("SDP/SR/SA/BV-01-C")
160
161    @PtsBaseClass.pts_test_wrap
162    def test_sdp_sr_sa_bv_03_c(self):
163        return self.pts.execute_test("SDP/SR/SA/BV-03-C")
164
165    @PtsBaseClass.pts_test_wrap
166    def test_sdp_sr_sa_bv_04_c(self):
167        return self.pts.execute_test("SDP/SR/SA/BV-04-C")
168
169    @PtsBaseClass.pts_test_wrap
170    def test_sdp_sr_sa_bv_05_c(self):
171        return self.pts.execute_test("SDP/SR/SA/BV-05-C")
172
173    @PtsBaseClass.pts_test_wrap
174    def test_sdp_sr_sa_bv_08_c(self):
175        return self.pts.execute_test("SDP/SR/SA/BV-08-C")
176
177    @PtsBaseClass.pts_test_wrap
178    def test_sdp_sr_sa_bv_09_c(self):
179        return self.pts.execute_test("SDP/SR/SA/BV-09-C")
180
181    @PtsBaseClass.pts_test_wrap
182    def test_sdp_sr_sa_bv_12_c(self):
183        return self.pts.execute_test("SDP/SR/SA/BV-12-C")
184
185    @PtsBaseClass.pts_test_wrap
186    def test_sdp_sr_sa_bv_13_c(self):
187        return self.pts.execute_test("SDP/SR/SA/BV-13-C")
188
189    @PtsBaseClass.pts_test_wrap
190    def test_sdp_sr_sa_bv_14_c(self):
191        return self.pts.execute_test("SDP/SR/SA/BV-14-C")
192
193    @PtsBaseClass.pts_test_wrap
194    def test_sdp_sr_sa_bv_17_c(self):
195        return self.pts.execute_test("SDP/SR/SA/BV-17-C")
196
197    @PtsBaseClass.pts_test_wrap
198    def test_sdp_sr_sa_bv_20_c(self):
199        return self.pts.execute_test("SDP/SR/SA/BV-20-C")
200
201    @PtsBaseClass.pts_test_wrap
202    def test_sdp_sr_sa_bv_21_c(self):
203        return self.pts.execute_test("SDP/SR/SA/BV-21-C")
204
205    @PtsBaseClass.pts_test_wrap
206    def test_sdp_sr_sa_bi_01_c(self):
207        return self.pts.execute_test("SDP/SR/SA/BI-01-C")
208
209    @PtsBaseClass.pts_test_wrap
210    def test_sdp_sr_sa_bi_02_c(self):
211        return self.pts.execute_test("SDP/SR/SA/BI-02-C")
212
213    @PtsBaseClass.pts_test_wrap
214    def test_sdp_sr_sa_bi_03_c(self):
215        return self.pts.execute_test("SDP/SR/SA/BI-03-C")
216
217    @PtsBaseClass.pts_test_wrap
218    def test_sdp_sr_ss_bv_01_c(self):
219        return self.pts.execute_test("SDP/SR/SS/BV-01-C")
220
221    @PtsBaseClass.pts_test_wrap
222    def test_sdp_sr_ss_bv_03_c(self):
223        # Triggers continuation response for supported devices.
224        num_of_records = 9
225        for _ in range(num_of_records):
226            self.dut.sdp_add_service(SDP_RECORD)
227        return self.pts.execute_test("SDP/SR/SS/BV-03-C")
228
229    @PtsBaseClass.pts_test_wrap
230    def test_sdp_sr_ss_bv_04_c(self):
231        # Triggers continuation response for supported devices.
232        num_of_records = 9
233        for _ in range(num_of_records):
234            self.dut.sdp_add_service(SDP_RECORD)
235        return self.pts.execute_test("SDP/SR/SS/BV-04-C")
236
237    @PtsBaseClass.pts_test_wrap
238    def test_sdp_sr_ss_bi_01_c(self):
239        return self.pts.execute_test("SDP/SR/SS/BI-01-C")
240
241    @PtsBaseClass.pts_test_wrap
242    def test_sdp_sr_ss_bi_02_c(self):
243        return self.pts.execute_test("SDP/SR/SS/BI-02-C")
244
245    @PtsBaseClass.pts_test_wrap
246    def test_sdp_sr_ssa_bv_01_c(self):
247        return self.pts.execute_test("SDP/SR/SSA/BV-01-C")
248
249    @PtsBaseClass.pts_test_wrap
250    def test_sdp_sr_ssa_bv_02_c(self):
251        return self.pts.execute_test("SDP/SR/SSA/BV-02-C")
252
253    @PtsBaseClass.pts_test_wrap
254    def test_sdp_sr_ssa_bv_03_c(self):
255        return self.pts.execute_test("SDP/SR/SSA/BV-03-C")
256
257    @PtsBaseClass.pts_test_wrap
258    def test_sdp_sr_ssa_bv_04_c(self):
259        return self.pts.execute_test("SDP/SR/SSA/BV-04-C")
260
261    @PtsBaseClass.pts_test_wrap
262    def test_sdp_sr_ssa_bv_06_c(self):
263        return self.pts.execute_test("SDP/SR/SSA/BV-06-C")
264
265    @PtsBaseClass.pts_test_wrap
266    def test_sdp_sr_ssa_bv_10_c(self):
267        return self.pts.execute_test("SDP/SR/SSA/BV-10-C")
268
269    @PtsBaseClass.pts_test_wrap
270    def test_sdp_sr_ssa_bv_11_c(self):
271        return self.pts.execute_test("SDP/SR/SSA/BV-11-C")
272
273    @PtsBaseClass.pts_test_wrap
274    def test_sdp_sr_ssa_bv_12_c(self):
275        return self.pts.execute_test("SDP/SR/SSA/BV-12-C")
276
277    @PtsBaseClass.pts_test_wrap
278    def test_sdp_sr_ssa_bv_13_c(self):
279        return self.pts.execute_test("SDP/SR/SSA/BV-13-C")
280
281    @PtsBaseClass.pts_test_wrap
282    def test_sdp_sr_ssa_bv_16_c(self):
283        return self.pts.execute_test("SDP/SR/SSA/BV-16-C")
284
285    @PtsBaseClass.pts_test_wrap
286    def test_sdp_sr_ssa_bv_17_c(self):
287        return self.pts.execute_test("SDP/SR/SSA/BV-17-C")
288
289    @PtsBaseClass.pts_test_wrap
290    def test_sdp_sr_ssa_bv_18_c(self):
291        return self.pts.execute_test("SDP/SR/SSA/BV-18-C")
292
293    @PtsBaseClass.pts_test_wrap
294    def test_sdp_sr_ssa_bv_20_c(self):
295        return self.pts.execute_test("SDP/SR/SSA/BV-20-C")
296
297    @PtsBaseClass.pts_test_wrap
298    def test_sdp_sr_ssa_bv_23_c(self):
299        return self.pts.execute_test("SDP/SR/SSA/BV-23-C")
300
301    @PtsBaseClass.pts_test_wrap
302    def test_sdp_sr_ssa_bi_01_c(self):
303        return self.pts.execute_test("SDP/SR/SSA/BI-01-C")
304
305    @PtsBaseClass.pts_test_wrap
306    def test_sdp_sr_ssa_bi_02_c(self):
307        return self.pts.execute_test("SDP/SR/SSA/BI-02-C")
308
309    # END SDP TESTCASES #
310