1 // 2 // Copyright 2015 Google, Inc. 3 // 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: 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 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. 15 // 16 17 #include "service/gatt_client.h" 18 19 #include <base/logging.h> 20 21 using std::lock_guard; 22 using std::mutex; 23 24 namespace bluetooth { 25 26 // GattClient implementation 27 // ======================================================== 28 29 GattClient::GattClient(const Uuid& uuid, int client_id) 30 : app_identifier_(uuid), client_id_(client_id) {} 31 32 GattClient::~GattClient() { 33 // Automatically unregister the client. 34 VLOG(1) << "GattClient unregistering client: " << client_id_; 35 36 hal::BluetoothGattInterface::Get() 37 ->GetClientHALInterface() 38 ->unregister_client(client_id_); 39 } 40 41 const Uuid& GattClient::GetAppIdentifier() const { return app_identifier_; } 42 43 int GattClient::GetInstanceId() const { return client_id_; } 44 45 // GattClientFactory implementation 46 // ======================================================== 47 48 GattClientFactory::GattClientFactory() { 49 hal::BluetoothGattInterface::Get()->AddClientObserver(this); 50 } 51 52 GattClientFactory::~GattClientFactory() { 53 hal::BluetoothGattInterface::Get()->RemoveClientObserver(this); 54 } 55 56 bool GattClientFactory::RegisterInstance(const Uuid& uuid, 57 const RegisterCallback& callback) { 58 VLOG(1) << __func__ << " - Uuid: " << uuid.ToString(); 59 lock_guard<mutex> lock(pending_calls_lock_); 60 61 if (pending_calls_.find(uuid) != pending_calls_.end()) { 62 LOG(ERROR) << "GATT client with given Uuid already registered - " 63 << "Uuid: " << uuid.ToString(); 64 return false; 65 } 66 67 const btgatt_client_interface_t* hal_iface = 68 hal::BluetoothGattInterface::Get()->GetClientHALInterface(); 69 70 if (hal_iface->register_client(uuid) != BT_STATUS_SUCCESS) return false; 71 72 pending_calls_[uuid] = callback; 73 74 return true; 75 } 76 77 void GattClientFactory::RegisterClientCallback( 78 hal::BluetoothGattInterface* /* gatt_iface */, int status, int client_id, 79 const Uuid& app_uuid) { 80 Uuid uuid(app_uuid); 81 82 auto iter = pending_calls_.find(uuid); 83 if (iter == pending_calls_.end()) { 84 VLOG(1) << "Ignoring callback for unknown app_id: " << uuid.ToString(); 85 return; 86 } 87 88 bool success = (status == BT_STATUS_SUCCESS); 89 BLEStatus result = success ? BLE_STATUS_SUCCESS : BLE_STATUS_FAILURE; 90 91 // No need to construct a client if the call wasn't successful. 92 std::unique_ptr<GattClient> client; 93 if (success) client.reset(new GattClient(uuid, client_id)); 94 95 // Notify the result via the result callback. 96 iter->second(result, uuid, std::move(client)); 97 98 pending_calls_.erase(iter); 99 } 100 101 } // namespace bluetooth 102