• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 #include <vsomeip/vsomeip.hpp>
6 #include <chrono>
7 #include <thread>
8 #include <condition_variable>
9 #include <mutex>
10 
11 #if defined ANDROID || defined __ANDROID__
12 #include "android/log.h"
13 #define LOG_TAG "hello_world_service"
14 #define LOG_INF(...) fprintf(stdout, __VA_ARGS__), fprintf(stdout, "\n"), (void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, ##__VA_ARGS__)
15 #define LOG_ERR(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), (void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, ##__VA_ARGS__)
16 #else
17 #include <cstdio>
18 #define LOG_INF(...) fprintf(stdout, __VA_ARGS__), fprintf(stdout, "\n")
19 #define LOG_ERR(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n")
20 #endif
21 
22 static vsomeip::service_t service_id = 0x1111;
23 static vsomeip::instance_t service_instance_id = 0x2222;
24 static vsomeip::method_t service_method_id = 0x3333;
25 
26 class hello_world_service {
27 public:
28     // Get the vSomeIP runtime and
29     // create a application via the runtime, we could pass the application name
30     // here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME
31     // environment variable is used
hello_world_service()32     hello_world_service() :
33                     rtm_(vsomeip::runtime::get()),
34                     app_(rtm_->create_application()),
35                     stop_(false),
36                     stop_thread_(std::bind(&hello_world_service::stop, this))
37     {
38     }
39 
~hello_world_service()40     ~hello_world_service()
41     {
42         stop_thread_.join();
43     }
44 
init()45     bool init()
46     {
47         // init the application
48         if (!app_->init()) {
49             LOG_ERR("Couldn't initialize application");
50             return false;
51         }
52 
53         // register a message handler callback for messages sent to our service
54         app_->register_message_handler(service_id, service_instance_id,
55                 service_method_id,
56                 std::bind(&hello_world_service::on_message_cbk, this,
57                         std::placeholders::_1));
58 
59         // register a state handler to get called back after registration at the
60         // runtime was successful
61         app_->register_state_handler(
62                 std::bind(&hello_world_service::on_state_cbk, this,
63                         std::placeholders::_1));
64         return true;
65     }
66 
start()67     void start()
68     {
69         // start the application and wait for the on_event callback to be called
70         // this method only returns when app_->stop() is called
71         app_->start();
72     }
73 
stop()74     void stop()
75     {
76         std::unique_lock<std::mutex> its_lock(mutex_);
77         while(!stop_) {
78             condition_.wait(its_lock);
79         }
80         std::this_thread::sleep_for(std::chrono::seconds(5));
81         // Stop offering the service
82         app_->stop_offer_service(service_id, service_instance_id);
83         // unregister the state handler
84         app_->unregister_state_handler();
85         // unregister the message handler
86         app_->unregister_message_handler(service_id, service_instance_id,
87                 service_method_id);
88         // shutdown the application
89         app_->stop();
90     }
91 
terminate()92     void terminate() {
93         std::lock_guard<std::mutex> its_lock(mutex_);
94         stop_ = true;
95         condition_.notify_one();
96     }
97 
on_state_cbk(vsomeip::state_type_e _state)98     void on_state_cbk(vsomeip::state_type_e _state)
99     {
100         if(_state == vsomeip::state_type_e::ST_REGISTERED)
101         {
102             // we are registered at the runtime and can offer our service
103             app_->offer_service(service_id, service_instance_id);
104         }
105     }
106 
on_message_cbk(const std::shared_ptr<vsomeip::message> & _request)107     void on_message_cbk(const std::shared_ptr<vsomeip::message> &_request)
108     {
109         // Create a response based upon the request
110         std::shared_ptr<vsomeip::message> resp = rtm_->create_response(_request);
111 
112         // Construct string to send back
113         std::string str("Hello ");
114         str.append(
115                 reinterpret_cast<const char*>(_request->get_payload()->get_data()),
116                 0, _request->get_payload()->get_length());
117 
118         // Create a payload which will be sent back to the client
119         std::shared_ptr<vsomeip::payload> resp_pl = rtm_->create_payload();
120         std::vector<vsomeip::byte_t> pl_data(str.begin(), str.end());
121         resp_pl->set_data(pl_data);
122         resp->set_payload(resp_pl);
123 
124         // Send the response back
125         app_->send(resp);
126         // we have finished
127         terminate();
128     }
129 
130 private:
131     std::shared_ptr<vsomeip::runtime> rtm_;
132     std::shared_ptr<vsomeip::application> app_;
133     bool stop_;
134     std::mutex mutex_;
135     std::condition_variable condition_;
136     std::thread stop_thread_;
137 };
138