Merge "L2CAP: add test case L2CAP/ERM/BI-01-C"
diff --git a/btif/src/btif_hh.cc b/btif/src/btif_hh.cc
index 650923a..a1df515 100644
--- a/btif/src/btif_hh.cc
+++ b/btif/src/btif_hh.cc
@@ -537,7 +537,8 @@
   p_dev = btif_hh_find_dev_by_bda(*bd_addr);
   if ((p_dev != NULL) && (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED) &&
       (p_dev->attr_mask & HID_VIRTUAL_CABLE)) {
-    BTIF_TRACE_DEBUG("%s Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG", __func__);
+    BTIF_TRACE_DEBUG("%s: Sending BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG for: %s", __func__,
+                     bd_addr->ToString().c_str());
     /* start the timer */
     btif_hh_start_vup_timer(bd_addr);
     p_dev->local_vup = true;
@@ -545,7 +546,8 @@
     return BT_STATUS_SUCCESS;
   } else if ((p_dev != NULL) &&
              (p_dev->dev_status == BTHH_CONN_STATE_CONNECTED)) {
-    BTIF_TRACE_ERROR("%s: Virtual unplug not suported, disconnecting device");
+    BTIF_TRACE_ERROR("%s: Virtual unplug not suported, disconnecting device: %s",
+                     __func__, bd_addr->ToString().c_str());
     /* start the timer */
     btif_hh_start_vup_timer(bd_addr);
     p_dev->local_vup = true;
diff --git a/gd/Android.bp b/gd/Android.bp
index 037c517..7020f66 100644
--- a/gd/Android.bp
+++ b/gd/Android.bp
@@ -135,6 +135,7 @@
         ":BluetoothFacade_hci_hal",
         ":BluetoothFacade_hci_layer",
         ":BluetoothFacade_l2cap_layer",
+        ":BluetoothFacade_security_layer",
     ],
     generated_headers: [
         "BluetoothGeneratedPackets_h",
@@ -400,6 +401,7 @@
         "hci/facade.proto",
         "hci/facade/le_advertising_manager_facade.proto",
         "l2cap/classic/facade.proto",
+        "security/facade.proto",
     ],
 }
 
@@ -426,6 +428,8 @@
         "hci/facade/le_advertising_manager_facade.pb.h",
         "l2cap/classic/facade.grpc.pb.h",
         "l2cap/classic/facade.pb.h",
+        "security/facade.grpc.pb.h",
+        "security/facade.pb.h",
     ],
 }
 
@@ -452,6 +456,8 @@
         "hci/facade/le_advertising_manager_facade.pb.cc",
         "l2cap/classic/facade.grpc.pb.cc",
         "l2cap/classic/facade.pb.cc",
+        "security/facade.grpc.pb.cc",
+        "security/facade.pb.cc",
     ],
 }
 
diff --git a/gd/facade/common.proto b/gd/facade/common.proto
index 358db04..377de36 100644
--- a/gd/facade/common.proto
+++ b/gd/facade/common.proto
@@ -31,6 +31,11 @@
   RANDOM_IDENTITY_ADDRESS = 0x3;
 }
 
+message BluetoothAddressWithType {
+  BluetoothAddress address = 1;
+  BluetoothAddressTypeEnum type = 2;
+}
+
 enum BluetoothPeerAddressTypeEnum {
   PUBLIC_DEVICE_OR_IDENTITY_ADDRESS = 0x0;
   RANDOM_DEVICE_OR_IDENTITY_ADDRESS = 0x1;
diff --git a/gd/security/Android.bp b/gd/security/Android.bp
index 7407f6d..590558a 100644
--- a/gd/security/Android.bp
+++ b/gd/security/Android.bp
@@ -26,3 +26,10 @@
         ":BluetoothSecurityPairingTestSources",
     ],
 }
+
+filegroup {
+     name: "BluetoothFacade_security_layer",
+     srcs: [
+         "facade.cc",
+     ],
+}
diff --git a/gd/security/facade.cc b/gd/security/facade.cc
new file mode 100644
index 0000000..2f772fa
--- /dev/null
+++ b/gd/security/facade.cc
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "security/facade.h"
+#include "hci/hci_layer.h"
+#include "l2cap/classic/l2cap_classic_module.h"
+#include "l2cap/le/l2cap_le_module.h"
+#include "os/handler.h"
+#include "security/facade.grpc.pb.h"
+#include "security/security_module.h"
+
+namespace bluetooth {
+namespace security {
+
+class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public ISecurityManagerListener {
+ public:
+  SecurityModuleFacadeService(SecurityModule* security_module, l2cap::le::L2capLeModule* l2cap_le_module,
+                              l2cap::classic::L2capClassicModule* l2cap_classic_module, hci::HciLayer* hci_layer,
+                              ::bluetooth::os::Handler* security_handler)
+      : security_module_(security_module), l2cap_le_module_(l2cap_le_module),
+        l2cap_classic_module_(l2cap_classic_module), security_handler_(security_handler) {
+    security_module_->GetSecurityManager()->RegisterCallbackListener(this, security_handler_);
+  }
+
+  ::grpc::Status CreateBond(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request,
+                            ::google::protobuf::Empty* response) override {
+    hci::Address peer;
+    ASSERT(hci::Address::FromString(request->address().address(), peer));
+    hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
+    security_module_->GetSecurityManager()->CreateBond(hci::AddressWithType(peer, peer_type));
+    return ::grpc::Status::OK;
+  }
+
+  ::grpc::Status CancelBond(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request,
+                            ::google::protobuf::Empty* response) override {
+    hci::Address peer;
+    ASSERT(hci::Address::FromString(request->address().address(), peer));
+    hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
+    security_module_->GetSecurityManager()->CancelBond(hci::AddressWithType(peer, peer_type));
+    return ::grpc::Status::OK;
+  }
+
+  ::grpc::Status RemoveBond(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request,
+                            ::google::protobuf::Empty* response) override {
+    hci::Address peer;
+    ASSERT(hci::Address::FromString(request->address().address(), peer));
+    hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
+    security_module_->GetSecurityManager()->RemoveBond(hci::AddressWithType(peer, peer_type));
+    return ::grpc::Status::OK;
+  }
+
+  void OnDeviceBonded(hci::AddressWithType device) {}
+
+  void OnDeviceUnbonded(hci::AddressWithType device) {}
+
+  void OnDeviceBondFailed(hci::AddressWithType device) {}
+
+ private:
+  SecurityModule* security_module_ __attribute__((unused));
+  l2cap::le::L2capLeModule* l2cap_le_module_ __attribute__((unused));
+  l2cap::classic::L2capClassicModule* l2cap_classic_module_ __attribute__((unused));
+  ::bluetooth::os::Handler* security_handler_ __attribute__((unused));
+};
+
+void SecurityModuleFacadeModule::ListDependencies(ModuleList* list) {
+  ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
+  list->add<SecurityModule>();
+  list->add<l2cap::le::L2capLeModule>();
+  list->add<l2cap::classic::L2capClassicModule>();
+  list->add<hci::HciLayer>();
+}
+
+void SecurityModuleFacadeModule::Start() {
+  ::bluetooth::grpc::GrpcFacadeModule::Start();
+  service_ = new SecurityModuleFacadeService(GetDependency<SecurityModule>(), GetDependency<l2cap::le::L2capLeModule>(),
+                                             GetDependency<l2cap::classic::L2capClassicModule>(),
+                                             GetDependency<hci::HciLayer>(), GetHandler());
+}
+
+void SecurityModuleFacadeModule::Stop() {
+  delete service_;
+  ::bluetooth::grpc::GrpcFacadeModule::Stop();
+}
+
+::grpc::Service* SecurityModuleFacadeModule::GetService() const {
+  return service_;
+}
+
+const ModuleFactory SecurityModuleFacadeModule::Factory =
+    ::bluetooth::ModuleFactory([]() { return new SecurityModuleFacadeModule(); });
+
+}  // namespace security
+}  // namespace bluetooth
diff --git a/gd/security/facade.h b/gd/security/facade.h
new file mode 100644
index 0000000..fb655d1
--- /dev/null
+++ b/gd/security/facade.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <grpc++/grpc++.h>
+
+#include "grpc/grpc_module.h"
+#include "hci/address_with_type.h"
+
+namespace bluetooth {
+namespace security {
+
+class SecurityModuleFacadeService;
+
+class SecurityModuleFacadeModule : public ::bluetooth::grpc::GrpcFacadeModule {
+ public:
+  static const ModuleFactory Factory;
+
+  void ListDependencies(ModuleList* list) override;
+  void Start() override;
+  void Stop() override;
+  ::grpc::Service* GetService() const override;
+
+ private:
+  SecurityModuleFacadeService* service_;
+};
+
+}  // namespace security
+}  // namespace bluetooth
diff --git a/gd/security/facade.proto b/gd/security/facade.proto
new file mode 100644
index 0000000..394c35b
--- /dev/null
+++ b/gd/security/facade.proto
@@ -0,0 +1,12 @@
+syntax = "proto3";
+
+package bluetooth.security;
+
+import "google/protobuf/empty.proto";
+import "facade/common.proto";
+
+service SecurityModuleFacade {
+  rpc CreateBond(facade.BluetoothAddressWithType) returns (google.protobuf.Empty) {}
+  rpc CancelBond(facade.BluetoothAddressWithType) returns (google.protobuf.Empty) {}
+  rpc RemoveBond(facade.BluetoothAddressWithType) returns (google.protobuf.Empty) {}
+}