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