1 /*
2 * Copyright (C) 2015 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 "VehicleNetwork"
18
19 #include <utils/Log.h>
20
21 #include <IVehicleNetwork.h>
22 #include "VehicleNetworkProtoUtil.h"
23
24 namespace android {
25
copyString(const std::string & in,uint8_t ** out,int32_t * len)26 static status_t copyString(const std::string& in, uint8_t** out, int32_t* len) {
27 *len = in.length();
28 if (*len == 0) {
29 *out = NULL;
30 return NO_ERROR;
31 }
32 *out = new uint8_t[*len];
33 ASSERT_OR_HANDLE_NO_MEMORY(*out, return NO_MEMORY);
34 memcpy(*out, in.data(), *len);
35 return NO_ERROR;
36 }
37
toVehiclePropValue(const vehicle_prop_value_t & in,VehiclePropValue & out,bool)38 status_t VehicleNetworkProtoUtil::toVehiclePropValue(const vehicle_prop_value_t& in,
39 VehiclePropValue& out, bool /*inPlace*/) {
40 out.set_prop(in.prop);
41 out.set_value_type(in.value_type);
42 out.set_timestamp(in.timestamp);
43 out.set_zone(in.zone);
44 switch (in.value_type) {
45 case VEHICLE_VALUE_TYPE_STRING: {
46 //TODO fix ugly copy here for inplace mode
47 if (in.value.str_value.len > 0) {
48 out.set_string_value((char*)in.value.str_value.data, in.value.str_value.len);
49 }
50 } break;
51 case VEHICLE_VALUE_TYPE_BYTES: {
52 if (in.value.bytes_value.len > 0) {
53 out.set_bytes_value(in.value.bytes_value.data, in.value.bytes_value.len);
54 }
55 } break;
56 case VEHICLE_VALUE_TYPE_FLOAT:
57 case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
58 case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
59 case VEHICLE_VALUE_TYPE_FLOAT_VEC4: {
60 int expectedSize = in.value_type - VEHICLE_VALUE_TYPE_FLOAT + 1;
61 for (int i = 0; i < expectedSize; i++) {
62 out.add_float_values(in.value.float_array[i]);
63 }
64 } break;
65 case VEHICLE_VALUE_TYPE_INT64: {
66 out.set_int64_value(in.value.int64_value);
67 } break;
68 case VEHICLE_VALUE_TYPE_BOOLEAN:
69 case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN: {
70 out.add_int32_values(in.value.int32_value);
71 } break;
72 case VEHICLE_VALUE_TYPE_INT32:
73 case VEHICLE_VALUE_TYPE_INT32_VEC2:
74 case VEHICLE_VALUE_TYPE_INT32_VEC3:
75 case VEHICLE_VALUE_TYPE_INT32_VEC4: {
76 int expectedSize = in.value_type - VEHICLE_VALUE_TYPE_INT32 + 1;
77 for (int i = 0; i < expectedSize; i++) {
78 out.add_int32_values(in.value.int32_array[i]);
79 }
80 } break;
81 case VEHICLE_VALUE_TYPE_ZONED_INT32:
82 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
83 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
84 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: {
85 int expectedSize = in.value_type - VEHICLE_VALUE_TYPE_ZONED_INT32 + 1;
86 for (int i = 0; i < expectedSize; i++) {
87 out.add_int32_values(in.value.int32_array[i]);
88 }
89 } break;
90 case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
91 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
92 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
93 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4: {
94 int expectedSize = in.value_type - VEHICLE_VALUE_TYPE_ZONED_FLOAT + 1;
95 for (int i = 0; i < expectedSize; i++) {
96 out.add_float_values(in.value.float_array[i]);
97 }
98 } break;
99 }
100 return NO_ERROR;
101 }
102
fromVehiclePropValue(const VehiclePropValue & in,vehicle_prop_value_t & out,bool,bool canIgnoreNoData)103 status_t VehicleNetworkProtoUtil::fromVehiclePropValue(const VehiclePropValue& in,
104 vehicle_prop_value_t& out, bool /*inPlace*/, bool canIgnoreNoData) {
105 out.prop = in.prop();
106 out.value_type = in.value_type();
107 out.timestamp = in.timestamp();
108 out.zone = in.zone();
109 switch (out.value_type) {
110 case VEHICLE_VALUE_TYPE_STRING: {
111 if (!in.has_string_value()) {
112 // set to NULL so that client can just delete this safely.
113 out.value.str_value.data = NULL;
114 out.value.str_value.len = 0;
115 if (canIgnoreNoData) {
116 return NO_ERROR;
117 } else {
118 ALOGE("fromVehiclePropValue, no string data");
119 return BAD_VALUE;
120 }
121 }
122 //TODO fix copy...
123 status_t r = copyString(in.string_value(), &(out.value.str_value.data),
124 &(out.value.str_value.len));
125 if (r != NO_ERROR) {
126 out.value.str_value.data = NULL;
127 out.value.str_value.len = 0;
128 ALOGE("copyString for string failed %d", r);
129 return r;
130 }
131 } break;
132 case VEHICLE_VALUE_TYPE_BYTES: {
133 if (!in.has_bytes_value()) {
134 out.value.bytes_value.data = NULL;
135 out.value.bytes_value.len = 0;
136 if (canIgnoreNoData) {
137 return NO_ERROR;
138 } else {
139 ALOGE("fromVehiclePropValue, no byte data");
140 return BAD_VALUE;
141 }
142 }
143 status_t r = copyString(in.bytes_value(), &(out.value.bytes_value.data),
144 &(out.value.bytes_value.len));
145 if (r != NO_ERROR) {
146 out.value.bytes_value.data = NULL;
147 out.value.bytes_value.len = 0;
148 ALOGE("copyString for bytes failed %d", r);
149 return r;
150 }
151 } break;
152 case VEHICLE_VALUE_TYPE_FLOAT:
153 case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
154 case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
155 case VEHICLE_VALUE_TYPE_FLOAT_VEC4: {
156 int expectedSize = out.value_type - VEHICLE_VALUE_TYPE_FLOAT + 1;
157 if (in.float_values_size() != expectedSize) {
158 if (canIgnoreNoData) {
159 return NO_ERROR;
160 }
161 ALOGE("float value, wrong size %d, expecting %d", in.float_values_size(),
162 expectedSize);
163 return BAD_VALUE;
164 }
165 for (int i = 0; i < expectedSize; i++) {
166 out.value.float_array[i] = in.float_values(i);
167 }
168 } break;
169 case VEHICLE_VALUE_TYPE_INT64: {
170 if (!in.has_int64_value()) {
171 if (canIgnoreNoData) {
172 return NO_ERROR;
173 }
174 ALOGE("no int64 value");
175 return BAD_VALUE;
176 }
177 out.value.int64_value = in.int64_value();
178 } break;
179 case VEHICLE_VALUE_TYPE_BOOLEAN:
180 case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN: {
181 if (in.int32_values_size() != 1) {
182 if (canIgnoreNoData) {
183 return NO_ERROR;
184 }
185 ALOGE("no int32 value");
186 return BAD_VALUE;
187 }
188 out.value.int32_value = in.int32_values(0);
189 } break;
190 case VEHICLE_VALUE_TYPE_INT32:
191 case VEHICLE_VALUE_TYPE_INT32_VEC2:
192 case VEHICLE_VALUE_TYPE_INT32_VEC3:
193 case VEHICLE_VALUE_TYPE_INT32_VEC4: {
194 int expectedSize = out.value_type - VEHICLE_VALUE_TYPE_INT32 + 1;
195 if (in.int32_values_size() != expectedSize) {
196 if (canIgnoreNoData) {
197 return NO_ERROR;
198 }
199 ALOGE("int32 value, wrong size %d, expecting %d", in.int32_values_size(),
200 expectedSize);
201 return BAD_VALUE;
202 }
203 for (int i = 0; i < expectedSize; i++) {
204 out.value.int32_array[i] = in.int32_values(i);
205 }
206 } break;
207
208 case VEHICLE_VALUE_TYPE_ZONED_INT32:
209 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
210 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
211 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: {
212 int expectedSize = out.value_type - VEHICLE_VALUE_TYPE_ZONED_INT32 + 1;
213 if (in.int32_values_size() != expectedSize) {
214 if (canIgnoreNoData) {
215 return NO_ERROR;
216 }
217 ALOGE("int32 value, wrong size %d, expecting %d", in.int32_values_size(),
218 expectedSize);
219 return BAD_VALUE;
220 }
221 for (int i = 0; i < expectedSize; i++) {
222 out.value.int32_array[i] = in.int32_values(i);
223 }
224 } break;
225 case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
226 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
227 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
228 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4:{
229 int expectedSize = out.value_type - VEHICLE_VALUE_TYPE_ZONED_FLOAT + 1;
230 if (in.float_values_size() != expectedSize) {
231 if (canIgnoreNoData) {
232 return NO_ERROR;
233 }
234 ALOGE("float value, wrong size %d, expecting %d", in.float_values_size(),
235 expectedSize);
236 return BAD_VALUE;
237 }
238 for (int i = 0; i < expectedSize; i++) {
239 out.value.float_array[i] = in.float_values(i);
240 }
241 } break;
242 default: {
243 if (canIgnoreNoData) {
244 return NO_ERROR;
245 }
246 ALOGE("fromVehiclePropValue unknown type 0x%x", out.value_type);
247 return BAD_VALUE;
248 }
249 }
250 return NO_ERROR;
251 }
252
toVehiclePropValues(const List<vehicle_prop_value_t * > & in,VehiclePropValues & out)253 status_t VehicleNetworkProtoUtil::toVehiclePropValues(const List<vehicle_prop_value_t*>& in,
254 VehiclePropValues& out) {
255 status_t r;
256 for (auto& v : in) {
257 VehiclePropValue* value = out.add_values();
258 r = toVehiclePropValue(*v, *value);
259 if (r != NO_ERROR) {
260 out.clear_values();
261 return r;
262 }
263 }
264 return NO_ERROR;
265 }
266
fromVehiclePropValues(const VehiclePropValues & in,List<vehicle_prop_value_t * > & out)267 status_t VehicleNetworkProtoUtil::fromVehiclePropValues(const VehiclePropValues& in,
268 List<vehicle_prop_value_t*>& out) {
269 status_t r;
270 for (int i = 0; i < in.values_size(); i++) {
271 vehicle_prop_value_t* v = new vehicle_prop_value_t();
272 memset(v, 0, sizeof(vehicle_prop_value_t));
273 ASSERT_OR_HANDLE_NO_MEMORY(v, r = NO_MEMORY;goto error);
274 r = fromVehiclePropValue(in.values(i), *v);
275 if (r != NO_ERROR) {
276 delete v;
277 goto error;
278 }
279 out.push_back(v);
280 }
281 return NO_ERROR;
282 error:
283 // clean up everything in List
284 for (auto pv : out) {
285 VehiclePropValueUtil::deleteMembers(pv);
286 }
287 return r;
288 }
289
toVehiclePropConfig(const vehicle_prop_config_t & in,VehiclePropConfig & out)290 status_t VehicleNetworkProtoUtil::toVehiclePropConfig(const vehicle_prop_config_t& in,
291 VehiclePropConfig& out) {
292 out.set_prop(in.prop);
293 out.set_access(in.access);
294 out.set_change_mode(in.change_mode);
295 out.set_value_type(in.value_type);
296 out.set_permission_model(in.permission_model);
297 out.set_zones(in.vehicle_zone_flags);
298 for (unsigned int i = 0; i < sizeof(in.config_array) / sizeof(int32_t); i++) {
299 out.add_config_array(in.config_array[i]);
300 }
301 if (in.config_string.data != NULL && in.config_string.len != 0) {
302 out.set_config_string((char*)in.config_string.data, in.config_string.len);
303 } else {
304 out.clear_config_string();
305 }
306 switch (in.value_type) {
307 case VEHICLE_VALUE_TYPE_FLOAT:
308 case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
309 case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
310 case VEHICLE_VALUE_TYPE_FLOAT_VEC4: {
311 out.add_float_maxs(in.float_max_value);
312 out.add_float_mins(in.float_min_value);
313 } break;
314 case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
315 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
316 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
317 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4: {
318 int numZones = VehicleNetworkUtil::countNumberOfZones(in.vehicle_zone_flags);
319 if (in.float_min_values == NULL) {
320 if (in.float_max_values == NULL) {
321 // all the same min/max
322 for (int i = 0; i < numZones; i++) {
323 out.add_float_maxs(in.float_max_value);
324 out.add_float_mins(in.float_min_value);
325 }
326 } else { // invalid combination
327 ALOGW("Zoned property 0x%x, min_values NULL while max_values not NULL",
328 in.prop);
329 return BAD_VALUE;
330 }
331 } else {
332 if (in.float_max_values != NULL) {
333 for (int i = 0; i < numZones; i++) {
334 out.add_float_maxs(in.float_max_values[i]);
335 out.add_float_mins(in.float_min_values[i]);
336 }
337 } else { // invalid combination
338 ALOGW("Zoned property 0x%x, max_values NULL while min_values not NULL",
339 in.prop);
340 return BAD_VALUE;
341 }
342 }
343 } break;
344 case VEHICLE_VALUE_TYPE_INT64: {
345 out.add_int64_maxs(in.int64_max_value);
346 out.add_int64_mins(in.int64_min_value);
347 } break;
348 case VEHICLE_VALUE_TYPE_INT32:
349 case VEHICLE_VALUE_TYPE_INT32_VEC2:
350 case VEHICLE_VALUE_TYPE_INT32_VEC3:
351 case VEHICLE_VALUE_TYPE_INT32_VEC4: {
352 out.add_int32_maxs(in.int32_max_value);
353 out.add_int32_mins(in.int32_min_value);
354 } break;
355 case VEHICLE_VALUE_TYPE_ZONED_INT32:
356 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
357 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
358 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: {
359 int numZones = VehicleNetworkUtil::countNumberOfZones(in.vehicle_zone_flags);
360 if (in.int32_min_values == NULL) {
361 if (in.int32_max_values == NULL) {
362 // all the same min/max
363 for (int i = 0; i < numZones; i++) {
364 out.add_int32_maxs(in.int32_max_value);
365 out.add_int32_mins(in.int32_min_value);
366 }
367 } else { // invalid combination
368 ALOGW("Zoned property 0x%x, min_values NULL while max_values not NULL",
369 in.prop);
370 return BAD_VALUE;
371 }
372 } else {
373 if (in.int32_max_values != NULL) {
374 for (int i = 0; i < numZones; i++) {
375 out.add_int32_maxs(in.int32_max_values[i]);
376 out.add_int32_mins(in.int32_min_values[i]);
377 }
378 } else { // invalid combination
379 ALOGW("Zoned property 0x%x, max_values NULL while min_values not NULL",
380 in.prop);
381 return BAD_VALUE;
382 }
383 }
384 } break;
385 }
386 out.set_sample_rate_max(in.max_sample_rate);
387 out.set_sample_rate_min(in.min_sample_rate);
388 return NO_ERROR;
389 }
390
fromVehiclePropConfig(const VehiclePropConfig & in,vehicle_prop_config_t & out)391 status_t VehicleNetworkProtoUtil::fromVehiclePropConfig(const VehiclePropConfig& in,
392 vehicle_prop_config_t& out) {
393 out.prop = in.prop();
394 out.access = in.access();
395 out.change_mode = in.change_mode();
396 out.value_type = in.value_type();
397 out.permission_model = in.permission_model();
398 out.vehicle_zone_flags = in.zones();
399 int maxConfigSize = sizeof(out.config_array) / sizeof(int32_t);
400 int configSize = in.config_array_size();
401 if (configSize > maxConfigSize) {
402 return BAD_VALUE;
403 }
404 int i = 0;
405 for (; i < configSize; i++) {
406 out.config_array[i] = in.config_array(i);
407 }
408 for (; i < maxConfigSize; i++) {
409 out.config_array[i] = 0;
410 }
411 if (in.has_config_string()) {
412 status_t r = copyString(in.config_string(), &(out.config_string.data),
413 &(out.config_string.len));
414 if (r != NO_ERROR) {
415 return r;
416 }
417 } else {
418 out.config_string.data = NULL;
419 out.config_string.len = 0;
420 }
421 switch (out.value_type) {
422 case VEHICLE_VALUE_TYPE_FLOAT:
423 case VEHICLE_VALUE_TYPE_FLOAT_VEC2:
424 case VEHICLE_VALUE_TYPE_FLOAT_VEC3:
425 case VEHICLE_VALUE_TYPE_FLOAT_VEC4: {
426 if ((in.float_maxs_size() == 1) && (in.float_mins_size() == 1)) {
427 out.float_max_value = in.float_maxs(0);
428 out.float_min_value = in.float_mins(0);
429 } else {
430 ALOGW("no float max/min for property 0x%x", out.prop);
431 out.float_max_value = 0;
432 out.float_min_value = 0;
433 }
434 } break;
435 case VEHICLE_VALUE_TYPE_ZONED_FLOAT:
436 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2:
437 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3:
438 case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4: {
439 int numZones = VehicleNetworkUtil::countNumberOfZones(out.vehicle_zone_flags);
440 int maxSize = in.float_maxs_size();
441 int minSize = in.float_mins_size();
442 if (maxSize != minSize) {
443 ALOGW("Zoned property 0x%x, config maxSize %d minSize %d", out.prop, maxSize,
444 minSize);
445 return BAD_VALUE;
446 }
447 if (maxSize == 0) {
448 out.float_max_value = 0;
449 out.float_min_value = 0;
450 out.float_max_values = NULL;
451 out.float_min_values = NULL;
452 } else if (maxSize == 1) { // one for all
453 out.float_max_value = in.float_maxs(0);
454 out.float_min_value = in.float_mins(0);
455 out.float_max_values = NULL;
456 out.float_min_values = NULL;
457 } else if (numZones > 1){
458 if (numZones != maxSize) {
459 ALOGW("Zoned property 0x%x, config maxSize %d num Zones %d", out.prop, maxSize,
460 numZones);
461 return BAD_VALUE;
462 }
463 out.float_max_values = new float[numZones];
464 ASSERT_OR_HANDLE_NO_MEMORY(out.float_max_values, return NO_MEMORY);
465 out.float_min_values = new float[numZones];
466 ASSERT_OR_HANDLE_NO_MEMORY(out.float_min_values, return NO_MEMORY);
467 for (int i = 0; i < numZones; i++) {
468 out.float_max_values[i] = in.float_maxs(i);
469 out.float_min_values[i] = in.float_mins(i);
470 }
471 }
472 } break;
473 case VEHICLE_VALUE_TYPE_INT64: {
474 if ((in.int64_maxs_size() == 1) && (in.int64_mins_size() == 1)) {
475 out.int64_max_value = in.int64_maxs(0);
476 out.int64_min_value = in.int64_mins(0);
477 } else {
478 ALOGW("no int64 max/min for property 0x%x", out.prop);
479 out.int64_max_value = 0;
480 out.int64_min_value = 0;
481 }
482 } break;
483 case VEHICLE_VALUE_TYPE_INT32:
484 case VEHICLE_VALUE_TYPE_INT32_VEC2:
485 case VEHICLE_VALUE_TYPE_INT32_VEC3:
486 case VEHICLE_VALUE_TYPE_INT32_VEC4: {
487 if ((in.int32_maxs_size() == 1) && (in.int32_mins_size() == 1)) {
488 out.int32_max_value = in.int32_maxs(0);
489 out.int32_min_value = in.int32_mins(0);
490 } else {
491 ALOGW("no int32 max/min for property 0x%x", out.prop);
492 out.int32_max_value = 0;
493 out.int32_min_value = 0;
494 }
495 } break;
496 case VEHICLE_VALUE_TYPE_ZONED_INT32:
497 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2:
498 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3:
499 case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: {
500 int numZones = VehicleNetworkUtil::countNumberOfZones(out.vehicle_zone_flags);
501 int maxSize = in.int32_maxs_size();
502 int minSize = in.int32_mins_size();
503 if (maxSize != minSize) {
504 ALOGW("Zoned property 0x%x, config maxSize %d minSize %d", out.prop, maxSize,
505 minSize);
506 return BAD_VALUE;
507 }
508 if (maxSize == 0) {
509 out.int32_max_value = 0;
510 out.int32_min_value = 0;
511 out.int32_max_values = NULL;
512 out.int32_min_values = NULL;
513 } else if (maxSize == 1) { // one for all
514 out.int32_max_value = in.int32_maxs(0);
515 out.int32_min_value = in.int32_mins(0);
516 out.int32_max_values = NULL;
517 out.int32_min_values = NULL;
518 } else if (numZones > 1){
519 if (numZones != maxSize) {
520 ALOGW("Zoned property 0x%x, config maxSize %d num Zones %d", out.prop, maxSize,
521 numZones);
522 return BAD_VALUE;
523 }
524 out.int32_max_values = new int32_t[numZones];
525 ASSERT_OR_HANDLE_NO_MEMORY(out.int32_max_values, return NO_MEMORY);
526 out.int32_min_values = new int32_t[numZones];
527 ASSERT_OR_HANDLE_NO_MEMORY(out.int32_min_values, return NO_MEMORY);
528 for (int i = 0; i < numZones; i++) {
529 out.int32_max_values[i] = in.int32_maxs(i);
530 out.int32_min_values[i] = in.int32_mins(i);
531 }
532 }
533 } break;
534 }
535 out.max_sample_rate = in.sample_rate_max();
536 out.min_sample_rate = in.sample_rate_min();
537 return NO_ERROR;
538 }
539
toVehiclePropConfigs(List<vehicle_prop_config_t const * > & in,VehiclePropConfigs & out)540 status_t VehicleNetworkProtoUtil::toVehiclePropConfigs(List<vehicle_prop_config_t const*> &in,
541 VehiclePropConfigs& out) {
542 status_t r;
543 for (auto& inEntry : in) {
544 VehiclePropConfig* config = out.add_configs();
545 r = toVehiclePropConfig(*inEntry, *config);
546 if (r != NO_ERROR) {
547 out.clear_configs();
548 return r;
549 }
550 }
551 return NO_ERROR;
552 }
553
fromVehiclePropConfigs(const VehiclePropConfigs & in,List<vehicle_prop_config_t const * > & out)554 status_t VehicleNetworkProtoUtil::fromVehiclePropConfigs(const VehiclePropConfigs& in,
555 List<vehicle_prop_config_t const*>& out) {
556 int32_t n = in.configs_size();
557 status_t r;
558 for (int32_t i = 0; i < n; i++) {
559 vehicle_prop_config_t* entry = new vehicle_prop_config_t();
560 ASSERT_OR_HANDLE_NO_MEMORY(entry, r = NO_MEMORY; goto error);
561 memset(entry, 0, sizeof(vehicle_prop_config_t));
562 r = fromVehiclePropConfig(in.configs(i), *entry);
563 if (r != NO_ERROR) {
564 goto error;
565 }
566 out.push_back(entry);
567 }
568 return NO_ERROR;
569 error:
570 for (auto& e : out) {
571 vehicle_prop_config_t* eDelete = const_cast<vehicle_prop_config_t*>(e);
572 VehiclePropertiesUtil::deleteMembers(eDelete);
573 delete eDelete;
574 }
575 out.clear();
576 return r;
577 }
578
writeToParcel(Parcel & parcel,const vehicle_prop_value_t & value)579 status_t VehiclePropValueBinderUtil::writeToParcel(Parcel& parcel,
580 const vehicle_prop_value_t& value) {
581 parcel.writeInt32(1); // 0 means no value. For compatibility with aidl based code.
582 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
583 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
584 VehicleNetworkProtoUtil::toVehiclePropValue(value, *v.get());
585 int size = v->ByteSize();
586 WritableBlobHolder blob(new Parcel::WritableBlob());
587 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
588 parcel.writeInt32(size);
589 parcel.writeBlob(size, false, blob.blob);
590 v->SerializeToArray(blob.blob->data(), size);
591 return NO_ERROR;
592 }
593
readFromParcel(const Parcel & parcel,vehicle_prop_value_t * value,bool deleteMembers,bool canIgnoreNoData)594 status_t VehiclePropValueBinderUtil::readFromParcel(const Parcel& parcel,
595 vehicle_prop_value_t* value, bool deleteMembers, bool canIgnoreNoData) {
596 if (parcel.readInt32() == 0) { // no result
597 ALOGE("readFromParcel, null data");
598 return BAD_VALUE;
599 }
600 ReadableBlobHolder blob(new Parcel::ReadableBlob());
601 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY);
602 int32_t size = parcel.readInt32();
603 status_t status = parcel.readBlob(size, blob.blob);
604 if (status != NO_ERROR) {
605 ALOGE("readFromParcel, cannot read blob");
606 return status;
607 }
608 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue());
609 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY);
610 if (!v->ParseFromArray(blob.blob->data(), size)) {
611 ALOGE("readFromParcel, cannot parse");
612 return BAD_VALUE;
613 }
614 if (deleteMembers) {
615 VehiclePropValueUtil::deleteMembers(value);
616 }
617 return VehicleNetworkProtoUtil::fromVehiclePropValue(*v.get(), *value, false /*inPlace*/,
618 canIgnoreNoData);
619 }
620
621 }; //namespace android
622
623