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