Skip to content

Commit

Permalink
feat: create SOME/IP provider service
Browse files Browse the repository at this point in the history
- Create a service based on https://github.com/COVESA/test-someip-service
and respective config files;
- Also, add a .md with simple instructions on how to generate CommonAPI
files and run the service inside the emulator;
  • Loading branch information
MaironLucas committed Jan 24, 2025
1 parent 33f2d1b commit ece2ba4
Show file tree
Hide file tree
Showing 20 changed files with 1,120 additions and 6 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@ This repository contains the code to build an emulator image containing the **he
* `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. 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
./fetch_someip_libs.sh
./add_to_aosp.sh /pathTo/aosp
```

If you use VSCode, you can use [Run on Save](https://marketplace.visualstudio.com/items?itemName=emeraldwalk.RunOnSave) to automatically update the files with this script on save.

#### 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** works. Then, feel free to take a look at the [HAL Documentation](doc/HAL.md).
This repository also contains examples of developing and using HALs through the SDK-Addon. First, focus on how the **hello-world-service** works. Then, feel free to 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

Expand Down
6 changes: 2 additions & 4 deletions device/profusion/profusion_sdk_addon/profusion_sdk_addon.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions device/profusion/sepolicy/daemon/file_contexts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/vendor/bin/hw/profusion.hardware.dummy_car_info_hal-service u:object_r:dummy_car_info_hal_exec:s0
/vendor/bin/hw/some_ip_playground-service u:object_r:some_ip_hal_exec:s0
9 changes: 9 additions & 0 deletions device/profusion/sepolicy/daemon/someip.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type some_ip_hal, domain;
type some_ip_hal_exec, exec_type, file_type, vendor_file_type;

init_daemon_domain(some_ip_hal)

allow system_app some_ip_hal:binder { call };
allow platform_app some_ip_hal:binder { call };

domain_auto_trans(init, some_ip_hal_exec, some_ip_hal)
34 changes: 34 additions & 0 deletions doc/SOME-IP-HAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# HAL with SOME/IP
This repository also contains a HAL implementation using SOME/IP. The HAL is implemented in the `hardware/implementations/some_ip_hal` directory.
The SOME/IP service of this implementation is based on the implementation that can be found at [test-someip-service](https://github.com/COVESA/test-someip-service).

## Generating CommonAPI Files

Run this command to generate CommonAPI Core files:

```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
```

Run this command to generate CommonAPI SomeIP files:

```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
```

## Initialize SOME/IP Service
The service will be compiled and installed in the `vendor/bin` directory. To execute it, you will need to access the ADB Shell of the emulator generated onto AOSP. While running the emulator, type this command:

```bash
adb shell
```

Then, you can run the service using the following command:

```bash
VSOMEIP_CONFIGURATION=vendor/etc/some_ip_playground/vsomeip.json VSOMEIP_APPLICATION_NAME=playground-service ./vendor/bin/some_ip_playground-service
```
1 change: 1 addition & 0 deletions hardware/implementations/some_ip_hal/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default/include/*
56 changes: 56 additions & 0 deletions hardware/implementations/some_ip_hal/default/Android.bp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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",
],

ldflags: ["-Wl,-export-dynamic"],
}

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",
],
local_include_dirs: [
"mock",
"include",
],
srcs: [
"PlaygroundService.cpp",
"PlaygroundStubImpl.cpp",
"include/v1/org/genivi/vehicle/playground/PlaygroundSomeIPDeployment.cpp",
"include/v1/org/genivi/vehicle/playground/PlaygroundSomeIPStubAdapter.cpp",
"mock/MockedAttributes.cpp",
],
required: runtime_required,
vendor: true,
}
38 changes: 38 additions & 0 deletions hardware/implementations/some_ip_hal/default/PlaygroundService.cpp
Original file line number Diff line number Diff line change
@@ -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 <iostream>
#include <thread>
#include <CommonAPI/CommonAPI.hpp>
#include "PlaygroundStubImpl.hpp"

using namespace std;

int main() {
std::cout << "SOMEIPPlayground: Successfully Registered Service!" << std::endl;
std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get();
std::shared_ptr<PlaygroundStubImpl> playgroundService =
std::make_shared<PlaygroundStubImpl>();
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... (Abort with CTRL+C)" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return 0;
}

104 changes: 104 additions & 0 deletions hardware/implementations/some_ip_hal/default/PlaygroundStubImpl.cpp
Original file line number Diff line number Diff line change
@@ -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 <cstdint>
#include <csignal>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <sys/types.h>

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<CommonAPI::ClientId> _client,
CarDoorsCommand _commands, changeDoorsStateReply_t _reply) {

DoorsStatus lockedDoorsStatus =
PlaygroundStubDefault::getDoorsOpeningStatusAttribute();

const bool &currentFrontLeftState = lockedDoorsStatus.getFrontLeft();
const bool &currentFrontRightState = lockedDoorsStatus.getFrontRight();
const bool &currentRearLeftState = lockedDoorsStatus.getRearLeft();
const bool &currentRearRightState = 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();
};
Original file line number Diff line number Diff line change
@@ -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 <CommonAPI/CommonAPI.hpp>
#include <cstdint>
#include <v1/org/genivi/vehicle/playground/PlaygroundStubDefault.hpp>

#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<uint8_t> 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<CommonAPI::ClientId> _client,
CarDoorsCommand _commands, changeDoorsStateReply_t _reply);
};
#endif /* PLAYGROUNDSTUBIMPL_H_ */
Loading

0 comments on commit ece2ba4

Please sign in to comment.