-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create SOME/IP provider service
- 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
1 parent
e28b360
commit 7519854
Showing
21 changed files
with
1,205 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/some_ip_playground-service u:object_r:some_ip_playground-service_exec:s0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<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..." << 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
default/include/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
} |
38 changes: 38 additions & 0 deletions
38
hardware/implementations/some_ip_hal/default/playground_service/PlaygroundService.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ([email protected]) | ||
* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, | ||
* Author: Leandro Ferlin ([email protected]) | ||
* | ||
* 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..." << std::endl; | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
} | ||
return 0; | ||
} | ||
|
104 changes: 104 additions & 0 deletions
104
hardware/implementations/some_ip_hal/default/playground_service/PlaygroundStubImpl.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ([email protected]) | ||
* Copyright (C) 2021, ProFUSION Sistemas e Soluções LTDA, | ||
* Author: Leandro Ferlin ([email protected]) | ||
* | ||
* 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 ¤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(); | ||
}; |
Oops, something went wrong.