1 /*
2  * Copyright 2024 The Android Open Source Project
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 "host/frontend/webrtc/webrtc_command_channel.h"
18 
19 #include <android-base/logging.h>
20 
21 namespace cuttlefish {
22 namespace {
23 
24 constexpr const uint32_t kUnusedCommandField = 0;
25 
26 template <typename ProtoT>
ToMessage(const ProtoT & proto)27 Result<transport::ManagedMessage> ToMessage(const ProtoT& proto) {
28   std::string proto_str;
29   CF_EXPECT(proto.SerializeToString(&proto_str), "Failed to serialize proto.");
30 
31   auto msg = CF_EXPECT(
32       transport::CreateMessage(kUnusedCommandField, proto_str.size()));
33   std::memcpy(msg->payload, proto_str.data(), proto_str.size());
34   return msg;
35 }
36 
37 template <typename ProtoT>
ToProto(transport::ManagedMessage msg)38 Result<ProtoT> ToProto(transport::ManagedMessage msg) {
39   ProtoT proto;
40   CF_EXPECT(proto.ParseFromArray(msg->payload, msg->payload_size),
41             "Failed to serialize proto from message.");
42   return proto;
43 }
44 
45 }  // namespace
46 
WebrtcClientCommandChannel(SharedFD fd)47 WebrtcClientCommandChannel::WebrtcClientCommandChannel(SharedFD fd)
48     : channel_(fd, fd) {}
49 
SendCommand(const webrtc::WebrtcCommandRequest & request)50 Result<webrtc::WebrtcCommandResponse> WebrtcClientCommandChannel::SendCommand(
51     const webrtc::WebrtcCommandRequest& request) {
52   auto request_msg = CF_EXPECT(
53       ToMessage(request),
54       "Failed to convert webrtc command request to transport message.");
55 
56   CF_EXPECT(channel_.SendRequest(*request_msg),
57             "Failed to send webrtc command request.");
58 
59   CF_EXPECT(channel_.WaitForMessage(),
60             "Failed to wait for webrtc command response.");
61 
62   auto response_msg = CF_EXPECT(channel_.ReceiveMessage(),
63                                 "Failed to receive webrtc command response.");
64 
65   return CF_EXPECT(
66       ToProto<webrtc::WebrtcCommandResponse>(std::move(response_msg)));
67 }
68 
69 Result<webrtc::WebrtcCommandRequest>
ReceiveRequest()70 WebrtcServerCommandChannel::ReceiveRequest() {
71   CF_EXPECT(channel_.WaitForMessage(),
72             "Failed to wait for webrtc command response.");
73 
74   auto request_msg = CF_EXPECT(channel_.ReceiveMessage(),
75                                "Failed to receive webrtc command request.");
76 
77   return CF_EXPECT(
78       ToProto<webrtc::WebrtcCommandRequest>(std::move(request_msg)),
79       "Failed to deserialize webrtc command request.");
80 }
81 
WebrtcServerCommandChannel(SharedFD fd)82 WebrtcServerCommandChannel::WebrtcServerCommandChannel(SharedFD fd)
83     : channel_(fd, fd) {}
84 
SendResponse(const webrtc::WebrtcCommandResponse & response)85 Result<void> WebrtcServerCommandChannel::SendResponse(
86     const webrtc::WebrtcCommandResponse& response) {
87   auto response_msg = CF_EXPECT(
88       ToMessage(response),
89       "Failed to convert webrtc command response to transport message.");
90 
91   CF_EXPECT(channel_.SendRequest(*response_msg),
92             "Failed to send webrtc command response.");
93 
94   return {};
95 }
96 
97 }  // namespace cuttlefish