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 24namespace android { 25 26static 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 38status_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 103status_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 253status_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 267status_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; 282error: 283 // clean up everything in List 284 for (auto pv : out) { 285 VehiclePropValueUtil::deleteMembers(pv); 286 } 287 return r; 288} 289 290status_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 391status_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 540status_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 554status_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; 569error: 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 579status_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 594status_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