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, false) != BT_STATUS_SUCCESS) 71 return false; 72 73 pending_calls_[uuid] = callback; 74 75 return true; 76 } 77 78 void GattClientFactory::RegisterClientCallback( 79 hal::BluetoothGattInterface* /* gatt_iface */, int status, int client_id, 80 const Uuid& app_uuid) { 81 Uuid uuid(app_uuid); 82 83 auto iter = pending_calls_.find(uuid); 84 if (iter == pending_calls_.end()) { 85 VLOG(1) << "Ignoring callback for unknown app_id: " << uuid.ToString(); 86 return; 87 } 88 89 bool success = (status == BT_STATUS_SUCCESS); 90 BLEStatus result = success ? BLE_STATUS_SUCCESS : BLE_STATUS_FAILURE; 91 92 // No need to construct a client if the call wasn't successful. 93 std::unique_ptr<GattClient> client; 94 if (success) client.reset(new GattClient(uuid, client_id)); 95 96 // Notify the result via the result callback. 97 iter->second(result, uuid, std::move(client)); 98 99 pending_calls_.erase(iter); 100 } 101 102 } // namespace bluetooth 103