Cert: Add IRK to LeAclManagerFacade

Bug: 230123996
Test: cert/run LeAclManagerTest
Change-Id: I93f36dcac745f8801cc77223042525ac45a395ab
diff --git a/system/blueberry/facade/hci/le_acl_manager_facade.proto b/system/blueberry/facade/hci/le_acl_manager_facade.proto
index 4f16c2c..844f21a 100644
--- a/system/blueberry/facade/hci/le_acl_manager_facade.proto
+++ b/system/blueberry/facade/hci/le_acl_manager_facade.proto
@@ -13,6 +13,7 @@
   rpc SendAclData(LeAclData) returns (google.protobuf.Empty) {}
   rpc FetchAclData(LeHandleMsg) returns (stream LeAclData) {}
   rpc FetchIncomingConnection(google.protobuf.Empty) returns (stream LeConnectionEvent) {}
+  rpc AddDeviceToResolvingList(IrkMsg) returns (google.protobuf.Empty) {}
 }
 
 message LeHandleMsg {
@@ -37,3 +38,9 @@
   bool is_direct = 2;
 }
 
+message IrkMsg {
+  blueberry.facade.BluetoothAddressWithType peer = 1;
+  bytes peer_irk = 2;
+  bytes local_irk = 3;
+}
+
diff --git a/system/gd/hci/facade/le_acl_manager_facade.cc b/system/gd/hci/facade/le_acl_manager_facade.cc
index 9a67f73..4299a8b 100644
--- a/system/gd/hci/facade/le_acl_manager_facade.cc
+++ b/system/gd/hci/facade/le_acl_manager_facade.cc
@@ -169,6 +169,36 @@
     return incoming_connection_events_->RunLoop(context, writer);
   }
 
+  ::grpc::Status AddDeviceToResolvingList(
+      ::grpc::ServerContext* context, const IrkMsg* request, ::google::protobuf::Empty* response) override {
+    Address peer_address;
+    ASSERT(Address::FromString(request->peer().address().address(), peer_address));
+    AddressWithType peer(peer_address, static_cast<AddressType>(request->peer().type()));
+
+    auto request_peer_irk_length = request->peer_irk().end() - request->peer_irk().begin();
+
+    if (request_peer_irk_length != crypto_toolbox::OCTET16_LEN) {
+      return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid Peer IRK");
+    }
+
+    auto request_local_irk_length = request->local_irk().end() - request->local_irk().begin();
+    if (request_local_irk_length != crypto_toolbox::OCTET16_LEN) {
+      return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid Local IRK");
+    }
+
+    crypto_toolbox::Octet16 peer_irk = {};
+    crypto_toolbox::Octet16 local_irk = {};
+
+    std::vector<uint8_t> peer_irk_data(request->peer_irk().begin(), request->peer_irk().end());
+    std::copy_n(peer_irk_data.begin(), crypto_toolbox::OCTET16_LEN, peer_irk.begin());
+
+    std::vector<uint8_t> local_irk_data(request->local_irk().begin(), request->local_irk().end());
+    std::copy_n(local_irk_data.begin(), crypto_toolbox::OCTET16_LEN, local_irk.begin());
+
+    acl_manager_->AddDeviceToResolvingList(peer, peer_irk, local_irk);
+    return ::grpc::Status::OK;
+  }
+
   ::grpc::Status SendAclData(
       ::grpc::ServerContext* context, const LeAclData* request, ::google::protobuf::Empty* response) override {
     std::promise<void> promise;