2 // Copyright (C) 2015 Google, Inc.
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:
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "service/gatt_server.h"
19 #include "service/common/bluetooth/util/address_helper.h"
20 #include "service/hal/gatt_helpers.h"
21 #include "service/logging_helpers.h"
23 using std::lock_guard;
30 bool operator==(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
31 return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
34 bool operator!=(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
40 // GattServer implementation
41 // ========================================================
43 GattServer::GattServer(const UUID& uuid, int server_id)
44 : app_identifier_(uuid),
45 server_id_(server_id),
49 GattServer::~GattServer() {
50 // Automatically unregister the server.
51 VLOG(1) << "GattServer unregistering: " << server_id_;
53 // Unregister as observer so we no longer receive any callbacks.
54 hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
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_);
63 void GattServer::SetDelegate(Delegate* delegate) {
64 lock_guard<mutex> lock(mutex_);
68 const UUID& GattServer::GetAppIdentifier() const {
69 return app_identifier_;
72 int GattServer::GetInstanceId() const {
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_);
84 LOG(ERROR) << "Already began service declaration";
89 CHECK(!pending_decl_);
90 CHECK(!pending_end_decl_cb_);
92 auto service_id = GetIdForService(uuid, is_primary);
95 // Pass 0 for permissions and properties as this is a service decl.
97 *service_id, kCharacteristicPropertyNone, kAttributePermissionNone);
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);
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_);
115 if (!pending_decl_) {
116 LOG(ERROR) << "Service declaration not begun";
120 if (pending_end_decl_cb_) {
121 LOG(ERROR) << "EndServiceDeclaration in progress, cannot modify service";
125 auto char_id = GetIdForCharacteristic(uuid);
127 AttributeEntry entry(*char_id, properties, permissions);
129 // 2 handles for the characteristic declaration and the value attributes.
130 pending_decl_->num_handles += 2;
131 pending_decl_->attributes.push_back(entry);
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_);
143 if (!pending_decl_) {
144 LOG(ERROR) << "Service declaration not begun";
148 if (pending_end_decl_cb_) {
149 LOG(ERROR) << "EndServiceDeclaration in progress, cannot modify service";
153 auto desc_id = GetIdForDescriptor(uuid);
157 AttributeEntry entry(*desc_id, kCharacteristicPropertyNone, permissions);
159 // 1 handle for the descriptor attribute.
160 pending_decl_->num_handles += 1;
161 pending_decl_->attributes.push_back(entry);
166 bool GattServer::EndServiceDeclaration(const ResultCallback& callback) {
167 VLOG(1) << __func__ << " server_id: " << server_id_;
168 lock_guard<mutex> lock(mutex_);
171 LOG(ERROR) << "|callback| cannot be NULL";
175 if (!pending_decl_) {
176 LOG(ERROR) << "Service declaration not begun";
180 if (pending_end_decl_cb_) {
181 LOG(ERROR) << "EndServiceDeclaration already in progress";
187 // There has to be at least one entry here for the service declaration
189 CHECK(pending_decl_->num_handles > 0);
190 CHECK(!pending_decl_->attributes.empty());
192 std::unique_ptr<GattIdentifier> service_id = PopNextId();
193 CHECK(service_id->IsService());
194 CHECK(*service_id == pending_decl_->service_id);
196 btgatt_srvc_id_t hal_id;
197 hal::GetHALServiceId(*service_id, &hal_id);
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();
208 pending_id_ = std::move(service_id);
209 pending_end_decl_cb_ = callback;
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.
219 for (const auto& iter : id_to_handle_map_) {
220 const GattIdentifier* gatt_id = &iter.first;
222 if (!gatt_id->IsService())
225 if (gatt_id->service_uuid() == uuid)
229 // Pass empty string for the address as this is a local service.
230 return GattIdentifier::CreateServiceId("", inst_id, uuid, is_primary);
233 std::unique_ptr<GattIdentifier> GattServer::GetIdForCharacteristic(
235 CHECK(pending_decl_);
237 // Calculate the instance ID for this characteristic by searching through the
240 for (const auto& entry : pending_decl_->attributes) {
241 const GattIdentifier& gatt_id = entry.id;
243 if (!gatt_id.IsCharacteristic())
246 if (gatt_id.characteristic_uuid() == uuid)
250 CHECK(pending_decl_->service_id.IsService());
252 return GattIdentifier::CreateCharacteristicId(
253 inst_id, uuid, pending_decl_->service_id);
256 std::unique_ptr<GattIdentifier> GattServer::GetIdForDescriptor(
258 CHECK(pending_decl_);
260 // Calculate the instance ID for this descriptor by searching through the
261 // pending entries. We iterate in reverse until we find a characteristic
263 CHECK(!pending_decl_->attributes.empty());
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
270 const GattIdentifier& gatt_id = iter->id;
272 if (gatt_id.IsCharacteristic()) {
273 // Found the owning characteristic.
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.";
286 if (gatt_id.descriptor_uuid() == uuid)
291 LOG(ERROR) << "No characteristic found to add the descriptor to.";
295 return GattIdentifier::CreateDescriptorId(inst_id, uuid, char_id);
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_);
310 if (!util::BdAddrFromString(device_address, &addr)) {
311 LOG(ERROR) << "Invalid device address given: " << device_address;
315 if (value.size() + offset > BTGATT_MAX_ATTR_LEN) {
316 LOG(ERROR) << "Value is too large";
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;
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())
337 LOG(ERROR) << "Pending request with ID " << request_id
338 << " not found for device with BD_ADDR: " << device_address;
342 btgatt_response_t response;
343 memset(&response, 0, sizeof(response));
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;
351 memcpy(response.attr_value.value, value.data(), value.size());
352 response.attr_value.offset = offset;
353 response.attr_value.len = value.size();
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";
364 connection->request_id_to_handle.erase(request_id);
369 bool GattServer::SendNotification(
370 const std::string& device_address,
371 const GattIdentifier& characteristic_id,
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_);
381 if (!util::BdAddrFromString(device_address, &addr)) {
382 LOG(ERROR) << "Invalid device address given: " << device_address;
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: "
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";
401 std::shared_ptr<PendingIndication> pending_ind(
402 new PendingIndication(callback));
404 // Send the notification/indication on all matching connections.
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;
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(
425 reinterpret_cast<char*>(const_cast<uint8_t*>(value.data())));
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
432 if (status != BT_STATUS_SUCCESS)
436 pending_indications_[conn->conn_id] = pending_ind;
439 if (send_count == 0) {
440 LOG(ERROR) << "Failed to send notifications/indications to device: "
448 void GattServer::ConnectionCallback(
449 hal::BluetoothGattInterface* /* gatt_iface */,
450 int conn_id, int server_id,
452 const bt_bdaddr_t& bda) {
453 lock_guard<mutex> lock(mutex_);
455 if (server_id != server_id_)
458 std::string device_address = BtAddrString(&bda);
460 VLOG(1) << __func__ << " conn_id: " << conn_id << " connected: " << connected
461 << " BD_ADDR: " << device_address;
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())
471 // Remove the appropriate connection objects in the address.
472 for (auto conn_iter = iter->second.begin(); conn_iter != iter->second.end();
474 if ((*conn_iter)->conn_id != conn_id)
477 iter->second.erase(conn_iter);
484 if (conn_id_map_.find(conn_id) != conn_id_map_.end()) {
485 LOG(WARNING) << "Connection entry already exists; "
486 << "ignoring ConnectionCallback";
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);
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_);
504 if (server_id != server_id_)
507 // Construct a GATT identifier.
508 auto gatt_id = hal::GetServiceIdFromHAL(srvc_id);
510 CHECK(*gatt_id == *pending_id_);
511 CHECK(*gatt_id == pending_decl_->service_id);
512 CHECK(pending_id_->IsService());
514 VLOG(1) << __func__ << " - status: " << status
515 << " server_id: " << server_id
516 << " handle: " << service_handle
517 << " UUID: " << gatt_id->service_uuid().ToString();
519 if (status != BT_STATUS_SUCCESS) {
520 NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status), *gatt_id);
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;
529 HandleNextEntry(gatt_iface);
532 void GattServer::CharacteristicAddedCallback(
533 hal::BluetoothGattInterface* gatt_iface,
534 int status, int server_id,
535 const bt_uuid_t& uuid,
538 lock_guard<mutex> lock(mutex_);
540 if (server_id != server_id_)
543 CHECK(pending_decl_);
544 CHECK(pending_decl_->service_handle == service_handle);
546 CHECK(pending_id_->IsCharacteristic());
547 CHECK(pending_id_->characteristic_uuid() == UUID(uuid));
549 VLOG(1) << __func__ << " - status: " << status
550 << " server_id: " << server_id
551 << " service_handle: " << service_handle
552 << " char_handle: " << char_handle;
554 if (status != BT_STATUS_SUCCESS) {
555 NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
556 pending_decl_->service_id);
560 // Add this to the handle map and continue.
561 pending_handle_map_[*pending_id_] = char_handle;
562 HandleNextEntry(gatt_iface);
565 void GattServer::DescriptorAddedCallback(
566 hal::BluetoothGattInterface* gatt_iface,
567 int status, int server_id,
568 const bt_uuid_t& uuid,
571 lock_guard<mutex> lock(mutex_);
573 if (server_id != server_id_)
576 CHECK(pending_decl_);
577 CHECK(pending_decl_->service_handle == service_handle);
579 CHECK(pending_id_->IsDescriptor());
580 CHECK(pending_id_->descriptor_uuid() == UUID(uuid));
582 VLOG(1) << __func__ << " - status: " << status
583 << " server_id: " << server_id
584 << " service_handle: " << service_handle
585 << " desc_handle: " << desc_handle;
587 if (status != BT_STATUS_SUCCESS) {
588 NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
589 pending_decl_->service_id);
593 // Add this to the handle map and contiue.
594 pending_handle_map_[*pending_id_] = desc_handle;
595 HandleNextEntry(gatt_iface);
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_);
604 if (server_id != server_id_)
608 CHECK(pending_decl_);
609 CHECK(pending_decl_->service_handle == service_handle);
611 VLOG(1) << __func__ << " - server_id: " << server_id
612 << " handle: " << service_handle;
614 // If we failed to start the service, remove it from the database and ignore
616 if (status != BT_STATUS_SUCCESS) {
617 gatt_iface->GetServerHALInterface()->delete_service(
618 server_id_, service_handle);
621 // Complete the operation.
622 NotifyEndCallbackAndClearData(static_cast<BLEStatus>(status),
623 pending_decl_->service_id);
626 void GattServer::ServiceStoppedCallback(
627 hal::BluetoothGattInterface* /* gatt_iface */,
630 int /* service_handle */) {
631 // TODO(armansito): Support stopping a service.
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,
640 lock_guard<mutex> lock(mutex_);
642 // Check to see if we know about this connection. Otherwise ignore the
644 auto conn = GetConnection(conn_id, bda, trans_id);
648 std::string device_address = BtAddrString(&bda);
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;
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;
662 conn->request_id_to_handle[trans_id] = attribute_handle;
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.
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 "
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);
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";
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_);
698 LOG(WARNING) << "Negative length value received";
702 // Check to see if we know about this connection. Otherwise ignore the
704 auto conn = GetConnection(conn_id, bda, trans_id);
708 std::string device_address = BtAddrString(&bda);
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;
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;
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.
727 conn->request_id_to_handle[trans_id] = attr_handle;
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.
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 "
740 std::vector<uint8_t> value_vec(value, value + length);
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);
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";
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_);
764 // Check to see if we know about this connection. Otherwise ignore the
766 auto conn = GetConnection(conn_id, bda, trans_id);
770 std::string device_address = BtAddrString(&bda);
772 VLOG(1) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
773 << " BD_ADDR: " << device_address << " exec_write: " << exec_write;
775 // Just store a dummy invalid handle as this request doesn't apply to a
777 conn->request_id_to_handle[trans_id] = -1;
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.
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 "
790 delegate_->OnExecuteWriteRequest(this, device_address, trans_id, exec_write);
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_);
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;
805 std::shared_ptr<PendingIndication> pending_ind = pending_ind_iter->second;
806 pending_indications_.erase(pending_ind_iter);
808 if (status == BT_STATUS_SUCCESS)
809 pending_ind->has_success = true;
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));
819 void GattServer::NotifyEndCallbackAndClearData(
820 BLEStatus status, const GattIdentifier& id) {
821 VLOG(1) << __func__ << " status: " << status;
822 CHECK(pending_end_decl_cb_);
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;
831 pending_end_decl_cb_(status, id);
833 CleanUpPendingData();
836 void GattServer::CleanUpPendingData() {
837 pending_id_ = nullptr;
838 pending_decl_ = nullptr;
839 pending_end_decl_cb_ = ResultCallback();
840 pending_handle_map_.clear();
843 void GattServer::HandleNextEntry(hal::BluetoothGattInterface* gatt_iface) {
844 CHECK(pending_decl_);
847 auto next_entry = PopNextEntry();
849 // No more entries. Call start_service to finish up.
850 bt_status_t status = gatt_iface->GetServerHALInterface()->start_service(
852 pending_decl_->service_handle,
853 TRANSPORT_BREDR | TRANSPORT_LE);
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);
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()->
869 pending_decl_->service_handle,
871 next_entry->char_properties,
872 next_entry->permissions);
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);
881 pending_id_.reset(new GattIdentifier(next_entry->id));
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()->
890 pending_decl_->service_handle,
892 next_entry->permissions);
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);
901 pending_id_.reset(new GattIdentifier(next_entry->id));
905 NOTREACHED() << "Unexpected entry type";
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";
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;
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;
933 std::unique_ptr<GattServer::AttributeEntry> GattServer::PopNextEntry() {
934 CHECK(pending_decl_);
936 if (pending_decl_->attributes.empty())
939 const auto& next = pending_decl_->attributes.front();
940 std::unique_ptr<AttributeEntry> entry(new AttributeEntry(next));
942 pending_decl_->attributes.pop_front();
947 std::unique_ptr<GattIdentifier> GattServer::PopNextId() {
948 auto entry = PopNextEntry();
952 return std::unique_ptr<GattIdentifier>(new GattIdentifier(entry->id));
955 // GattServerFactory implementation
956 // ========================================================
958 GattServerFactory::GattServerFactory() {
959 hal::BluetoothGattInterface::Get()->AddServerObserver(this);
962 GattServerFactory::~GattServerFactory() {
963 hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
966 bool GattServerFactory::RegisterInstance(
968 const RegisterCallback& callback) {
969 VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
970 lock_guard<mutex> lock(pending_calls_lock_);
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();
978 const btgatt_server_interface_t* hal_iface =
979 hal::BluetoothGattInterface::Get()->GetServerHALInterface();
980 bt_uuid_t app_uuid = uuid.GetBlueDroid();
982 if (hal_iface->register_server(&app_uuid) != BT_STATUS_SUCCESS)
985 pending_calls_[uuid] = callback;
990 void GattServerFactory::RegisterServerCallback(
991 hal::BluetoothGattInterface* gatt_iface,
992 int status, int server_id,
993 const bt_uuid_t& app_uuid) {
996 VLOG(1) << __func__ << " - UUID: " << uuid.ToString();
997 lock_guard<mutex> lock(pending_calls_lock_);
999 auto iter = pending_calls_.find(uuid);
1000 if (iter == pending_calls_.end()) {
1001 VLOG(1) << "Ignoring callback for unknown app_id: " << uuid.ToString();
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));
1011 gatt_iface->AddServerObserver(server.get());
1013 result = BLE_STATUS_SUCCESS;
1016 // Notify the result via the result callback.
1017 iter->second(result, uuid, std::move(server));
1019 pending_calls_.erase(iter);
1022 } // namespace bluetooth