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/hal/gatt_helpers.h"
21#include "service/logging_helpers.h"
22
23using std::lock_guard;
24using std::mutex;
25
26namespace bluetooth {
27
28namespace {
29
30bool operator==(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
31  return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
32}
33
34bool operator!=(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
35  return !(lhs == rhs);
36}
37
38}  // namespace
39
40// GattServer implementation
41// ========================================================
42
43GattServer::GattServer(const UUID& uuid, int server_id)
44    : app_identifier_(uuid),
45      server_id_(server_id),
46      delegate_(nullptr) {
47}
48
49GattServer::~GattServer() {
50  // Automatically unregister the server.
51  VLOG(1) << "GattServer unregistering: " << server_id_;
52
53  // Unregister as observer so we no longer receive any callbacks.
54  hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
55
56  // Unregister this server, stop all services, and ignore the result.
57  // TODO(armansito): stop and remove all services here? unregister_server
58  // should really take care of that.
59  hal::BluetoothGattInterface::Get()->
60      GetServerHALInterface()->unregister_server(server_id_);
61}
62
63void GattServer::SetDelegate(Delegate* delegate) {
64  lock_guard<mutex> lock(mutex_);
65  delegate_ = delegate;
66}
67
68const UUID& GattServer::GetAppIdentifier() const {
69  return app_identifier_;
70}
71
72int GattServer::GetInstanceId() const {
73  return server_id_;
74}
75
76std::unique_ptr<GattIdentifier> GattServer::BeginServiceDeclaration(
77    const UUID& uuid, bool is_primary) {
78  VLOG(1) << __func__ << " server_id: " << server_id_
79          << " - UUID: " << uuid.ToString()
80          << ", is_primary: " << is_primary;
81  lock_guard<mutex> lock(mutex_);
82
83  if (pending_decl_) {
84    LOG(ERROR) << "Already began service declaration";
85    return nullptr;
86  }
87
88  CHECK(!pending_id_);
89  CHECK(!pending_decl_);
90  CHECK(!pending_end_decl_cb_);
91
92  auto service_id = GetIdForService(uuid, is_primary);
93  CHECK(service_id);
94
95  // Pass 0 for permissions and properties as this is a service decl.
96  AttributeEntry entry(
97      *service_id, kCharacteristicPropertyNone, kAttributePermissionNone);
98
99  pending_decl_.reset(new ServiceDeclaration());
100  pending_decl_->num_handles++;  // 1 handle for the service decl. attribute
101  pending_decl_->service_id = *service_id;
102  pending_decl_->attributes.push_back(entry);
103
104  return service_id;
105}
106
107std::unique_ptr<GattIdentifier> GattServer::AddCharacteristic(
108      const UUID& uuid, int properties, int permissions) {
109  VLOG(1) << __func__ << " server_id: " << server_id_
110          << " - UUID: " << uuid.ToString()
111          << ", properties: " << properties
112          << ", permissions: " << permissions;
113  lock_guard<mutex> lock(mutex_);
114
115  if (!pending_decl_) {
116    LOG(ERROR) << "Service declaration not begun";
117    return nullptr;
118  }
119
120  if (pending_end_decl_cb_) {
121    LOG(ERROR) << "EndServiceDeclaration in progress, cannot modify service";
122    return nullptr;
123  }
124
125  auto char_id = GetIdForCharacteristic(uuid);
126  CHECK(char_id);
127  AttributeEntry entry(*char_id, properties, permissions);
128
129  // 2 handles for the characteristic declaration and the value attributes.
130  pending_decl_->num_handles += 2;
131  pending_decl_->attributes.push_back(entry);
132
133  return char_id;
134}
135
136std::unique_ptr<GattIdentifier> GattServer::AddDescriptor(
137    const UUID& uuid, int permissions) {
138  VLOG(1) << __func__ << " server_id: " << server_id_
139          << " - UUID: " << uuid.ToString()
140          << ", permissions: " << permissions;
141  lock_guard<mutex> lock(mutex_);
142
143  if (!pending_decl_) {
144    LOG(ERROR) << "Service declaration not begun";
145    return nullptr;
146  }
147
148  if (pending_end_decl_cb_) {
149    LOG(ERROR) << "EndServiceDeclaration in progress, cannot modify service";
150    return nullptr;
151  }
152
153  auto desc_id = GetIdForDescriptor(uuid);
154  if (!desc_id)
155    return nullptr;
156
157  AttributeEntry entry(*desc_id, kCharacteristicPropertyNone, permissions);
158
159  // 1 handle for the descriptor attribute.
160  pending_decl_->num_handles += 1;
161  pending_decl_->attributes.push_back(entry);
162
163  return desc_id;
164}
165
166bool GattServer::EndServiceDeclaration(const ResultCallback& callback) {
167  VLOG(1) << __func__ << " server_id: " << server_id_;
168  lock_guard<mutex> lock(mutex_);
169
170  if (!callback) {
171    LOG(ERROR) << "|callback| cannot be NULL";
172    return false;
173  }
174
175  if (!pending_decl_) {
176    LOG(ERROR) << "Service declaration not begun";
177    return false;
178  }
179
180  if (pending_end_decl_cb_) {
181    LOG(ERROR) << "EndServiceDeclaration already in progress";
182    return false;
183  }
184
185  CHECK(!pending_id_);
186
187  // There has to be at least one entry here for the service declaration
188  // attribute.
189  CHECK(pending_decl_->num_handles > 0);
190  CHECK(!pending_decl_->attributes.empty());
191
192  std::unique_ptr<GattIdentifier> service_id = PopNextId();
193  CHECK(service_id->IsService());
194  CHECK(*service_id == pending_decl_->service_id);
195
196  btgatt_srvc_id_t hal_id;
197  hal::GetHALServiceId(*service_id, &hal_id);
198
199  bt_status_t status = hal::BluetoothGattInterface::Get()->
200      GetServerHALInterface()->add_service(
201          server_id_, &hal_id, pending_decl_->num_handles);
202  if (status != BT_STATUS_SUCCESS) {
203    LOG(ERROR) << "Failed to initiate call to populate GATT service";
204    CleanUpPendingData();
205    return false;
206  }
207
208  pending_id_ = std::move(service_id);
209  pending_end_decl_cb_ = callback;
210
211  return true;
212}
213
214std::unique_ptr<GattIdentifier> GattServer::GetIdForService(
215    const UUID& uuid, bool is_primary) {
216  // Calculate the instance ID for this service by searching through the handle
217  // map to see how many occurrences of the same service UUID we find.
218  int inst_id = 0;
219  for (const auto& iter : id_to_handle_map_) {
220    const GattIdentifier* gatt_id = &iter.first;
221
222    if (!gatt_id->IsService())
223      continue;
224
225    if (gatt_id->service_uuid() == uuid)
226      ++inst_id;
227  }
228
229  // Pass empty string for the address as this is a local service.
230  return GattIdentifier::CreateServiceId("", inst_id, uuid, is_primary);
231}
232
233std::unique_ptr<GattIdentifier> GattServer::GetIdForCharacteristic(
234    const UUID& uuid) {
235  CHECK(pending_decl_);
236
237  // Calculate the instance ID for this characteristic by searching through the
238  // pending entries.
239  int inst_id = 0;
240  for (const auto& entry : pending_decl_->attributes) {
241    const GattIdentifier& gatt_id = entry.id;
242
243    if (!gatt_id.IsCharacteristic())
244      continue;
245
246    if (gatt_id.characteristic_uuid() == uuid)
247      ++inst_id;
248  }
249
250  CHECK(pending_decl_->service_id.IsService());
251
252  return GattIdentifier::CreateCharacteristicId(
253      inst_id, uuid, pending_decl_->service_id);
254}
255
256std::unique_ptr<GattIdentifier> GattServer::GetIdForDescriptor(
257    const UUID& uuid) {
258  CHECK(pending_decl_);
259
260  // Calculate the instance ID for this descriptor by searching through the
261  // pending entries. We iterate in reverse until we find a characteristic
262  // entry.
263  CHECK(!pending_decl_->attributes.empty());
264  int inst_id = 0;
265  bool char_found = false;
266  GattIdentifier char_id;
267  for (auto iter = pending_decl_->attributes.end() - 1;
268       iter != pending_decl_->attributes.begin();  // Begin is always a service
269       --iter) {
270    const GattIdentifier& gatt_id = iter->id;
271
272    if (gatt_id.IsCharacteristic()) {
273      // Found the owning characteristic.
274      char_found = true;
275      char_id = gatt_id;
276      break;
277    }
278
279    if (!gatt_id.IsDescriptor()) {
280      // A descriptor must be preceded by a descriptor or a characteristic.
281      LOG(ERROR) << "Descriptors must come directly after a characteristic or "
282                 << "another descriptor.";
283      return nullptr;
284    }
285
286    if (gatt_id.descriptor_uuid() == uuid)
287      ++inst_id;
288  }
289
290  if (!char_found) {
291    LOG(ERROR) << "No characteristic found to add the descriptor to.";
292    return nullptr;
293  }
294
295  return GattIdentifier::CreateDescriptorId(inst_id, uuid, char_id);
296}
297
298bool GattServer::SendResponse(
299    const std::string& device_address, int request_id,
300    GATTError error, int offset,
301    const std::vector<uint8_t>& value) {
302  VLOG(1) << __func__ << " - server_id: " << server_id_
303          << " device_address: " << device_address
304          << " request_id: " << request_id
305          << " error: " << error
306          << " offset: " << offset;
307  lock_guard<mutex> lock(mutex_);
308
309  bt_bdaddr_t addr;
310  if (!util::BdAddrFromString(device_address, &addr)) {
311    LOG(ERROR) << "Invalid device address given: " << device_address;
312    return false;
313  }
314
315  if (value.size() + offset > BTGATT_MAX_ATTR_LEN) {
316    LOG(ERROR) << "Value is too large";
317    return false;
318  }
319
320  // Find the correct connection ID for |device_address| and |request_id|.
321  auto iter = conn_addr_map_.find(device_address);
322  if (iter == conn_addr_map_.end()) {
323    LOG(ERROR) << "No known connections for device address: " << device_address;
324    return false;
325  }
326
327  std::shared_ptr<Connection> connection;
328  for (auto tmp : iter->second) {
329    if (tmp->request_id_to_handle.find(request_id) ==
330        tmp->request_id_to_handle.end())
331      continue;
332
333    connection = tmp;
334  }
335
336  if (!connection) {
337    LOG(ERROR) << "Pending request with ID " << request_id
338               << " not found for device with BD_ADDR: " << device_address;
339    return false;
340  }
341
342  btgatt_response_t response;
343  memset(&response, 0, sizeof(response));
344
345  // We keep -1 as the handle for "Execute Write Request". In that case,
346  // there is no need to populate the response data. Just send zeros back.
347  int handle = connection->request_id_to_handle[request_id];
348  response.handle = handle;
349  response.attr_value.handle = handle;
350  if (handle != -1) {
351    memcpy(response.attr_value.value, value.data(), value.size());
352    response.attr_value.offset = offset;
353    response.attr_value.len = value.size();
354  }
355
356  bt_status_t result = hal::BluetoothGattInterface::Get()->
357      GetServerHALInterface()->send_response(
358          connection->conn_id, request_id, error, &response);
359  if (result != BT_STATUS_SUCCESS) {
360    LOG(ERROR) << "Failed to initiate call to send GATT response";
361    return false;
362  }
363
364  connection->request_id_to_handle.erase(request_id);
365
366  return true;
367}
368
369bool GattServer::SendNotification(
370    const std::string& device_address,
371    const GattIdentifier& characteristic_id,
372    bool confirm,
373    const std::vector<uint8_t>& value,
374    const GattCallback& callback) {
375  VLOG(1) << " - server_id: " << server_id_
376          << " device_address: " << device_address
377          << " confirm: " << confirm;
378  lock_guard<mutex> lock(mutex_);
379
380  bt_bdaddr_t addr;
381  if (!util::BdAddrFromString(device_address, &addr)) {
382    LOG(ERROR) << "Invalid device address given: " << device_address;
383    return false;
384  }
385
386  // Get the connection IDs for which we will send this notification.
387  auto conn_iter = conn_addr_map_.find(device_address);
388  if (conn_iter == conn_addr_map_.end()) {
389    LOG(ERROR) << "No known connections for device with address: "
390               << device_address;
391    return false;
392  }
393
394  // Make sure that |characteristic_id| matches a valid attribute handle.
395  auto handle_iter = id_to_handle_map_.find(characteristic_id);
396  if (handle_iter == id_to_handle_map_.end()) {
397    LOG(ERROR) << "Unknown characteristic";
398    return false;
399  }
400
401  std::shared_ptr<PendingIndication> pending_ind(
402      new PendingIndication(callback));
403
404  // Send the notification/indication on all matching connections.
405  int send_count = 0;
406  for (auto conn : conn_iter->second) {
407    // Make sure that one isn't already pending for this connection.
408    if (pending_indications_.find(conn->conn_id) !=
409        pending_indications_.end()) {
410      VLOG(1) << "A" << (confirm ? "n indication" : " notification")
411              << " is already pending for connection: " << conn->conn_id;
412      continue;
413    }
414
415    // The HAL API takes char* rather const char* for |value|, so we have to
416    // cast away the const.
417    // TODO(armansito): Make HAL accept const char*.
418    bt_status_t status = hal::BluetoothGattInterface::Get()->
419        GetServerHALInterface()->send_indication(
420            server_id_,
421            handle_iter->second,
422            conn->conn_id,
423            value.size(),
424            confirm,
425            reinterpret_cast<char*>(const_cast<uint8_t*>(value.data())));
426
427    // Increment the send count if this was successful. We don't immediately
428    // fail if the HAL returned an error. It's better to report success as long
429    // as we sent out at least one notification to this device as
430    // multi-transport GATT connections from the same BD_ADDR will be rare
431    // enough already.
432    if (status != BT_STATUS_SUCCESS)
433      continue;
434
435    send_count++;
436    pending_indications_[conn->conn_id] = pending_ind;
437  }
438
439  if (send_count == 0) {
440    LOG(ERROR) << "Failed to send notifications/indications to device: "
441               << device_address;
442    return false;
443  }
444
445  return true;
446}
447
448void GattServer::ConnectionCallback(
449    hal::BluetoothGattInterface* /* gatt_iface */,
450    int conn_id, int server_id,
451    int connected,
452    const bt_bdaddr_t& bda) {
453  lock_guard<mutex> lock(mutex_);
454
455  if (server_id != server_id_)
456    return;
457
458  std::string device_address = BtAddrString(&bda);
459
460  VLOG(1) << __func__ << " conn_id: " << conn_id << " connected: " << connected
461          << " BD_ADDR: " << device_address;
462
463  if (!connected) {
464    // Erase the entry if we were connected to it.
465    VLOG(1) << "No longer connected: " << device_address;
466    conn_id_map_.erase(conn_id);
467    auto iter = conn_addr_map_.find(device_address);
468    if (iter == conn_addr_map_.end())
469      return;
470
471    // Remove the appropriate connection objects in the address.
472    for (auto conn_iter = iter->second.begin(); conn_iter != iter->second.end();
473         ++conn_iter) {
474      if ((*conn_iter)->conn_id != conn_id)
475        continue;
476
477      iter->second.erase(conn_iter);
478      break;
479    }
480
481    return;
482  }
483
484  if (conn_id_map_.find(conn_id) != conn_id_map_.end()) {
485    LOG(WARNING) << "Connection entry already exists; "
486                 << "ignoring ConnectionCallback";
487    return;
488  }
489
490  LOG(INFO) << "Added connection entry for conn_id: " << conn_id
491            << " device address: " << device_address;
492  std::shared_ptr<Connection> connection(new Connection(conn_id, bda));
493  conn_id_map_[conn_id] = connection;
494  conn_addr_map_[device_address].push_back(connection);
495}
496
497void GattServer::ServiceAddedCallback(
498    hal::BluetoothGattInterface* gatt_iface,
499    int status, int server_id,
500    const btgatt_srvc_id_t& srvc_id,
501    int service_handle) {
502  lock_guard<mutex> lock(mutex_);
503
504  if (server_id != server_id_)
505    return;
506
507  // Construct a GATT identifier.
508  auto gatt_id = hal::GetServiceIdFromHAL(srvc_id);
509  CHECK(pending_id_);
510  CHECK(*gatt_id == *pending_id_);
511  CHECK(*gatt_id == pending_decl_->service_id);
512  CHECK(pending_id_->IsService());
513
514  VLOG(1) << __func__ << " - status: " << status
515          << " server_id: " << server_id
516          << " handle: " << service_handle
517          << " UUID: " << gatt_id->service_uuid().ToString();
518
519  if (status != BT_STATUS_SUCCESS) {
520    NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status), *gatt_id);
521    return;
522  }
523
524  // Add this to the handle map.
525  pending_handle_map_[*gatt_id] = service_handle;
526  CHECK(-1 == pending_decl_->service_handle);
527  pending_decl_->service_handle = service_handle;
528
529  HandleNextEntry(gatt_iface);
530}
531
532void GattServer::CharacteristicAddedCallback(
533    hal::BluetoothGattInterface* gatt_iface,
534    int status, int server_id,
535    const bt_uuid_t& uuid,
536    int service_handle,
537    int char_handle) {
538  lock_guard<mutex> lock(mutex_);
539
540  if (server_id != server_id_)
541    return;
542
543  CHECK(pending_decl_);
544  CHECK(pending_decl_->service_handle == service_handle);
545  CHECK(pending_id_);
546  CHECK(pending_id_->IsCharacteristic());
547  CHECK(pending_id_->characteristic_uuid() == UUID(uuid));
548
549  VLOG(1) << __func__ << " - status: " << status
550          << " server_id: " << server_id
551          << " service_handle: " << service_handle
552          << " char_handle: " << char_handle;
553
554  if (status != BT_STATUS_SUCCESS) {
555    NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
556                                  pending_decl_->service_id);
557    return;
558  }
559
560  // Add this to the handle map and continue.
561  pending_handle_map_[*pending_id_] = char_handle;
562  HandleNextEntry(gatt_iface);
563}
564
565void GattServer::DescriptorAddedCallback(
566    hal::BluetoothGattInterface* gatt_iface,
567    int status, int server_id,
568    const bt_uuid_t& uuid,
569    int service_handle,
570    int desc_handle) {
571  lock_guard<mutex> lock(mutex_);
572
573  if (server_id != server_id_)
574    return;
575
576  CHECK(pending_decl_);
577  CHECK(pending_decl_->service_handle == service_handle);
578  CHECK(pending_id_);
579  CHECK(pending_id_->IsDescriptor());
580  CHECK(pending_id_->descriptor_uuid() == UUID(uuid));
581
582  VLOG(1) << __func__ << " - status: " << status
583          << " server_id: " << server_id
584          << " service_handle: " << service_handle
585          << " desc_handle: " << desc_handle;
586
587  if (status != BT_STATUS_SUCCESS) {
588    NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
589                                  pending_decl_->service_id);
590    return;
591  }
592
593  // Add this to the handle map and contiue.
594  pending_handle_map_[*pending_id_] = desc_handle;
595  HandleNextEntry(gatt_iface);
596}
597
598void GattServer::ServiceStartedCallback(
599    hal::BluetoothGattInterface* gatt_iface,
600    int status, int server_id,
601    int service_handle) {
602  lock_guard<mutex> lock(mutex_);
603
604  if (server_id != server_id_)
605    return;
606
607  CHECK(pending_id_);
608  CHECK(pending_decl_);
609  CHECK(pending_decl_->service_handle == service_handle);
610
611  VLOG(1) << __func__ << " - server_id: " << server_id
612          << " handle: " << service_handle;
613
614  // If we failed to start the service, remove it from the database and ignore
615  // the result.
616  if (status != BT_STATUS_SUCCESS) {
617    gatt_iface->GetServerHALInterface()->delete_service(
618        server_id_, service_handle);
619  }
620
621  // Complete the operation.
622  NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
623                                pending_decl_->service_id);
624}
625
626void GattServer::ServiceStoppedCallback(
627    hal::BluetoothGattInterface* /* gatt_iface */,
628    int /* status */,
629    int /* server_id */,
630    int /* service_handle */) {
631  // TODO(armansito): Support stopping a service.
632}
633
634void GattServer::RequestReadCallback(
635    hal::BluetoothGattInterface* /* gatt_iface */,
636    int conn_id, int trans_id,
637    const bt_bdaddr_t& bda,
638    int attribute_handle, int offset,
639    bool is_long) {
640  lock_guard<mutex> lock(mutex_);
641
642  // Check to see if we know about this connection. Otherwise ignore the
643  // request.
644  auto conn = GetConnection(conn_id, bda, trans_id);
645  if (!conn)
646    return;
647
648  std::string device_address = BtAddrString(&bda);
649
650  VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
651          << " BD_ADDR: " << device_address
652          << " attribute_handle: " << attribute_handle << " offset: " << offset
653          << " is_long: " << is_long;
654
655  // Make sure that the handle is valid.
656  auto iter = handle_to_id_map_.find(attribute_handle);
657  if (iter == handle_to_id_map_.end()) {
658    LOG(ERROR) << "Request received for unknown handle: " << attribute_handle;
659    return;
660  }
661
662  conn->request_id_to_handle[trans_id] = attribute_handle;
663
664  // If there is no delegate then there is nobody to handle request. The request
665  // will eventually timeout and we should get a connection update that
666  // terminates the connection.
667  if (!delegate_) {
668    // TODO(armansito): Require a delegate at server registration so that this
669    // is never possible.
670    LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
671                 << "will time out.";
672    return;
673  }
674
675  if (iter->second.IsCharacteristic()) {
676    delegate_->OnCharacteristicReadRequest(
677        this, device_address, trans_id, offset, is_long, iter->second);
678  } else if (iter->second.IsDescriptor()) {
679    delegate_->OnDescriptorReadRequest(
680        this, device_address, trans_id, offset, is_long, iter->second);
681  } else {
682    // Our API only delegates to applications those read requests for
683    // characteristic value and descriptor attributes. Everything else should be
684    // handled by the stack.
685    LOG(WARNING) << "Read request received for unsupported attribute";
686  }
687}
688
689void GattServer::RequestWriteCallback(
690    hal::BluetoothGattInterface* /* gatt_iface */,
691    int conn_id, int trans_id,
692    const bt_bdaddr_t& bda,
693    int attr_handle, int offset, int length,
694    bool need_rsp, bool is_prep, uint8_t* value) {
695  lock_guard<mutex> lock(mutex_);
696
697  if (length < 0) {
698    LOG(WARNING) << "Negative length value received";
699    return;
700  }
701
702  // Check to see if we know about this connection. Otherwise ignore the
703  // request.
704  auto conn = GetConnection(conn_id, bda, trans_id);
705  if (!conn)
706    return;
707
708  std::string device_address = BtAddrString(&bda);
709
710  VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
711          << " BD_ADDR: " << device_address
712          << " attr_handle: " << attr_handle << " offset: " << offset
713          << " length: " << length << " need_rsp: " << need_rsp
714          << " is_prep: " << is_prep;
715
716  // Make sure that the handle is valid.
717  auto iter = handle_to_id_map_.find(attr_handle);
718  if (iter == handle_to_id_map_.end()) {
719    LOG(ERROR) << "Request received for unknown handle: " << attr_handle;
720    return;
721  }
722
723  // Store the request ID only if this is not a write-without-response. If
724  // another request occurs after this with the same request ID, then we'll
725  // simply process it normally, though that shouldn't ever happen.
726  if (need_rsp)
727    conn->request_id_to_handle[trans_id] = attr_handle;
728
729  // If there is no delegate then there is nobody to handle request. The request
730  // will eventually timeout and we should get a connection update that
731  // terminates the connection.
732  if (!delegate_) {
733    // TODO(armansito): Require a delegate at server registration so that this
734    // is never possible.
735    LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
736                 << "will time out.";
737    return;
738  }
739
740  std::vector<uint8_t> value_vec(value, value + length);
741
742  if (iter->second.IsCharacteristic()) {
743    delegate_->OnCharacteristicWriteRequest(
744        this, device_address, trans_id, offset, is_prep, need_rsp,
745        value_vec, iter->second);
746  } else if (iter->second.IsDescriptor()) {
747    delegate_->OnDescriptorWriteRequest(
748        this, device_address, trans_id, offset, is_prep, need_rsp,
749        value_vec, iter->second);
750  } else {
751    // Our API only delegates to applications those read requests for
752    // characteristic value and descriptor attributes. Everything else should be
753    // handled by the stack.
754    LOG(WARNING) << "Write request received for unsupported attribute";
755  }
756}
757
758void GattServer::RequestExecWriteCallback(
759    hal::BluetoothGattInterface* /* gatt_iface */,
760    int conn_id, int trans_id,
761    const bt_bdaddr_t& bda, int exec_write) {
762  lock_guard<mutex> lock(mutex_);
763
764  // Check to see if we know about this connection. Otherwise ignore the
765  // request.
766  auto conn = GetConnection(conn_id, bda, trans_id);
767  if (!conn)
768    return;
769
770  std::string device_address = BtAddrString(&bda);
771
772  VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
773          << " BD_ADDR: " << device_address << " exec_write: " << exec_write;
774
775  // Just store a dummy invalid handle as this request doesn't apply to a
776  // specific handle.
777  conn->request_id_to_handle[trans_id] = -1;
778
779  // If there is no delegate then there is nobody to handle request. The request
780  // will eventually timeout and we should get a connection update that
781  // terminates the connection.
782  if (!delegate_) {
783    // TODO(armansito): Require a delegate at server registration so that this
784    // is never possible.
785    LOG(WARNING) << "No delegate was assigned to GattServer. Incoming request "
786                 << "will time out.";
787    return;
788  }
789
790  delegate_->OnExecuteWriteRequest(this, device_address, trans_id, exec_write);
791}
792
793void GattServer::IndicationSentCallback(
794    hal::BluetoothGattInterface* /* gatt_iface */,
795    int conn_id, int status) {
796  VLOG(1) << __func__ << " conn_id: " << conn_id << " status: " << status;
797  lock_guard<mutex> lock(mutex_);
798
799  const auto& pending_ind_iter = pending_indications_.find(conn_id);
800  if (pending_ind_iter == pending_indications_.end()) {
801    VLOG(1) << "Unknown connection: " << conn_id;
802    return;
803  }
804
805  std::shared_ptr<PendingIndication> pending_ind = pending_ind_iter->second;
806  pending_indications_.erase(pending_ind_iter);
807
808  if (status == BT_STATUS_SUCCESS)
809    pending_ind->has_success = true;
810
811  // Invoke it if this was the last reference to the confirmation callback.
812  if (pending_ind.unique() && pending_ind->callback) {
813    pending_ind->callback(
814        pending_ind->has_success ?
815        GATT_ERROR_NONE : static_cast<GATTError>(status));
816  }
817}
818
819void GattServer::NotifyEndCallbackAndClearData(
820    BLEStatus status, const GattIdentifier& id) {
821  VLOG(1) << __func__ << " status: " << status;
822  CHECK(pending_end_decl_cb_);
823
824  if (status == BLE_STATUS_SUCCESS) {
825    id_to_handle_map_.insert(pending_handle_map_.begin(),
826                             pending_handle_map_.end());
827    for (auto& iter : pending_handle_map_)
828      handle_to_id_map_[iter.second] = iter.first;
829  }
830
831  pending_end_decl_cb_(status, id);
832
833  CleanUpPendingData();
834}
835
836void GattServer::CleanUpPendingData() {
837  pending_id_ = nullptr;
838  pending_decl_ = nullptr;
839  pending_end_decl_cb_ = ResultCallback();
840  pending_handle_map_.clear();
841}
842
843void GattServer::HandleNextEntry(hal::BluetoothGattInterface* gatt_iface) {
844  CHECK(pending_decl_);
845  CHECK(gatt_iface);
846
847  auto next_entry = PopNextEntry();
848  if (!next_entry) {
849    // No more entries. Call start_service to finish up.
850    bt_status_t status = gatt_iface->GetServerHALInterface()->start_service(
851        server_id_,
852        pending_decl_->service_handle,
853        TRANSPORT_BREDR | TRANSPORT_LE);
854
855    // Terminate the procedure in the case of an error.
856    if (status != BT_STATUS_SUCCESS) {
857      NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
858                                    pending_decl_->service_id);
859    }
860
861    return;
862  }
863
864  if (next_entry->id.IsCharacteristic()) {
865    bt_uuid_t char_uuid = next_entry->id.characteristic_uuid().GetBlueDroid();
866    bt_status_t status = gatt_iface->GetServerHALInterface()->
867        add_characteristic(
868            server_id_,
869            pending_decl_->service_handle,
870            &char_uuid,
871            next_entry->char_properties,
872            next_entry->permissions);
873
874    // Terminate the procedure in the case of an error.
875    if (status != BT_STATUS_SUCCESS) {
876      NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
877                                    pending_decl_->service_id);
878      return;
879    }
880
881    pending_id_.reset(new GattIdentifier(next_entry->id));
882    return;
883  }
884
885  if (next_entry->id.IsDescriptor()) {
886    bt_uuid_t desc_uuid = next_entry->id.descriptor_uuid().GetBlueDroid();
887    bt_status_t status = gatt_iface->GetServerHALInterface()->
888        add_descriptor(
889            server_id_,
890            pending_decl_->service_handle,
891            &desc_uuid,
892            next_entry->permissions);
893
894    // Terminate the procedure in the case of an error.
895    if (status != BT_STATUS_SUCCESS) {
896      NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
897                                    pending_decl_->service_id);
898      return;
899    }
900
901    pending_id_.reset(new GattIdentifier(next_entry->id));
902    return;
903  }
904
905  NOTREACHED() << "Unexpected entry type";
906}
907
908std::shared_ptr<GattServer::Connection> GattServer::GetConnection(
909    int conn_id, const bt_bdaddr_t& bda, int request_id) {
910  auto iter = conn_id_map_.find(conn_id);
911  if (iter == conn_id_map_.end()) {
912    VLOG(1) << "Connection doesn't belong to this server";
913    return nullptr;
914  }
915
916  auto conn = iter->second;
917  if (conn->bdaddr != bda) {
918    LOG(WARNING) << "BD_ADDR: " << BtAddrString(&bda) << " doesn't match "
919                 << "connection ID: " << conn_id;
920    return nullptr;
921  }
922
923  if (conn->request_id_to_handle.find(request_id) !=
924      conn->request_id_to_handle.end()) {
925    VLOG(1) << "Request with ID: " << request_id << " already exists for "
926            << " connection: " << conn_id;
927    return nullptr;
928  }
929
930  return conn;
931}
932
933std::unique_ptr<GattServer::AttributeEntry> GattServer::PopNextEntry() {
934  CHECK(pending_decl_);
935
936  if (pending_decl_->attributes.empty())
937    return nullptr;
938
939  const auto& next = pending_decl_->attributes.front();
940  std::unique_ptr<AttributeEntry> entry(new AttributeEntry(next));
941
942  pending_decl_->attributes.pop_front();
943
944  return entry;
945}
946
947std::unique_ptr<GattIdentifier> GattServer::PopNextId() {
948  auto entry = PopNextEntry();
949  if (!entry)
950    return nullptr;
951
952  return std::unique_ptr<GattIdentifier>(new GattIdentifier(entry->id));
953}
954
955// GattServerFactory implementation
956// ========================================================
957
958GattServerFactory::GattServerFactory() {
959  hal::BluetoothGattInterface::Get()->AddServerObserver(this);
960}
961
962GattServerFactory::~GattServerFactory() {
963  hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
964}
965
966bool GattServerFactory::RegisterInstance(
967    const UUID& uuid,
968    const RegisterCallback& callback) {
969  VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
970  lock_guard<mutex> lock(pending_calls_lock_);
971
972  if (pending_calls_.find(uuid) != pending_calls_.end()) {
973    LOG(ERROR) << "GATT-server client with given UUID already being registered "
974               << " - UUID: " << uuid.ToString();
975    return false;
976  }
977
978  const btgatt_server_interface_t* hal_iface =
979      hal::BluetoothGattInterface::Get()->GetServerHALInterface();
980  bt_uuid_t app_uuid = uuid.GetBlueDroid();
981
982  if (hal_iface->register_server(&app_uuid) != BT_STATUS_SUCCESS)
983    return false;
984
985  pending_calls_[uuid] = callback;
986
987  return true;
988}
989
990void GattServerFactory::RegisterServerCallback(
991    hal::BluetoothGattInterface* gatt_iface,
992    int status, int server_id,
993    const bt_uuid_t& app_uuid) {
994  UUID uuid(app_uuid);
995
996  VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
997  lock_guard<mutex> lock(pending_calls_lock_);
998
999  auto iter = pending_calls_.find(uuid);
1000  if (iter == pending_calls_.end()) {
1001    VLOG(1) << "Ignoring callback for unknown app_id: " << uuid.ToString();
1002    return;
1003  }
1004
1005  // No need to construct a server if the call wasn't successful.
1006  std::unique_ptr<GattServer> server;
1007  BLEStatus result = BLE_STATUS_FAILURE;
1008  if (status == BT_STATUS_SUCCESS) {
1009    server.reset(new GattServer(uuid, server_id));
1010
1011    gatt_iface->AddServerObserver(server.get());
1012
1013    result = BLE_STATUS_SUCCESS;
1014  }
1015
1016  // Notify the result via the result callback.
1017  iter->second(result, uuid, std::move(server));
1018
1019  pending_calls_.erase(iter);
1020}
1021
1022}  // namespace bluetooth
1023