1 /******************************************************************************
2 *
3 * Copyright (C) 2015 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #include "adapter/bluetooth_test.h"
20 #include <mutex>
21 #include "btcore/include/bdaddr.h"
22 #include "btcore/include/property.h"
23
24 namespace {
25
26 // Mutex lock used by callbacks to protect |callback_semaphores_| from
27 // racey behaviour caused when Wait and Notify are called at the same time
28 std::mutex callback_lock;
29
30 } // namespace
31
32 namespace bttest {
33
SetUp()34 void BluetoothTest::SetUp() {
35 bt_interface_ = nullptr;
36 state_ = BT_STATE_OFF;
37 properties_changed_count_ = 0;
38 last_changed_properties_ = nullptr;
39 remote_device_properties_changed_count_ = 0;
40 remote_device_last_changed_properties_ = nullptr;
41 discovery_state_ = BT_DISCOVERY_STOPPED;
42 acl_state_ = BT_ACL_STATE_DISCONNECTED;
43 bond_state_ = BT_BOND_STATE_NONE;
44
45 adapter_properties_callback_sem_ = semaphore_new(0);
46 remote_device_properties_callback_sem_ = semaphore_new(0);
47 adapter_state_changed_callback_sem_ = semaphore_new(0);
48 discovery_state_changed_callback_sem_ = semaphore_new(0);
49
50 bluetooth::hal::BluetoothInterface::Initialize();
51 ASSERT_TRUE(bluetooth::hal::BluetoothInterface::IsInitialized());
52 auto bt_hal_interface = bluetooth::hal::BluetoothInterface::Get();
53 bt_hal_interface->AddObserver(this);
54 bt_interface_ = bt_hal_interface->GetHALInterface();
55 ASSERT_NE(nullptr, bt_interface_) << "bt_interface is null.";
56 }
57
TearDown()58 void BluetoothTest::TearDown() {
59 semaphore_free(adapter_properties_callback_sem_);
60 semaphore_free(remote_device_properties_callback_sem_);
61 semaphore_free(adapter_state_changed_callback_sem_);
62 semaphore_free(discovery_state_changed_callback_sem_);
63
64 auto bt_hal_interface = bluetooth::hal::BluetoothInterface::Get();
65 bt_hal_interface->RemoveObserver(this);
66 bt_hal_interface->CleanUp();
67 ASSERT_FALSE(bt_hal_interface->IsInitialized());
68 }
69
ClearSemaphore(semaphore_t * sem)70 void BluetoothTest::ClearSemaphore(semaphore_t* sem) {
71 while (semaphore_try_wait(sem))
72 ;
73 }
74
bt_interface()75 const bt_interface_t* BluetoothTest::bt_interface() { return bt_interface_; }
76
GetState()77 bt_state_t BluetoothTest::GetState() { return state_; }
78
GetPropertiesChangedCount()79 int BluetoothTest::GetPropertiesChangedCount() {
80 return properties_changed_count_;
81 }
82
GetProperty(bt_property_type_t type)83 bt_property_t* BluetoothTest::GetProperty(bt_property_type_t type) {
84 for (int i = 0; i < properties_changed_count_; ++i) {
85 if (last_changed_properties_[i].type == type) {
86 return &last_changed_properties_[i];
87 }
88 }
89 return nullptr;
90 }
91
GetRemoteDeviceProperty(const bt_bdaddr_t * addr,bt_property_type_t type)92 bt_property_t* BluetoothTest::GetRemoteDeviceProperty(const bt_bdaddr_t* addr,
93 bt_property_type_t type) {
94 if (!bdaddr_equals(&curr_remote_device_, addr)) return nullptr;
95
96 for (int i = 0; i < remote_device_properties_changed_count_; i++) {
97 if (remote_device_last_changed_properties_[i].type == type) {
98 return &remote_device_last_changed_properties_[i];
99 }
100 }
101 return nullptr;
102 }
103
GetDiscoveryState()104 bt_discovery_state_t BluetoothTest::GetDiscoveryState() {
105 return discovery_state_;
106 }
107
GetAclState()108 bt_acl_state_t BluetoothTest::GetAclState() { return acl_state_; }
109
110 // Returns the device bond state.
GetBondState()111 bt_bond_state_t BluetoothTest::GetBondState() { return bond_state_; }
112
113 // callback
AdapterStateChangedCallback(bt_state_t new_state)114 void BluetoothTest::AdapterStateChangedCallback(bt_state_t new_state) {
115 state_ = new_state;
116 semaphore_post(adapter_state_changed_callback_sem_);
117 }
118
119 // callback
AdapterPropertiesCallback(bt_status_t status,int num_properties,bt_property_t * new_properties)120 void BluetoothTest::AdapterPropertiesCallback(bt_status_t status,
121 int num_properties,
122 bt_property_t* new_properties) {
123 property_free_array(last_changed_properties_, properties_changed_count_);
124 last_changed_properties_ =
125 property_copy_array(new_properties, num_properties);
126 properties_changed_count_ = num_properties;
127 semaphore_post(adapter_properties_callback_sem_);
128 }
129
130 // callback
RemoteDevicePropertiesCallback(bt_status_t status,bt_bdaddr_t * remote_bd_addr,int num_properties,bt_property_t * properties)131 void BluetoothTest::RemoteDevicePropertiesCallback(bt_status_t status,
132 bt_bdaddr_t* remote_bd_addr,
133 int num_properties,
134 bt_property_t* properties) {
135 bdaddr_copy(&curr_remote_device_, remote_bd_addr);
136 property_free_array(remote_device_last_changed_properties_,
137 remote_device_properties_changed_count_);
138 remote_device_last_changed_properties_ =
139 property_copy_array(properties, num_properties);
140 remote_device_properties_changed_count_ = num_properties;
141 semaphore_post(remote_device_properties_callback_sem_);
142 }
143
144 // callback
DiscoveryStateChangedCallback(bt_discovery_state_t state)145 void BluetoothTest::DiscoveryStateChangedCallback(bt_discovery_state_t state) {
146 discovery_state_ = state;
147 semaphore_post(discovery_state_changed_callback_sem_);
148 }
149
150 } // bttest
151