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