// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // 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 #include #include #include #include #if defined ANDROID || defined __ANDROID__ #include "android/log.h" #define LOG_TAG "hello_world_service" #define LOG_INF(...) fprintf(stdout, __VA_ARGS__), fprintf(stdout, "\n"), (void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, ##__VA_ARGS__) #define LOG_ERR(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), (void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, ##__VA_ARGS__) #else #include #define LOG_INF(...) fprintf(stdout, __VA_ARGS__), fprintf(stdout, "\n") #define LOG_ERR(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n") #endif static vsomeip::service_t service_id = 0x1111; static vsomeip::instance_t service_instance_id = 0x2222; static vsomeip::method_t service_method_id = 0x3333; class hello_world_service { public: // Get the vSomeIP runtime and // create a application via the runtime, we could pass the application name // here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME // environment variable is used hello_world_service() : rtm_(vsomeip::runtime::get()), app_(rtm_->create_application()), stop_(false), stop_thread_(std::bind(&hello_world_service::stop, this)) { } ~hello_world_service() { stop_thread_.join(); } bool init() { // init the application if (!app_->init()) { LOG_ERR("Couldn't initialize application"); return false; } // register a message handler callback for messages sent to our service app_->register_message_handler(service_id, service_instance_id, service_method_id, std::bind(&hello_world_service::on_message_cbk, this, std::placeholders::_1)); // register a state handler to get called back after registration at the // runtime was successful app_->register_state_handler( std::bind(&hello_world_service::on_state_cbk, this, std::placeholders::_1)); return true; } void start() { // start the application and wait for the on_event callback to be called // this method only returns when app_->stop() is called app_->start(); } void stop() { std::unique_lock its_lock(mutex_); while(!stop_) { condition_.wait(its_lock); } std::this_thread::sleep_for(std::chrono::seconds(5)); // Stop offering the service app_->stop_offer_service(service_id, service_instance_id); // unregister the state handler app_->unregister_state_handler(); // unregister the message handler app_->unregister_message_handler(service_id, service_instance_id, service_method_id); // shutdown the application app_->stop(); } void terminate() { std::lock_guard its_lock(mutex_); stop_ = true; condition_.notify_one(); } void on_state_cbk(vsomeip::state_type_e _state) { if(_state == vsomeip::state_type_e::ST_REGISTERED) { // we are registered at the runtime and can offer our service app_->offer_service(service_id, service_instance_id); } } void on_message_cbk(const std::shared_ptr &_request) { // Create a response based upon the request std::shared_ptr resp = rtm_->create_response(_request); // Construct string to send back std::string str("Hello "); str.append( reinterpret_cast(_request->get_payload()->get_data()), 0, _request->get_payload()->get_length()); // Create a payload which will be sent back to the client std::shared_ptr resp_pl = rtm_->create_payload(); std::vector pl_data(str.begin(), str.end()); resp_pl->set_data(pl_data); resp->set_payload(resp_pl); // Send the response back app_->send(resp); // we have finished terminate(); } private: std::shared_ptr rtm_; std::shared_ptr app_; bool stop_; std::mutex mutex_; std::condition_variable condition_; std::thread stop_thread_; };