• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
23  using std::lock_guard;
24  using std::mutex;
25  
26  namespace bluetooth {
27  
28  namespace {
29  
operator ==(const bt_bdaddr_t & lhs,const bt_bdaddr_t & rhs)30  bool operator==(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
31    return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
32  }
33  
operator !=(const bt_bdaddr_t & lhs,const bt_bdaddr_t & rhs)34  bool 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  
GattServer(const UUID & uuid,int server_id)43  GattServer::GattServer(const UUID& uuid, int server_id)
44      : app_identifier_(uuid),
45        server_id_(server_id),
46        delegate_(nullptr) {
47  }
48  
~GattServer()49  GattServer::~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  
SetDelegate(Delegate * delegate)63  void GattServer::SetDelegate(Delegate* delegate) {
64    lock_guard<mutex> lock(mutex_);
65    delegate_ = delegate;
66  }
67  
GetAppIdentifier() const68  const UUID& GattServer::GetAppIdentifier() const {
69    return app_identifier_;
70  }
71  
GetInstanceId() const72  int GattServer::GetInstanceId() const {
73    return server_id_;
74  }
75  
BeginServiceDeclaration(const UUID & uuid,bool is_primary)76  std::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  
AddCharacteristic(const UUID & uuid,int properties,int permissions)107  std::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  
AddDescriptor(const UUID & uuid,int permissions)136  std::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  
EndServiceDeclaration(const ResultCallback & callback)166  bool 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  
GetIdForService(const UUID & uuid,bool is_primary)214  std::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  
GetIdForCharacteristic(const UUID & uuid)233  std::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  
GetIdForDescriptor(const UUID & uuid)256  std::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  
SendResponse(const std::string & device_address,int request_id,GATTError error,int offset,const std::vector<uint8_t> & value)298  bool 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  
SendNotification(const std::string & device_address,const GattIdentifier & characteristic_id,bool confirm,const std::vector<uint8_t> & value,const GattCallback & callback)369  bool 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  
ConnectionCallback(hal::BluetoothGattInterface *,int conn_id,int server_id,int connected,const bt_bdaddr_t & bda)448  void 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  
ServiceAddedCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,const btgatt_srvc_id_t & srvc_id,int service_handle)497  void 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  
CharacteristicAddedCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,const bt_uuid_t & uuid,int service_handle,int char_handle)532  void 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  
DescriptorAddedCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,const bt_uuid_t & uuid,int service_handle,int desc_handle)565  void 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  
ServiceStartedCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,int service_handle)598  void 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  
ServiceStoppedCallback(hal::BluetoothGattInterface *,int,int,int)626  void 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  
RequestReadCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const bt_bdaddr_t & bda,int attribute_handle,int offset,bool is_long)634  void 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  
RequestWriteCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const bt_bdaddr_t & bda,int attr_handle,int offset,int length,bool need_rsp,bool is_prep,uint8_t * value)689  void 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  
RequestExecWriteCallback(hal::BluetoothGattInterface *,int conn_id,int trans_id,const bt_bdaddr_t & bda,int exec_write)758  void 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  
IndicationSentCallback(hal::BluetoothGattInterface *,int conn_id,int status)793  void 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  
NotifyEndCallbackAndClearData(BLEStatus status,const GattIdentifier & id)819  void 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  
CleanUpPendingData()836  void GattServer::CleanUpPendingData() {
837    pending_id_ = nullptr;
838    pending_decl_ = nullptr;
839    pending_end_decl_cb_ = ResultCallback();
840    pending_handle_map_.clear();
841  }
842  
HandleNextEntry(hal::BluetoothGattInterface * gatt_iface)843  void 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  
GetConnection(int conn_id,const bt_bdaddr_t & bda,int request_id)908  std::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  
PopNextEntry()933  std::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  
PopNextId()947  std::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  
GattServerFactory()958  GattServerFactory::GattServerFactory() {
959    hal::BluetoothGattInterface::Get()->AddServerObserver(this);
960  }
961  
~GattServerFactory()962  GattServerFactory::~GattServerFactory() {
963    hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
964  }
965  
RegisterInstance(const UUID & uuid,const RegisterCallback & callback)966  bool 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  
RegisterServerCallback(hal::BluetoothGattInterface * gatt_iface,int status,int server_id,const bt_uuid_t & app_uuid)990  void 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