Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fc57417 authored by Hansong Zhang's avatar Hansong Zhang Committed by android-build-merger
Browse files

Initial entry for L2CAP data pipeline and cert am: 84341c48 am: f7cc8060 am: 17f348d0

am: bf43b873

Change-Id: I16093f4035fbbb032b897d1add3ca381e0c01b4c
parents 4aea8f91 bf43b873
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -79,3 +79,5 @@ class GdCertDevice(GdDeviceBase):
        self.hci.disconnection_stream = EventStream(self.hci.FetchDisconnection)
        self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed)
        self.hci.acl_stream = EventStream(self.hci.FetchAclData)
        self.l2cap.packet_stream = EventStream(self.l2cap.FetchL2capData)
        self.l2cap.connection_complete_stream = EventStream(self.l2cap.FetchConnectionComplete)
+2 −0
Original line number Diff line number Diff line
@@ -81,3 +81,5 @@ class GdDevice(GdDeviceBase):
        self.hci.connection_failed_stream = EventStream(self.hci.FetchConnectionFailed)
        self.hci.acl_stream = EventStream(self.hci.FetchAclData)
        self.hci_classic_security.command_complete_stream = EventStream(self.hci_classic_security.FetchCommandCompleteEvent)
        self.l2cap.packet_stream = EventStream(self.l2cap.FetchL2capData)
        self.l2cap.connection_complete_stream = EventStream(self.l2cap.FetchConnectionComplete)
+0 −1
Original line number Diff line number Diff line
@@ -441,7 +441,6 @@ struct AclManager::impl {

  AclConnection::QueueUpEnd* get_acl_queue_end(uint16_t handle) {
    auto& connection = check_and_get_connection(handle);
    ASSERT_LOG(connection.disconnect_handler_ != nullptr, "No disconnect handler registered.");
    return connection.queue_->GetUpEnd();
  }

+13 −1
Original line number Diff line number Diff line
@@ -6,5 +6,17 @@ import "google/protobuf/empty.proto";
import "facade/common.proto";

service L2capModuleCert {
  rpc NoOp(google.protobuf.Empty) returns (google.protobuf.Empty) {}
  rpc SendL2capPacket(L2capPacket) returns (google.protobuf.Empty) {}
  rpc FetchL2capData(facade.EventStreamRequest) returns (stream L2capPacket) {}
  rpc FetchConnectionComplete(facade.EventStreamRequest) returns (stream ConnectionCompleteEvent) {}
}

message L2capPacket {
  facade.BluetoothAddress remote = 1;
  uint32 channel = 2;
  bytes payload = 3;
}

message ConnectionCompleteEvent {
  facade.BluetoothAddress remote = 1;
}
+100 −11
Original line number Diff line number Diff line
@@ -19,10 +19,13 @@
#include <cstdint>
#include <memory>
#include <mutex>
#include <queue>
#include <unordered_map>

#include "common/blocking_queue.h"
#include "grpc/grpc_event_stream.h"
#include "hci/acl_manager.h"
#include "hci/cert/cert.h"
#include "l2cap/cert/api.grpc.pb.h"
#include "l2cap/l2cap_layer.h"
#include "l2cap/l2cap_packets.h"
@@ -44,31 +47,117 @@ using namespace facade;

class L2capModuleCertService : public L2capModuleCert::Service {
 public:
  L2capModuleCertService(l2cap::L2capLayer* l2cap_layer, ::bluetooth::os::Handler* facade_handler)
      : l2cap_layer_(l2cap_layer), facade_handler_(facade_handler) {
    ASSERT(l2cap_layer_ != nullptr);
    ASSERT(facade_handler_ != nullptr);
  L2capModuleCertService(hci::AclManager* acl_manager, os::Handler* facade_handler)
      : handler_(facade_handler), acl_manager_(acl_manager) {
    ASSERT(handler_ != nullptr);
    acl_manager_->RegisterCallbacks(&acl_callbacks, handler_);
  }

  ::grpc::Status NoOp(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
  class ConnectionCompleteCallback
      : public grpc::GrpcEventStreamCallback<ConnectionCompleteEvent, ConnectionCompleteEvent> {
   public:
    void OnWriteResponse(ConnectionCompleteEvent* response, const ConnectionCompleteEvent& event) override {
      response->CopyFrom(event);
    }

  } connection_complete_callback_;
  ::bluetooth::grpc::GrpcEventStream<ConnectionCompleteEvent, ConnectionCompleteEvent> connection_complete_stream_{
      &connection_complete_callback_};

  ::grpc::Status FetchConnectionComplete(
      ::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request,
      ::grpc::ServerWriter<::bluetooth::l2cap::cert::ConnectionCompleteEvent>* writer) override {
    return connection_complete_stream_.HandleRequest(context, request, writer);
  }

  ::grpc::Status SendL2capPacket(::grpc::ServerContext* context, const ::bluetooth::l2cap::cert::L2capPacket* request,
                                 ::google::protobuf::Empty* response) override {
    std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>();
    auto req_string = request->payload();
    packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end()));
    std::unique_ptr<BasicFrameBuilder> l2cap_builder = BasicFrameBuilder::Create(request->channel(), std::move(packet));
    outgoing_packet_queue_.push(std::move(l2cap_builder));
    if (outgoing_packet_queue_.size() == 1) {
      acl_connection_->GetAclQueueEnd()->RegisterEnqueue(
          handler_, common::Bind(&L2capModuleCertService::enqueue_packet_to_acl, common::Unretained(this)));
    }
    return ::grpc::Status::OK;
  }

 private:
  l2cap::L2capLayer* l2cap_layer_;
  ::bluetooth::os::Handler* facade_handler_;
  std::unique_ptr<packet::BasePacketBuilder> enqueue_packet_to_acl() {
    auto basic_frame_builder = std::move(outgoing_packet_queue_.front());
    outgoing_packet_queue_.pop();
    if (outgoing_packet_queue_.size() == 0) {
      acl_connection_->GetAclQueueEnd()->UnregisterEnqueue();
    }
    return basic_frame_builder;
  }

  ::grpc::Status FetchL2capData(::grpc::ServerContext* context, const ::bluetooth::facade::EventStreamRequest* request,
                                ::grpc::ServerWriter<L2capPacket>* writer) override {
    return l2cap_stream_.HandleRequest(context, request, writer);
  }

  class L2capStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<L2capPacket, L2capPacket> {
   public:
    void OnWriteResponse(L2capPacket* response, const L2capPacket& event) override {
      response->CopyFrom(event);
    }

  } l2cap_stream_callback_;
  ::bluetooth::grpc::GrpcEventStream<L2capPacket, L2capPacket> l2cap_stream_{&l2cap_stream_callback_};

  void on_incoming_packet() {
    auto packet = acl_connection_->GetAclQueueEnd()->TryDequeue();
    BasicFrameView basic_frame_view = BasicFrameView::Create(*packet);
    ASSERT(basic_frame_view.IsValid());
    L2capPacket l2cap_packet;
    std::string data = std::string(packet->begin(), packet->end());
    l2cap_packet.set_payload(data);
    l2cap_packet.set_channel(basic_frame_view.GetChannelId());
    l2cap_stream_.OnIncomingEvent(l2cap_packet);
  }

  std::queue<std::unique_ptr<BasicFrameBuilder>> outgoing_packet_queue_;
  ::bluetooth::os::Handler* handler_;
  hci::AclManager* acl_manager_;
  std::unique_ptr<hci::AclConnection> acl_connection_;

  class AclCallbacks : public hci::ConnectionCallbacks {
   public:
    AclCallbacks(L2capModuleCertService* module) : module_(module) {}
    void OnConnectSuccess(std::unique_ptr<hci::AclConnection> connection) override {
      ConnectionCompleteEvent event;
      event.mutable_remote()->set_address(connection->GetAddress().ToString());
      module_->connection_complete_stream_.OnIncomingEvent(event);
      module_->acl_connection_ = std::move(connection);
      module_->acl_connection_->RegisterDisconnectCallback(common::BindOnce([](hci::ErrorCode) {}), module_->handler_);
      module_->acl_connection_->GetAclQueueEnd()->RegisterDequeue(
          module_->handler_, common::Bind(&L2capModuleCertService::on_incoming_packet, common::Unretained(module_)));
    }
    void OnConnectFail(hci::Address address, hci::ErrorCode reason) override {}

    ~AclCallbacks() {
      module_->acl_connection_->GetAclQueueEnd()->UnregisterDequeue();
    }

    L2capModuleCertService* module_;
  } acl_callbacks{this};

  std::mutex mutex_;
};

void L2capModuleCertModule::ListDependencies(ModuleList* list) {
  ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
  list->add<l2cap::L2capLayer>();
  list->add<hci::AclManager>();
  list->add<hci::HciLayer>();
}

void L2capModuleCertModule::Start() {
  ::bluetooth::grpc::GrpcFacadeModule::Start();
  service_ = new L2capModuleCertService(GetDependency<l2cap::L2capLayer>(), GetHandler());
  GetDependency<hci::HciLayer>()->EnqueueCommand(hci::WriteScanEnableBuilder::Create(hci::ScanEnable::PAGE_SCAN_ONLY),
                                                 common::BindOnce([](hci::CommandCompleteView) {}), GetHandler());
  service_ = new L2capModuleCertService(GetDependency<hci::AclManager>(), GetHandler());
}

void L2capModuleCertModule::Stop() {
Loading