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