1 /*
2 * Copyright (C) 2025 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 <string>
18 #include <vector>
19
20 #include <android-base/logging.h>
21 #include <gflags/gflags.h>
22
23 #include "common/libs/transport/channel_sharedfd.h"
24 #include "host/commands/sensors_simulator/sensors_simulator.h"
25 #include "host/libs/config/logging.h"
26
27 DEFINE_int32(sensors_in_fd, -1, "Sensors virtio-console from host to guest");
28 DEFINE_int32(sensors_out_fd, -1, "Sensors virtio-console from guest to host");
29 DEFINE_int32(webrtc_fd, -1, "A file descriptor to communicate with webrtc");
30
31 namespace cuttlefish {
32 namespace sensors {
33
34 namespace {
35
36 static constexpr char kReqMisFormatted[] = "The request is mis-formatted.";
37
ProcessWebrtcRequest(transport::SharedFdChannel & channel,SensorsSimulator & sensors_simulator)38 Result<void> ProcessWebrtcRequest(transport::SharedFdChannel& channel,
39 SensorsSimulator& sensors_simulator) {
40 auto request =
41 CF_EXPECT(channel.ReceiveMessage(), "Couldn't receive message.");
42 std::stringstream ss(std::string(
43 reinterpret_cast<const char*>(request->payload), request->payload_size));
44 SensorsCmd cmd = request->command;
45 switch (cmd) {
46 case kUpdateRotationVec: {
47 double x, y, z;
48 char delimiter;
49 CF_EXPECT((ss >> x >> delimiter) && (delimiter == INNER_DELIM),
50 kReqMisFormatted);
51 CF_EXPECT((ss >> y >> delimiter) && (delimiter == INNER_DELIM),
52 kReqMisFormatted);
53 CF_EXPECT(static_cast<bool>(ss >> z), kReqMisFormatted);
54 sensors_simulator.RefreshSensors(x, y, z);
55 break;
56 }
57 case kGetSensorsData: {
58 int mask;
59 CF_EXPECT(static_cast<bool>(ss >> mask), kReqMisFormatted);
60 auto sensors_data = sensors_simulator.GetSensorsData(mask);
61 auto size = sensors_data.size();
62 cmd = kGetSensorsData;
63 auto response =
64 CF_EXPECT(transport::CreateMessage(cmd, true, size),
65 "Failed to allocate message for cmd: "
66 << cmd << " with size: " << size << " bytes.");
67 memcpy(response->payload, sensors_data.data(), size);
68 CF_EXPECT(channel.SendResponse(*response),
69 "Can't send request for cmd: " << cmd);
70 break;
71 }
72 default: {
73 return CF_ERR("Unsupported cmd: " << cmd);
74 }
75 }
76 return {};
77 }
78
SensorsSimulatorMain(int argc,char ** argv)79 int SensorsSimulatorMain(int argc, char** argv) {
80 DefaultSubprocessLogging(argv);
81 gflags::ParseCommandLineFlags(&argc, &argv, true);
82 auto webrtc_fd = SharedFD::Dup(FLAGS_webrtc_fd);
83 close(FLAGS_webrtc_fd);
84 if (!webrtc_fd->IsOpen()) {
85 LOG(FATAL) << "Unable to connect webrtc: " << webrtc_fd->StrError();
86 }
87 transport::SharedFdChannel channel(webrtc_fd, webrtc_fd);
88 SensorsSimulator sensors_simulator;
89 while (true) {
90 auto result = ProcessWebrtcRequest(channel, sensors_simulator);
91 if (!result.ok()) {
92 LOG(ERROR) << result.error().FormatForEnv();
93 }
94 }
95 return 0;
96 }
97
98 } // namespace
99
100 } // namespace sensors
101 } // namespace cuttlefish
102
main(int argc,char * argv[])103 int main(int argc, char* argv[]) {
104 return cuttlefish::sensors::SensorsSimulatorMain(argc, argv);
105 }