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

Commit 047df0fb authored by Hansong Zhang's avatar Hansong Zhang
Browse files

L2CAP Cert: Add support for sending I-Frame and S-Frame

Test: run_cert.sh
Bug: 144770885
Change-Id: I6fbe6ef8d8bb1e1c29ff20d32cdaaf7db865865b
parent afe7cebb
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@ import "facade/common.proto";

service L2capClassicModuleCert {
  rpc SendL2capPacket(L2capPacket) returns (google.protobuf.Empty) {}
  rpc SendIFrame(IFrame) returns (SendIFrameResult) {}
  rpc SendSFrame(SFrame) returns (SendSFrameResult) {}

  rpc SetupLink(SetupLinkRequest) returns (SetupLinkResponse) {}
  rpc DisconnectLink(DisconnectLinkRequest) returns (google.protobuf.Empty) {}
@@ -33,6 +35,30 @@ message L2capPacket {
  bytes payload = 3;
}

message IFrame {
  facade.BluetoothAddress remote = 1;
  uint32 channel = 2;
  uint32 sar = 3;
  uint32 tx_seq = 4;
  uint32 req_seq = 5;
  uint32 f = 6;
  uint32 sdu_size = 7;
  bytes information = 8;
}

message SendIFrameResult {}

message SFrame {
  facade.BluetoothAddress remote = 1;
  uint32 channel = 2;
  uint32 req_seq = 3;
  uint32 f = 4;
  uint32 p = 5;
  uint32 s = 6;
}

message SendSFrameResult {}

message DisconnectLinkRequest {
  facade.BluetoothAddress remote = 1;
}
+31 −0
Original line number Diff line number Diff line
@@ -80,6 +80,37 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service {
    return ::grpc::Status::OK;
  }

  ::grpc::Status SendIFrame(::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::IFrame* request,
                            ::bluetooth::l2cap::classic::cert::SendIFrameResult* response) override {
    std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>();
    auto req_string = request->information();
    packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end()));
    std::unique_ptr<BasePacketBuilder> l2cap_builder;
    auto f = static_cast<Final>(request->f());
    if (request->sar() == static_cast<int>(SegmentationAndReassembly::START)) {
      l2cap_builder = EnhancedInformationStartFrameBuilder::Create(
          request->channel(), request->tx_seq(), f, request->req_seq(), request->sdu_size(), std::move(packet));
    } else {
      l2cap_builder = EnhancedInformationFrameBuilder::Create(
          request->channel(), request->tx_seq(), f, request->req_seq(),
          static_cast<SegmentationAndReassembly>(request->sar()), std::move(packet));
    }
    outgoing_packet_queue_.push(std::move(l2cap_builder));
    send_packet_from_queue();
    return ::grpc::Status::OK;
  }

  ::grpc::Status SendSFrame(::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::SFrame* request,
                            ::bluetooth::l2cap::classic::cert::SendSFrameResult* response) override {
    auto f = static_cast<Final>(request->f());
    auto p = static_cast<Poll>(request->p());
    auto s = static_cast<SupervisoryFunction>(request->s());
    auto builder = EnhancedSupervisoryFrameBuilder::Create(request->channel(), s, p, f, request->req_seq());
    outgoing_packet_queue_.push(std::move(builder));
    send_packet_from_queue();
    return ::grpc::Status::OK;
  }

  ::grpc::Status SendConnectionRequest(::grpc::ServerContext* context, const cert::ConnectionRequest* request,
                                       ::google::protobuf::Empty* response) override {
    auto builder = ConnectionRequestBuilder::Create(request->signal_id(), request->psm(), request->scid());
+4 −1
Original line number Diff line number Diff line
@@ -215,6 +215,7 @@ class SimpleL2capTest(GdBaseTestClass):
            log = log.data_packet
            if (log.channel == scid):
                log.payload = basic_frame_to_enhanced_information_frame(log.payload)
                self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=1, s=0))
            data_received.append((log.channel, log.payload))
        event_handler.on(lambda log : log.HasField("data_packet"), on_data_received)
        logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
@@ -222,10 +223,12 @@ class SimpleL2capTest(GdBaseTestClass):
        assert (2, b"123") in data_received

        self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc'*34))

        self.cert_device.l2cap.SendIFrame(l2cap_cert_pb2.IFrame(channel=self.scid_dcid_map[scid], req_seq=1, tx_seq=0, sar=0, information=b"abcd"))

        logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
        event_handler.execute(logs)
        assert (scid, b"abc"*34) in data_received
        self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())

    def test_connect_and_send_data(self):
        self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2))