/* * Copyright 2022 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 "stack/include/sdp_api.h" #include "stack/include/sdpdefs.h" #include "stack/sdp/sdpint.h" namespace { constexpr char service_name[] = "TestServiceName"; constexpr uint32_t kFirstRecordHandle = 0x10000; } // namespace using bluetooth::legacy::stack::sdp::get_legacy_stack_sdp_api; class StackSdpDbTest : public ::testing::Test { protected: void SetUp() override { // Ensure no records exist in global state ASSERT_EQ((uint16_t)0, sdp_cb.server_db.num_records); } void TearDown() override { // Ensure all records have been deleted from global state ASSERT_EQ((uint16_t)0, sdp_cb.server_db.num_records); } }; TEST_F(StackSdpDbTest, SDP_AddAttribute__create_record) { uint32_t record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); ASSERT_NE((uint32_t)0, record_handle); ASSERT_EQ((uint16_t)1, sdp_cb.server_db.num_records); tSDP_RECORD* record = sdp_db_find_record(record_handle); ASSERT_TRUE(record != nullptr); // The sdp handle is always the first attribute ASSERT_EQ((uint16_t)1, record->num_attributes); ASSERT_EQ(kFirstRecordHandle, record->record_handle); ASSERT_EQ(sizeof(uint32_t), record->free_pad_ptr); ASSERT_TRUE( get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(record_handle)); } TEST_F(StackSdpDbTest, SDP_AddAttribute__add_service_name) { uint32_t record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); ASSERT_NE((uint32_t)0, record_handle); ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); tSDP_RECORD* record = sdp_db_find_record(record_handle); ASSERT_TRUE(record != nullptr); // The sdp handle is always the first attribute ASSERT_EQ((uint16_t)(1 /* record_handle */ + 1 /* service name */), record->num_attributes); ASSERT_EQ(kFirstRecordHandle, record->record_handle); ASSERT_EQ(sizeof(uint32_t) + strlen(service_name) + 1, record->free_pad_ptr); const tSDP_ATTRIBUTE* attribute = sdp_db_find_attr_in_rec( record, ATTR_ID_SERVICE_NAME, ATTR_ID_SERVICE_NAME); ASSERT_TRUE(attribute != nullptr); ASSERT_TRUE( get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(record_handle)); } TEST_F(StackSdpDbTest, SDP_AddAttribute__three_attributes) { uint32_t record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); ASSERT_NE((uint32_t)0, record_handle); ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); tSDP_RECORD* record = sdp_db_find_record(record_handle); ASSERT_TRUE(record != nullptr); // The sdp handle is always the first attribute ASSERT_EQ((uint16_t)(1 /* record_handle */ + 3 /* service name */), record->num_attributes); ASSERT_EQ(kFirstRecordHandle, record->record_handle); ASSERT_EQ(sizeof(uint32_t) + (3 * (strlen(service_name) + 1)), record->free_pad_ptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_SERVICE_NAME, ATTR_ID_SERVICE_NAME) != nullptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_SERVICE_DESCRIPTION, ATTR_ID_SERVICE_DESCRIPTION) != nullptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_PROVIDER_NAME, ATTR_ID_PROVIDER_NAME) != nullptr); ASSERT_TRUE( get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(record_handle)); } TEST_F(StackSdpDbTest, SDP_AddAttribute__too_many_attributes) { uint32_t record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); ASSERT_NE((uint32_t)0, record_handle); uint8_t boolean = 1; for (size_t i = 0; i < SDP_MAX_REC_ATTR; i++) { ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, (uint16_t)i, BOOLEAN_DESC_TYPE, boolean, &boolean)); } ASSERT_FALSE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, SDP_MAX_REC_ATTR + 1, BOOLEAN_DESC_TYPE, boolean, &boolean)); ASSERT_TRUE( get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(record_handle)); } TEST_F(StackSdpDbTest, SDP_AddAttribute__three_attributes_replace_middle) { uint32_t record_handle = get_legacy_stack_sdp_api()->handle.SDP_CreateRecord(); ASSERT_NE((uint32_t)0, record_handle); // Add 3 attributes to this record handle ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); ASSERT_TRUE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE, (uint32_t)(strlen(service_name) + 1), (uint8_t*)service_name)); tSDP_RECORD* record = sdp_db_find_record(record_handle); ASSERT_TRUE(record != nullptr); // The sdp handle is always the first attribute ASSERT_EQ((uint16_t)(1 /* record_handle */ + 3 /* attribute count */), record->num_attributes); ASSERT_EQ(kFirstRecordHandle, record->record_handle); ASSERT_EQ(sizeof(uint32_t) + (3 * (strlen(service_name) + 1)), record->free_pad_ptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_SERVICE_NAME, ATTR_ID_SERVICE_NAME) != nullptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_SERVICE_DESCRIPTION, ATTR_ID_SERVICE_DESCRIPTION) != nullptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_PROVIDER_NAME, ATTR_ID_PROVIDER_NAME) != nullptr); // Attempt to replace the middle attribute with an invalid attribute ASSERT_FALSE(get_legacy_stack_sdp_api()->handle.SDP_AddAttribute( record_handle, ATTR_ID_SERVICE_DESCRIPTION, TEXT_STR_DESC_TYPE, (uint32_t)0, (uint8_t*)nullptr)); // Ensure database is still intact. ASSERT_EQ((uint16_t)(1 /* record_handle */ + 3 /* attribute count */), record->num_attributes); ASSERT_EQ(kFirstRecordHandle, record->record_handle); ASSERT_EQ(sizeof(uint32_t) + (3 * (strlen(service_name) + 1)), record->free_pad_ptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_SERVICE_NAME, ATTR_ID_SERVICE_NAME) != nullptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_SERVICE_DESCRIPTION, ATTR_ID_SERVICE_DESCRIPTION) != nullptr); ASSERT_TRUE(sdp_db_find_attr_in_rec(record, ATTR_ID_PROVIDER_NAME, ATTR_ID_PROVIDER_NAME) != nullptr); ASSERT_TRUE( get_legacy_stack_sdp_api()->handle.SDP_DeleteRecord(record_handle)); }