10f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// 20f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// Copyright (C) 2015 Google, Inc. 30f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// 40f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// Licensed under the Apache License, Version 2.0 (the "License"); 50f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// you may not use this file except in compliance with the License. 60f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// You may obtain a copy of the License at: 70f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// 80f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// http://www.apache.org/licenses/LICENSE-2.0 90f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// 100f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// Unless required by applicable law or agreed to in writing, software 110f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// distributed under the License is distributed on an "AS IS" BASIS, 120f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// See the License for the specific language governing permissions and 140f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// limitations under the License. 150f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray// 160f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 170f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray#include <gmock/gmock.h> 180f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray#include <gtest/gtest.h> 190f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 20234138e2606dd7a54fbcc540643511abc0a3598dArman Uguray#include "service/common/bluetooth/util/address_helper.h" 210f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray#include "service/gatt_server.h" 220f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray#include "service/hal/fake_bluetooth_gatt_interface.h" 23df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray#include "service/hal/gatt_helpers.h" 240f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 250f2d4897046f037a9f181f47f3d349a9dd646478Arman Ugurayusing ::testing::_; 260f2d4897046f037a9f181f47f3d349a9dd646478Arman Ugurayusing ::testing::Return; 270f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 280f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguraynamespace bluetooth { 290f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguraynamespace { 300f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 310f2d4897046f037a9f181f47f3d349a9dd646478Arman Ugurayclass MockGattHandler 320f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray : public hal::FakeBluetoothGattInterface::TestServerHandler { 330f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray public: 340f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray MockGattHandler() = default; 350f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray ~MockGattHandler() override = default; 360f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 370f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray MOCK_METHOD1(RegisterServer, bt_status_t(bt_uuid_t*)); 380f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray MOCK_METHOD1(UnregisterServer, bt_status_t(int)); 3978a44cdb25616892087af2c92abd382878c2ccb4Arman Uguray MOCK_METHOD3(AddService, bt_status_t(int, btgatt_srvc_id_t*, int)); 4091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray MOCK_METHOD5(AddCharacteristic, bt_status_t(int, int, bt_uuid_t*, int, int)); 41d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray MOCK_METHOD4(AddDescriptor, bt_status_t(int, int, bt_uuid_t*, int)); 4278a44cdb25616892087af2c92abd382878c2ccb4Arman Uguray MOCK_METHOD3(StartService, bt_status_t(int, int, int)); 4378a44cdb25616892087af2c92abd382878c2ccb4Arman Uguray MOCK_METHOD2(DeleteService, bt_status_t(int, int)); 44cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray MOCK_METHOD6(SendIndication, bt_status_t(int, int, int, int, int, char*)); 45b10f96fa25266b69d0d31af166e93afe14134be7Arman Uguray MOCK_METHOD4(SendResponse, bt_status_t(int, int, int, btgatt_response_t*)); 460f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 470f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray private: 480f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray DISALLOW_COPY_AND_ASSIGN(MockGattHandler); 490f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray}; 500f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 51514bf6087093375351784b287cb29c5f4603273cArman Ugurayclass TestDelegate : public GattServer::Delegate { 52514bf6087093375351784b287cb29c5f4603273cArman Uguray public: 53514bf6087093375351784b287cb29c5f4603273cArman Uguray TestDelegate() = default; 54514bf6087093375351784b287cb29c5f4603273cArman Uguray ~TestDelegate() override = default; 55514bf6087093375351784b287cb29c5f4603273cArman Uguray 56514bf6087093375351784b287cb29c5f4603273cArman Uguray struct RequestData { 574ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray RequestData() : id(-1), offset(-1), is_long(false), is_prep(false), 584ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray need_rsp(false), is_exec(false), count(0) {} 59514bf6087093375351784b287cb29c5f4603273cArman Uguray ~RequestData() = default; 60514bf6087093375351784b287cb29c5f4603273cArman Uguray 61514bf6087093375351784b287cb29c5f4603273cArman Uguray std::string device_address; 62514bf6087093375351784b287cb29c5f4603273cArman Uguray int id; 63514bf6087093375351784b287cb29c5f4603273cArman Uguray int offset; 64514bf6087093375351784b287cb29c5f4603273cArman Uguray bool is_long; 654ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray bool is_prep; 664ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray bool need_rsp; 674ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray bool is_exec; 68514bf6087093375351784b287cb29c5f4603273cArman Uguray GattIdentifier gatt_id; 69514bf6087093375351784b287cb29c5f4603273cArman Uguray int count; 704ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray std::vector<uint8_t> write_value; 71514bf6087093375351784b287cb29c5f4603273cArman Uguray }; 72514bf6087093375351784b287cb29c5f4603273cArman Uguray 73514bf6087093375351784b287cb29c5f4603273cArman Uguray void OnCharacteristicReadRequest( 74514bf6087093375351784b287cb29c5f4603273cArman Uguray GattServer* gatt_server, 75514bf6087093375351784b287cb29c5f4603273cArman Uguray const std::string& device_address, 76514bf6087093375351784b287cb29c5f4603273cArman Uguray int request_id, int offset, bool is_long, 77514bf6087093375351784b287cb29c5f4603273cArman Uguray const bluetooth::GattIdentifier& characteristic_id) override { 78514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(gatt_server); 794ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_read_req_.device_address = device_address; 804ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_read_req_.id = request_id; 814ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_read_req_.offset = offset; 824ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_read_req_.is_long = is_long; 834ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_read_req_.gatt_id = characteristic_id; 844ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_read_req_.count++; 85514bf6087093375351784b287cb29c5f4603273cArman Uguray } 86514bf6087093375351784b287cb29c5f4603273cArman Uguray 87514bf6087093375351784b287cb29c5f4603273cArman Uguray void OnDescriptorReadRequest( 88514bf6087093375351784b287cb29c5f4603273cArman Uguray GattServer* gatt_server, 89514bf6087093375351784b287cb29c5f4603273cArman Uguray const std::string& device_address, 90514bf6087093375351784b287cb29c5f4603273cArman Uguray int request_id, int offset, bool is_long, 91514bf6087093375351784b287cb29c5f4603273cArman Uguray const bluetooth::GattIdentifier& descriptor_id) override { 92514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(gatt_server); 934ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_read_req_.device_address = device_address; 944ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_read_req_.id = request_id; 954ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_read_req_.offset = offset; 964ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_read_req_.is_long = is_long; 974ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_read_req_.gatt_id = descriptor_id; 984ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_read_req_.count++; 99514bf6087093375351784b287cb29c5f4603273cArman Uguray } 100514bf6087093375351784b287cb29c5f4603273cArman Uguray 1014ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray void OnCharacteristicWriteRequest( 1024ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GattServer* gatt_server, 1034ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::string& device_address, 1044ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray int request_id, int offset, bool is_prepare_write, bool need_response, 1054ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::vector<uint8_t>& value, 1064ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const bluetooth::GattIdentifier& characteristic_id) override { 1074ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray ASSERT_TRUE(gatt_server); 1084ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.device_address = device_address; 1094ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.id = request_id; 1104ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.offset = offset; 1114ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.is_prep = is_prepare_write; 1124ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.need_rsp = need_response; 1134ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.gatt_id = characteristic_id; 1144ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.count++; 1154ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray char_write_req_.write_value = value; 1164ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray } 1174ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 1184ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray void OnDescriptorWriteRequest( 1194ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GattServer* gatt_server, 1204ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::string& device_address, 1214ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray int request_id, int offset, bool is_prepare_write, bool need_response, 1224ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::vector<uint8_t>& value, 1234ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const bluetooth::GattIdentifier& descriptor_id) override { 1244ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray ASSERT_TRUE(gatt_server); 1254ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.device_address = device_address; 1264ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.id = request_id; 1274ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.offset = offset; 1284ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.is_prep = is_prepare_write; 1294ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.need_rsp = need_response; 1304ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.gatt_id = descriptor_id; 1314ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.count++; 1324ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray desc_write_req_.write_value = value; 1334ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray } 1344ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 1354ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray void OnExecuteWriteRequest( 1364ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GattServer* gatt_server, 1374ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::string& device_address, 1384ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray int request_id, bool is_execute) override { 1394ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray ASSERT_TRUE(gatt_server); 1404ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray exec_req_.device_address = device_address; 1414ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray exec_req_.id = request_id; 1424ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray exec_req_.is_exec = is_execute; 1434ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray exec_req_.count++; 1444ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray } 1454ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 1464ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const RequestData& char_read_req() const { return char_read_req_; } 1474ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const RequestData& desc_read_req() const { return desc_read_req_; } 1484ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const RequestData& char_write_req() const { return char_write_req_; } 1494ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const RequestData& desc_write_req() const { return desc_write_req_; } 150514bf6087093375351784b287cb29c5f4603273cArman Uguray 151514bf6087093375351784b287cb29c5f4603273cArman Uguray private: 1524ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray RequestData char_read_req_; 1534ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray RequestData desc_read_req_; 1544ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray RequestData char_write_req_; 1554ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray RequestData desc_write_req_; 1564ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray RequestData exec_req_; 157514bf6087093375351784b287cb29c5f4603273cArman Uguray}; 158514bf6087093375351784b287cb29c5f4603273cArman Uguray 1590f2d4897046f037a9f181f47f3d349a9dd646478Arman Ugurayclass GattServerTest : public ::testing::Test { 1600f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray public: 1610f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray GattServerTest() = default; 1620f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray ~GattServerTest() override = default; 1630f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 1640f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray void SetUp() override { 1650f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray mock_handler_.reset(new MockGattHandler()); 1660f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface( 1670f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray nullptr, 1680f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray std::static_pointer_cast< 1690f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray hal::FakeBluetoothGattInterface::TestServerHandler>(mock_handler_)); 1700f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 1710f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_); 1720f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray factory_.reset(new GattServerFactory()); 1730f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray } 1740f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 1750f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray void TearDown() override { 1760f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray factory_.reset(); 1770f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray hal::BluetoothGattInterface::CleanUp(); 1780f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray } 1790f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 1800f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray protected: 1810f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_; 1820f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray std::shared_ptr<MockGattHandler> mock_handler_; 1830f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray std::unique_ptr<GattServerFactory> factory_; 1840f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 1850f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray private: 1860f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray DISALLOW_COPY_AND_ASSIGN(GattServerTest); 1870f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray}; 1880f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 189df0b2714553cabc735222ce18a5f018c5a5fa138Arman Ugurayconst int kDefaultServerId = 4; 190df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 191df0b2714553cabc735222ce18a5f018c5a5fa138Arman Ugurayclass GattServerPostRegisterTest : public GattServerTest { 192df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray public: 193df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray GattServerPostRegisterTest() = default; 194df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray ~GattServerPostRegisterTest() override = default; 195df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 196df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray void SetUp() override { 197df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray GattServerTest::SetUp(); 198df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray UUID uuid = UUID::GetRandom(); 199df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto callback = [&](BLEStatus status, const UUID& in_uuid, 200bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray std::unique_ptr<BluetoothInstance> in_client) { 201df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray CHECK(in_uuid == uuid); 202df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray CHECK(in_client.get()); 203df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray CHECK(status == BLE_STATUS_SUCCESS); 204df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 205df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray gatt_server_ = std::unique_ptr<GattServer>( 206df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray static_cast<GattServer*>(in_client.release())); 207df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray }; 208df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 209df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_CALL(*mock_handler_, RegisterServer(_)) 210df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(1) 211df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 212df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 213bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray factory_->RegisterInstance(uuid, callback); 214df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 215df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray bt_uuid_t hal_uuid = uuid.GetBlueDroid(); 216df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyRegisterServerCallback( 217df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, 218df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray kDefaultServerId, 219df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray hal_uuid); 220df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray } 221df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 222df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray void TearDown() override { 223df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_CALL(*mock_handler_, UnregisterServer(_)) 224df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(1) 225df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 226df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray gatt_server_ = nullptr; 227df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray GattServerTest::TearDown(); 228df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray } 229df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 230514bf6087093375351784b287cb29c5f4603273cArman Uguray void SetUpTestService() { 231514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_CALL(*mock_handler_, AddService(_, _, _)) 232514bf6087093375351784b287cb29c5f4603273cArman Uguray .Times(1) 233514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 234514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_CALL(*mock_handler_, AddCharacteristic(_, _, _, _, _)) 235514bf6087093375351784b287cb29c5f4603273cArman Uguray .Times(1) 236514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 237514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_CALL(*mock_handler_, AddDescriptor(_, _, _, _)) 238514bf6087093375351784b287cb29c5f4603273cArman Uguray .Times(1) 239514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 240514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_CALL(*mock_handler_, StartService(_, _, _)) 241514bf6087093375351784b287cb29c5f4603273cArman Uguray .Times(1) 242514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 243514bf6087093375351784b287cb29c5f4603273cArman Uguray 244514bf6087093375351784b287cb29c5f4603273cArman Uguray UUID uuid0 = UUID::GetRandom(); 245514bf6087093375351784b287cb29c5f4603273cArman Uguray UUID uuid1 = UUID::GetRandom(); 246514bf6087093375351784b287cb29c5f4603273cArman Uguray UUID uuid2 = UUID::GetRandom(); 247514bf6087093375351784b287cb29c5f4603273cArman Uguray 248514bf6087093375351784b287cb29c5f4603273cArman Uguray bool register_success = false; 249514bf6087093375351784b287cb29c5f4603273cArman Uguray 250514bf6087093375351784b287cb29c5f4603273cArman Uguray // Doesn't matter what the permissions/properties are since this is all 251514bf6087093375351784b287cb29c5f4603273cArman Uguray // fake. 252514bf6087093375351784b287cb29c5f4603273cArman Uguray test_service_id_ = *gatt_server_->BeginServiceDeclaration(uuid0, true); 253514bf6087093375351784b287cb29c5f4603273cArman Uguray test_char_id_ = *gatt_server_->AddCharacteristic(uuid1, 0, 0); 254514bf6087093375351784b287cb29c5f4603273cArman Uguray test_desc_id_ = *gatt_server_->AddDescriptor(uuid2, 0); 255514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(gatt_server_->EndServiceDeclaration([&]( 256514bf6087093375351784b287cb29c5f4603273cArman Uguray BLEStatus status, const GattIdentifier& gatt_id) { 257514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_EQ(BLE_STATUS_SUCCESS, status); 258514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(gatt_id == test_service_id_); 259514bf6087093375351784b287cb29c5f4603273cArman Uguray register_success = true; 260514bf6087093375351784b287cb29c5f4603273cArman Uguray })); 261514bf6087093375351784b287cb29c5f4603273cArman Uguray 262514bf6087093375351784b287cb29c5f4603273cArman Uguray btgatt_srvc_id_t hal_srvc_id; 263514bf6087093375351784b287cb29c5f4603273cArman Uguray hal::GetHALServiceId(test_service_id_, &hal_srvc_id); 264514bf6087093375351784b287cb29c5f4603273cArman Uguray bt_uuid_t hal_uuid1 = uuid1.GetBlueDroid(); 265514bf6087093375351784b287cb29c5f4603273cArman Uguray bt_uuid_t hal_uuid2 = uuid2.GetBlueDroid(); 266514bf6087093375351784b287cb29c5f4603273cArman Uguray 267514bf6087093375351784b287cb29c5f4603273cArman Uguray srvc_handle_ = 0x0001; 268514bf6087093375351784b287cb29c5f4603273cArman Uguray char_handle_ = 0x0003; 269514bf6087093375351784b287cb29c5f4603273cArman Uguray desc_handle_ = 0x0004; 270514bf6087093375351784b287cb29c5f4603273cArman Uguray 271514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 272514bf6087093375351784b287cb29c5f4603273cArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_srvc_id, srvc_handle_); 273514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 274514bf6087093375351784b287cb29c5f4603273cArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_uuid1, 275514bf6087093375351784b287cb29c5f4603273cArman Uguray srvc_handle_, char_handle_); 276514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 277514bf6087093375351784b287cb29c5f4603273cArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_uuid2, 278514bf6087093375351784b287cb29c5f4603273cArman Uguray srvc_handle_, desc_handle_); 279514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyServiceStartedCallback( 280514bf6087093375351784b287cb29c5f4603273cArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, srvc_handle_); 281514bf6087093375351784b287cb29c5f4603273cArman Uguray 282514bf6087093375351784b287cb29c5f4603273cArman Uguray testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 283514bf6087093375351784b287cb29c5f4603273cArman Uguray 284514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(register_success); 285514bf6087093375351784b287cb29c5f4603273cArman Uguray } 286514bf6087093375351784b287cb29c5f4603273cArman Uguray 287df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray protected: 288df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray std::unique_ptr<GattServer> gatt_server_; 289df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 290514bf6087093375351784b287cb29c5f4603273cArman Uguray GattIdentifier test_service_id_; 291514bf6087093375351784b287cb29c5f4603273cArman Uguray GattIdentifier test_char_id_; 292514bf6087093375351784b287cb29c5f4603273cArman Uguray GattIdentifier test_desc_id_; 293514bf6087093375351784b287cb29c5f4603273cArman Uguray int srvc_handle_; 294514bf6087093375351784b287cb29c5f4603273cArman Uguray int char_handle_; 295514bf6087093375351784b287cb29c5f4603273cArman Uguray int desc_handle_; 296514bf6087093375351784b287cb29c5f4603273cArman Uguray 297df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray private: 298df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray DISALLOW_COPY_AND_ASSIGN(GattServerPostRegisterTest); 299df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray}; 300df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 3010f2d4897046f037a9f181f47f3d349a9dd646478Arman UgurayTEST_F(GattServerTest, RegisterServer) { 3020f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_CALL(*mock_handler_, RegisterServer(_)) 3030f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .Times(2) 3040f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 3050f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 3060f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3070f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // These will be asynchronously populate with a result when the callback 3080f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // executes. 3090f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray BLEStatus status = BLE_STATUS_SUCCESS; 3100f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray UUID cb_uuid; 3110f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray std::unique_ptr<GattServer> server; 3120f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray int callback_count = 0; 3130f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3140f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray auto callback = [&](BLEStatus in_status, const UUID& uuid, 315bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray std::unique_ptr<BluetoothInstance> in_server) { 3160f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray status = in_status; 3170f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray cb_uuid = uuid; 3180f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray server = std::unique_ptr<GattServer>( 3190f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray static_cast<GattServer*>(in_server.release())); 3200f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray callback_count++; 3210f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray }; 3220f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3230f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray UUID uuid0 = UUID::GetRandom(); 3240f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3250f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // HAL returns failure. 326bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback)); 3270f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(0, callback_count); 3280f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3290f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // HAL returns success. 330bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_TRUE(factory_->RegisterInstance(uuid0, callback)); 3310f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(0, callback_count); 3320f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3330f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // Calling twice with the same UUID should fail with no additional calls into 3340f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // the stack. 335bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_FALSE(factory_->RegisterInstance(uuid0, callback)); 3360f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3370f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 3380f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3390f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // Call with a different UUID while one is pending. 3400f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray UUID uuid1 = UUID::GetRandom(); 3410f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_CALL(*mock_handler_, RegisterServer(_)) 3420f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .Times(1) 3430f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 344bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_TRUE(factory_->RegisterInstance(uuid1, callback)); 3450f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3460f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // Trigger callback with an unknown UUID. This should get ignored. 3470f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray UUID uuid2 = UUID::GetRandom(); 3480f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray bt_uuid_t hal_uuid = uuid2.GetBlueDroid(); 3490f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray fake_hal_gatt_iface_->NotifyRegisterServerCallback(0, 0, hal_uuid); 3500f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(0, callback_count); 3510f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3520f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // |uuid0| succeeds. 3530f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray int server_if0 = 2; // Pick something that's not 0. 3540f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray hal_uuid = uuid0.GetBlueDroid(); 3550f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray fake_hal_gatt_iface_->NotifyRegisterServerCallback( 3560f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray BT_STATUS_SUCCESS, server_if0, hal_uuid); 3570f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3580f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(1, callback_count); 3590f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray ASSERT_TRUE(server.get() != nullptr); // Assert to terminate in case of error 3600f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(BLE_STATUS_SUCCESS, status); 361bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_EQ(server_if0, server->GetInstanceId()); 3620f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(uuid0, server->GetAppIdentifier()); 3630f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(uuid0, cb_uuid); 3640f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3650f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // The server should unregister itself when deleted. 3660f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_CALL(*mock_handler_, UnregisterServer(server_if0)) 3670f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .Times(1) 3680f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 3690f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray server.reset(); 3700f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3710f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 3720f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3730f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray // |uuid1| fails. 3740f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray int server_if1 = 3; 3750f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray hal_uuid = uuid1.GetBlueDroid(); 3760f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray fake_hal_gatt_iface_->NotifyRegisterServerCallback( 3770f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray BT_STATUS_FAIL, server_if1, hal_uuid); 3780f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 3790f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(2, callback_count); 3800f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray ASSERT_TRUE(server.get() == nullptr); // Assert to terminate in case of error 3810f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(BLE_STATUS_FAILURE, status); 3820f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray EXPECT_EQ(uuid1, cb_uuid); 3830f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray} 3840f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray 385df0b2714553cabc735222ce18a5f018c5a5fa138Arman UgurayTEST_F(GattServerPostRegisterTest, SimpleServiceTest) { 386df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Setup a service callback. 387df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray GattIdentifier cb_id; 388df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BLEStatus cb_status = BLE_STATUS_SUCCESS; 389df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray int cb_count = 0; 390df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto callback = [&](BLEStatus in_status, const GattIdentifier& in_id) { 391df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray cb_id = in_id; 392df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray cb_status = in_status; 393df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray cb_count++; 394df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray }; 395df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 396df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Service declaration not started. 397df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_FALSE(gatt_server_->EndServiceDeclaration(callback)); 398df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 399df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray const UUID uuid = UUID::GetRandom(); 400df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto service_id = gatt_server_->BeginServiceDeclaration(uuid, true); 401df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(service_id != nullptr); 402df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(service_id->IsService()); 403df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 404df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Already started. 405df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_FALSE(gatt_server_->BeginServiceDeclaration(uuid, false)); 406df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 407df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Callback is NULL. 408df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_FALSE( 409df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray gatt_server_->EndServiceDeclaration(GattServer::ResultCallback())); 410df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 411df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // We should get a call for a service with one handle. 412bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_CALL(*mock_handler_, AddService(gatt_server_->GetInstanceId(), _, 1)) 413df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(2) 414df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 415df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 416df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 417df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Stack returns failure. This will cause the entire service declaration to 418df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // end and needs to be restarted. 419df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_FALSE(gatt_server_->EndServiceDeclaration(callback)); 420df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 421df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray service_id = gatt_server_->BeginServiceDeclaration(uuid, true); 422df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(service_id != nullptr); 423df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(service_id->IsService()); 424df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 425df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Stack returns success. 426df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 427df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 428df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // EndServiceDeclaration already in progress. 429df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_FALSE(gatt_server_->EndServiceDeclaration(callback)); 430df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 431df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(0, cb_count); 432df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 433df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray btgatt_srvc_id_t hal_id; 434df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 435df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray int srvc_handle = 0x0001; 436df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 437df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report success for AddService but for wrong server. Should be ignored. 438df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 439df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId + 1, hal_id, srvc_handle); 440df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(0, cb_count); 441df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 442df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report success for AddService. 443df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_CALL(*mock_handler_, StartService(kDefaultServerId, srvc_handle, _)) 444df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(1) 445df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 446df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 447df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 448df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 449df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(0, cb_count); 450df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 451df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report success for StartService but for wrong server. Should be ignored. 452df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceStartedCallback( 453df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId + 1, srvc_handle); 454df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(0, cb_count); 455df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 456df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report success for StartService. 457df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceStartedCallback( 458df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, srvc_handle); 459df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(1, cb_count); 460df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(BLE_STATUS_SUCCESS, cb_status); 461df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(cb_id == *service_id); 462df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 463df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Start new service declaration with same UUID. We should get a different ID. 464df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto service_id1 = gatt_server_->BeginServiceDeclaration(uuid, true); 465df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(service_id1 != nullptr); 466df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(service_id1->IsService()); 467df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(*service_id != *service_id1); 468df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray} 469df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 470df0b2714553cabc735222ce18a5f018c5a5fa138Arman UgurayTEST_F(GattServerPostRegisterTest, AddServiceFailures) { 471df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Setup a service callback. 472df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray GattIdentifier cb_id; 473df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BLEStatus cb_status = BLE_STATUS_SUCCESS; 474df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray int cb_count = 0; 475df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto callback = [&](BLEStatus in_status, const GattIdentifier& in_id) { 476df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray cb_id = in_id; 477df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray cb_status = in_status; 478df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray cb_count++; 479df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray }; 480df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 481df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray const UUID uuid = UUID::GetRandom(); 482df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto service_id = gatt_server_->BeginServiceDeclaration(uuid, true); 483df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray btgatt_srvc_id_t hal_id; 484df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 485df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray int srvc_handle = 0x0001; 486df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 487bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_CALL(*mock_handler_, AddService(gatt_server_->GetInstanceId(), _, 1)) 488df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(3) 489df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillRepeatedly(Return(BT_STATUS_SUCCESS)); 490df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 491df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 492df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report failure for AddService. 493df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 494df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_FAIL, kDefaultServerId, hal_id, srvc_handle); 495df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(1, cb_count); 496df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 497df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(cb_id == *service_id); 498df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 499df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Restart. We should get the same ID back. 500df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray auto service_id1 = gatt_server_->BeginServiceDeclaration(uuid, true); 501df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(*service_id1 == *service_id); 502df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 503df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 504df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report success for AddService but return failure from StartService. 505bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray EXPECT_CALL(*mock_handler_, StartService(gatt_server_->GetInstanceId(), 1, _)) 506df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(2) 507df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 508df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 509df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 510df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 511df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 512df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(2, cb_count); 513df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 514df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(cb_id == *service_id); 515df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 516df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Restart. 517df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray service_id = gatt_server_->BeginServiceDeclaration(uuid, true); 518df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 519df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 520df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report success for AddService, return success from StartService. 521df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 522df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 523df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(2, cb_count); 524df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 525df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray // Report failure for StartService. Added service data should get deleted. 526df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_CALL(*mock_handler_, 527bb18c41ffa0370d4eb0c4a15904b114355606466Arman Uguray DeleteService(gatt_server_->GetInstanceId(), srvc_handle)) 528df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .Times(1) 529df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 530df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray fake_hal_gatt_iface_->NotifyServiceStartedCallback( 531df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray BT_STATUS_FAIL, kDefaultServerId, srvc_handle); 532df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_EQ(3, cb_count); 533df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 534df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray EXPECT_TRUE(cb_id == *service_id); 535df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray} 536df0b2714553cabc735222ce18a5f018c5a5fa138Arman Uguray 53791613743c9db02dbe05d93d2afa163b78068d054Arman UgurayTEST_F(GattServerPostRegisterTest, AddCharacteristic) { 53891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Just pick some values. 53991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray const int props = bluetooth::kCharacteristicPropertyRead | 54091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray bluetooth::kCharacteristicPropertyNotify; 54191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray const int perms = kAttributePermissionReadEncrypted; 54291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray const UUID char_uuid = UUID::GetRandom(); 54391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray bt_uuid_t hal_char_uuid = char_uuid.GetBlueDroid(); 54491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 54591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Declaration not started. 54691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(nullptr, gatt_server_->AddCharacteristic(char_uuid, props, perms)); 54791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 54891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Start a service declaration. 54991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray const UUID service_uuid = UUID::GetRandom(); 55091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray auto service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 55191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(service_id != nullptr); 55291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray btgatt_srvc_id_t hal_id; 55391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 55491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 55591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Add two characteristics with the same UUID. 55691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray auto char_id0 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 55791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray auto char_id1 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 55891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 55991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(char_id0 != nullptr); 56091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(char_id1 != nullptr); 56191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(char_id0 != char_id1); 56291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(char_id0->IsCharacteristic()); 56391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(char_id1->IsCharacteristic()); 56491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(*char_id0->GetOwningServiceId() == *service_id); 56591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(*char_id1->GetOwningServiceId() == *service_id); 56691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 56791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Expect calls for 5 handles in total as we have 2 characteristics. 56891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_CALL(*mock_handler_, AddService(kDefaultServerId, _, 5)) 56991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillRepeatedly(Return(BT_STATUS_SUCCESS)); 57091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 57191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray GattIdentifier cb_id; 57291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BLEStatus cb_status; 57391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray int cb_count = 0; 57491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray auto callback = [&](BLEStatus in_status, const GattIdentifier& in_id) { 57591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray cb_id = in_id; 57691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray cb_status = in_status; 57791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray cb_count++; 57891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray }; 57991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 58091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray int srvc_handle = 0x0001; 58191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray int char_handle0 = 0x0002; 58291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray int char_handle1 = 0x0004; 58391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 58491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 585d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Cannot add any more characteristics while EndServiceDeclaration is in 586d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // progress. 587d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(nullptr, gatt_server_->AddCharacteristic(char_uuid, props, perms)); 588d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 58991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_CALL(*mock_handler_, AddCharacteristic(_, _, _, _, _)) 59091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .Times(8) 59191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) // char_id0 - try 1 59291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // char_id0 - try 2 59391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // char_id0 - try 3 59491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) // char_id1 - try 3 59591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // char_id0 - try 4 59691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // char_id1 - try 4 59791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // char_id0 - try 5 59891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); // char_id1 - try 5 59991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 60091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // First AddCharacteristic call will fail. 60191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 60291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 60391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(1, cb_count); 60491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 60591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(cb_id == *service_id); 60691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 60791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Restart. (try 2) 60891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 60991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 61091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 61191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 61291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 61391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 61491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 61591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 61691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(1, cb_count); 61791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 61891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Report failure for pending AddCharacteristic. 61991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 62091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_FAIL, kDefaultServerId, hal_char_uuid, 62191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray srvc_handle, char_handle0); 62291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(2, cb_count); 62391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 62491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(cb_id == *service_id); 62591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 62691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Restart. (try 3) 62791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 62891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 62991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 63091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 63191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 63291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 63391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 63491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 63591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(2, cb_count); 63691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 63791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Report success for pending AddCharacteristic we should receive a call for 63891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // the second characteristic which will fail. 63991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 64091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid, 64191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray srvc_handle, char_handle0); 64291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(3, cb_count); 64391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 64491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(cb_id == *service_id); 64591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 64691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Restart. (try 4) 64791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 64891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 64991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 65091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 65191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 65291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 65391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 65491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 65591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(3, cb_count); 65691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 65791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Report success for pending AddCharacteristic. Second characteristic call 65891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // will start normally. We shouldn't receive any new callback. 65991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 66091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid, 66191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray srvc_handle, char_handle0); 66291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(3, cb_count); 66391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 66491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Report failure for pending AddCharacteristic call for second 66591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // characteristic. 66691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 66791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_FAIL, kDefaultServerId, hal_char_uuid, 66891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray srvc_handle, char_handle1); 66991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(4, cb_count); 67091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 67191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(cb_id == *service_id); 67291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 67391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Restart. (try 5) 67491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 67591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 67691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid, props, perms); 67791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray hal::GetHALServiceId(*service_id, &hal_id); 67891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 67991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 68091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 68191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 68291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(4, cb_count); 68391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 68491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Report success for pending AddCharacteristic. Second characteristic call 68591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // will start normally. We shouldn't receive any new callback. 68691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 68791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid, 68891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray srvc_handle, char_handle0); 68991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(4, cb_count); 69091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 69191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // Report success for pending AddCharacteristic call for second 69291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // characteristic. We shouldn't receive any new callback but we'll get a call 69391613743c9db02dbe05d93d2afa163b78068d054Arman Uguray // to StartService. 69491613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_CALL(*mock_handler_, StartService(kDefaultServerId, srvc_handle, _)) 69591613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .Times(1) 69691613743c9db02dbe05d93d2afa163b78068d054Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 69791613743c9db02dbe05d93d2afa163b78068d054Arman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 69891613743c9db02dbe05d93d2afa163b78068d054Arman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid, 69991613743c9db02dbe05d93d2afa163b78068d054Arman Uguray srvc_handle, char_handle1); 70091613743c9db02dbe05d93d2afa163b78068d054Arman Uguray EXPECT_EQ(4, cb_count); 70191613743c9db02dbe05d93d2afa163b78068d054Arman Uguray} 70291613743c9db02dbe05d93d2afa163b78068d054Arman Uguray 703d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman UgurayTEST_F(GattServerPostRegisterTest, AddDescriptor) { 704d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Set up some values for UUIDs, permissions, and properties. 705d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray const UUID service_uuid = UUID::GetRandom(); 706d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray const UUID char_uuid0 = UUID::GetRandom(); 707d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray const UUID char_uuid1 = UUID::GetRandom(); 708d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray const UUID desc_uuid = UUID::GetRandom(); 709d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray bt_uuid_t hal_char_uuid0 = char_uuid0.GetBlueDroid(); 710d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray bt_uuid_t hal_char_uuid1 = char_uuid1.GetBlueDroid(); 711d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray bt_uuid_t hal_desc_uuid = desc_uuid.GetBlueDroid(); 712d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray const int props = bluetooth::kCharacteristicPropertyRead | 713d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray bluetooth::kCharacteristicPropertyNotify; 714d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray const int perms = kAttributePermissionReadEncrypted; 715d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 716d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Service declaration not started. 717d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(nullptr, gatt_server_->AddDescriptor(desc_uuid, perms)); 718d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 719d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Start a service declaration. 720d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray auto service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 721d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray btgatt_srvc_id_t hal_id; 722d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray hal::GetHALServiceId(*service_id, &hal_id); 723d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 724d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // No characteristic was inserted. 725d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(nullptr, gatt_server_->AddDescriptor(desc_uuid, perms)); 726d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 727d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Add two characeristics. 728d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray auto char_id0 = gatt_server_->AddCharacteristic(char_uuid0, props, perms); 729d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray auto char_id1 = gatt_server_->AddCharacteristic(char_uuid1, props, perms); 730d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 731d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Add a descriptor. 732d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray auto desc_id = gatt_server_->AddDescriptor(desc_uuid, perms); 733d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_NE(nullptr, desc_id); 734d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(desc_id->IsDescriptor()); 735d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(*desc_id->GetOwningCharacteristicId() == *char_id1); 736d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(*desc_id->GetOwningServiceId() == *service_id); 737d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 738d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Add a second descriptor with the same UUID. 739d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray auto desc_id1 = gatt_server_->AddDescriptor(desc_uuid, perms); 740d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_NE(nullptr, desc_id1); 741d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(*desc_id1 != *desc_id); 742d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(desc_id1->IsDescriptor()); 743d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(*desc_id1->GetOwningCharacteristicId() == *char_id1); 744d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(*desc_id1->GetOwningServiceId() == *service_id); 745d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 746d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Expect calls for 7 handles. 747d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_CALL(*mock_handler_, AddService(kDefaultServerId, _, 7)) 748d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillRepeatedly(Return(BT_STATUS_SUCCESS)); 749d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_CALL(*mock_handler_, AddCharacteristic(_, _, _, _, _)) 750d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillRepeatedly(Return(BT_STATUS_SUCCESS)); 751d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 752d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray GattIdentifier cb_id; 753d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BLEStatus cb_status; 754d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray int cb_count = 0; 755d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray auto callback = [&](BLEStatus in_status, const GattIdentifier& in_id) { 756d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_id = in_id; 757d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_status = in_status; 758d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_count++; 759d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray }; 760d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 761d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray int srvc_handle = 0x0001; 762d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray int char_handle0 = 0x0002; 763d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray int char_handle1 = 0x0004; 764d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray int desc_handle0 = 0x0005; 765d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray int desc_handle1 = 0x0006; 766d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 767d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 768d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 769d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Cannot add any more descriptors while EndServiceDeclaration is in progress. 770d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(nullptr, gatt_server_->AddDescriptor(desc_uuid, perms)); 771d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 772d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 773d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 774d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 775d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 776d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_CALL(*mock_handler_, AddDescriptor(_, _, _, _)) 777d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .Times(8) 778d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_FAIL)) // desc_id0 - try 1 779d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // desc_id0 - try 2 780d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // desc_id0 - try 3 781d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_FAIL)) // desc_id1 - try 3 782d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // desc_id0 - try 4 783d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // desc_id1 - try 4 784d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)) // desc_id0 - try 5 785d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); // desc_id1 - try 5 786d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 787d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Notify success for both characteristics. First descriptor call will fail. 788d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 789d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid0, 790d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle0); 791d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 792d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 793d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid1, 794d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle1); 795d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(1, cb_count); 796d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 797d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(cb_id == *service_id); 798d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 799d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Restart (try 2) 800d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_count = 0; 801d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 802d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray hal::GetHALServiceId(*service_id, &hal_id); 803d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid0, props, perms); 804d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid1, props, perms); 805d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id = gatt_server_->AddDescriptor(desc_uuid, perms); 806d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id); 807d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id1 = gatt_server_->AddDescriptor(desc_uuid, perms); 808d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id1); 809d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 810d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 811d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 812d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 813d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 814d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 815d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid0, 816d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle0); 817d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 818d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 819d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid1, 820d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle1); 821d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 822d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 823d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Notify failure for first descriptor. 824d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 825d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_FAIL, kDefaultServerId, hal_desc_uuid, 826d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, desc_handle0); 827d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(1, cb_count); 828d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 829d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(cb_id == *service_id); 830d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 831d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Restart (try 3) 832d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_count = 0; 833d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 834d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray hal::GetHALServiceId(*service_id, &hal_id); 835d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid0, props, perms); 836d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid1, props, perms); 837d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id = gatt_server_->AddDescriptor(desc_uuid, perms); 838d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id); 839d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id1 = gatt_server_->AddDescriptor(desc_uuid, perms); 840d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id1); 841d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 842d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 843d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 844d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 845d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 846d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 847d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid0, 848d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle0); 849d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 850d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 851d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid1, 852d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle1); 853d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 854d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 855d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Notify success for first descriptor; the second descriptor will fail 856d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // immediately. 857d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 858d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_desc_uuid, 859d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, desc_handle0); 860d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(1, cb_count); 861d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 862d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(cb_id == *service_id); 863d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 864d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Restart (try 4) 865d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_count = 0; 866d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 867d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray hal::GetHALServiceId(*service_id, &hal_id); 868d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid0, props, perms); 869d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid1, props, perms); 870d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id = gatt_server_->AddDescriptor(desc_uuid, perms); 871d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id); 872d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id1 = gatt_server_->AddDescriptor(desc_uuid, perms); 873d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id1); 874d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 875d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 876d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 877d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 878d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 879d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 880d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid0, 881d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle0); 882d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 883d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 884d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid1, 885d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle1); 886d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 887d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 888d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Notify success for first first descriptor and failure for second 889d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // descriptor. 890d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 891d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_desc_uuid, 892d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, desc_handle0); 893d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 894d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 895d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 896d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_FAIL, kDefaultServerId, hal_desc_uuid, 897d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, desc_handle1); 898d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(1, cb_count); 899d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_NE(BLE_STATUS_SUCCESS, cb_status); 900d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(cb_id == *service_id); 901d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 902d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Restart (try 5) 903d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray cb_count = 0; 904d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray service_id = gatt_server_->BeginServiceDeclaration(service_uuid, true); 905d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray hal::GetHALServiceId(*service_id, &hal_id); 906d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id0 = gatt_server_->AddCharacteristic(char_uuid0, props, perms); 907d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray char_id1 = gatt_server_->AddCharacteristic(char_uuid1, props, perms); 908d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id = gatt_server_->AddDescriptor(desc_uuid, perms); 909d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id); 910d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray desc_id1 = gatt_server_->AddDescriptor(desc_uuid, perms); 911d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray ASSERT_NE(nullptr, desc_id1); 912d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_TRUE(gatt_server_->EndServiceDeclaration(callback)); 913d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 914d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyServiceAddedCallback( 915d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_id, srvc_handle); 916d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 917d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 918d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid0, 919d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle0); 920d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 921d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyCharacteristicAddedCallback( 922d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_char_uuid1, 923d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, char_handle1); 924d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 925d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 926d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // Notify success for both descriptors. 927d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 928d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_desc_uuid, 929d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, desc_handle0); 930d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 931d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 932d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray // The second descriptor callback should trigger the end routine. 933d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_CALL(*mock_handler_, StartService(kDefaultServerId, srvc_handle, _)) 934d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .Times(1) 935d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 936d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray fake_hal_gatt_iface_->NotifyDescriptorAddedCallback( 937d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray BT_STATUS_SUCCESS, kDefaultServerId, hal_desc_uuid, 938d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray srvc_handle, desc_handle1); 939d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray EXPECT_EQ(0, cb_count); 940d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray} 941d9b0552a7f75737b5c8c60cb87f892b1b9323acfArman Uguray 942514bf6087093375351784b287cb29c5f4603273cArman UgurayTEST_F(GattServerPostRegisterTest, RequestRead) { 943514bf6087093375351784b287cb29c5f4603273cArman Uguray SetUpTestService(); 944514bf6087093375351784b287cb29c5f4603273cArman Uguray 945514bf6087093375351784b287cb29c5f4603273cArman Uguray TestDelegate test_delegate; 946514bf6087093375351784b287cb29c5f4603273cArman Uguray gatt_server_->SetDelegate(&test_delegate); 947514bf6087093375351784b287cb29c5f4603273cArman Uguray 948514bf6087093375351784b287cb29c5f4603273cArman Uguray const std::vector<uint8_t> kTestValue = { 0x01, 0x02, 0x03 }; 949514bf6087093375351784b287cb29c5f4603273cArman Uguray const std::vector<uint8_t> kTestValueTooLarge(BTGATT_MAX_ATTR_LEN + 1, 0); 950514bf6087093375351784b287cb29c5f4603273cArman Uguray const std::string kTestAddress0 = "01:23:45:67:89:AB"; 951514bf6087093375351784b287cb29c5f4603273cArman Uguray const std::string kTestAddress1 = "CD:EF:01:23:45:67"; 952514bf6087093375351784b287cb29c5f4603273cArman Uguray const int kReqId0 = 0; 953514bf6087093375351784b287cb29c5f4603273cArman Uguray const int kReqId1 = 1; 954514bf6087093375351784b287cb29c5f4603273cArman Uguray const int kConnId0 = 1; 955514bf6087093375351784b287cb29c5f4603273cArman Uguray 956514bf6087093375351784b287cb29c5f4603273cArman Uguray // No pending request. 957514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 958514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId0, 959514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 960514bf6087093375351784b287cb29c5f4603273cArman Uguray 961514bf6087093375351784b287cb29c5f4603273cArman Uguray bt_bdaddr_t hal_addr0, hal_addr1; 962514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(util::BdAddrFromString(kTestAddress0, &hal_addr0)); 963514bf6087093375351784b287cb29c5f4603273cArman Uguray ASSERT_TRUE(util::BdAddrFromString(kTestAddress1, &hal_addr1)); 964514bf6087093375351784b287cb29c5f4603273cArman Uguray 965514bf6087093375351784b287cb29c5f4603273cArman Uguray // Send a connection callback. The GattServer should store the connection 966514bf6087093375351784b287cb29c5f4603273cArman Uguray // information and be able to process the incoming read requests for this 967514bf6087093375351784b287cb29c5f4603273cArman Uguray // connection. 968514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyServerConnectionCallback( 969514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kDefaultServerId, true, hal_addr0); 970514bf6087093375351784b287cb29c5f4603273cArman Uguray 971514bf6087093375351784b287cb29c5f4603273cArman Uguray // Unknown connection ID shouldn't trigger anything. 972514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 973514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0 + 1, kReqId0, hal_addr0, char_handle_, 0, false); 9744ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_read_req().count); 9754ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_read_req().count); 976514bf6087093375351784b287cb29c5f4603273cArman Uguray 977514bf6087093375351784b287cb29c5f4603273cArman Uguray // Unknown device address shouldn't trigger anything. 978514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 979514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kReqId0, hal_addr1, char_handle_, 0, false); 9804ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_read_req().count); 9814ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_read_req().count); 982514bf6087093375351784b287cb29c5f4603273cArman Uguray 983514bf6087093375351784b287cb29c5f4603273cArman Uguray // Unknown attribute handle shouldn't trigger anything. 984514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 985514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kReqId0, hal_addr0, char_handle_ + 50, 0, false); 9864ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_read_req().count); 9874ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_read_req().count); 988514bf6087093375351784b287cb29c5f4603273cArman Uguray 989514bf6087093375351784b287cb29c5f4603273cArman Uguray // Characteristic and descriptor handles should trigger correct callbacks. 990514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 991514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kReqId0, hal_addr0, char_handle_, 0, false); 9924ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.char_read_req().count); 9934ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kTestAddress0, test_delegate.char_read_req().device_address); 9944ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kReqId0, test_delegate.char_read_req().id); 9954ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_read_req().offset); 9964ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(test_delegate.char_read_req().is_long); 9974ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(test_char_id_ == test_delegate.char_read_req().gatt_id); 9984ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_read_req().count); 999514bf6087093375351784b287cb29c5f4603273cArman Uguray 1000514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 1001514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kReqId1, hal_addr0, desc_handle_, 2, true); 10024ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.char_read_req().count); 10034ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.desc_read_req().count); 10044ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kTestAddress0, test_delegate.desc_read_req().device_address); 10054ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kReqId1, test_delegate.desc_read_req().id); 10064ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(2, test_delegate.desc_read_req().offset); 10074ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(test_delegate.desc_read_req().is_long); 10084ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(test_desc_id_ == test_delegate.desc_read_req().gatt_id); 1009514bf6087093375351784b287cb29c5f4603273cArman Uguray 1010514bf6087093375351784b287cb29c5f4603273cArman Uguray // Callback with a pending request ID will be ignored. 1011514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 1012514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kReqId0, hal_addr0, char_handle_, 0, false); 1013514bf6087093375351784b287cb29c5f4603273cArman Uguray fake_hal_gatt_iface_->NotifyRequestReadCallback( 1014514bf6087093375351784b287cb29c5f4603273cArman Uguray kConnId0, kReqId1, hal_addr0, char_handle_, 0, false); 10154ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.char_read_req().count); 10164ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.desc_read_req().count); 1017514bf6087093375351784b287cb29c5f4603273cArman Uguray 1018514bf6087093375351784b287cb29c5f4603273cArman Uguray // Send response for wrong device address. 1019514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 1020514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress1, kReqId0, 1021514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 1022514bf6087093375351784b287cb29c5f4603273cArman Uguray 1023514bf6087093375351784b287cb29c5f4603273cArman Uguray // Send response for a value that's too large. 1024514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 1025514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId0, 1026514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValueTooLarge)); 1027514bf6087093375351784b287cb29c5f4603273cArman Uguray 1028514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_CALL(*mock_handler_, SendResponse(kConnId0, kReqId0, 1029514bf6087093375351784b287cb29c5f4603273cArman Uguray BT_STATUS_SUCCESS, _)) 1030514bf6087093375351784b287cb29c5f4603273cArman Uguray .Times(2) 1031514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 1032514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 1033514bf6087093375351784b287cb29c5f4603273cArman Uguray 1034514bf6087093375351784b287cb29c5f4603273cArman Uguray // Stack call fails. 1035514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 1036514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId0, 1037514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 1038514bf6087093375351784b287cb29c5f4603273cArman Uguray 1039514bf6087093375351784b287cb29c5f4603273cArman Uguray // Successful send response for characteristic. 1040514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_TRUE(gatt_server_->SendResponse( 1041514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId0, 1042514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 1043514bf6087093375351784b287cb29c5f4603273cArman Uguray 1044514bf6087093375351784b287cb29c5f4603273cArman Uguray // Characteristic request ID no longer pending. 1045514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 1046514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId0, 1047514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 1048514bf6087093375351784b287cb29c5f4603273cArman Uguray 1049514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_CALL(*mock_handler_, SendResponse(kConnId0, kReqId1, 1050514bf6087093375351784b287cb29c5f4603273cArman Uguray BT_STATUS_SUCCESS, _)) 1051514bf6087093375351784b287cb29c5f4603273cArman Uguray .Times(1) 1052514bf6087093375351784b287cb29c5f4603273cArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 1053514bf6087093375351784b287cb29c5f4603273cArman Uguray 1054514bf6087093375351784b287cb29c5f4603273cArman Uguray // Successful send response for descriptor. 1055514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_TRUE(gatt_server_->SendResponse( 1056514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId1, 1057514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 1058514bf6087093375351784b287cb29c5f4603273cArman Uguray 1059514bf6087093375351784b287cb29c5f4603273cArman Uguray // Descriptor request ID no longer pending. 1060514bf6087093375351784b287cb29c5f4603273cArman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 1061514bf6087093375351784b287cb29c5f4603273cArman Uguray kTestAddress0, kReqId1, 1062514bf6087093375351784b287cb29c5f4603273cArman Uguray GATT_ERROR_NONE, 0, kTestValue)); 1063514bf6087093375351784b287cb29c5f4603273cArman Uguray 1064514bf6087093375351784b287cb29c5f4603273cArman Uguray gatt_server_->SetDelegate(nullptr); 1065514bf6087093375351784b287cb29c5f4603273cArman Uguray} 1066514bf6087093375351784b287cb29c5f4603273cArman Uguray 10674ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman UgurayTEST_F(GattServerPostRegisterTest, RequestWrite) { 10684ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray SetUpTestService(); 10694ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 10704ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray TestDelegate test_delegate; 10714ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray gatt_server_->SetDelegate(&test_delegate); 10724ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 10734ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::vector<uint8_t> kTestValue = { 0x01, 0x02, 0x03 }; 10744ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::string kTestAddress0 = "01:23:45:67:89:AB"; 10754ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const std::string kTestAddress1 = "CD:EF:01:23:45:67"; 10764ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const int kReqId0 = 0; 10774ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const int kReqId1 = 1; 10784ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray const int kConnId0 = 1; 10794ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 10804ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // No pending request. 10814ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 10824ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId0, 10834ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 10844ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 10854ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray bt_bdaddr_t hal_addr0, hal_addr1; 10864ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray ASSERT_TRUE(util::BdAddrFromString(kTestAddress0, &hal_addr0)); 10874ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray ASSERT_TRUE(util::BdAddrFromString(kTestAddress1, &hal_addr1)); 10884ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 10894ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Send a connection callback. The GattServer should store the connection 10904ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // information and be able to process the incoming read requests for this 10914ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // connection. 10924ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyServerConnectionCallback( 10934ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kDefaultServerId, true, hal_addr0); 10944ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 10954ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Unknown connection ID shouldn't trigger anything. 10964ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 10974ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0 + 1, kReqId0, hal_addr0, char_handle_, 0, 10984ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 10994ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_write_req().count); 11004ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_write_req().count); 11014ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11024ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Unknown device address shouldn't trigger anything. 11034ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11044ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId0, hal_addr1, char_handle_, 0, 11054ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 11064ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_write_req().count); 11074ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_write_req().count); 11084ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11094ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Unknown attribute handle shouldn't trigger anything. 11104ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11114ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId0, hal_addr0, char_handle_ + 50, 0, 11124ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 11134ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_write_req().count); 11144ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_write_req().count); 11154ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11164ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Characteristic and descriptor handles should trigger correct callbacks. 11174ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11184ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId0, hal_addr0, char_handle_, 0, 11194ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 11204ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.char_write_req().count); 11214ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kTestAddress0, test_delegate.char_write_req().device_address); 11224ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kReqId0, test_delegate.char_write_req().id); 11234ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.char_write_req().offset); 11244ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(true, test_delegate.char_write_req().need_rsp); 11254ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(false, test_delegate.char_write_req().is_exec); 11264ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kTestValue, test_delegate.char_write_req().write_value); 11274ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(test_char_id_ == test_delegate.char_write_req().gatt_id); 11284ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(0, test_delegate.desc_write_req().count); 11294ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11304ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11314ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId1, hal_addr0, desc_handle_, 2, 11324ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 11334ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.char_write_req().count); 11344ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.desc_write_req().count); 11354ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kTestAddress0, test_delegate.desc_write_req().device_address); 11364ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kReqId1, test_delegate.desc_write_req().id); 11374ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(2, test_delegate.desc_write_req().offset); 11384ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(true, test_delegate.desc_write_req().need_rsp); 11394ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(false, test_delegate.desc_write_req().is_exec); 11404ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(kTestValue, test_delegate.desc_write_req().write_value); 11414ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(test_desc_id_ == test_delegate.desc_write_req().gatt_id); 11424ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11434ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Callback with a pending request ID will be ignored. 11444ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11454ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId0, hal_addr0, char_handle_, 0, 11464ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 11474ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11484ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId1, hal_addr0, char_handle_, 0, 11494ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), true, false, (uint8_t *)kTestValue.data()); 11504ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.char_write_req().count); 11514ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(1, test_delegate.desc_write_req().count); 11524ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11534ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Send response for wrong device address. 11544ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 11554ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress1, kReqId0, 11564ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 11574ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11584ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_CALL(*mock_handler_, SendResponse(kConnId0, kReqId0, 11594ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray BT_STATUS_SUCCESS, _)) 11604ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray .Times(2) 11614ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray .WillOnce(Return(BT_STATUS_FAIL)) 11624ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 11634ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11644ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Stack call fails. 11654ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 11664ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId0, 11674ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 11684ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11694ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Successful send response for characteristic. 11704ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(gatt_server_->SendResponse( 11714ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId0, 11724ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 11734ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11744ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Characteristic request ID no longer pending. 11754ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 11764ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId0, 11774ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 11784ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11794ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_CALL(*mock_handler_, SendResponse(kConnId0, kReqId1, 11804ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray BT_STATUS_SUCCESS, _)) 11814ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray .Times(1) 11824ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 11834ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11844ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Successful send response for descriptor. 11854ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_TRUE(gatt_server_->SendResponse( 11864ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId1, 11874ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 11884ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11894ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // Descriptor request ID no longer pending. 11904ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 11914ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId1, 11924ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 11934ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 11944ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray // SendResponse should fail for a "Write Without Response". 11954ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray fake_hal_gatt_iface_->NotifyRequestWriteCallback( 11964ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kConnId0, kReqId0, hal_addr0, char_handle_, 0, 11974ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestValue.size(), false, false, (uint8_t *)kTestValue.data()); 11984ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_EQ(false, test_delegate.char_write_req().need_rsp); 11994ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray EXPECT_FALSE(gatt_server_->SendResponse( 12004ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray kTestAddress0, kReqId0, 12014ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray GATT_ERROR_NONE, 0, kTestValue)); 12024ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 12034ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray gatt_server_->SetDelegate(nullptr); 12044ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray} 12054ebcbd9ede4006500c3ead0685befe0a8e4aadc2Arman Uguray 1206cd644e3c54a4321b7626b52531c59f88e24e87beArman UgurayTEST_F(GattServerPostRegisterTest, SendNotification) { 1207cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SetUpTestService(); 1208cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1209cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray const std::string kTestAddress0 = "01:23:45:67:89:AB"; 1210cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray const std::string kTestAddress1 = "cd:ef:01:23:45:67"; 1211cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray const std::string kInvalidAddress = "thingamajig blabbidyboop"; 1212cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray const int kConnId0 = 0; 1213cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray const int kConnId1 = 1; 1214cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray std::vector<uint8_t> value; 1215cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray bt_bdaddr_t hal_addr0; 1216cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray ASSERT_TRUE(util::BdAddrFromString(kTestAddress0, &hal_addr0)); 1217cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1218cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Set up two connections with the same address. 1219cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyServerConnectionCallback( 1220cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId0, kDefaultServerId, true, hal_addr0); 1221cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyServerConnectionCallback( 1222cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId1, kDefaultServerId, true, hal_addr0); 1223cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1224cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Set up a test callback. 1225cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray GATTError gatt_error; 1226cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray int callback_count = 0; 1227cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray auto callback = [&](GATTError in_error) { 1228cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray gatt_error = in_error; 1229cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray callback_count++; 1230cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray }; 1231cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1232cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Bad device address. 1233cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_FALSE(gatt_server_->SendNotification( 1234cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kInvalidAddress, 1235cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray test_char_id_, false, value, callback)); 1236cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1237cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Bad connection. 1238cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_FALSE(gatt_server_->SendNotification( 1239cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kTestAddress1, 1240cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray test_char_id_, false, value, callback)); 1241cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1242cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // We should get a HAL call for each connection for this address. The calls 1243cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // fail. 1244cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1245cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId0, 1246cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 0, nullptr)) 1247cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1248cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_FAIL)); 1249cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1250cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId1, 1251cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 0, nullptr)) 1252cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1253cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_FAIL)); 1254cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_FALSE(gatt_server_->SendNotification( 1255cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kTestAddress0, 1256cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray test_char_id_, false, value, callback)); 1257cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1258cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // One of the calls succeeds. 1259cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1260cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId0, 1261cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 0, nullptr)) 1262cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1263cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 1264cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1265cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId1, 1266cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 0, nullptr)) 1267cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1268cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_FAIL)); 1269cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_TRUE(gatt_server_->SendNotification( 1270cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kTestAddress0, 1271cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray test_char_id_, false, value, callback)); 1272cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1273cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // One of the connections is already pending so there should be only one call. 1274cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // This one we send with confirm=true. 1275cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1276cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId1, 1277cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 1, nullptr)) 1278cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1279cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 1280cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_TRUE(gatt_server_->SendNotification( 1281cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kTestAddress0, 1282cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray test_char_id_, true, value, callback)); 1283cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1284cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Calls are already pending. 1285cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_FALSE(gatt_server_->SendNotification( 1286cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kTestAddress0, test_char_id_, true, value, callback)); 1287cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1288cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Trigger one confirmation callback. We should get calls for two callbacks 1289cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // since we have two separate calls pending. 1290cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyIndicationSentCallback( 1291cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId0, BT_STATUS_SUCCESS); 1292cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyIndicationSentCallback( 1293cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId1, BT_STATUS_SUCCESS); 1294cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_EQ(2, callback_count); 1295cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_EQ(GATT_ERROR_NONE, gatt_error); 1296cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1297cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray callback_count = 0; 1298cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1299cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Restart. Both calls succeed now. 1300cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1301cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId0, 1302cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 0, nullptr)) 1303cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1304cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 1305cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_CALL(*mock_handler_, 1306cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray SendIndication(kDefaultServerId, char_handle_, kConnId1, 1307cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray value.size(), 0, nullptr)) 1308cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .Times(1) 1309cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray .WillOnce(Return(BT_STATUS_SUCCESS)); 1310cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_TRUE(gatt_server_->SendNotification( 1311cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kTestAddress0, 1312cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray test_char_id_, false, value, callback)); 1313cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1314cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Trigger one confirmation callback. The callback we passed should still be 1315cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // pending. The first callback is for the wrong connection ID. 1316cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyIndicationSentCallback( 1317cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId0 + 50, BT_STATUS_FAIL); 1318cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyIndicationSentCallback( 1319cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId0, BT_STATUS_SUCCESS); 1320cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_EQ(0, callback_count); 1321cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1322cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // This should be ignored since |kConnId0| was already processed. 1323cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyIndicationSentCallback( 1324cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId0, BT_STATUS_SUCCESS); 1325cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_EQ(0, callback_count); 1326cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 1327cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // Run the callback with failure. Since the previous callback reported 1328cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray // success, we should report success. 1329cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray fake_hal_gatt_iface_->NotifyIndicationSentCallback( 1330cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray kConnId1, BT_STATUS_SUCCESS); 1331cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_EQ(1, callback_count); 1332cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray EXPECT_EQ(GATT_ERROR_NONE, gatt_error); 1333cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray} 1334cd644e3c54a4321b7626b52531c59f88e24e87beArman Uguray 13350f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray} // namespace 13360f2d4897046f037a9f181f47f3d349a9dd646478Arman Uguray} // namespace bluetooth 1337