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 <memory> 20 #include <string.h> 21 22 #include <binder/IPCThreadState.h> 23 #include <binder/Status.h> 24 25 #include <utils/Log.h> 26 27 #include <IVehicleNetwork.h> 28 #include <VehicleNetworkProto.pb.h> 29 30 #include "BinderUtil.h" 31 #include "VehicleNetworkProtoUtil.h" 32 33 namespace android { 34 35 enum { 36 LIST_PROPERTIES = IBinder::FIRST_CALL_TRANSACTION, 37 SET_PROPERTY, 38 GET_PROPERTY, 39 SUBSCRIBE, 40 UNSUBSCRIBE, 41 INJECT_EVENT, 42 START_MOCKING, 43 STOP_MOCKING, 44 INJECT_HAL_ERROR, 45 START_ERROR_LISTENING, 46 STOP_ERROR_LISTENING, 47 START_HAL_RESTART_MONITORING, 48 STOP_HAL_RESTART_MONITORING 49 }; 50 51 // ---------------------------------------------------------------------------- 52 53 const char IVehicleNetwork::SERVICE_NAME[] = "com.android.car.vehiclenetwork.IVehicleNetwork"; 54 55 // ---------------------------------------------------------------------------- 56 57 class BpVehicleNetwork : public BpInterface<IVehicleNetwork> { 58 public: 59 BpVehicleNetwork(const sp<IBinder> & impl) 60 : BpInterface<IVehicleNetwork>(impl) { 61 } 62 63 virtual sp<VehiclePropertiesHolder> listProperties(int32_t property) { 64 sp<VehiclePropertiesHolder> holder; 65 Parcel data, reply; 66 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 67 data.writeInt32(property); 68 status_t status = remote()->transact(LIST_PROPERTIES, data, &reply); 69 if (status == NO_ERROR) { 70 reply.readExceptionCode(); // for compatibility with java 71 if (reply.readInt32() == 0) { // no result 72 return holder; 73 } 74 ReadableBlobHolder blob(new Parcel::ReadableBlob()); 75 if (blob.blob == NULL) { 76 ALOGE("listProperties, no memory"); 77 return holder; 78 } 79 int32_t size = reply.readInt32(); 80 status = reply.readBlob(size, blob.blob); 81 if (status != NO_ERROR) { 82 ALOGE("listProperties, cannot read blob %d", status); 83 return holder; 84 } 85 //TODO make this more memory efficient 86 std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs()); 87 if (configs.get() == NULL) { 88 return holder; 89 } 90 if(!configs->ParseFromArray(blob.blob->data(), size)) { 91 ALOGE("listProperties, cannot parse reply"); 92 return holder; 93 } 94 holder = new VehiclePropertiesHolder(); 95 ASSERT_OR_HANDLE_NO_MEMORY(holder.get(), return); 96 status = VehicleNetworkProtoUtil::fromVehiclePropConfigs(*configs.get(), 97 holder->getList()); 98 if (status != NO_ERROR) { 99 ALOGE("listProperties, cannot convert VehiclePropConfigs %d", status); 100 return holder; 101 } 102 103 } 104 return holder; 105 } 106 107 virtual status_t setProperty(const vehicle_prop_value_t& value) { 108 Parcel data, reply; 109 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 110 status_t status = VehiclePropValueBinderUtil::writeToParcel(data, value); 111 if (status != NO_ERROR) { 112 return status; 113 } 114 status = remote()->transact(SET_PROPERTY, data, &reply); 115 return status; 116 } 117 118 virtual status_t getProperty(vehicle_prop_value_t* value) { 119 Parcel data, reply; 120 if (value == NULL) { 121 return BAD_VALUE; 122 } 123 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 124 status_t status = VehiclePropValueBinderUtil::writeToParcel(data, *value); 125 if (status != NO_ERROR) { 126 ALOGE("getProperty, cannot write"); 127 return status; 128 } 129 status = remote()->transact(GET_PROPERTY, data, &reply); 130 if (status == NO_ERROR) { 131 int32_t exceptionCode = reply.readExceptionCode(); 132 if (exceptionCode != NO_ERROR) { 133 if (exceptionCode == binder::Status::EX_SERVICE_SPECIFIC) { 134 return -EAGAIN; 135 } 136 return exceptionCode; 137 } 138 status = VehiclePropValueBinderUtil::readFromParcel(reply, value); 139 } 140 return status; 141 } 142 143 virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property, 144 float sampleRate, int32_t zones) { 145 Parcel data, reply; 146 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 147 data.writeStrongBinder(IInterface::asBinder(listener)); 148 data.writeInt32(property); 149 data.writeFloat(sampleRate); 150 data.writeInt32(zones); 151 status_t status = remote()->transact(SUBSCRIBE, data, &reply); 152 return status; 153 } 154 155 virtual void unsubscribe(const sp<IVehicleNetworkListener> &listener, int32_t property) { 156 Parcel data, reply; 157 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 158 data.writeStrongBinder(IInterface::asBinder(listener)); 159 data.writeInt32(property); 160 status_t status = remote()->transact(UNSUBSCRIBE, data, &reply); 161 if (status != NO_ERROR) { 162 ALOGI("unsubscribing property %d failed %d", property, status); 163 } 164 } 165 166 virtual status_t injectEvent(const vehicle_prop_value_t& value) { 167 Parcel data, reply; 168 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 169 data.writeInt32(1); // 0 means no value. For compatibility with aidl based code. 170 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue()); 171 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY); 172 VehicleNetworkProtoUtil::toVehiclePropValue(value, *v.get()); 173 int size = v->ByteSize(); 174 WritableBlobHolder blob(new Parcel::WritableBlob()); 175 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY); 176 data.writeInt32(size); 177 data.writeBlob(size, false, blob.blob); 178 v->SerializeToArray(blob.blob->data(), size); 179 status_t status = remote()->transact(INJECT_EVENT, data, &reply); 180 return status; 181 } 182 183 virtual status_t startMocking(const sp<IVehicleNetworkHalMock>& mock) { 184 Parcel data, reply; 185 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 186 data.writeStrongBinder(IInterface::asBinder(mock)); 187 status_t status = remote()->transact(START_MOCKING, data, &reply); 188 return status; 189 } 190 191 virtual void stopMocking(const sp<IVehicleNetworkHalMock>& mock) { 192 Parcel data, reply; 193 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 194 data.writeStrongBinder(IInterface::asBinder(mock)); 195 status_t status = remote()->transact(STOP_MOCKING, data, &reply); 196 if (status != NO_ERROR) { 197 ALOGI("stop mocking failed %d", status); 198 } 199 } 200 201 status_t injectHalError(int32_t errorCode, int32_t property, int32_t operation) { 202 Parcel data, reply; 203 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 204 data.writeInt32(errorCode); 205 data.writeInt32(property); 206 data.writeInt32(operation); 207 status_t status = remote()->transact(INJECT_HAL_ERROR, data, &reply); 208 return status; 209 } 210 211 virtual status_t startErrorListening(const sp<IVehicleNetworkListener> &listener) { 212 Parcel data, reply; 213 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 214 data.writeStrongBinder(IInterface::asBinder(listener)); 215 status_t status = remote()->transact(START_ERROR_LISTENING, data, &reply); 216 return status; 217 } 218 219 virtual void stopErrorListening(const sp<IVehicleNetworkListener> &listener) { 220 Parcel data, reply; 221 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 222 data.writeStrongBinder(IInterface::asBinder(listener)); 223 status_t status = remote()->transact(STOP_ERROR_LISTENING, data, &reply); 224 if (status != NO_ERROR) { 225 ALOGI("stopErrorListening %d", status); 226 } 227 } 228 229 virtual status_t startHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener) { 230 Parcel data, reply; 231 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 232 data.writeStrongBinder(IInterface::asBinder(listener)); 233 status_t status = remote()->transact(START_HAL_RESTART_MONITORING, data, &reply); 234 return status; 235 } 236 237 virtual void stopHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener) { 238 Parcel data, reply; 239 data.writeInterfaceToken(IVehicleNetwork::getInterfaceDescriptor()); 240 data.writeStrongBinder(IInterface::asBinder(listener)); 241 status_t status = remote()->transact(STOP_HAL_RESTART_MONITORING, data, &reply); 242 if (status != NO_ERROR) { 243 ALOGI("stopHalRestartMonitoring %d", status); 244 } 245 } 246 }; 247 248 IMPLEMENT_META_INTERFACE(VehicleNetwork, IVehicleNetwork::SERVICE_NAME); 249 250 // ---------------------------------------------------------------------- 251 252 status_t BnVehicleNetwork::onTransact(uint32_t code, const Parcel& data, Parcel* reply, 253 uint32_t flags) { 254 status_t r; 255 switch (code) { 256 case LIST_PROPERTIES: { 257 CHECK_INTERFACE(IVehicleNetwork, data, reply); 258 if (!isOperationAllowed(0, false)) { 259 return PERMISSION_DENIED; 260 } 261 int32_t property = data.readInt32(); 262 sp<VehiclePropertiesHolder> holder = listProperties(property); 263 if (holder.get() == NULL) { // given property not found 264 BinderUtil::fillObjectResultReply(reply, false /* isValid */); 265 return NO_ERROR; 266 } 267 std::unique_ptr<VehiclePropConfigs> configs(new VehiclePropConfigs()); 268 ASSERT_OR_HANDLE_NO_MEMORY(configs.get(), return NO_MEMORY); 269 VehicleNetworkProtoUtil::toVehiclePropConfigs(holder->getList(), *configs.get()); 270 int size = configs->ByteSize(); 271 WritableBlobHolder blob(new Parcel::WritableBlob()); 272 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY); 273 BinderUtil::fillObjectResultReply(reply, true); 274 reply->writeInt32(size); 275 reply->writeBlob(size, false, blob.blob); 276 configs->SerializeToArray(blob.blob->data(), size); 277 return NO_ERROR; 278 } break; 279 case SET_PROPERTY: { 280 CHECK_INTERFACE(IVehicleNetwork, data, reply); 281 ScopedVehiclePropValue value; 282 r = VehiclePropValueBinderUtil::readFromParcel(data, &value.value, 283 false /* deleteMembers */); 284 if (r != NO_ERROR) { 285 return r; 286 } 287 if (!isOperationAllowed(value.value.prop, true)) { 288 return PERMISSION_DENIED; 289 } 290 r = setProperty(value.value); 291 BinderUtil::fillNoResultReply(reply); 292 return r; 293 } break; 294 case GET_PROPERTY: { 295 CHECK_INTERFACE(IVehicleNetwork, data, reply); 296 vehicle_prop_value_t value; 297 memset(&value, 0, sizeof(value)); 298 r = VehiclePropValueBinderUtil::readFromParcel(data, &value, 299 false /* deleteMembers */, true /*canIgnoreNoData*/); 300 if (r != NO_ERROR) { 301 ALOGE("getProperty cannot read %d", r); 302 return r; 303 } 304 if (!isOperationAllowed(value.prop, false)) { 305 return PERMISSION_DENIED; 306 } 307 r = getProperty(&value); 308 if (r == NO_ERROR) { 309 reply->writeNoException(); 310 r = VehiclePropValueBinderUtil::writeToParcel(*reply, value); 311 releaseMemoryFromGet(&value); 312 } else if (r == -EAGAIN) { 313 // this should be handled specially to throw ServiceSpecificException in java. 314 reply->writeInt32(binder::Status::EX_SERVICE_SPECIFIC); 315 return NO_ERROR; 316 } 317 return r; 318 } break; 319 case SUBSCRIBE: { 320 CHECK_INTERFACE(IVehicleNetwork, data, reply); 321 sp<IVehicleNetworkListener> listener = 322 interface_cast<IVehicleNetworkListener>(data.readStrongBinder()); 323 int32_t property = data.readInt32(); 324 if (!isOperationAllowed(property, false)) { 325 return PERMISSION_DENIED; 326 } 327 float sampleRate = data.readFloat(); 328 int32_t zones = data.readInt32(); 329 r = subscribe(listener, property, sampleRate, zones); 330 BinderUtil::fillNoResultReply(reply); 331 return r; 332 } break; 333 case UNSUBSCRIBE: { 334 CHECK_INTERFACE(IVehicleNetwork, data, reply); 335 sp<IVehicleNetworkListener> listener = 336 interface_cast<IVehicleNetworkListener>(data.readStrongBinder()); 337 int32_t property = data.readInt32(); 338 if (!isOperationAllowed(property, false)) { 339 return PERMISSION_DENIED; 340 } 341 unsubscribe(listener, property); 342 BinderUtil::fillNoResultReply(reply); 343 return NO_ERROR; 344 } break; 345 case INJECT_EVENT: { 346 CHECK_INTERFACE(IVehicleNetwork, data, reply); 347 if (data.readInt32() == 0) { // java side allows passing null with this. 348 return BAD_VALUE; 349 } 350 if (!isOperationAllowed(0, true)) { 351 return PERMISSION_DENIED; 352 } 353 ScopedVehiclePropValue value; 354 ReadableBlobHolder blob(new Parcel::ReadableBlob()); 355 ASSERT_OR_HANDLE_NO_MEMORY(blob.blob, return NO_MEMORY); 356 int32_t size = data.readInt32(); 357 r = data.readBlob(size, blob.blob); 358 if (r != NO_ERROR) { 359 ALOGE("injectEvent:service, cannot read blob"); 360 return r; 361 } 362 std::unique_ptr<VehiclePropValue> v(new VehiclePropValue()); 363 ASSERT_OR_HANDLE_NO_MEMORY(v.get(), return NO_MEMORY); 364 if (!v->ParseFromArray(blob.blob->data(), size)) { 365 ALOGE("injectEvent:service, cannot parse data"); 366 return BAD_VALUE; 367 } 368 r = VehicleNetworkProtoUtil::fromVehiclePropValue(*v.get(), value.value); 369 if (r != NO_ERROR) { 370 ALOGE("injectEvent:service, cannot convert data"); 371 return BAD_VALUE; 372 } 373 r = injectEvent(value.value); 374 BinderUtil::fillNoResultReply(reply); 375 return r; 376 } break; 377 case START_MOCKING: { 378 if (!isOperationAllowed(0, true)) { 379 return PERMISSION_DENIED; 380 } 381 CHECK_INTERFACE(IVehicleNetwork, data, reply); 382 sp<IVehicleNetworkHalMock> mock = 383 interface_cast<IVehicleNetworkHalMock>(data.readStrongBinder()); 384 r = startMocking(mock); 385 BinderUtil::fillNoResultReply(reply); 386 return r; 387 } break; 388 case STOP_MOCKING: { 389 if (!isOperationAllowed(0, true)) { 390 return PERMISSION_DENIED; 391 } 392 CHECK_INTERFACE(IVehicleNetwork, data, reply); 393 sp<IVehicleNetworkHalMock> mock = 394 interface_cast<IVehicleNetworkHalMock>(data.readStrongBinder()); 395 stopMocking(mock); 396 BinderUtil::fillNoResultReply(reply); 397 return NO_ERROR; 398 } break; 399 case INJECT_HAL_ERROR: { 400 if (!isOperationAllowed(0, true)) { 401 return PERMISSION_DENIED; 402 } 403 CHECK_INTERFACE(IVehicleNetwork, data, reply); 404 int32_t errorCode = data.readInt32(); 405 int32_t property = data.readInt32(); 406 int32_t operation = data.readInt32(); 407 r = injectHalError(errorCode, property, operation); 408 BinderUtil::fillNoResultReply(reply); 409 return r; 410 } break; 411 case START_ERROR_LISTENING: { 412 if (!isOperationAllowed(0, false)) { 413 return PERMISSION_DENIED; 414 } 415 CHECK_INTERFACE(IVehicleNetwork, data, reply); 416 sp<IVehicleNetworkListener> listener = 417 interface_cast<IVehicleNetworkListener>(data.readStrongBinder()); 418 r = startErrorListening(listener); 419 BinderUtil::fillNoResultReply(reply); 420 return r; 421 } break; 422 case STOP_ERROR_LISTENING: { 423 if (!isOperationAllowed(0, false)) { 424 return PERMISSION_DENIED; 425 } 426 CHECK_INTERFACE(IVehicleNetwork, data, reply); 427 sp<IVehicleNetworkListener> listener = 428 interface_cast<IVehicleNetworkListener>(data.readStrongBinder()); 429 stopErrorListening(listener); 430 BinderUtil::fillNoResultReply(reply); 431 return NO_ERROR; 432 } break; 433 case START_HAL_RESTART_MONITORING: { 434 if (!isOperationAllowed(0, false)) { 435 return PERMISSION_DENIED; 436 } 437 CHECK_INTERFACE(IVehicleNetwork, data, reply); 438 sp<IVehicleNetworkListener> listener = 439 interface_cast<IVehicleNetworkListener>(data.readStrongBinder()); 440 r = startHalRestartMonitoring(listener); 441 BinderUtil::fillNoResultReply(reply); 442 return r; 443 } break; 444 case STOP_HAL_RESTART_MONITORING: { 445 if (!isOperationAllowed(0, false)) { 446 return PERMISSION_DENIED; 447 } 448 CHECK_INTERFACE(IVehicleNetwork, data, reply); 449 sp<IVehicleNetworkListener> listener = 450 interface_cast<IVehicleNetworkListener>(data.readStrongBinder()); 451 stopHalRestartMonitoring(listener); 452 BinderUtil::fillNoResultReply(reply); 453 return NO_ERROR; 454 } break; 455 default: 456 return BBinder::onTransact(code, data, reply, flags); 457 } 458 } 459 460 }; // namespace android 461