/****************************************************************************** * * Copyright 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #include #include "bta/sdp/bta_sdp_int.h" #include "btif/include/btif_sock_sdp.h" #include "main/shim/metrics_api.h" #include "stack/include/sdpdefs.h" #include "test/mock/mock_stack_sdp_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" namespace { const RawAddress bdaddr({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); } // namespace tBTA_SDP_CB bta_sdp_cb; static tSDP_DISC_ATTR g_attr_service_class_id_list; static tSDP_DISC_ATTR g_sub_attr; static tSDP_DISC_ATTR g_attr_spec_id; static tSDP_DISC_ATTR g_attr_vendor_id; static tSDP_DISC_ATTR g_attr_vendor_id_src; static tSDP_DISC_ATTR g_attr_vendor_product_id; static tSDP_DISC_ATTR g_attr_vendor_product_version; static tSDP_DISC_ATTR g_attr_vendor_product_primary_record; static tSDP_DISC_REC g_rec; static void sdp_dm_cback(tBTA_SDP_EVT /*event*/, tBTA_SDP* /*p_data*/, void* /*user_data*/) { return; } class BtaDipTest : public ::testing::Test { protected: void SetUp() override { g_attr_service_class_id_list.p_next_attr = &g_attr_spec_id; g_attr_service_class_id_list.attr_id = ATTR_ID_SERVICE_CLASS_ID_LIST; g_attr_service_class_id_list.attr_len_type = (DATA_ELE_SEQ_DESC_TYPE << 12) | 2; g_attr_service_class_id_list.attr_value.v.p_sub_attr = &g_sub_attr; g_sub_attr.attr_len_type = (UUID_DESC_TYPE << 12) | 2; g_sub_attr.attr_value.v.u16 = 0x1200; g_attr_spec_id.p_next_attr = &g_attr_vendor_id; g_attr_spec_id.attr_id = ATTR_ID_SPECIFICATION_ID; g_attr_spec_id.attr_len_type = (UINT_DESC_TYPE << 12) | 2; g_attr_spec_id.attr_value.v.u16 = 0x0103; g_attr_vendor_id.p_next_attr = &g_attr_vendor_id_src; g_attr_vendor_id.attr_id = ATTR_ID_VENDOR_ID; g_attr_vendor_id.attr_len_type = (UINT_DESC_TYPE << 12) | 2; g_attr_vendor_id.attr_value.v.u16 = 0x18d1; // Allocation should succeed g_attr_vendor_id_src.p_next_attr = &g_attr_vendor_product_id; g_attr_vendor_id_src.attr_id = ATTR_ID_VENDOR_ID_SOURCE; g_attr_vendor_id_src.attr_len_type = (UINT_DESC_TYPE << 12) | 2; g_attr_vendor_id_src.attr_value.v.u16 = 1; g_attr_vendor_product_id.p_next_attr = &g_attr_vendor_product_version; g_attr_vendor_product_id.attr_id = ATTR_ID_PRODUCT_ID; g_attr_vendor_product_id.attr_len_type = (UINT_DESC_TYPE << 12) | 2; g_attr_vendor_product_id.attr_value.v.u16 = 0x1234; g_attr_vendor_product_version.p_next_attr = &g_attr_vendor_product_primary_record; g_attr_vendor_product_version.attr_id = ATTR_ID_PRODUCT_VERSION; g_attr_vendor_product_version.attr_len_type = (UINT_DESC_TYPE << 12) | 2; g_attr_vendor_product_version.attr_value.v.u16 = 0x0100; g_attr_vendor_product_primary_record.p_next_attr = &g_attr_vendor_product_primary_record; g_attr_vendor_product_primary_record.attr_id = ATTR_ID_PRIMARY_RECORD; g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 1; g_attr_vendor_product_primary_record.attr_value.v.u8 = 1; g_rec.p_first_attr = &g_attr_service_class_id_list; g_rec.p_next_rec = nullptr; g_rec.remote_bd_addr = bdaddr; g_rec.time_read = 0; bta_sdp_cb.p_dm_cback = sdp_dm_cback; bta_sdp_cb.remote_addr = bdaddr; p_bta_sdp_cfg->p_sdp_db->p_first_rec = &g_rec; } void TearDown() override {} }; namespace bluetooth { namespace testing { void bta_create_dip_sdp_record(bluetooth_sdp_record* record, tSDP_DISC_REC* p_rec); void bta_sdp_search_cback(Uuid uuid, const RawAddress& bd_addr, tSDP_RESULT result); } // namespace testing } // namespace bluetooth // 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) { bluetooth_sdp_record record; bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec); ASSERT_EQ(record.dip.spec_id, 0x0103); ASSERT_EQ(record.dip.vendor, 0x18d1); ASSERT_EQ(record.dip.vendor_id_source, 1); ASSERT_EQ(record.dip.product, 0x1234); ASSERT_EQ(record.dip.version, 0x0100); ASSERT_EQ(record.dip.primary_record, true); } // test for b/263958603 TEST_F(BtaDipTest, test_invalid_type_checks) { bluetooth_sdp_record record{}; // here we provide the wrong types of records // and verify that the provided values are not accepted g_attr_spec_id.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 1; g_attr_spec_id.attr_value.v.u16 = 0x0103; g_attr_vendor_id.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2; g_attr_vendor_id.attr_value.v.u16 = 0x18d1; g_attr_vendor_id_src.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2; g_attr_vendor_id_src.attr_value.v.u16 = 1; g_attr_vendor_product_id.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2; g_attr_vendor_product_id.attr_value.v.u16 = 0x1234; g_attr_vendor_product_version.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2; g_attr_vendor_product_version.attr_value.v.u16 = 0x0100; g_attr_vendor_product_primary_record.attr_len_type = (UINT_DESC_TYPE << 12) | 1; g_attr_vendor_product_primary_record.attr_value.v.u8 = 1; bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec); ASSERT_EQ(record.dip.spec_id, 0); ASSERT_EQ(record.dip.vendor, 0); ASSERT_EQ(record.dip.vendor_id_source, 0); ASSERT_EQ(record.dip.product, 0); ASSERT_EQ(record.dip.version, 0); ASSERT_EQ(record.dip.primary_record, false); } // test for b/263958603 TEST_F(BtaDipTest, test_invalid_size_checks) { bluetooth_sdp_record record{}; // here we provide the wrong sizes of records // and verify that the provided values are not accepted g_attr_spec_id.attr_len_type = (UINT_DESC_TYPE << 12) | 1; g_attr_spec_id.attr_value.v.u16 = 0x0103; g_attr_vendor_id.attr_len_type = (UINT_DESC_TYPE << 12) | 1; g_attr_vendor_id.attr_value.v.u16 = 0x18d1; g_attr_vendor_id_src.attr_len_type = (UINT_DESC_TYPE << 12) | 1; g_attr_vendor_id_src.attr_value.v.u16 = 1; g_attr_vendor_product_id.attr_len_type = (UINT_DESC_TYPE << 12) | 1; g_attr_vendor_product_id.attr_value.v.u16 = 0x1234; g_attr_vendor_product_version.attr_len_type = (UINT_DESC_TYPE << 12) | 1; g_attr_vendor_product_version.attr_value.v.u16 = 0x0100; // size greater than 1 is accepted g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 2; g_attr_vendor_product_primary_record.attr_value.v.u8 = 1; bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec); ASSERT_EQ(record.dip.spec_id, 0); ASSERT_EQ(record.dip.vendor, 0); ASSERT_EQ(record.dip.vendor_id_source, 0); ASSERT_EQ(record.dip.product, 0); ASSERT_EQ(record.dip.version, 0); ASSERT_EQ(record.dip.primary_record, true); // a size zero for boolean won't be accepted g_attr_vendor_product_primary_record.attr_len_type = (BOOLEAN_DESC_TYPE << 12) | 0; record = {}; g_attr_vendor_product_primary_record.attr_value.v.u8 = 1; bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec); ASSERT_EQ(record.dip.primary_record, false); } TEST_F(BtaDipTest, test_bta_sdp_search_cback) { bluetooth::testing::bta_sdp_search_cback(UUID_DIP, RawAddress::kEmpty, tSDP_STATUS::SDP_SUCCESS); }