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