-
Notifications
You must be signed in to change notification settings - Fork 75
Draft someip-network-daemon architecture #2342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
365aafa to
0f49d88
Compare
0f49d88 to
aaf635c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: It should be "Daemon" not "Deamon"
| For resource reasons, there will be only one instance of `vsomeip_v3::application` running within the | ||
| `SOME/IP network daemon`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to calculate the E2E checksum the Request ID [Client ID | Session ID] needs to be known at the ASIL side. Therefore it would make sense to calculate the Session ID at the ASIL side. That can only be done if each ASIL client gets a separate Client ID because otherwise two ASIL clients calling the same method via SOME/IP would cause a conflict. As far as I can grasp from the documentation of vsomeip_v3::application::get_client() this would imply that the network daemon has to create a separate application object for each ASIL client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. I guess you are right :( ... the application::send(), which is used to send a request (do a message call) clearly states, that client-id/session-id is taken from the application instance. I.e. one can not explicitly hand it over per send()call!
This is really "awful" then - if the documentation of class application is right:
Due to its heavy resource footprint, it should exist once per client and can be instantiated using the API of @ref runtime. It manages the lifecycle of the vsomeip client and allocates all resources needed to communicate.
we have to swallow this pill?
| 3. The `SOME/IP network daemon` receives the message in (2) and creates the proxy from the information contained. I.e. it | ||
| issues a `score::mw::com::GenericProxy::FindService` and expects to get instantly a handle back, from which it then | ||
| creates the proxy instance. | ||
| Afterward, it is capable of accessing the event/field slots: The DATA channel is now set up. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The network daemon should send a reply. For methods it needs to create a DATA skeleton used to communicate back responses and return that LoLa instance id to the upper layer. In general it might be useful for the upper layer to know when the setup is complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By looking at the current state of this PR/doc AND your comment I feel, that the documentation/these detailed steps described, somewhat miss, what the API interface to offer a service instance with the vsomeip-app shall look like ...
I.e. it directly starts with some "internal" implementation steps, without outlining 1st, how the API shall look like, which the upper layer calls ... and since this is missing and we therefore don't know what return code/error-code we shall support, things which you are mentioning here
In general it might be useful for the upper layer to know when the setup is complete.
So maybe it makes more sense to design our vsomeip-wrapper-API signatures first?
Like:
score::Result<ServiceHandle> VsomeipWrapper::CreateService(someip_service_id, someip_instance_id, DataChannelId)
score::ResultBlank VsomeipWrapper::OfferService(ServiceHandle)
...
and then describe the expected steps been taken within these APIs...
| 2. Then the upper layer sends a message via `score::message_passing` to the `SOME/IP network daemon`, to create the | ||
| SOME/IP service instance. Thus, the message contains a tag/message-id `CreateServiceInstance`. Further payload of this | ||
| message: | ||
| - `SomeIpServiceInstanceId` describing the service instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we need more config data (event ids, event groups, ports, etc.). How do we exchange that? Should each upper layer initially send a registration message which then spins up the application instance? The registration message could contain a flatbuffer with all of the config data and the reply could contain data like the Client ID assigned to the upper layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the main message of this sequence diagram? It is a bit confusing to me. Is it maybe detailed design? Then we should remove it from here and move it to the module documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry - work in progress! This is the reason, why it isn't yet referenced from the README.md (no svg generated from it)
|
|
||
| 1. The upper layer sends a message via `score::message_passing` to the `SOME/IP network daemon`, to trigger the search/ | ||
| discovery for the service instance on the SOME/IP (network) side. Thus, the message contains a tag/message-id | ||
| `DiscoverServiceInstance`. Further payload of this message: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not call it FindService?
| `score::message_passing` to the `SOME/IP network daemon`, to push the update to the SOME/IP service instance. Thus, | ||
| the message contains a tag/message-id `UpdateEvent`. Further payload of this message: | ||
| - `SomeIpServiceInstanceId` describing the service instance. | ||
| - `EventId` describing which event/field to update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - `EventId` describing which event/field to update | |
| - `ComponentId` describing which event/field/method to update |
In AUTOSAR SOME/IP the "Method ID" is used for all of the components. Methods have a Method ID in the range [0-0x7FFF] and events/fields have a Method ID in the range [0x8000-0xFFFF]. At least that is what is the nomenclature in the AUTOSAR specification. In the Open SOME/IP specification they introduced the Method ID and Event ID which is then the AUTOSAR Method ID without the highest bit. I mean it was confusing before, but now we have the same name used for different stuff in each specification.
Possible alternative terms: MemberId, ElementId
| But since a lot of the proxy side functionality is deeply coupled with service-discovery functionality, bypassing it | ||
| seems to generate a lot of effort! Thus, we will use existing `OfferService` (skeleton) and `FindService` (proxy) | ||
| functionality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would we need to simplify this? Can we make an issue to solve that?
| We intend to use shared-memory to implement the DATA channel. Mainly because payloads listed above might be large and | ||
| using shared-memory as exchange mechanism might save copies in certain cases, which helps with performance. | ||
| Additionally: Since there are already existing building blocks for shared-memory communication either in the more high | ||
| level form of the `score::mw::com` SHM/LoLa binding or in its underlying `lib/memory/shared`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so it will be on top of mw::com and not below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. You definitely have a point here! The thing is, that - depending on the usage scenario - you get something, which smells like a "cyclic dependency", if the functionality to interface with the vsomeip-network-daemon itself relies on score::mw::com (with SHM/LoLa binding).
Let me elaborate a bit:
In the usage scenarios, where the upper layer/user of this lib is a stand-alone gateway process using score::mw::com skeletons/proxies and also using this lib:
- Generic SOME/IP Gateway Daemon
- OEM specific SOME/IP Gateway Daemon
I do not see some weird "cyclic dependency". These gateway daemon apps/processes, will use score::mw::com skeletons/proxies with LoLa/shm binding die interact with the "normal" score::mw::com apps (based on the SHM/LoLa binding). To interface with the vsomeip-network daemon these apps will use our "interface lib". Whether this interface lib internally also uses score::mw::com skeletons/proxies with LoLa/shm binding is transparent to these gateway apps. (Yes there are some potential issues to solve, because in the context of these gateway apps, we then have at least two different mw_com_config.json configs -> one for the communication (lower level) of our lib to interface with the vsomeip-daemon and the other for the config to communicate to the "normal" score::mw::com apps.
In the other usage scenario, where we would deploy this vsomeip-interface-lib in a binding within the score::mw::com (i.e. it will be used somewhere in score::mw::com::impl::bindings::someip this kind of dependency could eventually REALLY turn out as some "cyclic dependency" with awkward side-effects ....
So this imho is really discussion worthy ... whether it is a good idea to base the implementation of this interfacing library on score::mw::com! Maybe we really should already from the beginning go the other route I mentioned above:
Implement the "control-channel" on the stand-alone message passing library and also implement "data channel" with lower level shmare-memory lib ....
| message: | ||
| - `SomeIpServiceInstanceId` describing the service instance | ||
| - LoLa service type and instance id, which allows the `SOME/IP network daemon` to create the corresponding proxy instance | ||
| to the skeleton created in (1). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why someipdeamon part uses lola and not mw::com ?
| to the skeleton created in (1). | ||
| 3. The `SOME/IP network daemon` receives the message in (2) and creates the proxy from the information contained. I.e. it | ||
| issues a `score::mw::com::GenericProxy::FindService` and expects to get instantly a handle back, from which it then | ||
| creates the proxy instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isnt mw::com FindService based on instance specifier and not lola ids ? 2/3 looks confusing but maybe I miss something?
| the `SOME/IP network daemon` accesses the received message payload containing event/field data update and calls the | ||
| corresponding `GenericSkeletonEvent`/`GenericSkeletonField` `Send`/`Update` method. | ||
| 7. The upper layer can then – via the GenericProxy it has created in (5) – access updated event/field data | ||
| with the standard mechanisms: (polling based or event notified) `GetNewSamples()` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what with set/get on fields coming from outside? Do we support fields really (is there a way currently to attach a setter for a field as internal mw:com is pure pub-sub. same with get I suppose ) ?
No description provided.