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_server.h"
18 
19 #include <base/logging.h>
20 
21 #include "osi/include/log.h"
22 #include "service/logging_helpers.h"
23 #include "stack/include/bt_types.h"
24 
25 using std::lock_guard;
26 using std::mutex;
27 
28 namespace bluetooth {
29 
30 // GattServer implementation
31 // ========================================================
32 
GattServer(const Uuid & uuid,int server_id)33 GattServer::GattServer(const Uuid& uuid, int server_id)
34     : app_identifier_(uuid), server_id_(server_id), delegate_(nullptr) {}
35 
~GattServer()36 GattServer::~GattServer() {
37   // Automatically unregister the server.
38   VLOG(1) << "GattServer unregistering: " << server_id_;
39 
40   // Unregister as observer so we no longer receive any callbacks.
41   hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
42 
43   // Unregister this server, stop all services, and ignore the result.
44   // TODO(armansito): stop and remove all services here? unregister_server
45   // should really take care of that.
46   hal::BluetoothGattInterface::Get()
47       ->GetServerHALInterface()
48       ->unregister_server(server_id_);
49 }
50 
SetDelegate(Delegate * delegate)51 void GattServer::SetDelegate(Delegate* delegate) {
52   lock_guard<mutex> lock(mutex_);
53   delegate_ = delegate;
54 }
55 
GetAppIdentifier() const56 const Uuid& GattServer::GetAppIdentifier() const { return app_identifier_; }
57 
GetInstanceId() const58 int GattServer::GetInstanceId() const { return server_id_; }
59 
AddService(const bluetooth::Service & service,const ResultCallback & callback)60 bool GattServer::AddService(const bluetooth::Service& service,
61                             const ResultCallback& callback) {
62   VLOG(1) << __func__ << " server_id: " << server_id_;
63   lock_guard<mutex> lock(mutex_);
64 
65   if (!callback) {
66     LOG(ERROR) << "|callback| cannot be NULL";
67     return false;
68   }
69 
70   std::vector<btgatt_db_element_t> svc;
71 
72   svc.push_back({
73       .uuid = service.uuid(),
74       .type = (service.primary() ? BTGATT_DB_PRIMARY_SERVICE
75                                  : BTGATT_DB_SECONDARY_SERVICE),
76   });
77 
78   for (const auto& characteristic : service.characteristics()) {
79     svc.push_back({.uuid = characteristic.uuid(),
80                    .type = BTGATT_DB_CHARACTERISTIC,
81                    .properties = characteristic.properties(),
82                    .permissions = characteristic.permissions()});
83     for (const auto& descriptor : characteristic.descriptors())
84       svc.push_back({.uuid = descriptor.uuid(),
85                      .type = BTGATT_DB_DESCRIPTOR,
86                      .permissions = descriptor.permissions()});
87   }
88 
89   for (const auto& incl_svc : service.included_services())
90     svc.push_back({.type = BTGATT_DB_INCLUDED_SERVICE,
91                    .attribute_handle = incl_svc.handle()});
92 
93   pending_end_decl_cb_ = callback;
94 
95   bt_status_t status =
96       hal::BluetoothGattInterface::Get()->GetServerHALInterface()->add_service(
97           server_id_, svc);
98   if (status != BT_STATUS_SUCCESS) {
99     LOG(ERROR) << "Failed to initiate call to populate GATT service";
100     CleanUpPendingData();
101     return false;
102   }
103 
104   return true;
105 }
106 
SendResponse(const std::string & device_address,int request_id,GATTError error,int offset,const std::vector<uint8_t> & value)107 bool GattServer::SendResponse(const std::string& device_address, int request_id,
108                               GATTError error, int offset,
109                               const std::vector<uint8_t>& value) {
110   VLOG(1) << __func__ << " - server_id: " << server_id_
111           << " device_address: " << device_address
112           << " request_id: " << request_id << " error: " << error
113           << " offset: " << offset;
114   lock_guard<mutex> lock(mutex_);
115 
116   RawAddress addr;
117   if (!RawAddress::FromString(device_address, addr)) {
118     LOG(ERROR) << "Invalid device address given: " << device_address;
119     return false;
120   }
121 
122   if (offset < 0) {
123     android_errorWriteLog(0x534e4554, "143231677");
124     LOG(ERROR) << "Offset is less than 0 offset: " << offset;
125     return false;
126   }
127 
128   if (value.size() + offset > BTGATT_MAX_ATTR_LEN) {
129     LOG(ERROR) << "Value is too large";
130     return false;
131   }
132 
133   // Find the correct connection ID for |device_address| and |request_id|.
134   auto iter = conn_addr_map_.find(device_address);
135   if (iter == conn_addr_map_.end()) {
136     LOG(ERROR) << "No known connections for device address: " << device_address;
137     return false;
138   }
139 
140   std::shared_ptr<Connection> connection;
141   for (const auto& tmp : iter->second) {
142     if (tmp->request_id_to_handle.find(request_id) ==
143         tmp->request_id_to_handle.end())
144       continue;
145 
146     connection = tmp;
147   }
148 
149   if (!connection) {
150     LOG(ERROR) << "Pending request with ID " << request_id
151                << " not found for device with BD_ADDR: " << device_address;
152     return false;
153   }
154 
155   btgatt_response_t response;
156   memset(&response, 0, sizeof(response));
157 
158   // We keep -1 as the handle for "Execute Write Request". In that case,
159   // there is no need to populate the response data. Just send zeros back.
160   int handle = connection->request_id_to_handle[request_id];
161   response.handle = handle;
162   response.attr_value.handle = handle;
163   if (handle != -1) {
164     memcpy(response.attr_value.value, value.data(), value.size());
165     response.attr_value.offset = offset;
166     response.attr_value.len = value.size();
167   }
168 
169   bt_status_t result =
170       hal::BluetoothGattInterface::Get()
171           ->GetServerHALInterface()
172           ->send_response(connection->conn_id, request_id, error, response);
173   if (result != BT_STATUS_SUCCESS) {
174     LOG(ERROR) << "Failed to initiate call to send GATT response";
175     return false;
176   }
177 
178   connection->request_id_to_handle.erase(request_id);
179 
180   return true;
181 }
182 
SendNotification(const std::string & device_address,const uint16_t handle,bool confirm,const std::vector<uint8_t> & value,const GattCallback & callback)183 bool GattServer::SendNotification(const std::string& device_address,
184                                   const uint16_t handle, bool confirm,
185                                   const std::vector<uint8_t>& value,
186                                   const GattCallback& callback) {
187   VLOG(1) << " - server_id: " << server_id_
188           << " device_address: " << device_address << " confirm: " << confirm;
189   lock_guard<mutex> lock(mutex_);
190 
191   RawAddress addr;
192   if (!RawAddress::FromString(device_address, addr)) {
193     LOG(ERROR) << "Invalid device address given: " << device_address;
194     return false;
195   }
196 
197   // Get the connection IDs for which we will send this notification.
198   auto conn_iter = conn_addr_map_.find(device_address);
199   if (conn_iter == conn_addr_map_.end()) {
200     LOG(ERROR) << "No known connections for device with address: "
201                << device_address;
202     return false;
203   }
204 
205   std::shared_ptr<PendingIndication> pending_ind(
206       new PendingIndication(callback));
207 
208   // Send the notification/indication on all matching connections.
209   int send_count = 0;
210   for (const auto& conn : conn_iter->second) {
211     // Make sure that one isn't already pending for this connection.
212     if (pending_indications_.find(conn->conn_id) !=
213         pending_indications_.end()) {
214       VLOG(1) << "A" << (confirm ? "n indication" : " notification")
215               << " is already pending for connection: " << conn->conn_id;
216       continue;
217     }
218 
219     // The HAL API takes char* rather const char* for |value|, so we have to
220     // cast away the const.
221     // TODO(armansito): Make HAL accept const char*.
222     bt_status_t status = hal::BluetoothGattInterface::Get()
223                              ->GetServerHALInterface()
224                              ->send_indication(server_id_, handle,
225                                                conn->conn_id, confirm, value);
226 
227     // Increment the send count if this was successful. We don't immediately
228     // fail if the HAL returned an error. It's better to report success as long
229     // as we sent out at least one notification to this device as
230     // multi-transport GATT connections from the same BD_ADDR will be rare
231     // enough already.
232     if (status != BT_STATUS_SUCCESS) continue;
233 
234     send_count++;
235     pending_indications_[conn->conn_id] = pending_ind;
236   }
237 
238   if (send_count == 0) {
239     LOG(ERROR) << "Failed to send notifications/indications to device: "
240                << device_address;
241     return false;
242   }
243 
244   return true;
245 }
246 
ConnectionCallback(hal::BluetoothGattInterface *,int conn_id,int server_id,int connected,const RawAddress & bda)247 void GattServer::ConnectionCallback(
248     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int server_id,
249     int connected, const RawAddress& bda) {
250   lock_guard<mutex> lock(mutex_);
251 
252   if (server_id != server_id_) return;
253 
254   std::string device_address = BtAddrString(&bda);
255 
256   VLOG(1) << __func__ << " conn_id: " << conn_id << " connected: " << connected
257           << " BD_ADDR: " << device_address;
258 
259   if (!connected) {
260     // Erase the entry if we were connected to it.
261     VLOG(1) << "No longer connected: " << device_address;
262     conn_id_map_.erase(conn_id);
263     auto iter = conn_addr_map_.find(device_address);
264     if (iter == conn_addr_map_.end()) return;
265 
266     // Remove the appropriate connection objects in the address.
267     for (auto conn_iter = iter->second.begin(); conn_iter != iter->second.end();
268          ++conn_iter) {
269       if ((*conn_iter)->conn_id != conn_id) continue;
270 
271       iter->second.erase(conn_iter);
272       break;
273     }
274 
275     if (delegate_)
276       delegate_->OnConnectionStateChanged(this, device_address, false);
277 
278     return;
279   }
280 
281   if (conn_id_map_.find(conn_id) != conn_id_map_.end()) {
282     LOG(WARNING) << "Connection entry already exists; "
283                  << "ignoring ConnectionCallback";
284     return;
285   }
286 
287   LOG(INFO) << "Added connection entry for conn_id: " << conn_id
288             << " device address: " << device_address;
289   std::shared_ptr<Connection> connection(new Connection(conn_id, bda));
290   conn_id_map_[conn_id] = connection;
291   conn_addr_map_[device_address].push_back(connection);
292 
293   if (delegate_)
294     delegate_->OnConnectionStateChanged(this, device_address, true);
295 }
296 
ServiceAddedCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,std::vector<btgatt_db_element_t> svc)297 void GattServer::ServiceAddedCallback(hal::BluetoothGattInterface* gatt_iface,
298                                       int status, int server_id,
299                                       std::vector<btgatt_db_element_t> svc) {
300   lock_guard<mutex> lock(mutex_);
301 
302   if (server_id != server_id_) return;
303 
304   VLOG(1) << __func__ << " - status: " << status << " server_id: " << server_id
305           << " first handle: " << svc[0].attribute_handle
306           << " service Uuid: " << Uuid(svc[0].uuid).ToString()
307           << " count: " << svc.size();
308 
309   Service service(svc[0].attribute_handle, true, Uuid(svc[0].uuid), {}, {});
310 
311   for (size_t i = 1; i < svc.size(); i++) {
312     const btgatt_db_element_t& curr = svc[i];
313     VLOG(1) << " - processing item no: " << i
314             << " handle: " << curr.attribute_handle;
315     if (curr.type == BTGATT_DB_CHARACTERISTIC) {
316       service.characteristics().push_back({curr.attribute_handle,
317                                            Uuid(curr.uuid),
318                                            curr.properties,
319                                            curr.permissions,
320                                            {}});
321     } else if (curr.type == BTGATT_DB_DESCRIPTOR) {
322       service.characteristics().back().descriptors().push_back(
323           {curr.attribute_handle, Uuid(curr.uuid), curr.permissions});
324     } else if (svc[i].type == BTGATT_DB_INCLUDED_SERVICE) {
325     }
326   }
327 
328   pending_end_decl_cb_((bluetooth::BLEStatus)status, service);
329 
330   CleanUpPendingData();
331 }
332 
ServiceStoppedCallback(hal::BluetoothGattInterface *,int,int,int)333 void GattServer::ServiceStoppedCallback(
334     hal::BluetoothGattInterface* /* gatt_iface */, int /* status */,
335     int /* server_id */, int /* service_handle */) {
336   // TODO(armansito): Support stopping a service.
337 }
338 
RequestReadCharacteristicCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const RawAddress & bda,int attribute_handle,int offset,bool is_long)339 void GattServer::RequestReadCharacteristicCallback(
340     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
341     const RawAddress& bda, int attribute_handle, int offset, bool is_long) {
342   lock_guard<mutex> lock(mutex_);
343 
344   // Check to see if we know about this connection. Otherwise ignore the
345   // request.
346   auto conn = GetConnection(conn_id, bda, trans_id);
347   if (!conn) return;
348 
349   std::string device_address = BtAddrString(&bda);
350 
351   VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
352           << " BD_ADDR: " << device_address
353           << " attribute_handle: " << attribute_handle << " offset: " << offset
354           << " is_long: " << is_long;
355 
356   conn->request_id_to_handle[trans_id] = attribute_handle;
357 
358   // If there is no delegate then there is nobody to handle request. The request
359   // will eventually timeout and we should get a connection update that
360   // terminates the connection.
361   if (!delegate_) {
362     // TODO(armansito): Require a delegate at server registration so that this
363     // is never possible.
364     LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
365                  << "will time out.";
366     return;
367   }
368 
369   delegate_->OnCharacteristicReadRequest(this, device_address, trans_id, offset,
370                                          is_long, attribute_handle);
371 }
RequestReadDescriptorCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const RawAddress & bda,int attribute_handle,int offset,bool is_long)372 void GattServer::RequestReadDescriptorCallback(
373     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
374     const RawAddress& bda, int attribute_handle, int offset, bool is_long) {
375   lock_guard<mutex> lock(mutex_);
376 
377   // Check to see if we know about this connection. Otherwise ignore the
378   // request.
379   auto conn = GetConnection(conn_id, bda, trans_id);
380   if (!conn) return;
381 
382   std::string device_address = BtAddrString(&bda);
383 
384   VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
385           << " BD_ADDR: " << device_address
386           << " attribute_handle: " << attribute_handle << " offset: " << offset
387           << " is_long: " << is_long;
388 
389   conn->request_id_to_handle[trans_id] = attribute_handle;
390 
391   // If there is no delegate then there is nobody to handle request. The request
392   // will eventually timeout and we should get a connection update that
393   // terminates the connection.
394   if (!delegate_) {
395     // TODO(armansito): Require a delegate at server registration so that this
396     // is never possible.
397     LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
398                  << "will time out.";
399     return;
400   }
401 
402   delegate_->OnDescriptorReadRequest(this, device_address, trans_id, offset,
403                                      is_long, attribute_handle);
404 }
405 
RequestWriteCharacteristicCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,std::vector<uint8_t> value)406 void GattServer::RequestWriteCharacteristicCallback(
407     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
408     const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
409     bool is_prep, std::vector<uint8_t> value) {
410   lock_guard<mutex> lock(mutex_);
411 
412   // Check to see if we know about this connection. Otherwise ignore the
413   // request.
414   auto conn = GetConnection(conn_id, bda, trans_id);
415   if (!conn) return;
416 
417   std::string device_address = BtAddrString(&bda);
418 
419   VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
420           << " BD_ADDR: " << device_address << " attr_handle: " << attr_handle
421           << " offset: " << offset << " length: " << value.size()
422           << " need_rsp: " << need_rsp << " is_prep: " << is_prep;
423 
424   // Store the request ID only if this is not a write-without-response. If
425   // another request occurs after this with the same request ID, then we'll
426   // simply process it normally, though that shouldn't ever happen.
427   if (need_rsp) conn->request_id_to_handle[trans_id] = attr_handle;
428 
429   // If there is no delegate then there is nobody to handle request. The request
430   // will eventually timeout and we should get a connection update that
431   // terminates the connection.
432   if (!delegate_) {
433     // TODO(armansito): Require a delegate at server registration so that this
434     // is never possible.
435     LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
436                  << "will time out.";
437     return;
438   }
439 
440   delegate_->OnCharacteristicWriteRequest(this, device_address, trans_id,
441                                           offset, is_prep, need_rsp,
442                                           std::move(value), attr_handle);
443 }
444 
RequestWriteDescriptorCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,std::vector<uint8_t> value)445 void GattServer::RequestWriteDescriptorCallback(
446     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
447     const RawAddress& bda, int attr_handle, int offset, bool need_rsp,
448     bool is_prep, std::vector<uint8_t> value) {
449   lock_guard<mutex> lock(mutex_);
450 
451   // Check to see if we know about this connection. Otherwise ignore the
452   // request.
453   auto conn = GetConnection(conn_id, bda, trans_id);
454   if (!conn) return;
455 
456   std::string device_address = BtAddrString(&bda);
457 
458   VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
459           << " BD_ADDR: " << device_address << " attr_handle: " << attr_handle
460           << " offset: " << offset << " length: " << value.size()
461           << " need_rsp: " << need_rsp << " is_prep: " << is_prep;
462 
463   // Store the request ID only if this is not a write-without-response. If
464   // another request occurs after this with the same request ID, then we'll
465   // simply process it normally, though that shouldn't ever happen.
466   if (need_rsp) conn->request_id_to_handle[trans_id] = attr_handle;
467 
468   // If there is no delegate then there is nobody to handle request. The request
469   // will eventually timeout and we should get a connection update that
470   // terminates the connection.
471   if (!delegate_) {
472     // TODO(armansito): Require a delegate at server registration so that this
473     // is never possible.
474     LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
475                  << "will time out.";
476     return;
477   }
478 
479   delegate_->OnDescriptorWriteRequest(this, device_address, trans_id, offset,
480                                       is_prep, need_rsp, std::move(value),
481                                       attr_handle);
482 }
483 
RequestExecWriteCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const RawAddress & bda,int exec_write)484 void GattServer::RequestExecWriteCallback(
485     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int trans_id,
486     const RawAddress& bda, int exec_write) {
487   lock_guard<mutex> lock(mutex_);
488 
489   // Check to see if we know about this connection. Otherwise ignore the
490   // request.
491   auto conn = GetConnection(conn_id, bda, trans_id);
492   if (!conn) return;
493 
494   std::string device_address = BtAddrString(&bda);
495 
496   VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
497           << " BD_ADDR: " << device_address << " exec_write: " << exec_write;
498 
499   // Just store a dummy invalid handle as this request doesn't apply to a
500   // specific handle.
501   conn->request_id_to_handle[trans_id] = -1;
502 
503   // If there is no delegate then there is nobody to handle request. The request
504   // will eventually timeout and we should get a connection update that
505   // terminates the connection.
506   if (!delegate_) {
507     // TODO(armansito): Require a delegate at server registration so that this
508     // is never possible.
509     LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
510                  << "will time out.";
511     return;
512   }
513 
514   delegate_->OnExecuteWriteRequest(this, device_address, trans_id, exec_write);
515 }
516 
IndicationSentCallback(hal::BluetoothGattInterface *,int conn_id,int status)517 void GattServer::IndicationSentCallback(
518     hal::BluetoothGattInterface* /* gatt_iface */, int conn_id, int status) {
519   VLOG(1) << __func__ << " conn_id: " << conn_id << " status: " << status;
520   lock_guard<mutex> lock(mutex_);
521 
522   const auto& pending_ind_iter = pending_indications_.find(conn_id);
523   if (pending_ind_iter == pending_indications_.end()) {
524     VLOG(1) << "Unknown connection: " << conn_id;
525     return;
526   }
527 
528   std::shared_ptr<PendingIndication> pending_ind = pending_ind_iter->second;
529   pending_indications_.erase(pending_ind_iter);
530 
531   if (status == BT_STATUS_SUCCESS) pending_ind->has_success = true;
532 
533   // Invoke it if this was the last reference to the confirmation callback.
534   if (pending_ind.unique() && pending_ind->callback) {
535     pending_ind->callback(pending_ind->has_success
536                               ? GATT_ERROR_NONE
537                               : static_cast<GATTError>(status));
538   }
539 }
540 
CleanUpPendingData()541 void GattServer::CleanUpPendingData() {
542   pending_end_decl_cb_ = ResultCallback();
543 }
544 
GetConnection(int conn_id,const RawAddress & bda,int request_id)545 std::shared_ptr<GattServer::Connection> GattServer::GetConnection(
546     int conn_id, const RawAddress& bda, int request_id) {
547   auto iter = conn_id_map_.find(conn_id);
548   if (iter == conn_id_map_.end()) {
549     VLOG(1) << "Connection doesn't belong to this server";
550     return nullptr;
551   }
552 
553   auto conn = iter->second;
554   if (conn->bdaddr != bda) {
555     LOG(WARNING) << "BD_ADDR: " << BtAddrString(&bda) << " doesn't match "
556                  << "connection ID: " << conn_id;
557     return nullptr;
558   }
559 
560   if (conn->request_id_to_handle.find(request_id) !=
561       conn->request_id_to_handle.end()) {
562     VLOG(1) << "Request with ID: " << request_id << " already exists for "
563             << " connection: " << conn_id;
564     return nullptr;
565   }
566 
567   return conn;
568 }
569 
570 // GattServerFactory implementation
571 // ========================================================
572 
GattServerFactory()573 GattServerFactory::GattServerFactory() {
574   hal::BluetoothGattInterface::Get()->AddServerObserver(this);
575 }
576 
~GattServerFactory()577 GattServerFactory::~GattServerFactory() {
578   hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
579 }
580 
RegisterInstance(const Uuid & uuid,const RegisterCallback & callback)581 bool GattServerFactory::RegisterInstance(const Uuid& uuid,
582                                          const RegisterCallback& callback) {
583   VLOG(1) << __func__ << " - Uuid: " << uuid.ToString();
584   lock_guard<mutex> lock(pending_calls_lock_);
585 
586   if (pending_calls_.find(uuid) != pending_calls_.end()) {
587     LOG(ERROR) << "GATT-server client with given Uuid already being registered "
588                << " - Uuid: " << uuid.ToString();
589     return false;
590   }
591 
592   const btgatt_server_interface_t* hal_iface =
593       hal::BluetoothGattInterface::Get()->GetServerHALInterface();
594 
595   if (hal_iface->register_server(uuid) != BT_STATUS_SUCCESS) return false;
596 
597   pending_calls_[uuid] = callback;
598 
599   return true;
600 }
601 
RegisterServerCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,const Uuid & app_uuid)602 void GattServerFactory::RegisterServerCallback(
603     hal::BluetoothGattInterface* gatt_iface, int status, int server_id,
604     const Uuid& app_uuid) {
605   Uuid uuid(app_uuid);
606 
607   VLOG(1) << __func__ << " - Uuid: " << uuid.ToString();
608   lock_guard<mutex> lock(pending_calls_lock_);
609 
610   auto iter = pending_calls_.find(uuid);
611   if (iter == pending_calls_.end()) {
612     VLOG(1) << "Ignoring callback for unknown app_id: " << uuid.ToString();
613     return;
614   }
615 
616   // No need to construct a server if the call wasn't successful.
617   std::unique_ptr<GattServer> server;
618   BLEStatus result = BLE_STATUS_FAILURE;
619   if (status == BT_STATUS_SUCCESS) {
620     server.reset(new GattServer(uuid, server_id));
621 
622     gatt_iface->AddServerObserver(server.get());
623 
624     result = BLE_STATUS_SUCCESS;
625   }
626 
627   // Notify the result via the result callback.
628   iter->second(result, uuid, std::move(server));
629 
630   pending_calls_.erase(iter);
631 }
632 
633 }  // namespace bluetooth
634