diff options
Diffstat (limited to 'src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc')
-rw-r--r-- | src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc | 361 |
1 files changed, 212 insertions, 149 deletions
diff --git a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc index 65f4fde0b2..b125a7de7d 100644 --- a/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc +++ b/src/components/application_manager/rpc_plugins/vehicle_info_plugin/src/commands/mobile/subscribe_vehicle_data_request.cc @@ -29,8 +29,10 @@ #include "vehicle_info_plugin/commands/mobile/subscribe_vehicle_data_request.h" +#include <boost/algorithm/string.hpp> #include "application_manager/application_impl.h" #include "application_manager/message_helper.h" +#include "smart_objects/enum_schema_item.h" #include "utils/helpers.h" #include "vehicle_info_plugin/vehicle_info_app_extension.h" @@ -40,15 +42,13 @@ namespace commands { SubscribeVehicleDataRequest::SubscribeVehicleDataRequest( const application_manager::commands::MessageSharedPtr& message, - ApplicationManager& application_manager, - app_mngr::rpc_service::RPCService& rpc_service, - app_mngr::HMICapabilities& hmi_capabilities, - policy::PolicyHandlerInterface& policy_handler) + VehicleInfoCommandParams params) : CommandRequestImpl(message, - application_manager, - rpc_service, - hmi_capabilities, - policy_handler) {} + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) + , custom_vehicle_data_manager_(params.custom_vehicle_data_manager_) {} SubscribeVehicleDataRequest::~SubscribeVehicleDataRequest() {} @@ -73,6 +73,7 @@ void SubscribeVehicleDataRequest::Run() { app, info, result_code, response_params, msg_params, result); if (mobile_apis::Result::INVALID_ENUM != result_code) { + AppendDataTypesToMobileResponse(response_params); SendResponse(result, result_code, info.empty() ? NULL : info.c_str(), @@ -118,35 +119,103 @@ void SubscribeVehicleDataRequest::on_event(const event_engine::Event& event) { mobile_apis::Result::eType result_code = MessageHelper::HMIToMobileResult(hmi_result); + smart_objects::SmartObject converted_msg_params(message[strings::msg_params]); + custom_vehicle_data_manager_.CreateMobileMessageParams(converted_msg_params); + if (is_succeeded) { if (!vi_already_subscribed_by_this_app_.empty()) { result_code = mobile_apis::Result::IGNORED; response_info = "Already subscribed on some provided VehicleData."; } - if (!vi_waiting_for_subscribe_.empty()) { - LOG4CXX_DEBUG(logger_, "Subscribing to all pending VehicleData"); - VehicleInfoSubscriptions::const_iterator key = - vi_waiting_for_subscribe_.begin(); - for (; key != vi_waiting_for_subscribe_.end(); ++key) { - auto& ext = VehicleInfoAppExtension::ExtractVIExtension(*app); - ext.subscribeToVehicleInfo(*key); + for (const auto& param : converted_msg_params.enumerate()) { + const auto& converted_name = ConvertResponseToRequestName(param); + if (vi_waiting_for_subscribe_.end() == + vi_waiting_for_subscribe_.find(converted_name)) { + LOG4CXX_DEBUG(logger_, "erase " << converted_name); + converted_msg_params.erase(param); } } - } - UnsubscribeFailedSubscriptions(app, message[strings::msg_params]); + if (!SubscribePendingVehicleData(app, converted_msg_params)) { + result_code = mobile_apis::Result::GENERIC_ERROR; + response_info = "Subscription failed for some Vehicle data"; + SendResponse(false, result_code, response_info.c_str()); + return; + } + } if (!vi_already_subscribed_by_another_apps_.empty() || !vi_already_subscribed_by_this_app_.empty()) { - AddAlreadySubscribedVI( - const_cast<smart_objects::SmartObject&>(message[strings::msg_params])); + AddAlreadySubscribedVI(converted_msg_params); } + AppendDataTypesToMobileResponse(converted_msg_params); SendResponse(is_succeeded, result_code, response_info.empty() ? NULL : response_info.c_str(), - &(message[strings::msg_params])); + &converted_msg_params); +} + +void SubscribeVehicleDataRequest::AppendDataTypesToMobileResponse( + smart_objects::SmartObject& msg_params) const { + using namespace smart_objects; + + std::string oem_vehicle_data_type_str; + EnumConversionHelper<VehicleDataType>::EnumToString( + VehicleDataType::VEHICLEDATA_OEM_CUSTOM_DATA, &oem_vehicle_data_type_str); + + const auto& rpc_spec_vehicle_data = MessageHelper::vehicle_data(); + for (const auto& item : msg_params.enumerate()) { + const auto& rpc_spec_vehicle_data_item = rpc_spec_vehicle_data.find(item); + if (rpc_spec_vehicle_data.end() == rpc_spec_vehicle_data_item) { + msg_params[item][strings::data_type] = oem_vehicle_data_type_str; + msg_params[item][strings::oem_custom_data_type] = + custom_vehicle_data_manager_.GetVehicleDataItemType(item); + } else { + msg_params[item][strings::data_type] = rpc_spec_vehicle_data_item->second; + } + } +} + +bool SubscribeVehicleDataRequest::CheckSubscriptionStatus( + std::string vi_name, const smart_objects::SmartObject& msg_params) { + const auto subscribed_items = msg_params.enumerate(); + if (subscribed_items.end() == subscribed_items.find(vi_name)) { + LOG4CXX_WARN(logger_, + vi_name << " is waiting to be subscribed, but missing in " + "vehicle response."); + return false; + } + + auto res_code = msg_params[vi_name][strings::result_code].asInt(); + if (hmi_apis::Common_VehicleDataResultCode::VDRC_SUCCESS != res_code && + hmi_apis::Common_VehicleDataResultCode::VDRC_DATA_ALREADY_SUBSCRIBED != + res_code) { + LOG4CXX_WARN(logger_, + "Subscription to " << vi_name << " for " << connection_key() + << " failed."); + return false; + } + return true; +} + +bool SubscribeVehicleDataRequest::SubscribePendingVehicleData( + ApplicationSharedPtr app, const smart_objects::SmartObject& msg_params) { + LOG4CXX_DEBUG(logger_, "Subscribing to all pending VehicleData"); + + for (const auto& vi_name : vi_waiting_for_subscribe_) { + const bool is_subscription_successful = CheckSubscriptionStatus( + ConvertRequestToResponseName(vi_name), msg_params); + + if (is_subscription_successful) { + auto& ext = VehicleInfoAppExtension::ExtractVIExtension(*app); + ext.subscribeToVehicleInfo(vi_name); + vi_waiting_for_subscribe_.erase(vi_name); + } + } + + return vi_waiting_for_subscribe_.empty(); } bool SubscribeVehicleDataRequest::Init() { @@ -158,76 +227,33 @@ void SubscribeVehicleDataRequest::AddAlreadySubscribedVI( smart_objects::SmartObject& msg_params) const { LOG4CXX_AUTO_TRACE(logger_); using namespace mobile_apis; - auto vi_to_string = - [](const mobile_apis::VehicleDataType::eType vehicle_data) { - for (auto& vi_str_to_int_pair : MessageHelper::vehicle_data()) { - if (vehicle_data == vi_str_to_int_pair.second) { - return vi_str_to_int_pair.first; - } - } - return std::string(); - }; - VehicleInfoSubscriptions::const_iterator it_same_app = - vi_already_subscribed_by_this_app_.begin(); - for (; vi_already_subscribed_by_this_app_.end() != it_same_app; - ++it_same_app) { - msg_params[vi_to_string(*it_same_app)][strings::result_code] = + for (const auto& item : vi_already_subscribed_by_this_app_) { + msg_params[item][strings::result_code] = VehicleDataResultCode::VDRC_DATA_ALREADY_SUBSCRIBED; - msg_params[vi_to_string(*it_same_app)][strings::data_type] = *it_same_app; } - VehicleInfoSubscriptions::const_iterator it_another_app = - vi_already_subscribed_by_another_apps_.begin(); - for (; vi_already_subscribed_by_another_apps_.end() != it_another_app; - ++it_another_app) { - msg_params[vi_to_string(*it_another_app)][strings::result_code] = + for (const auto& item : vi_already_subscribed_by_another_apps_) { + msg_params[item][strings::result_code] = VehicleDataResultCode::VDRC_SUCCESS; - msg_params[vi_to_string(*it_another_app)][strings::data_type] = - *it_another_app; - } -} - -void SubscribeVehicleDataRequest::UnsubscribeFailedSubscriptions( - ApplicationSharedPtr app, - const smart_objects::SmartObject& msg_params) const { - LOG4CXX_AUTO_TRACE(logger_); - const VehicleData& vehicle_data = MessageHelper::vehicle_data(); - VehicleData::const_iterator it = vehicle_data.begin(); - - for (; vehicle_data.end() != it; ++it) { - if (msg_params.keyExists(it->first)) { - if (msg_params[it->first][strings::result_code].asInt() != - hmi_apis::Common_VehicleDataResultCode::VDRC_SUCCESS) { - LOG4CXX_DEBUG(logger_, - "Subscription for VehicleDataType " - << it->first - << " is unsuccessfull. " - "Unsubscribing app with connection key " - << connection_key() << " from it."); - VehicleInfoAppExtension::ExtractVIExtension(*app) - .unsubscribeFromVehicleInfo(it->second); - } - } } } struct SubscribedToIVIPredicate { - int32_t vehicle_info_; - SubscribedToIVIPredicate(int32_t vehicle_info) + std::string vehicle_info_; + SubscribedToIVIPredicate(std::string vehicle_info) : vehicle_info_(vehicle_info) {} bool operator()(const ApplicationSharedPtr app) const { DCHECK_OR_RETURN(app, false); auto& ext = VehicleInfoAppExtension::ExtractVIExtension(*app); - return ext.isSubscribedToVehicleInfo( - static_cast<mobile_apis::VehicleDataType::eType>(vehicle_info_)); + return ext.isSubscribedToVehicleInfo(vehicle_info_); } }; bool SubscribeVehicleDataRequest::IsSomeoneSubscribedFor( - const uint32_t param_id) const { + const std::string& param_name) const { LOG4CXX_AUTO_TRACE(logger_); - SubscribedToIVIPredicate finder(param_id); + SubscribedToIVIPredicate finder(param_name); DataAccessor<ApplicationSet> accessor = application_manager_.applications(); ApplicationSetConstIt it = std::find_if( accessor.GetData().begin(), accessor.GetData().end(), finder); @@ -241,93 +267,101 @@ void SubscribeVehicleDataRequest::CheckVISubscriptions( smart_objects::SmartObject& out_response_params, smart_objects::SmartObject& out_request_params, bool& out_result) { - // counter for items to subscribe - VehicleInfoSubscriptions::size_type items_to_subscribe = 0; - // counter for subscribed items by application - uint32_t subscribed_items = 0; + const bool is_interface_not_available = + (HmiInterfaces::STATE_NOT_AVAILABLE == + application_manager_.hmi_interfaces().GetInterfaceState( + HmiInterfaces::HMI_INTERFACE_VehicleInfo)); + + VehicleInfoSubscriptions::size_type subscribed_items = 0; + + auto app_already_subscribed = + [this, &out_response_params]( + const std::string& key_name, + const mobile_apis::VehicleDataType::eType vd_type) { + LOG4CXX_DEBUG( + logger_, + "App with connection key " + << connection_key() + << " is subscribed already for VehicleData: " << key_name); + vi_already_subscribed_by_this_app_.insert(key_name); + out_response_params[key_name][strings::data_type] = vd_type; + out_response_params[key_name][strings::result_code] = + mobile_apis::VehicleDataResultCode::VDRC_DATA_ALREADY_SUBSCRIBED; + }; - const VehicleData& vehicle_data = MessageHelper::vehicle_data(); - VehicleData::const_iterator it = vehicle_data.begin(); + auto another_app_subscribed = + [this, &out_response_params, &subscribed_items]( + const std::string& key_name, + const mobile_apis::VehicleDataType::eType vd_type, + vehicle_info_plugin::VehicleInfoAppExtension& ext) { + LOG4CXX_DEBUG(logger_, + "There are apps subscribed already for " + "VehicleDataType: " + << key_name); + + if (!ext.subscribeToVehicleInfo(key_name)) { + LOG4CXX_ERROR( + logger_, "Unable to subscribe for VehicleDataType: " << key_name); + return; + } + LOG4CXX_DEBUG( + logger_, + "App with connection key " + << connection_key() + << " have been subscribed for VehicleDataType: " << key_name); + vi_already_subscribed_by_another_apps_.insert(key_name); + out_response_params[key_name][strings::data_type] = vd_type; + out_response_params[key_name][strings::result_code] = + mobile_apis::VehicleDataResultCode::VDRC_SUCCESS; + ++subscribed_items; + }; - HmiInterfaces::InterfaceState interface_state = - application_manager_.hmi_interfaces().GetInterfaceState( - HmiInterfaces::HMI_INTERFACE_VehicleInfo); + auto first_subscription = [this, &out_request_params, &subscribed_items]( + const std::string& vi_name) { + out_request_params[vi_name] = (*message_)[strings::msg_params][vi_name]; - const bool is_interface_not_available = - interface_state == HmiInterfaces::STATE_NOT_AVAILABLE; - - for (; vehicle_data.end() != it; ++it) { - const std::string& key_name = it->first; - if ((*message_)[strings::msg_params].keyExists(key_name)) { - const bool is_key_enabled = - (*message_)[strings::msg_params][key_name].asBool(); - if (is_key_enabled) { - ++items_to_subscribe; - } - if (!is_interface_not_available && is_key_enabled) { - mobile_apis::VehicleDataType::eType key_type = it->second; - const auto is_subscribed = - VehicleInfoAppExtension::ExtractVIExtension(*app) - .isSubscribedToVehicleInfo(key_type); - if (is_subscribed) { - LOG4CXX_DEBUG(logger_, - "App with connection key " - << connection_key() - << " is subscribed already for VehicleDataType: " - << key_type); - ++subscribed_items; - vi_already_subscribed_by_this_app_.insert(key_type); - out_response_params[key_name][strings::data_type] = key_type; - out_response_params[key_name][strings::result_code] = - mobile_apis::VehicleDataResultCode::VDRC_DATA_ALREADY_SUBSCRIBED; - continue; - } + vi_waiting_for_subscribe_.insert(vi_name); + LOG4CXX_DEBUG( + logger_, + "App with connection key " + << connection_key() + << " will be subscribed for VehicleDataType: " << vi_name); + ++subscribed_items; + return true; + }; - if (IsSomeoneSubscribedFor(key_type)) { - LOG4CXX_DEBUG(logger_, - "There are apps subscribed already for " - "VehicleDataType: " - << key_type); - auto& ext = VehicleInfoAppExtension::ExtractVIExtension(*app); - - if (!ext.subscribeToVehicleInfo(key_type)) { - LOG4CXX_ERROR( - logger_, - "Unable to subscribe for VehicleDataType: " << key_type); - continue; - } - LOG4CXX_DEBUG( - logger_, - "App with connection key " - << connection_key() - << " have been subscribed for VehicleDataType: " << key_type); - ++subscribed_items; - vi_already_subscribed_by_another_apps_.insert(key_type); - out_response_params[key_name][strings::data_type] = key_type; - out_response_params[key_name][strings::result_code] = - mobile_apis::VehicleDataResultCode::VDRC_SUCCESS; - continue; - } + auto rpc_spec_vehicle_data = MessageHelper::vehicle_data(); + auto& ext = VehicleInfoAppExtension::ExtractVIExtension(*app); - out_request_params[key_name] = is_key_enabled; + VehicleInfoSubscriptions::size_type items_to_subscribe = 0; + auto item_names = (*message_)[strings::msg_params].enumerate(); + if (!is_interface_not_available) { + for (const auto& name : item_names) { + auto enabled = (*message_)[strings::msg_params][name].asBool(); + if (!enabled) { + continue; + } - if (is_key_enabled) { - vi_waiting_for_subscribe_.insert(key_type); - LOG4CXX_DEBUG( - logger_, - "App with connection key " - << connection_key() - << " will be subscribed for VehicleDataType: " << key_type); - ++subscribed_items; - } + auto vehicle_data = rpc_spec_vehicle_data.find(name); + auto vehicle_data_type = + (vehicle_data == rpc_spec_vehicle_data.end()) + ? VehicleDataType::VEHICLEDATA_OEM_CUSTOM_DATA + : vehicle_data->second; + if (ext.isSubscribedToVehicleInfo(name)) { + app_already_subscribed(name, vehicle_data_type); + } else if (IsSomeoneSubscribedFor(name)) { + another_app_subscribed(name, vehicle_data_type, ext); + } else if (!first_subscription(name)) { + continue; } + + ++items_to_subscribe; } } const bool is_everything_already_subscribed = - items_to_subscribe == - vi_already_subscribed_by_another_apps_.size() + - vi_already_subscribed_by_this_app_.size(); + items_to_subscribe == vi_already_subscribed_by_another_apps_.size() + + vi_already_subscribed_by_this_app_.size(); if (0 == items_to_subscribe) { if (HasDisallowedParams()) { @@ -337,12 +371,14 @@ void SubscribeVehicleDataRequest::CheckVISubscriptions( out_info = "No data in the request"; } out_result = false; + return; } if (0 == subscribed_items && !is_interface_not_available) { out_result_code = mobile_apis::Result::IGNORED; out_info = "Already subscribed on provided VehicleData."; out_result = false; + return; } if (is_everything_already_subscribed) { @@ -353,8 +389,35 @@ void SubscribeVehicleDataRequest::CheckVISubscriptions( out_info = "Already subscribed on some provided VehicleData."; } out_result = true; + return; } } +const std::string& SubscribeVehicleDataRequest::ConvertResponseToRequestName( + const std::string& name) { + static std::map<std::string, std::string> parameter_name_conversion_map = { + {strings::cluster_modes, strings::cluster_mode_status}}; + const auto converted_it = parameter_name_conversion_map.find(name); + auto result = parameter_name_conversion_map.end() == converted_it + ? name + : converted_it->second; + return parameter_name_conversion_map.end() == converted_it + ? name + : converted_it->second; +} + +const std::string& SubscribeVehicleDataRequest::ConvertRequestToResponseName( + const std::string& name) { + static std::map<std::string, std::string> parameter_name_conversion_map = { + {strings::cluster_mode_status, strings::cluster_modes}}; + const auto converted_it = parameter_name_conversion_map.find(name); + auto result = parameter_name_conversion_map.end() == converted_it + ? name + : converted_it->second; + return parameter_name_conversion_map.end() == converted_it + ? name + : converted_it->second; +} + } // namespace commands -} // namespace application_manager +} // namespace vehicle_info_plugin |