1 /*
2 * Copyright (C) 2023 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 <log/log.h>
18 #include <multihal_sensors.h>
19 #include <multihal_sensors_transport.h>
20
21 #include "common/libs/transport/channel_sharedfd.h"
22
23 using ::android::hardware::sensors::V2_1::implementation::ISensorsSubHal;
24
25 namespace {
26
27 class VconsoleSensorsTransport : public goldfish::SensorsTransport {
28 public:
VconsoleSensorsTransport(cuttlefish::SharedFD fd)29 VconsoleSensorsTransport(cuttlefish::SharedFD fd)
30 : console_sensors_fd_(std::move(fd)),
31 pure_sensors_fd_(console_sensors_fd_->UNMANAGED_Dup()),
32 sensors_channel_(console_sensors_fd_, console_sensors_fd_) {}
33
~VconsoleSensorsTransport()34 ~VconsoleSensorsTransport() override { close(pure_sensors_fd_); }
35
Send(const void * msg,int size)36 int Send(const void* msg, int size) override {
37 auto message_result = cuttlefish::transport::CreateMessage(0, size);
38 if (!message_result.ok()) {
39 LOG(ERROR) << "Failed to allocate sensors message with size: " << size
40 << " bytes. "
41 << "Error message: " << message_result.error().Message();
42 return -1;
43 }
44
45 auto message = std::move(message_result.value());
46 std::memcpy(message->payload, msg, size);
47
48 auto send_result = sensors_channel_.SendRequest(*message);
49 if (!send_result.ok()) {
50 LOG(ERROR) << "Failed to send sensors message with size: " << size
51 << " bytes. "
52 << "Error message: " << send_result.error().Message();
53 return -1;
54 }
55
56 return size;
57 }
58
Receive(void * msg,int maxsize)59 int Receive(void* msg, int maxsize) override {
60 auto message_result = sensors_channel_.ReceiveMessage();
61 if (!message_result.ok()) {
62 LOG(ERROR) << "Failed to receive sensors message. "
63 << "Error message: " << message_result.error().Message();
64 return -1;
65 }
66
67 auto message = std::move(message_result.value());
68 if (message->payload_size > maxsize) {
69 LOG(ERROR) << "Received sensors message size is " << message->payload_size
70 << " maximum supported size is " << maxsize;
71 return -1;
72 }
73
74 std::memcpy(msg, message->payload, message->payload_size);
75
76 return message->payload_size;
77 }
78
Ok() const79 bool Ok() const override { return console_sensors_fd_->IsOpen(); }
80
Fd() const81 int Fd() const override { return pure_sensors_fd_; }
82
Name() const83 const char* Name() const override { return "vconsole_channel"; }
84
85 private:
86 cuttlefish::SharedFD console_sensors_fd_;
87 // Store pure dup of console_sensors_fd_ to return it from
88 // Fd() method which supposed to return pure fd used for
89 // receive/send sensors data.
90 int pure_sensors_fd_;
91 cuttlefish::transport::SharedFdChannel sensors_channel_;
92 };
93
94 } // namespace
95
96 inline constexpr const char kSensorsConsolePath[] = "/dev/hvc13";
97
sensorsHalGetSubHal_2_1(uint32_t * version)98 extern "C" ISensorsSubHal* sensorsHalGetSubHal_2_1(uint32_t* version) {
99 // Leaking the memory intentionally to make sure this object is available
100 // for other threads after main thread is terminated:
101 // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
102 // go/totw/110#destruction
103 static goldfish::MultihalSensors* impl = new goldfish::MultihalSensors([]() {
104 const auto fd = cuttlefish::SharedFD::Open(kSensorsConsolePath, O_RDWR);
105 if (!fd->IsOpen()) {
106 LOG(FATAL) << "Could not connect to sensors: " << fd->StrError();
107 }
108 if (fd->SetTerminalRaw() < 0) {
109 LOG(FATAL) << "Could not make " << kSensorsConsolePath
110 << " a raw terminal: " << fd->StrError();
111 }
112 return std::make_unique<VconsoleSensorsTransport>(fd);
113 });
114
115 *version = SUB_HAL_2_1_VERSION;
116 return impl;
117 }
118