diff --git a/README.md b/README.md index 1ec3e33..a5aee41 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,13 @@ This repository contains the code to build an emulator image containing some ser * `target`: contains files related to the emulator that will be created. Instead of creating a new device, we just modified the `sdk_car_x86_64.mk` and `car_generic_system.mk` to include our add-on. -We supply a shell script `add_to_aosp.sh` to automatically copy all code to the correct place in the AOSP source tree. Pass to the script the path to where the AOSP repo is: +We supply two different shell scripts. The first one, `fetch_someip_libs.sh`, is responsible for cloning all the necessary libraries to work with SOME/IP and CommonAPI. You only need to run this script once. It's also necessary to generate the files of some_ip_hal example to compile the project. So clone the libraries with the script below and run the commands described at [Generating CommonAPI Files](doc/SOME-IP-HAL.md#generating-commonapi-files) (Don't worry about understanding the whole context of SOME/IP right now, just run the commands in this topic for now). + +```bash +./fetch_someip_libs.sh +``` + +The second one called `add_to_aosp.sh` will automatically copy all code to the correct place in the AOSP source tree. Run these two scripts one after the other, changing `/pathTo/aosp` for the path to your AOSP source tree: ```bash ./add_to_aosp.sh /pathTo/aosp @@ -36,7 +42,7 @@ If you use VSCode, you can use [Run on Save](https://marketplace.visualstudio.co #### Sample HAL implementation -This repository also contains an example of how to develop a HAL and use it through the SDK-Addon. First, focus on how the **hello-world-service** example is described here. Then, take a look at the [HAL Documentation](doc/HAL.md). +This repository also contains an example of how to develop a HAL and use it through the SDK-Addon. First, focus on how the **hello-world-service** example is described here. Then, take a look at the [HAL Documentation](doc/HAL.md).And then, if you are comfortable going further, take a look at the [HAL using SOME/IP](doc/SOME-IP-HAL.md), which is a more complex example involving a HAL that uses SOME/IP to communicate with a provider service. ## Hello World System Service diff --git a/assets/playground_service_log.png b/assets/playground_service_log.png new file mode 100644 index 0000000..5a1920e Binary files /dev/null and b/assets/playground_service_log.png differ diff --git a/device/profusion/profusion_sdk_addon/profusion_sdk_addon.mk b/device/profusion/profusion_sdk_addon/profusion_sdk_addon.mk index ee052c8..52f6129 100644 --- a/device/profusion/profusion_sdk_addon/profusion_sdk_addon.mk +++ b/device/profusion/profusion_sdk_addon/profusion_sdk_addon.mk @@ -11,14 +11,12 @@ PRODUCT_SDK_ADDON_NAME := profusion_sdk_addon INTERNAL_SDK_HOST_OS_NAME := $(HOST_OS) PRODUCT_PACKAGES := \ - libvsomeip \ - libvsomeip_cfg \ - libvsomeip_sd \ - libvsomeip_e2e \ + libvsomeip3 \ libCommonAPI \ libCommonAPI-SomeIP \ helloworld \ profusion.hardware.dummy_car_info_hal-service \ + some_ip_playground-service \ DummyCarInfoManager # Copy the manifest and hardware files for the SDK add-on. diff --git a/device/profusion/sepolicy/daemon/file_contexts b/device/profusion/sepolicy/daemon/file_contexts index 2a93c63..472c453 100644 --- a/device/profusion/sepolicy/daemon/file_contexts +++ b/device/profusion/sepolicy/daemon/file_contexts @@ -1 +1,2 @@ /vendor/bin/hw/profusion.hardware.dummy_car_info_hal-service u:object_r:dummy_car_info_hal_exec:s0 +/vendor/bin/some_ip_playground-service u:object_r:some_ip_playground-service_exec:s0 diff --git a/device/profusion/sepolicy/daemon/someip.te b/device/profusion/sepolicy/daemon/someip.te new file mode 100644 index 0000000..6930bd8 --- /dev/null +++ b/device/profusion/sepolicy/daemon/someip.te @@ -0,0 +1,12 @@ +type some_ip_playground-service, domain; +type some_ip_playground-service_exec, exec_type, file_type, vendor_file_type; + +init_daemon_domain(some_ip_playground-service) + +allow some_ip_playground-service sysfs:file { open read }; +allow some_ip_playground-service vendor_data_file:dir { add_name remove_name write }; +allow some_ip_playground-service vendor_data_file:file { create open read write lock }; +allow some_ip_playground-service vendor_data_file:sock_file { create setattr read write unlink}; +allow some_ip_playground-service self:netlink_route_socket { create bind shutdown nlmsg_read nlmsg_readpriv read write }; +allow some_ip_playground-service self:tcp_socket create; +allow some_ip_playground-service self:udp_socket { create ioctl }; diff --git a/doc/SOME-IP-HAL.md b/doc/SOME-IP-HAL.md new file mode 100644 index 0000000..334406e --- /dev/null +++ b/doc/SOME-IP-HAL.md @@ -0,0 +1,105 @@ +# HAL with SOME/IP and CommonAPI +The idea is that at some moment this repository also contains an implementation of a HAL that uses SOME/IP (through CommonAPI). The `hardware/implementations/some_ip_hal` directory already has some files related to the PlaygroundService, which will provide some mocked data through SOME/IP. +This PlaygroundService module is based on the implementation that can be found at [test-someip-service](https://github.com/COVESA/test-someip-service). + +## About version + +In this implementation, we use `capicxx-someip-runtime`, `capicxx-core-runtime`, and respective generators at version `3.2.0`. This version was chosen because we faced some problems when trying to compile the most recent versions, due to the vsomeip that comes with AOSP on API 34 don't have the rule to make `libsomeip3_dlt` and `libboost_log`, which are dependencies required by versions `<3.2.3`. + +## CommonAPI Files +At this documentation, I will not go deeper into CommonAPI framework concepts. If you want to know more about it, please refer to the [CommonAPI documentation](https://covesa.github.io/capicxx-core-tools/). + +#### `hardware/implementation/some_ip_hal/franca` +This directory contains the Franca files that will be used to generate the CommonAPI files. The `.fdepl` and `.fidl` files here are strictly the same as the ones used in [test-someip-service](https://github.com/COVESA/test-someip-service). These files define how CommonAPI should generate files to provide information about a vehicle, such as speed, gear, fuel level, etc. + +#### `hardware/implementation/some_ip_hal/default/playground_service/mock` +This directory contains the mock values that will be used by the PlaygroundService to provide information about the vehicle. + +#### `hardware/implementation/some_ip_hal/default/include` +This directory will contain the generated CommonAPI files. Commands to generate these files are shown below. + +#### `hardware/implementation/some_ip_hal/default/playground_service/PlaygroundStubImpl.cpp` and `hardware/implementation/some_ip_hal/default/playground_service/PlaygroundStubImpl.hpp` +These files contain the implementation to `PlaygroundStubDefault`, which is basically the class that will provide the information about the vehicle to the PlaygroundService. Note that in `PlaygroundStubImpl.hpp` all the attributes come from the `Mock` class. + +#### `hardware/implementation/some_ip_hal/default/playground_service/PlaygroundService.cpp` +```cpp +... +using namespace std; + +int main() { + std::cout << "SOMEIPPlayground: Successfully Registered Service!" << std::endl; + std::shared_ptr runtime = CommonAPI::Runtime::get(); + std::shared_ptr playgroundService = + std::make_shared(); + runtime->registerService("local", "1", playgroundService); + std::cout << "SOMEIPPlayground: Successfully Registered Service!" << std::endl; + + while (true) { + playgroundService->updateTankVolume(); + playgroundService->monitorTankLevel(); + std::cout << "SOMEIPPlayground: Waiting for calls..." << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + return 0; + } +``` + +This file contains the main function of the PlaygroundService. The principal responsibility of this file is to register a service using the `PlaygroundStubImpl`. Also, this main function will loop indefinitely simulating the vehicle use, and updating the tank volume. + +### Generating CommonAPI Files + +Since you already cloned the necessary libs using `fetch_someip_libs.sh`, generate CommonAPI is very simple. To generate core files run: + +```bash +./libs/someip-generators/commonapi_core_generator/commonapi-core-generator-linux-x86 -nv -sk \ +--dest "hardware/implementations/some_ip_hal/default/include" \ +hardware/implementations/some_ip_hal/franca/instances/org.genivi.vehicle.playground.fdepl +``` + +And to generate SOME/IP files run: + +```bash +./libs/someip-generators/commonapi_someip_generator/commonapi-someip-generator-linux-x86 -nv \ +--dest "hardware/implementations/some_ip_hal/default/include" \ +hardware/implementations/some_ip_hal/franca/instances/org.genivi.vehicle.playground.fdepl +``` + +### Its necessary to start the service manualy? +No, the service will be started automatically through the `some_ip_playground-init.rc` file at Android boot: + +``` +service some_ip_playground-service /vendor/bin/some_ip_playground-service + class main + user none + group none + disabled + setenv VSOMEIP_APPLICATION_NAME playground-service + setenv VSOMEIP_CONFIGURATION /vendor/etc/some_ip_playground/vsomeip.json + setenv VSOMEIP_BASE_PATH /data/vendor/vsomeip/ + +on property:sys.boot_completed=1 + mkdir /data/vendor/vsomeip 0771 none none + start some_ip_playground-service +``` + +This file defines the necessary environment variables to start the service and also starts the service when the property `sys.boot_completed` is set to 1. Another important part is to create the directory `/data/vendor/vsomeip` where the vsomeip files will be located. This path will also be important when starting our HAL. + +## Verify if Playground Service is running + +To verify if the Playground Service is running, you can check the logcat output. With the emulator running, open a terminal and run this command: + +```bash +adb shell logcat | grep some_ip +``` + +If the output is something like that, everything is working fine: + +![Logcat of some_ip](../assets/playground_service_log.png "Logcat of some_ip") + +## Next steps + +The next step is to implement the HAL that will communicate with the Playground Service. Probably, the first step is to create a class responsible for instantiating and handling the communication with `PlaygroundSomeIPProxy`, as it will be more sophisticated than handling everything in the HAL. + +About the HAL, I would say that this implementation could be a good opportunity to understand how to communicate between application and the HAL using callbacks since it's a common pattern in Android development. Maybe register a callback to receive the car information updated by a loop in the Playground Service or something like that. + +Another thing that is not exactly clear to me is if we should expose the AIDL interface from HAL in the sdk-addon to get a return of types and not only strings from the Manager or if we should create a new AIDL interface under the `packages` directory and map between the two interfaces. I think that this is an important point to discuss and understand the best approach. diff --git a/hardware/implementations/some_ip_hal/.gitignore b/hardware/implementations/some_ip_hal/.gitignore new file mode 100644 index 0000000..d43c532 --- /dev/null +++ b/hardware/implementations/some_ip_hal/.gitignore @@ -0,0 +1 @@ +default/include/* diff --git a/hardware/implementations/some_ip_hal/default/Android.bp b/hardware/implementations/some_ip_hal/default/Android.bp new file mode 100644 index 0000000..9fe380e --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/Android.bp @@ -0,0 +1,55 @@ +cc_defaults { + name: "some_ip_playground-defaults", + vendor: true, + rtti: true, + cppflags: [ + "-fexceptions", + "-Wall", + "-Werror", + "-Wno-ignored-attributes", + "-Wno-unused-parameter", + "-Wno-overloaded-virtual", + "-DCOMMONAPI_INTERNAL_COMPILATION", + ], + + shared_libs: [ + "libvsomeip3-cfg", + "libvsomeip3", + "libCommonAPI", + "libCommonAPI-SomeIP", + "libbase", + ], +} + +runtime_required = [ + "some_ip_playground-vsomeip.json", +] + +prebuilt_etc { + name: "some_ip_playground-vsomeip.json", + vendor: true, + sub_dir: "some_ip_playground", + src: "vsomeip.json", + filename:"vsomeip.json" +} + +cc_binary { + name: "some_ip_playground-service", + defaults: [ + "some_ip_playground-defaults", + ], + init_rc: ["playground_service/some_ip_playground-init.rc"], + local_include_dirs: [ + "playground_service/mock", + "include", + ], + srcs: [ + "playground_service/PlaygroundService.cpp", + "playground_service/PlaygroundStubImpl.cpp", + "include/v1/org/genivi/vehicle/playground/PlaygroundSomeIPDeployment.cpp", + "include/v1/org/genivi/vehicle/playground/PlaygroundSomeIPStubAdapter.cpp", + "playground_service/mock/MockedAttributes.cpp", + ], + required: runtime_required, + vendor: true, +} diff --git a/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundService.cpp b/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundService.cpp new file mode 100644 index 0000000..c783203 --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundService.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), + * Author: Alexander Domin (Alexander.Domin@bmw.de) + * Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, + * Author: Leandro Ferlin (leandroferlin@profusion.mobi) + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was + * not distributed with this file, You can obtain one at + * http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include +#include "PlaygroundStubImpl.hpp" + +using namespace std; + +int main() { + std::cout << "SOMEIPPlayground: Successfully Registered Service!" << std::endl; + std::shared_ptr runtime = CommonAPI::Runtime::get(); + std::shared_ptr playgroundService = + std::make_shared(); + runtime->registerService("local", "1", playgroundService); + std::cout << "SOMEIPPlayground: Successfully Registered Service!" << std::endl; + + while (true) { + playgroundService->updateTankVolume(); + playgroundService->monitorTankLevel(); + std::cout << "SOMEIPPlayground: Waiting for calls..." << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + return 0; + } + \ No newline at end of file diff --git a/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.cpp b/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.cpp new file mode 100644 index 0000000..1c9d608 --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), + * Author: Alexander Domin (Alexander.Domin@bmw.de) + * Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, + * Author: Leandro Ferlin (leandroferlin@profusion.mobi) + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was + * not distributed with this file, You can obtain one at + * http://mozilla.org/MPL/2.0/. + */ + +#include "PlaygroundStubImpl.hpp" +#include "mock/MockedAttributes.hpp" +#include +#include +#include +#include +#include +#include + +typedef v1_0::org::genivi::vehicle::playground::PlaygroundStubDefault + PlaygroundStubDefault; + +PlaygroundStubImpl::PlaygroundStubImpl() + : consumption{}, capacity{}, volume{}, engineSpeed{}, currentGear{}, + isReverseGearOn{}, drivePowerTransmission{}, doorsOpeningStatus{}, + seatHeatingStatus{}, seatHeatingLevel{} { + initializeAttributes(); +} +PlaygroundStubImpl::~PlaygroundStubImpl() {} + +void PlaygroundStubImpl::initializeAttributes() { + PlaygroundStubDefault::setConsumptionAttribute(consumption.getValue()); + PlaygroundStubDefault::setCapacityAttribute(capacity.getValue()); + PlaygroundStubDefault::setVolumeAttribute(volume.getValue()); + PlaygroundStubDefault::setEngineSpeedAttribute(engineSpeed.getValue()); + PlaygroundStubDefault::setCurrentGearAttribute(currentGear.getValue()); + PlaygroundStubDefault::setIsReverseGearOnAttribute( + isReverseGearOn.getValue()); + PlaygroundStubDefault::setDrivePowerTransmissionAttribute( + drivePowerTransmission.getValue()); + PlaygroundStubDefault::setDoorsOpeningStatusAttribute( + doorsOpeningStatus.getValue()); + PlaygroundStubDefault::setSeatHeatingStatusAttribute( + seatHeatingStatus.getValue()); + PlaygroundStubDefault::setSeatHeatingLevelAttribute( + seatHeatingLevel.getValue()); +} + +void PlaygroundStubImpl::updateTankVolume() { + const float currentVolume = PlaygroundStubDefault::getVolumeAttribute(); + float updatedVolume; + if (currentVolume > 0.0) { + updatedVolume = currentVolume - 0.1; + } else { + updatedVolume = capacity.getCapacityInLiters(); + } + PlaygroundStubDefault::setVolumeAttribute(updatedVolume); +} + +void PlaygroundStubImpl::monitorTankLevel() { + const double capacityInLiters = capacity.getCapacityInLiters(); + const int currentVolume = PlaygroundStubDefault::getVolumeAttribute(); + + const uint8_t &level = (uint8_t)(100 * currentVolume / capacityInLiters); + fireCurrentTankVolumeEvent(level); +} + +void PlaygroundStubImpl::changeDoorsState( + const std::shared_ptr _client, + CarDoorsCommand _commands, changeDoorsStateReply_t _reply) { + + DoorsStatus lockedDoorsStatus = + PlaygroundStubDefault::getDoorsOpeningStatusAttribute(); + + const bool ¤tFrontLeftState = lockedDoorsStatus.getFrontLeft(); + const bool ¤tFrontRightState = lockedDoorsStatus.getFrontRight(); + const bool ¤tRearLeftState = lockedDoorsStatus.getRearLeft(); + const bool ¤tRearRightState = lockedDoorsStatus.getRearRight(); + + const DoorCommand &frontLeftCommand = _commands.getFrontLeftDoor(); + const DoorCommand &frontRightCommand = _commands.getFrontRightDoor(); + const DoorCommand &rearLeftCommand = _commands.getRearLeftDoor(); + const DoorCommand &rearRightCommand = _commands.getRearRightDoor(); + + const bool &nextFrontLeftState = doorsOpeningStatus.getNextStateFromCommand( + currentFrontLeftState, frontLeftCommand); + const bool &nextFrontRightState = doorsOpeningStatus.getNextStateFromCommand( + currentFrontRightState, frontRightCommand); + const bool &nextRearLeftState = doorsOpeningStatus.getNextStateFromCommand( + currentRearLeftState, rearLeftCommand); + const bool &nextRearRightState = doorsOpeningStatus.getNextStateFromCommand( + currentRearRightState, rearRightCommand); + + const DoorsStatus &doorsStatus = + DoorsStatus(nextFrontLeftState, nextFrontRightState, nextRearLeftState, + nextRearRightState); + + PlaygroundStubDefault::setDoorsOpeningStatusAttribute(doorsStatus); + _reply(); +}; diff --git a/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.hpp b/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.hpp new file mode 100644 index 0000000..37cf045 --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.hpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), + * Author: Alexander Domin (Alexander.Domin@bmw.de) + * Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, + * Author: Leandro Ferlin (leandroferlin@profusion.mobi) + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was + * not distributed with this file, You can obtain one at + * http://mozilla.org/MPL/2.0/. + */ + +#ifndef PLAYGROUNDSTUBIMPL_H_ +#define PLAYGROUNDSTUBIMPL_H_ +#include +#include +#include + +#include "mock/MockedAttributes.hpp" + +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::Gear Gear; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::DoorsStatus + DoorsStatus; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::DriveType + DriveType; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::DoorCommand + DoorCommand; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes:: + CarDoorsCommand CarDoorsCommand; +typedef CommonAPI::Event CurrentTankVolumeEvent; + +class PlaygroundStubImpl + : public v1_0::org::genivi::vehicle::playground::PlaygroundStubDefault { +private: + Mock::Consumption consumption; + Mock::Capacity capacity; + Mock::Volume volume; + Mock::EngineSpeed engineSpeed; + Mock::CurrentGear currentGear; + Mock::IsReverseGearOn isReverseGearOn; + Mock::DrivePowerTransmission drivePowerTransmission; + Mock::DoorsOpeningStatus doorsOpeningStatus; + Mock::SeatHeatingStatus seatHeatingStatus; + Mock::SeatHeatingLevel seatHeatingLevel; + +public: + PlaygroundStubImpl(); + virtual ~PlaygroundStubImpl(); + + void initializeAttributes(); + + void updateTankVolume(); + + void monitorTankLevel(); + + virtual void + changeDoorsState(const std::shared_ptr _client, + CarDoorsCommand _commands, changeDoorsStateReply_t _reply); +}; +#endif /* PLAYGROUNDSTUBIMPL_H_ */ diff --git a/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedAttributes.cpp b/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedAttributes.cpp new file mode 100644 index 0000000..2921d0b --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedAttributes.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), + * Author: Alexander Domin (Alexander.Domin@bmw.de) + * Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, + * Author: Leandro Ferlin (leandroferlin@profusion.mobi) + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was + * not distributed with this file, You can obtain one at + * http://mozilla.org/MPL/2.0/. + */ + +#include "MockedAttributes.hpp" +#include + +namespace Mock { + +Consumption::Consumption(float v) : MockedValue{v} {}; + +Consumption::Consumption() : MockedValue{4.5} {}; + +Capacity::Capacity(uint8_t v, double minValue, double maxValue, + double maxValueInMilliliters) + : MockedValue{v}, m_MinValue(minValue), m_MaxValue(maxValue), + m_MaxValueInMilliliters(maxValueInMilliliters){}; + +Capacity::Capacity(uint8_t v) + : MockedValue{v}, m_MinValue(0.0), m_MaxValue(255.0), + m_MaxValueInMilliliters(80000.0){}; + +Capacity::Capacity() + : MockedValue{200}, m_MinValue(0.0), m_MaxValue(255.0), + m_MaxValueInMilliliters(80000.0){}; + +double Capacity::getMinValue() { return m_MinValue; } + +double Capacity::getMaxValue() { return m_MaxValue; } + +double Capacity::getMaxValueInMilliliters() { return m_MaxValueInMilliliters; } + +double Capacity::getCapacityInLiters() { + return m_MaxValueInMilliliters * (value / (m_MaxValue - m_MinValue)) / 1000; +} + +Volume::Volume(float v) : MockedValue{v} {}; + +Volume::Volume() : MockedValue{60.8} {}; + +EngineSpeed::EngineSpeed(uint16_t v) : MockedValue{v} {}; + +EngineSpeed::EngineSpeed() : MockedValue{2000} {}; + +CurrentGear::CurrentGear(Gear v) : MockedValue{v} {}; + +CurrentGear::CurrentGear() + : MockedValue{Gear(Gear::Literal::FOURTH_GEAR)} {}; + +IsReverseGearOn::IsReverseGearOn(bool v) : MockedValue{v} {}; + +IsReverseGearOn::IsReverseGearOn() : MockedValue{false} {}; + +DrivePowerTransmission::DrivePowerTransmission(DriveType v) + : MockedValue{v} {}; + +DrivePowerTransmission::DrivePowerTransmission() + : MockedValue{ + DriveType(DriveType::Literal::REAR_WHEEL_DRIVE)} {}; + +DoorsOpeningStatus::DoorsOpeningStatus(DoorsStatus v) + : MockedValue{v} {}; + +DoorsOpeningStatus::DoorsOpeningStatus() + : MockedValue{DoorsStatus(true, false, false, false)} {}; + +bool DoorsOpeningStatus::getNextStateFromCommand(const bool ¤tState, + const DoorCommand &command) { + if (command == DoorCommand::Literal::NOTHING) { + return currentState; + } + return (command == DoorCommand::Literal::OPEN_DOOR); +} + +SeatHeatingStatus::SeatHeatingStatus(std::vector v) + : MockedValue>{v} {}; + +SeatHeatingStatus::SeatHeatingStatus() + : MockedValue>{ + {true, true, false, true, false, true, false}} {}; + +SeatHeatingLevel::SeatHeatingLevel(std::vector v) + : MockedValue>{v} {}; + +SeatHeatingLevel::SeatHeatingLevel() + : MockedValue>{{50, 45, 30, 30, 60, 65, 70}} {}; + +} // namespace Mock diff --git a/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedAttributes.hpp b/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedAttributes.hpp new file mode 100644 index 0000000..52f68d0 --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedAttributes.hpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), + * Author: Alexander Domin (Alexander.Domin@bmw.de) + * Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, + * Author: Leandro Ferlin (leandroferlin@profusion.mobi) + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was + * not distributed with this file, You can obtain one at + * http://mozilla.org/MPL/2.0/. + */ + +#ifndef CONSUMPTION_H_ +#define CONSUMPTION_H_ + +#include "MockedValue.hpp" +#include +#include +#include + +namespace Mock { + +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::Gear Gear; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::DoorsStatus + DoorsStatus; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::DriveType + DriveType; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes::DoorCommand + DoorCommand; +typedef ::org::genivi::vehicle::playgroundtypes::PlaygroundTypes:: + CarDoorsCommand CarDoorsCommand; +typedef CommonAPI::Event CurrentTankVolumeEvent; + +class Consumption : public MockedValue { + +public: + Consumption(float v); + Consumption(); +}; + +class Capacity : public MockedValue { + +private: + const double m_MinValue; + const double m_MaxValue; + const double m_MaxValueInMilliliters; + +public: + Capacity(uint8_t v, double minValue, double maxValue, + double maxValueInMilliliters); + Capacity(uint8_t v); + Capacity(); + + double getMinValue(); + double getMaxValue(); + double getMaxValueInMilliliters(); + double getCapacityInLiters(); +}; + +class Volume : public MockedValue { + +public: + Volume(float v); + Volume(); +}; + +class EngineSpeed : public MockedValue { + +public: + EngineSpeed(uint16_t v); + EngineSpeed(); +}; + +class CurrentGear : public MockedValue { + +public: + CurrentGear(Gear v); + CurrentGear(); +}; + +class IsReverseGearOn : public MockedValue { + +public: + IsReverseGearOn(bool v); + IsReverseGearOn(); +}; + +class DrivePowerTransmission : public MockedValue { + +public: + DrivePowerTransmission(DriveType v); + DrivePowerTransmission(); +}; + +class DoorsOpeningStatus : public MockedValue { + +public: + DoorsOpeningStatus(DoorsStatus v); + DoorsOpeningStatus(); + + bool getNextStateFromCommand(const bool ¤tState, + const DoorCommand &command); + bool getNextStateFromCommand(); +}; + +class SeatHeatingStatus : public MockedValue> { + +public: + SeatHeatingStatus(std::vector v); + SeatHeatingStatus(); +}; + +class SeatHeatingLevel : public MockedValue> { + +public: + SeatHeatingLevel(std::vector v); + SeatHeatingLevel(); +}; + +} // namespace Mock + +#endif diff --git a/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedValue.hpp b/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedValue.hpp new file mode 100644 index 0000000..663a18b --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/mock/MockedValue.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), + * Author: Alexander Domin (Alexander.Domin@bmw.de) + * Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, + * Author: Leandro Ferlin (leandroferlin@profusion.mobi) + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was + * not distributed with this file, You can obtain one at + * http://mozilla.org/MPL/2.0/. + */ + +#ifndef MOCKED_VALUE_H_ +#define MOCKED_VALUE_H_ + +template class MockedValue { +protected: + T value; + +public: + MockedValue(T v) : value(v) {} + + T getValue() { return value; } +}; + +#endif diff --git a/hardware/implementations/some_ip_hal/default/playground_service/some_ip_playground-init.rc b/hardware/implementations/some_ip_hal/default/playground_service/some_ip_playground-init.rc new file mode 100644 index 0000000..f7b7a4d --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/playground_service/some_ip_playground-init.rc @@ -0,0 +1,12 @@ +service some_ip_playground-service /vendor/bin/some_ip_playground-service + class main + user none + group none + disabled + setenv VSOMEIP_APPLICATION_NAME playground-service + setenv VSOMEIP_CONFIGURATION /vendor/etc/some_ip_playground/vsomeip.json + setenv VSOMEIP_BASE_PATH /data/vendor/vsomeip/ + +on property:sys.boot_completed=1 + mkdir /data/vendor/vsomeip 0771 none none + start some_ip_playground-service diff --git a/hardware/implementations/some_ip_hal/default/vsomeip.json b/hardware/implementations/some_ip_hal/default/vsomeip.json new file mode 100644 index 0000000..7a896d8 --- /dev/null +++ b/hardware/implementations/some_ip_hal/default/vsomeip.json @@ -0,0 +1,21 @@ +{ + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "false" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "playground-service", + "id" : "0x4444" + } + ], + "routing" : "playground-service", + "service-discovery" : + { + "enable" : "false" + } +} diff --git a/hardware/implementations/some_ip_hal/franca/instances/org.genivi.vehicle.playground.fdepl b/hardware/implementations/some_ip_hal/franca/instances/org.genivi.vehicle.playground.fdepl new file mode 100644 index 0000000..8ed2b8c --- /dev/null +++ b/hardware/implementations/some_ip_hal/franca/instances/org.genivi.vehicle.playground.fdepl @@ -0,0 +1,28 @@ +/* +* Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), +* Author: Alexander Domin (Alexander.Domin@bmw.de) +* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, +* Author: Leonardo Ramos (leo.ramos@profusion.mobi) +* +* SPDX-License-Identifier: MPL-2.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was +* not distributed with this file, You can obtain one at +* http://mozilla.org/MPL/2.0/. +*/ + +import "platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-SOMEIP_deployment_spec.fdepl" +import "../org/genivi/vehicle/playground.fdepl" +import "../org/genivi/vehicle/playground.fidl" + +define org.genivi.commonapi.someip.deployment for provider as +org.genivi.vehicle.playground { + instance org.genivi.vehicle.playground.Playground as PlaygroundInst1 { + SomeIpInstanceID = 1 + InstanceId = "1" + SomeIpUnicastAddress = "" + SomeIpReliableUnicastPort = 0 + SomeIpUnreliableUnicastPort = 0 + } +} diff --git a/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playground.fdepl b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playground.fdepl new file mode 100644 index 0000000..aabcb82 --- /dev/null +++ b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playground.fdepl @@ -0,0 +1,120 @@ +/* +* Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), +* Author: Alexander Domin (Alexander.Domin@bmw.de) +* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, +* Author: Leonardo Ramos (leo.ramos@profusion.mobi) +* +* SPDX-License-Identifier: MPL-2.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was +* not distributed with this file, You can obtain one at +* http://mozilla.org/MPL/2.0/. +*/ + +import +"platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-4-SOMEIP_deployment_spec.fdepl" +import "playground.fidl" +import "playgroundTypes.fidl" +import "playgroundTypes.fdepl" + +define org.genivi.commonapi.someip.deployment for interface +org.genivi.vehicle.playground.Playground { + SomeIpServiceID = 65344 + + attribute consumption { + SomeIpGetterID = 1 + SomeIpNotifierID = 32769 + SomeIpNotifierEventGroups = { + 1 + } + } + + attribute capacity { + SomeIpGetterID = 2 + } + + attribute volume { + SomeIpGetterID = 3 + } + + attribute engineSpeed { + SomeIpGetterID = 4 + SomeIpNotifierID = 32770 + SomeIpNotifierEventGroups = { + 2 + } + } + + attribute currentGear { + SomeIpGetterID = 5 + SomeIpNotifierID = 32771 + SomeIpNotifierEventGroups = { + 3 + } + } + + attribute isReverseGearOn { + SomeIpGetterID = 6 + SomeIpNotifierID = 32772 + SomeIpNotifierEventGroups = { + 4 + } + } + + attribute drivePowerTransmission { + SomeIpGetterID = 7 + SomeIpNotifierID = 32773 + SomeIpNotifierEventGroups = { + 5 + } + } + + attribute doorsOpeningStatus { + SomeIpGetterID = 8 + SomeIpNotifierID = 32774 + SomeIpNotifierEventGroups = { + 6 + } + } + + attribute seatHeatingStatus { + SomeIpGetterID = 9 + SomeIpSetterID = 10 + SomeIpNotifierID = 32775 + SomeIpNotifierEventGroups = { + 7 + } + } + + attribute seatHeatingLevel { + SomeIpGetterID = 11 + SomeIpSetterID = 12 + SomeIpNotifierID = 32776 + SomeIpNotifierEventGroups = { + 8 + } + } + + method initTirePressureCalibration { + SomeIpMethodID = 13 + } + + method changeDoorsState { + SomeIpMethodID = 14 + } + + broadcast vehiclePosition { + SomeIpEventID = 32777 + SomeIpEventGroups = { + 9 + } + } + + broadcast currentTankVolume { + SomeIpEventID = 32778 + SomeIpEventGroups = { + 10 + } + } +} diff --git a/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playground.fidl b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playground.fidl new file mode 100644 index 0000000..abfc1b8 --- /dev/null +++ b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playground.fidl @@ -0,0 +1,118 @@ +/* +* Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), +* Author: Alexander Domin (Alexander.Domin@bmw.de) +* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, +* Author: Leonardo Ramos (leo.ramos@profusion.mobi) +* +* SPDX-License-Identifier: MPL-2.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was +* not distributed with this file, You can obtain one at +* http://mozilla.org/MPL/2.0/. +*/ + +package org.genivi.vehicle.playground + import org.genivi.vehicle.playgroundtypes.* from "playgroundTypes.fidl" + interface Playground { + version { + major 1 + minor 0 + } + <** + @description : Current consumption in liters per 100 km + **> + attribute Float consumption readonly + <** + @description : Capacity of the fuel tank in milliliters + Unit: ml + **> + attribute UInt8 capacity readonly noSubscriptions + <** + @description : Current volume of fuel in the tank in liters + **> + attribute Float volume readonly noSubscriptions + <** + @description : Engine speed measured as rotations per minute + **> + attribute UInt16 engineSpeed readonly + <** + @description : Current gear + **> + attribute PlaygroundTypes.Gear currentGear readonly + <** + @description : Is reverse gear selected + **> + attribute Boolean isReverseGearOn readonly + <** + @description : Drive Type + **> + attribute PlaygroundTypes.DriveType drivePowerTransmission readonly + <** + @description : Report the opening status for each door + **> + attribute PlaygroundTypes.DoorsStatus doorsOpeningStatus readonly + <** + @description : Describes the seat heating status set by the user. + index 0 == Driver + index 1 == Co-Driver + index 3 == Passenger in the second row on the Driver side + index 4 == Passenger in the second row on the Middle side + index 5 == Passenger in the second row on the Co-driver side + index 6 == Passenger in the third row on the Driver side + index 7 == Passenger in the third row on the Co-driver side + Just for demo the some SomeIP service will return values for Driver and Co-Driver only + **> + attribute Boolean [] seatHeatingStatus + <** + @description : Describes the seat heating level selected by the user + index 0 == Driver + index 1 == Co-Driver + index 3 == Passenger in the second row on the Driver side + index 4 == Passenger in the second row on the Middle side + index 5 == Passenger in the second row on the Co-driver side + index 6 == Passenger in the third row on the Driver side + index 7 == Passenger in the third row on the Co-driver side + Just for demo the some SomeIP service will return values for Driver and Co-Driver only + **> + attribute UInt8 [] seatHeatingLevel + <** + @description : Trigger tire pressure initialization process + **> + method initTirePressureCalibration { + } + <** + @description : Trigger the change on doors opening state + **> + method changeDoorsState { + in { + <** + @description : Commands for closing or opening the doors. + **> + PlaygroundTypes.CarDoorsCommand commands + } + } + <** + @description : Vehicle position data provided by GPS + **> + broadcast vehiclePosition { + out { + <** + @description : The structure containg the GPS data status informations + **> + PlaygroundTypes.StatusGPS statusGPS + } + } + <** + @description : The current tank volume + **> + broadcast currentTankVolume { + out { + <** + @description : Current tank volume in liters + Unit: l + **> + UInt8 volume + } + } +} diff --git a/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playgroundTypes.fdepl b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playgroundTypes.fdepl new file mode 100644 index 0000000..2202c0f --- /dev/null +++ b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playgroundTypes.fdepl @@ -0,0 +1,51 @@ +/* +* Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), +* Author: Alexander Domin (Alexander.Domin@bmw.de) +* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, +* Author: Leonardo Ramos (leo.ramos@profusion.mobi) +* +* SPDX-License-Identifier: MPL-2.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was +* not distributed with this file, You can obtain one at +* http://mozilla.org/MPL/2.0/. +*/ + +import +"platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-4-SOMEIP_deployment_spec.fdepl" +import "playgroundTypes.fidl" + +define org.genivi.commonapi.someip.deployment for typeCollection +org.genivi.vehicle.playgroundtypes.PlaygroundTypes { + + enumeration Gear { + } + + enumeration DriveType { + } + + struct GPSDate { + } + + struct GPSTime { + } + + struct GPSPosition { + } + + struct StatusGPS { + } + + struct DoorsStatus { + } + + enumeration DoorsID { + } + + enumeration DoorCommand { + } + + struct CarDoorsCommand { + } +} diff --git a/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playgroundTypes.fidl b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playgroundTypes.fidl new file mode 100644 index 0000000..ad9090d --- /dev/null +++ b/hardware/implementations/some_ip_hal/franca/org/genivi/vehicle/playgroundTypes.fidl @@ -0,0 +1,217 @@ +/* +* Copyright (C) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG), +* Author: Alexander Domin (Alexander.Domin@bmw.de) +* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, +* Author: Leonardo Ramos (leo.ramos@profusion.mobi) +* +* SPDX-License-Identifier: MPL-2.0 +* +* This Source Code Form is subject to the terms of the +* Mozilla Public License, v. 2.0. If a copy of the MPL was +* not distributed with this file, You can obtain one at +* http://mozilla.org/MPL/2.0/. +*/ + +package org.genivi.vehicle.playgroundtypes + typeCollection PlaygroundTypes { + <** + @description : The gear enumaration value + **> + enumeration Gear { + <** + @description : The unit is being initialized + **> + UNKNOWN_GEAR = 0 + <** + @description : No gear is selected. + **> + NEUTRAL = 1 + <** + @description : First gear is selected. + **> + FIRST_GEAR = 2 + <** + @description : Second gear is selected. + **> + SECOND_GEAR = 3 + <** + @description : Third gear is selected. + **> + THIRD_GEAR = 4 + <** + @description : Fourth gear is selected. + **> + FOURTH_GEAR = 5 + <** + @description : Fifth gear is selected. + **> + FIFTH_GEAR = 6 + <** + @description : Sixth gear is selected. + **> + SIXTH_GEAR = 7 + <** + @description : The gear sensor is reporting an error + **> + ERROR = 8 + } + + <** + @description : Drive Type, + **> + enumeration DriveType { + <** + @description : Power transmission drive on front axle + **> + FRONT_WHEEL_DRIVE = 1 + <** + @description : Power transmission drive on rear axle + **> + REAR_WHEEL_DRIVE = 2 + <** + @description : Power transmission drive on front and rear axles + **> + ALL_WHEEL_DRIVE = 3 + } + + struct GPSDate { + <** + @description : The current day provided by GPS + **> + UInt8 day + <** + @description : The current month provided by GPS + **> + UInt8 month + <** + @description : The current year provided by GPS + **> + UInt16 year + } + + struct GPSTime { + <** + @description : Time seconds provided by GPS + **> + UInt8 second + <** + @description : Time minutes provided by GPS + **> + UInt8 minute + <** + @description : Time hours provided by GPS + **> + UInt8 hour + } + + struct GPSPosition { + <** + @description : The current latitude coordinates of the vehicle + **> + Double currentLatitude + <** + @description : The current longitude coordinates of the vehicle + **> + Double currentLongitude + <** + @description : The current altitude coordinates of the vehicle + **> + Double currentAltitude + } + + struct StatusGPS { + <** + @description : GPS status date + **> + GPSDate statusGPSDate + <** + @description : GPS status time + **> + GPSTime statusGPSTime + <** + @description : GPS status position + **> + GPSPosition statusfGPSPosition + } + + struct DoorsStatus { + <** + @description : The opening status of the front left door + **> + Boolean frontLeft + <** + @description : The opening status of the front right door + **> + Boolean frontRight + <** + @description : The opening status of the rear left door + **> + Boolean rearLeft + <** + @description : The opening status of the rear right door + **> + Boolean rearRight + } + + <** + @description : The gear enumaration value + **> + enumeration DoorsID { + <** + @description : Front left door + **> + FRONT_LEFT = 0 + <** + @description : Front right door + **> + FRONT_RIGHT = 1 + <** + @description : Rear left door + **> + REAR_LEFT = 2 + <** + @description : Rear right door + **> + REAR_RIGHT = 3 + } + + <** + @description : Command to define the opening state of doors + **> + enumeration DoorCommand { + <** + @description : Command for keeping the current door state + **> + NOTHING = 0 + <** + @description : Command for opening the door + **> + OPEN_DOOR = 1 + <** + @description : Command for closing the door + **> + CLOSE_DOOR = 2 + } + + <** + @description : All the doors opening state for the vehicle + **> + struct CarDoorsCommand { + <** + @description : Front left door command + **> + DoorCommand frontLeftDoor + <** + @description : Front right door command + **> + DoorCommand frontRightDoor + <** + @description : Rear left door command + **> + DoorCommand rearLeftDoor + <** + @description : Rear right door command + **> + DoorCommand rearRightDoor + } +}