1 /*
2 * Copyright (C) 2021 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 #define LOG_TAG "ProtoMsgConverter"
18
19 #include "ProtoMessageConverter.h"
20
21 #include <VehicleUtils.h>
22
23 #include <memory>
24 #include <vector>
25
26 namespace android {
27 namespace hardware {
28 namespace automotive {
29 namespace vehicle {
30 namespace proto_msg_converter {
31
32 namespace aidl_vehicle = ::aidl::android::hardware::automotive::vehicle;
33 namespace proto = ::android::hardware::automotive::vehicle::proto;
34
35 // Copy the vector PROTO_VECNAME of protobuf class PROTO_VALUE to
36 // VHAL_TYPE_VALUE->VHAL_TYPE_VECNAME, every element of PROTO_VECNAME is casted by CAST.
37 #define CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE(PROTO_VALUE, PROTO_VECNAME, VHAL_TYPE_VALUE, \
38 VHAL_TYPE_VECNAME, CAST) \
39 do { \
40 (VHAL_TYPE_VALUE)->VHAL_TYPE_VECNAME.resize(PROTO_VALUE.PROTO_VECNAME##_size()); \
41 size_t idx = 0; \
42 for (auto& value : PROTO_VALUE.PROTO_VECNAME()) { \
43 VHAL_TYPE_VALUE->VHAL_TYPE_VECNAME[idx++] = CAST(value); \
44 } \
45 } while (0)
46
47 // Copying the vector PROTO_VECNAME of protobuf class PROTO_VALUE to
48 // VHAL_TYPE_VALUE->VHAL_TYPE_VECNAME.
49 #define COPY_PROTOBUF_VEC_TO_VHAL_TYPE(PROTO_VALUE, PROTO_VECNAME, VHAL_TYPE_VALUE, \
50 VHAL_TYPE_VECNAME) \
51 CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE( \
52 PROTO_VALUE, PROTO_VECNAME, VHAL_TYPE_VALUE, VHAL_TYPE_VECNAME, /*NO CAST*/)
53
aidlToProto(const aidl_vehicle::VehiclePropConfig & in,proto::VehiclePropConfig * out)54 void aidlToProto(const aidl_vehicle::VehiclePropConfig& in, proto::VehiclePropConfig* out) {
55 out->set_prop(in.prop);
56 out->set_access(static_cast<proto::VehiclePropertyAccess>(toInt(in.access)));
57 out->set_change_mode(static_cast<proto::VehiclePropertyChangeMode>(toInt(in.changeMode)));
58 out->set_config_string(in.configString.c_str(), in.configString.size());
59 out->set_min_sample_rate(in.minSampleRate);
60 out->set_max_sample_rate(in.maxSampleRate);
61
62 for (auto& configElement : in.configArray) {
63 out->add_config_array(configElement);
64 }
65
66 out->clear_area_configs();
67 for (auto& areaConfig : in.areaConfigs) {
68 auto* protoACfg = out->add_area_configs();
69 protoACfg->set_area_id(areaConfig.areaId);
70 protoACfg->set_access(static_cast<proto::VehiclePropertyAccess>(toInt(areaConfig.access)));
71 protoACfg->set_min_int64_value(areaConfig.minInt64Value);
72 protoACfg->set_max_int64_value(areaConfig.maxInt64Value);
73 protoACfg->set_min_float_value(areaConfig.minFloatValue);
74 protoACfg->set_max_float_value(areaConfig.maxFloatValue);
75 protoACfg->set_min_int32_value(areaConfig.minInt32Value);
76 protoACfg->set_max_int32_value(areaConfig.maxInt32Value);
77 if (areaConfig.supportedEnumValues.has_value()) {
78 for (auto& supportedEnumValue : areaConfig.supportedEnumValues.value()) {
79 protoACfg->add_supported_enum_values(supportedEnumValue);
80 }
81 }
82 protoACfg->set_support_variable_update_rate(areaConfig.supportVariableUpdateRate);
83 }
84 }
85
protoToAidl(const proto::VehiclePropConfig & in,aidl_vehicle::VehiclePropConfig * out)86 void protoToAidl(const proto::VehiclePropConfig& in, aidl_vehicle::VehiclePropConfig* out) {
87 out->prop = in.prop();
88 out->access = static_cast<aidl_vehicle::VehiclePropertyAccess>(in.access());
89 out->changeMode = static_cast<aidl_vehicle::VehiclePropertyChangeMode>(in.change_mode());
90 out->configString = in.config_string();
91 out->minSampleRate = in.min_sample_rate();
92 out->maxSampleRate = in.max_sample_rate();
93
94 COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, config_array, out, configArray);
95
96 auto cast_to_acfg = [](const proto::VehicleAreaConfig& protoAcfg) {
97 auto vehicleAreaConfig = aidl_vehicle::VehicleAreaConfig{
98 .areaId = protoAcfg.area_id(),
99 .access = static_cast<aidl_vehicle::VehiclePropertyAccess>(protoAcfg.access()),
100 .minInt32Value = protoAcfg.min_int32_value(),
101 .maxInt32Value = protoAcfg.max_int32_value(),
102 .minInt64Value = protoAcfg.min_int64_value(),
103 .maxInt64Value = protoAcfg.max_int64_value(),
104 .minFloatValue = protoAcfg.min_float_value(),
105 .maxFloatValue = protoAcfg.max_float_value(),
106 .supportVariableUpdateRate = protoAcfg.support_variable_update_rate(),
107 };
108 if (protoAcfg.supported_enum_values().size() != 0) {
109 vehicleAreaConfig.supportedEnumValues = std::vector<int64_t>();
110 COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoAcfg, supported_enum_values, (&vehicleAreaConfig),
111 supportedEnumValues.value());
112 }
113
114 return vehicleAreaConfig;
115 };
116 CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, area_configs, out, areaConfigs, cast_to_acfg);
117 }
118
aidlToProto(const aidl_vehicle::VehiclePropValue & in,proto::VehiclePropValue * out)119 void aidlToProto(const aidl_vehicle::VehiclePropValue& in, proto::VehiclePropValue* out) {
120 out->set_prop(in.prop);
121 out->set_timestamp(in.timestamp);
122 out->set_status(static_cast<proto::VehiclePropertyStatus>(in.status));
123 out->set_area_id(in.areaId);
124 out->set_string_value(in.value.stringValue);
125 out->set_byte_values(in.value.byteValues.data(), in.value.byteValues.size());
126
127 for (auto& int32Value : in.value.int32Values) {
128 out->add_int32_values(int32Value);
129 }
130
131 for (auto& int64Value : in.value.int64Values) {
132 out->add_int64_values(int64Value);
133 }
134
135 for (auto& floatValue : in.value.floatValues) {
136 out->add_float_values(floatValue);
137 }
138 }
139
protoToAidl(const proto::VehiclePropValue & in,aidl_vehicle::VehiclePropValue * out)140 void protoToAidl(const proto::VehiclePropValue& in, aidl_vehicle::VehiclePropValue* out) {
141 out->prop = in.prop();
142 out->timestamp = in.timestamp();
143 out->status = static_cast<aidl_vehicle::VehiclePropertyStatus>(in.status());
144 out->areaId = in.area_id();
145 out->value.stringValue = in.string_value();
146 for (const char& byte : in.byte_values()) {
147 out->value.byteValues.push_back(byte);
148 }
149
150 COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, int32_values, out, value.int32Values);
151 COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, int64_values, out, value.int64Values);
152 COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, float_values, out, value.floatValues);
153 }
154
aidlToProto(const aidl_vehicle::SubscribeOptions & in,proto::SubscribeOptions * out)155 void aidlToProto(const aidl_vehicle::SubscribeOptions& in, proto::SubscribeOptions* out) {
156 out->set_prop_id(in.propId);
157 for (int areaId : in.areaIds) {
158 out->add_area_ids(areaId);
159 }
160 out->set_sample_rate(in.sampleRate);
161 out->set_resolution(in.resolution);
162 out->set_enable_variable_update_rate(in.enableVariableUpdateRate);
163 }
164
protoToAidl(const proto::SubscribeOptions & in,aidl_vehicle::SubscribeOptions * out)165 void protoToAidl(const proto::SubscribeOptions& in, aidl_vehicle::SubscribeOptions* out) {
166 out->propId = in.prop_id();
167 COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, area_ids, out, areaIds);
168 out->sampleRate = in.sample_rate();
169 out->resolution = in.resolution();
170 out->enableVariableUpdateRate = in.enable_variable_update_rate();
171 }
172
173 #undef COPY_PROTOBUF_VEC_TO_VHAL_TYPE
174 #undef CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE
175
176 } // namespace proto_msg_converter
177 } // namespace vehicle
178 } // namespace automotive
179 } // namespace hardware
180 } // namespace android
181