1515#include < csignal>
1616#include < cstdlib>
1717#include < iostream>
18+ #include < set>
1819#include < thread>
1920#include < vsomeip/defines.hpp>
2021#include < vsomeip/primitive_types.hpp>
2324#include " score/mw/com/runtime.h"
2425#include " score/span.hpp"
2526#include " src/network_service/interfaces/message_transfer.h"
26-
27- const char * someipd_name = " someipd" ;
28-
29- static const vsomeip::service_t service_id = 0x1111 ;
30- static const vsomeip::instance_t service_instance_id = 0x2222 ;
31- static const vsomeip::method_t service_method_id = 0x3333 ;
27+ #include " src/someipd/vsomeip_config_reader.h"
3228
3329static const std::size_t max_sample_count = 10 ;
3430
35- #define SAMPLE_SERVICE_ID 0x1234
36- #define RESPONSE_SAMPLE_SERVICE_ID 0x4321
37- #define SAMPLE_INSTANCE_ID 0x5678
38- #define SAMPLE_METHOD_ID 0x0421
39-
40- #define SAMPLE_EVENT_ID 0x8778
41- #define SAMPLE_GET_METHOD_ID 0x0001
42- #define SAMPLE_SET_METHOD_ID 0x0002
43-
44- #define SAMPLE_EVENTGROUP_ID 0x4465
45-
46- #define OTHER_SAMPLE_SERVICE_ID 0x0248
47- #define OTHER_SAMPLE_INSTANCE_ID 0x5422
48- #define OTHER_SAMPLE_METHOD_ID 0x1421
49-
5031using score::someip_gateway::network_service::interfaces::message_transfer::
5132 SomeipMessageTransferProxy;
5233using score::someip_gateway::network_service::interfaces::message_transfer::
5334 SomeipMessageTransferSkeleton;
35+ using score::someip_gateway::someipd::SomeipDConfig;
5436
5537// Global flag to control application shutdown
5638static std::atomic<bool > shutdown_requested{false };
@@ -66,16 +48,32 @@ int main(int argc, const char* argv[]) {
6648 std::signal (SIGTERM, termination_handler);
6749 std::signal (SIGINT, termination_handler);
6850
51+ std::string someipd_config_path = " etc/someipd_config.json" ;
52+ for (int i = 1 ; i < argc - 1 ; ++i) {
53+ if (std::string (argv[i]) == " -someipd_config" ) {
54+ someipd_config_path = argv[i + 1 ];
55+ break ;
56+ }
57+ }
58+
59+ SomeipDConfig config{};
60+ try {
61+ config = score::someip_gateway::someipd::ReadSomeipDConfig (someipd_config_path);
62+ } catch (const std::exception& ex) {
63+ std::cerr << " Failed to load someipd config: " << ex.what () << std::endl;
64+ return 1 ;
65+ }
66+
6967 score::mw::com::runtime::InitializeRuntime (argc, argv);
7068
7169 auto runtime = vsomeip::runtime::get ();
72- auto application = runtime->create_application (someipd_name );
70+ auto application = runtime->create_application (" someipd " );
7371 if (!application->init ()) {
7472 std::cerr << " App init failed" ;
7573 return 1 ;
7674 }
7775
78- std::thread ([application]() {
76+ std::thread ([application, config ]() {
7977 auto handles =
8078 SomeipMessageTransferProxy::FindService (
8179 score::mw::com::InstanceSpecifier::Create (std::string (" someipd/gatewayd_messages" ))
@@ -94,39 +92,56 @@ int main(int argc, const char* argv[]) {
9492 auto skeleton = std::move (create_result).value ();
9593 (void )skeleton.OfferService ();
9694
97- application->register_message_handler (
98- RESPONSE_SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID,
99- [&skeleton](const std::shared_ptr<vsomeip::message>& msg) {
100- auto maybe_message = skeleton.message_ .Allocate ();
101- if (!maybe_message.has_value ()) {
102- std::cerr << " Failed to allocate SOME/IP message:"
103- << maybe_message.error ().Message () << std::endl;
104- return ;
105- }
106- auto message_sample = std::move (maybe_message).value ();
107- memcpy (message_sample->data + VSOMEIP_FULL_HEADER_SIZE,
108- msg->get_payload ()->get_data (), msg->get_payload ()->get_length ());
109- message_sample->size =
110- msg->get_payload ()->get_length () + VSOMEIP_FULL_HEADER_SIZE;
111- skeleton.message_ .Send (std::move (message_sample));
112- });
113-
114- application->request_service (RESPONSE_SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
115- std::set<vsomeip::eventgroup_t > its_groups;
116- its_groups.insert (SAMPLE_EVENTGROUP_ID);
117- application->request_event (RESPONSE_SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
118- SAMPLE_EVENT_ID, its_groups,
119- vsomeip::event_type_e::ET_EVENT);
120- application->subscribe (RESPONSE_SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
121- SAMPLE_EVENTGROUP_ID);
122-
123- std::set<vsomeip::eventgroup_t > groups{SAMPLE_EVENTGROUP_ID};
124- application->offer_event (SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID,
125- groups);
126- application->offer_service (SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
127-
128- // application->update_service_configuration(
129- // SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, 12345u, true, true, true);
95+ // Register message handlers for all subscribed services
96+ for (const auto & svc : config.subscribed_services ) {
97+ for (const auto & ev : svc.events ) {
98+ application->register_message_handler (
99+ svc.service_id , svc.instance_id , ev.event_id ,
100+ [&skeleton](const std::shared_ptr<vsomeip::message>& msg) {
101+ auto maybe_message = skeleton.message_ .Allocate ();
102+ if (!maybe_message.has_value ()) {
103+ std::cerr << " Failed to allocate SOME/IP message:"
104+ << maybe_message.error ().Message () << std::endl;
105+ return ;
106+ }
107+ auto message_sample = std::move (maybe_message).value ();
108+ memcpy (message_sample->data + VSOMEIP_FULL_HEADER_SIZE,
109+ msg->get_payload ()->get_data (),
110+ msg->get_payload ()->get_length ());
111+ message_sample->size =
112+ msg->get_payload ()->get_length () + VSOMEIP_FULL_HEADER_SIZE;
113+ skeleton.message_ .Send (std::move (message_sample));
114+ });
115+ }
116+
117+ application->request_service (svc.service_id , svc.instance_id );
118+ for (const auto & ev : svc.events ) {
119+ std::set<vsomeip::eventgroup_t > groups{ev.eventgroup_id };
120+ application->request_event (svc.service_id , svc.instance_id , ev.event_id , groups,
121+ vsomeip::event_type_e::ET_EVENT);
122+ application->subscribe (svc.service_id , svc.instance_id , ev.eventgroup_id );
123+ }
124+ }
125+
126+ // Offer all configured local services to the SOME/IP network.
127+ // Order matters: offer_event → offer_service (local) → update_service_configuration
128+ // (promote to network). update_service_configuration requires the service to already
129+ // be offered locally — see vsomeip application.hpp docs.
130+ for (const auto & svc : config.offered_services ) {
131+ for (const auto & ev : svc.events ) {
132+ std::set<vsomeip::eventgroup_t > groups{ev.eventgroup_id };
133+ application->offer_event (svc.service_id , svc.instance_id , ev.event_id , groups);
134+ }
135+ application->offer_service (svc.service_id , svc.instance_id );
136+ if (svc.unreliable_port != 0 ) {
137+ // Expose the locally offered service on the network via UDP.
138+ // This replaces the "services" section in vsomeip.json.
139+ application->update_service_configuration (
140+ svc.service_id , svc.instance_id , svc.unreliable_port ,
141+ /* reliable=*/ false , /* magic_cookies_enabled=*/ false , /* offer=*/ true );
142+ }
143+ }
144+
130145 auto payload = vsomeip::runtime::get ()->create_payload ();
131146
132147 std::cout << " SOME/IP daemon started, waiting for messages..." << std::endl;
@@ -136,7 +151,6 @@ int main(int argc, const char* argv[]) {
136151 // TODO: Use ReceiveHandler + async runtime instead of polling
137152 proxy.message_ .GetNewSamples (
138153 [&](auto message_sample) {
139- // TODO: Check if size is larger than capacity of data
140154 score::cpp::span<const std::byte> message (message_sample->data ,
141155 message_sample->size );
142156
@@ -155,8 +169,7 @@ int main(int argc, const char* argv[]) {
155169 payload->set_data (
156170 reinterpret_cast <const vsomeip_v3::byte_t *>(payload_data.data ()),
157171 payload_data.size ());
158- application->notify (SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID,
159- payload);
172+ application->notify (service_id, instance_id, event_id, payload);
160173 },
161174 max_sample_count);
162175 std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
0 commit comments