2 // Copyright (C) 2015 Google, Inc.
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at:
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 #include "service/adapter.h"
19 #include <base/logging.h>
21 #include "service/logging_helpers.h"
26 const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
28 const char Adapter::kDefaultName[] = "not-initialized";
30 // The minimum number of advertising instances required for multi-advertisement
33 // TODO(armansito): This number comes straight from
34 // packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
35 // nice to know if there were a way to obtain this number from the stack instead
36 // of hardcoding it here.
37 const char kMinAdvInstancesForMultiAdv = 5;
39 void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
40 AdapterState prev_state,
41 AdapterState new_state) {
42 // Default implementation does nothing
45 void Adapter::Observer::OnDeviceConnectionStateChanged(
46 Adapter* adapter, const std::string& device_address, bool connected) {
47 // Default implementation does nothing
51 : state_(ADAPTER_STATE_OFF),
52 address_(kDefaultAddress),
54 memset(&local_le_features_, 0, sizeof(local_le_features_));
55 hal::BluetoothInterface::Get()->AddObserver(this);
56 ble_client_factory_.reset(new LowEnergyClientFactory());
57 gatt_client_factory_.reset(new GattClientFactory());
58 gatt_server_factory_.reset(new GattServerFactory());
59 hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
63 hal::BluetoothInterface::Get()->RemoveObserver(this);
66 void Adapter::AddObserver(Observer* observer) {
67 std::lock_guard<std::mutex> lock(observers_lock_);
68 observers_.AddObserver(observer);
71 void Adapter::RemoveObserver(Observer* observer) {
72 std::lock_guard<std::mutex> lock(observers_lock_);
73 observers_.RemoveObserver(observer);
76 AdapterState Adapter::GetState() const {
80 bool Adapter::IsEnabled() const {
81 return state_.load() == ADAPTER_STATE_ON;
84 bool Adapter::Enable() {
85 AdapterState current_state = GetState();
86 if (current_state != ADAPTER_STATE_OFF) {
87 LOG(INFO) << "Adapter not disabled - state: "
88 << AdapterStateToString(current_state);
92 // Set the state before calling enable() as there might be a race between here
93 // and the AdapterStateChangedCallback.
94 state_ = ADAPTER_STATE_TURNING_ON;
95 NotifyAdapterStateChanged(current_state, state_);
97 int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
98 if (status != BT_STATUS_SUCCESS) {
99 LOG(ERROR) << "Failed to enable Bluetooth - status: "
100 << BtStatusText((const bt_status_t)status);
101 state_ = ADAPTER_STATE_OFF;
102 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
109 bool Adapter::Disable() {
111 LOG(INFO) << "Adapter is not enabled";
115 AdapterState current_state = GetState();
117 // Set the state before calling enable() as there might be a race between here
118 // and the AdapterStateChangedCallback.
119 state_ = ADAPTER_STATE_TURNING_OFF;
120 NotifyAdapterStateChanged(current_state, state_);
122 int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
123 if (status != BT_STATUS_SUCCESS) {
124 LOG(ERROR) << "Failed to disable Bluetooth - status: "
125 << BtStatusText((const bt_status_t)status);
126 state_ = current_state;
127 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
134 std::string Adapter::GetName() const {
138 bool Adapter::SetName(const std::string& name) {
139 bt_bdname_t hal_name;
140 size_t max_name_len = sizeof(hal_name.name);
142 // Include the \0 byte in size measurement.
143 if (name.length() >= max_name_len) {
144 LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum allowed"
145 << " size: " << max_name_len;
149 strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
152 VLOG(1) << "Setting adapter name: " << name;
154 if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
155 LOG(ERROR) << "Failed to set adapter name: " << name;
162 std::string Adapter::GetAddress() const {
163 return address_.Get();
166 bool Adapter::IsMultiAdvertisementSupported() const {
167 return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
170 bool Adapter::IsDeviceConnected(const std::string& device_address) {
171 std::lock_guard<std::mutex> lock(connected_devices_lock_);
172 return connected_devices_.find(device_address) != connected_devices_.end();
175 LowEnergyClientFactory* Adapter::GetLowEnergyClientFactory() const {
176 return ble_client_factory_.get();
179 GattClientFactory* Adapter::GetGattClientFactory() const {
180 return gatt_client_factory_.get();
183 GattServerFactory* Adapter::GetGattServerFactory() const {
184 return gatt_server_factory_.get();
187 void Adapter::AdapterStateChangedCallback(bt_state_t state) {
188 LOG(INFO) << "Adapter state changed: " << BtStateText(state);
190 AdapterState prev_state = GetState();
194 state_ = ADAPTER_STATE_OFF;
198 state_ = ADAPTER_STATE_ON;
205 NotifyAdapterStateChanged(prev_state, GetState());
208 void Adapter::AdapterPropertiesCallback(bt_status_t status,
210 bt_property_t* properties) {
211 LOG(INFO) << "Adapter properties changed";
213 if (status != BT_STATUS_SUCCESS) {
214 LOG(ERROR) << "status: " << BtStatusText(status);
218 for (int i = 0; i < num_properties; i++) {
219 bt_property_t* property = properties + i;
220 switch (property->type) {
221 case BT_PROPERTY_BDADDR: {
222 std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>(
224 LOG(INFO) << "Adapter address changed: " << address;
225 address_.Set(address);
228 case BT_PROPERTY_BDNAME: {
229 bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
230 std::string name = reinterpret_cast<char*>(hal_name->name);
231 LOG(INFO) << "Adapter name changed: " << name;
235 case BT_PROPERTY_LOCAL_LE_FEATURES: {
236 if (property->len != sizeof(bt_local_le_features_t)) {
237 LOG(WARNING) << "Malformed value received for property: "
238 << "BT_PROPERTY_LOCAL_LE_FEATURES";
241 bt_local_le_features_t* features =
242 reinterpret_cast<bt_local_le_features_t*>(property->val);
243 memcpy(&local_le_features_, features, sizeof(*features));
244 LOG(INFO) << "Supported LE features updated";
248 VLOG(1) << "Unhandled adapter property: "
249 << BtPropertyText(property->type);
253 // TODO(armansito): notify others of the updated properties
257 void Adapter::AclStateChangedCallback(bt_status_t status,
258 const bt_bdaddr_t& remote_bdaddr,
259 bt_acl_state_t state) {
260 std::string device_address = BtAddrString(&remote_bdaddr);
261 bool connected = (state == BT_ACL_STATE_CONNECTED);
262 LOG(INFO) << "ACL state changed: " << device_address << " - connected: "
263 << (connected ? "true" : "false");
265 // If this is reported with an error status, I suppose the best thing we can
266 // do is to log it and ignore the event.
267 if (status != BT_STATUS_SUCCESS) {
268 LOG(ERROR) << "AclStateChangedCallback called with status: "
269 << BtStatusText(status);
273 // Introduce a scope to manage |connected_devices_lock_| with RAII.
275 std::lock_guard<std::mutex> lock(connected_devices_lock_);
277 connected_devices_.insert(device_address);
279 connected_devices_.erase(device_address);
282 std::lock_guard<std::mutex> lock(observers_lock_);
284 Observer, observers_,
285 OnDeviceConnectionStateChanged(this, device_address, connected));
288 bool Adapter::SetAdapterProperty(bt_property_type_t type,
289 void* value, int length) {
293 bt_property_t property;
294 property.len = length;
295 property.val = value;
296 property.type = type;
298 int status = hal::BluetoothInterface::Get()->GetHALInterface()->
299 set_adapter_property(&property);
300 if (status != BT_STATUS_SUCCESS) {
301 VLOG(1) << "Failed to set property";
308 void Adapter::NotifyAdapterStateChanged(AdapterState prev_state,
309 AdapterState new_state) {
310 if (prev_state == new_state)
313 std::lock_guard<std::mutex> lock(observers_lock_);
314 FOR_EACH_OBSERVER(Observer, observers_,
315 OnAdapterStateChanged(this, prev_state, new_state));
318 } // namespace bluetooth