1 /******************************************************************************
2 *
3 * Copyright 2021 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 *
17 ******************************************************************************/
18
19 #include <gtest/gtest.h>
20
21 #include "bta/sdp/bta_sdp_int.h"
22 #include "btif/include/btif_sock_sdp.h"
23 #include "main/shim/metrics_api.h"
24 #include "stack/include/sdpdefs.h"
25 #include "test/mock/mock_stack_sdp_api.h"
26 #include "types/bluetooth/uuid.h"
27 #include "types/raw_address.h"
28
29 namespace {
30 const RawAddress bdaddr({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
31 } // namespace
32
33 tBTA_SDP_CB bta_sdp_cb;
34
35 static tSDP_DISC_ATTR g_attr_service_class_id_list;
36 static tSDP_DISC_ATTR g_sub_attr;
37 static tSDP_DISC_ATTR g_attr_spec_id;
38 static tSDP_DISC_ATTR g_attr_vendor_id;
39 static tSDP_DISC_ATTR g_attr_vendor_id_src;
40 static tSDP_DISC_ATTR g_attr_vendor_product_id;
41 static tSDP_DISC_ATTR g_attr_vendor_product_version;
42 static tSDP_DISC_ATTR g_attr_vendor_product_primary_record;
43 static tSDP_DISC_REC g_rec;
44
sdp_dm_cback(tBTA_SDP_EVT,tBTA_SDP *,void *)45 static void sdp_dm_cback(tBTA_SDP_EVT /*event*/, tBTA_SDP* /*p_data*/, void* /*user_data*/) {
46 return;
47 }
48
49 class BtaDipTest : public ::testing::Test {
50 protected:
SetUp()51 void SetUp() override {
52 g_attr_service_class_id_list.p_next_attr = &g_attr_spec_id;
53 g_attr_service_class_id_list.attr_id = ATTR_ID_SERVICE_CLASS_ID_LIST;
54 g_attr_service_class_id_list.attr_len_type = (DATA_ELE_SEQ_DESC_TYPE << 12) | 2;
55 g_attr_service_class_id_list.attr_value.v.p_sub_attr = &g_sub_attr;
56 g_sub_attr.attr_len_type = (UUID_DESC_TYPE << 12) | 2;
57 g_sub_attr.attr_value.v.u16 = 0x1200;
58
59 g_attr_spec_id.p_next_attr = &g_attr_vendor_id;
60 g_attr_spec_id.attr_id = ATTR_ID_SPECIFICATION_ID;
61 g_attr_spec_id.attr_len_type = (UINT_DESC_TYPE << 12) | 2;
62 g_attr_spec_id.attr_value.v.u16 = 0x0103;
63
64 g_attr_vendor_id.p_next_attr = &g_attr_vendor_id_src;
65 g_attr_vendor_id.attr_id = ATTR_ID_VENDOR_ID;
66 g_attr_vendor_id.attr_len_type = (UINT_DESC_TYPE << 12) | 2;
67 g_attr_vendor_id.attr_value.v.u16 = 0x18d1;
68
69 // Allocation should succeed
70 g_attr_vendor_id_src.p_next_attr = &g_attr_vendor_product_id;
71 g_attr_vendor_id_src.attr_id = ATTR_ID_VENDOR_ID_SOURCE;
72 g_attr_vendor_id_src.attr_len_type = (UINT_DESC_TYPE << 12) | 2;
73 g_attr_vendor_id_src.attr_value.v.u16 = 1;
74
75 g_attr_vendor_product_id.p_next_attr = &g_attr_vendor_product_version;
76 g_attr_vendor_product_id.attr_id = ATTR_ID_PRODUCT_ID;
77 g_attr_vendor_product_id.attr_len_type = (UINT_DESC_TYPE << 12) | 2;
78 g_attr_vendor_product_id.attr_value.v.u16 = 0x1234;
79
80 g_attr_vendor_product_version.p_next_attr = &g_attr_vendor_product_primary_record;
81 g_attr_vendor_product_version.attr_id = ATTR_ID_PRODUCT_VERSION;
82 g_attr_vendor_product_version.attr_len_type = (UINT_DESC_TYPE << 12) | 2;
83 g_attr_vendor_product_version.attr_value.v.u16 = 0x0100;
84
85 g_attr_vendor_product_primary_record.p_next_attr = &g_attr_vendor_product_primary_record;
86 g_attr_vendor_product_primary_record.attr_id = ATTR_ID_PRIMARY_RECORD;
87 g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 1;
88 g_attr_vendor_product_primary_record.attr_value.v.u8 = 1;
89
90 g_rec.p_first_attr = &g_attr_service_class_id_list;
91 g_rec.p_next_rec = nullptr;
92 g_rec.remote_bd_addr = bdaddr;
93 g_rec.time_read = 0;
94
95 bta_sdp_cb.p_dm_cback = sdp_dm_cback;
96 bta_sdp_cb.remote_addr = bdaddr;
97
98 p_bta_sdp_cfg->p_sdp_db->p_first_rec = &g_rec;
99 }
100
TearDown()101 void TearDown() override {}
102 };
103
104 namespace bluetooth {
105 namespace testing {
106
107 void bta_create_dip_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec);
108 void bta_sdp_search_cback(Uuid uuid, const RawAddress& bd_addr, tSDP_RESULT result);
109
110 } // namespace testing
111 } // namespace bluetooth
112
113 // Test that bta_create_dip_sdp_record can parse sdp record to bluetooth_sdp_record correctly
TEST_F(BtaDipTest,test_bta_create_dip_sdp_record)114 TEST_F(BtaDipTest, test_bta_create_dip_sdp_record) {
115 bluetooth_sdp_record record;
116
117 bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec);
118
119 ASSERT_EQ(record.dip.spec_id, 0x0103);
120 ASSERT_EQ(record.dip.vendor, 0x18d1);
121 ASSERT_EQ(record.dip.vendor_id_source, 1);
122 ASSERT_EQ(record.dip.product, 0x1234);
123 ASSERT_EQ(record.dip.version, 0x0100);
124 ASSERT_EQ(record.dip.primary_record, true);
125 }
126
127 // test for b/263958603
TEST_F(BtaDipTest,test_invalid_type_checks)128 TEST_F(BtaDipTest, test_invalid_type_checks) {
129 bluetooth_sdp_record record{};
130
131 // here we provide the wrong types of records
132 // and verify that the provided values are not accepted
133 g_attr_spec_id.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 1;
134 g_attr_spec_id.attr_value.v.u16 = 0x0103;
135
136 g_attr_vendor_id.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2;
137 g_attr_vendor_id.attr_value.v.u16 = 0x18d1;
138
139 g_attr_vendor_id_src.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2;
140 g_attr_vendor_id_src.attr_value.v.u16 = 1;
141
142 g_attr_vendor_product_id.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2;
143 g_attr_vendor_product_id.attr_value.v.u16 = 0x1234;
144
145 g_attr_vendor_product_version.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2;
146 g_attr_vendor_product_version.attr_value.v.u16 = 0x0100;
147
148 g_attr_vendor_product_primary_record.attr_len_type = (UINT_DESC_TYPE << 12) | 1;
149 g_attr_vendor_product_primary_record.attr_value.v.u8 = 1;
150
151 bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec);
152
153 ASSERT_EQ(record.dip.spec_id, 0);
154 ASSERT_EQ(record.dip.vendor, 0);
155 ASSERT_EQ(record.dip.vendor_id_source, 0);
156 ASSERT_EQ(record.dip.product, 0);
157 ASSERT_EQ(record.dip.version, 0);
158 ASSERT_EQ(record.dip.primary_record, false);
159 }
160
161 // test for b/263958603
TEST_F(BtaDipTest,test_invalid_size_checks)162 TEST_F(BtaDipTest, test_invalid_size_checks) {
163 bluetooth_sdp_record record{};
164
165 // here we provide the wrong sizes of records
166 // and verify that the provided values are not accepted
167 g_attr_spec_id.attr_len_type = (UINT_DESC_TYPE << 12) | 1;
168 g_attr_spec_id.attr_value.v.u16 = 0x0103;
169
170 g_attr_vendor_id.attr_len_type = (UINT_DESC_TYPE << 12) | 1;
171 g_attr_vendor_id.attr_value.v.u16 = 0x18d1;
172
173 g_attr_vendor_id_src.attr_len_type = (UINT_DESC_TYPE << 12) | 1;
174 g_attr_vendor_id_src.attr_value.v.u16 = 1;
175
176 g_attr_vendor_product_id.attr_len_type = (UINT_DESC_TYPE << 12) | 1;
177 g_attr_vendor_product_id.attr_value.v.u16 = 0x1234;
178
179 g_attr_vendor_product_version.attr_len_type = (UINT_DESC_TYPE << 12) | 1;
180 g_attr_vendor_product_version.attr_value.v.u16 = 0x0100;
181
182 // size greater than 1 is accepted
183 g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2;
184 g_attr_vendor_product_primary_record.attr_value.v.u8 = 1;
185
186 bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec);
187
188 ASSERT_EQ(record.dip.spec_id, 0);
189 ASSERT_EQ(record.dip.vendor, 0);
190 ASSERT_EQ(record.dip.vendor_id_source, 0);
191 ASSERT_EQ(record.dip.product, 0);
192 ASSERT_EQ(record.dip.version, 0);
193 ASSERT_EQ(record.dip.primary_record, true);
194
195 // a size zero for boolean won't be accepted
196 g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 0;
197
198 record = {};
199
200 g_attr_vendor_product_primary_record.attr_value.v.u8 = 1;
201 bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec);
202 ASSERT_EQ(record.dip.primary_record, false);
203 }
204
TEST_F(BtaDipTest,test_bta_sdp_search_cback)205 TEST_F(BtaDipTest, test_bta_sdp_search_cback) {
206 bluetooth::testing::bta_sdp_search_cback(UUID_DIP, RawAddress::kEmpty, tSDP_STATUS::SDP_SUCCESS);
207 }
208