OSDN Git Service

SDP: Bounds check 'id' parameter for free_sdp_slot()
[android-x86/system-bt.git] / service / gatt_server.cpp
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
30 bool operator==(const bt_bdaddr_t& lhs, const bt_bdaddr_t& rhs) {
31   return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
32 }
33
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
43 GattServer::GattServer(const UUID& uuid, int server_id)
44     : app_identifier_(uuid),
45       server_id_(server_id),
46       delegate_(nullptr) {
47 }
48
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
63 void GattServer::SetDelegate(Delegate* delegate) {
64   lock_guard<mutex> lock(mutex_);
65   delegate_ = delegate;
66 }
67
68 const UUID& GattServer::GetAppIdentifier() const {
69   return app_identifier_;
70 }
71
72 int GattServer::GetInstanceId() const {
73   return server_id_;
74 }
75
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
958 GattServerFactory::GattServerFactory() {
959   hal::BluetoothGattInterface::Get()->AddServerObserver(this);
960 }
961
962 GattServerFactory::~GattServerFactory() {
963   hal::BluetoothGattInterface::Get()->RemoveServerObserver(this);
964 }
965
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
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