diff options
Diffstat (limited to 'src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands')
18 files changed, 2688 insertions, 0 deletions
diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_button_press_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_button_press_request.cc new file mode 100644 index 0000000000..75faf5db8c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_button_press_request.cc @@ -0,0 +1,58 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_button_press_request.h" +#include "rc_rpc_plugin/resource_allocation_manager_impl.h" + +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCButtonPressRequest::RCButtonPressRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : app_mngr::commands::RequestToHMI(message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +RCButtonPressRequest::~RCButtonPressRequest() {} + +void RCButtonPressRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + SendRequest(); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_button_press_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_button_press_response.cc new file mode 100644 index 0000000000..5c1691ed7b --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_button_press_response.cc @@ -0,0 +1,61 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_button_press_response.h" +#include "application_manager/event_engine/event.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCButtonPressResponse::RCButtonPressResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::ResponseFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void RCButtonPressResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + app_mngr::event_engine::Event event( + hmi_apis::FunctionID::Buttons_ButtonPress); + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +RCButtonPressResponse::~RCButtonPressResponse() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_consent_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_consent_request.cc new file mode 100644 index 0000000000..774ee04677 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_consent_request.cc @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_get_interior_vehicle_data_consent_request.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCGetInteriorVehicleDataConsentRequest::RCGetInteriorVehicleDataConsentRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::RequestToHMI(message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +RCGetInteriorVehicleDataConsentRequest:: + ~RCGetInteriorVehicleDataConsentRequest() {} + +void RCGetInteriorVehicleDataConsentRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + SendRequest(); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_consent_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_consent_response.cc new file mode 100644 index 0000000000..3244857656 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_consent_response.cc @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_get_interior_vehicle_data_consent_response.h" +#include "application_manager/event_engine/event.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCGetInteriorVehicleDataConsentResponse:: + RCGetInteriorVehicleDataConsentResponse( + const application_manager::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::ResponseFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void RCGetInteriorVehicleDataConsentResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + app_mngr::event_engine::Event event( + hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent); + + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +RCGetInteriorVehicleDataConsentResponse:: + ~RCGetInteriorVehicleDataConsentResponse() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_request.cc new file mode 100644 index 0000000000..c7baf75e27 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_request.cc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_get_interior_vehicle_data_request.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCGetInteriorVehicleDataRequest::RCGetInteriorVehicleDataRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::RequestToHMI(message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +RCGetInteriorVehicleDataRequest::~RCGetInteriorVehicleDataRequest() {} + +void RCGetInteriorVehicleDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + SendRequest(); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_response.cc new file mode 100644 index 0000000000..e56f9088bc --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_get_interior_vehicle_data_response.cc @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_get_interior_vehicle_data_response.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "application_manager/event_engine/event.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCGetInteriorVehicleDataResponse::RCGetInteriorVehicleDataResponse( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::ResponseFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void RCGetInteriorVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + app_mngr::event_engine::Event event( + hmi_apis::FunctionID::RC_GetInteriorVehicleData); + + smart_objects::SmartObject& module_data = (*message_) + [application_manager::strings::msg_params][message_params::kModuleData]; + if (module_data.keyExists(message_params::kAudioControlData)) { + smart_objects::SmartObject& audio_control_data = + module_data[message_params::kAudioControlData]; + if (audio_control_data.keyExists(message_params::kKeepContext)) { + audio_control_data.erase(message_params::kKeepContext); + } + } + + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +RCGetInteriorVehicleDataResponse::~RCGetInteriorVehicleDataResponse() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_interior_vehicle_data_notification.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_interior_vehicle_data_notification.cc new file mode 100644 index 0000000000..0117003f11 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_interior_vehicle_data_notification.cc @@ -0,0 +1,71 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/rc_module_constants.h" +#include "rc_rpc_plugin/commands/hmi/rc_on_interior_vehicle_data_notification.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCOnInteriorVehicleDataNotification::RCOnInteriorVehicleDataNotification( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::NotificationFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +RCOnInteriorVehicleDataNotification::~RCOnInteriorVehicleDataNotification() {} + +void RCOnInteriorVehicleDataNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + (*message_)[app_mngr::strings::params][app_mngr::strings::function_id] = + static_cast<int>(mobile_apis::FunctionID::eType::OnInteriorVehicleDataID); + + smart_objects::SmartObject& module_data = (*message_) + [application_manager::strings::msg_params][message_params::kModuleData]; + if (module_data.keyExists(rc_rpc_plugin::message_params::kAudioControlData)) { + smart_objects::SmartObject& audio_control_data = + module_data[message_params::kAudioControlData]; + if (audio_control_data.keyExists(message_params::kKeepContext)) { + audio_control_data.erase(message_params::kKeepContext); + } + } + + SendNotificationToMobile(message_); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc new file mode 100644 index 0000000000..91cb6cb7ee --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_on_remote_control_settings_notification.cc @@ -0,0 +1,138 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_on_remote_control_settings_notification.h" +#include "rc_rpc_plugin/rc_rpc_plugin.h" +#include "rc_rpc_plugin/interior_data_manager.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "rc_rpc_plugin/rc_helpers.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +namespace { +std::map<std::string, hmi_apis::Common_RCAccessMode::eType> access_modes{ + {enums_value::kAutoAllow, hmi_apis::Common_RCAccessMode::AUTO_ALLOW}, + {enums_value::kAutoDeny, hmi_apis::Common_RCAccessMode::AUTO_DENY}, + {enums_value::kAskDriver, hmi_apis::Common_RCAccessMode::ASK_DRIVER}}; +} + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +RCOnRemoteControlSettingsNotification::RCOnRemoteControlSettingsNotification( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::NotificationFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) + , resource_allocation_manager_(params.resource_allocation_manager_) + , interior_data_manager_(params.interior_data_manager_) {} + +RCOnRemoteControlSettingsNotification:: + ~RCOnRemoteControlSettingsNotification() {} + +hmi_apis::Common_RCAccessMode::eType AccessModeFromString( + const std::string& access_mode) { + std::map<std::string, hmi_apis::Common_RCAccessMode::eType>::const_iterator + mode = access_modes.find(access_mode); + return access_modes.end() != mode + ? mode->second + : hmi_apis::Common_RCAccessMode::INVALID_ENUM; +} + +std::string AccessModeToString( + const hmi_apis::Common_RCAccessMode::eType access_mode) { + std::map<std::string, hmi_apis::Common_RCAccessMode::eType>::const_iterator + it = access_modes.begin(); + for (; access_modes.end() != it; ++it) { + if (access_mode == it->second) { + return it->first; + } + } + const std::string error = "UNKNOW_ACCESS_MODE"; + DCHECK_OR_RETURN(false, error); + return error; +} + +void RCOnRemoteControlSettingsNotification::DisallowRCFunctionality() { + LOG4CXX_AUTO_TRACE(logger_); + interior_data_manager_.OnDisablingRC(); +} + +void RCOnRemoteControlSettingsNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!(*message_)[app_mngr::strings::msg_params].keyExists( + message_params::kAllowed)) { + LOG4CXX_DEBUG(logger_, + "Notification is ignored due to \"allow\" parameter absense"); + LOG4CXX_DEBUG(logger_, "RC Functionality remains unchanged"); + return; + } + + const bool is_allowed = + (*message_)[app_mngr::strings::msg_params][message_params::kAllowed] + .asBool(); + if (is_allowed) { + hmi_apis::Common_RCAccessMode::eType access_mode = + hmi_apis::Common_RCAccessMode::INVALID_ENUM; + LOG4CXX_DEBUG(logger_, "Allowing RC Functionality"); + resource_allocation_manager_.set_rc_enabled(true); + if ((*message_)[app_mngr::strings::msg_params].keyExists( + message_params::kAccessMode)) { + access_mode = static_cast<hmi_apis::Common_RCAccessMode::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kAccessMode].asUInt()); + LOG4CXX_DEBUG( + logger_, + "Setting up access mode : " << AccessModeToString(access_mode)); + } else { + access_mode = resource_allocation_manager_.GetAccessMode(); + LOG4CXX_DEBUG(logger_, + "No access mode received. Using last known: " + << AccessModeToString(access_mode)); + } + resource_allocation_manager_.SetAccessMode(access_mode); + } else { + LOG4CXX_DEBUG(logger_, "Disallowing RC Functionality"); + DisallowRCFunctionality(); + resource_allocation_manager_.ResetAllAllocations(); + resource_allocation_manager_.set_rc_enabled(false); + } +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_interior_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_interior_vehicle_data_request.cc new file mode 100644 index 0000000000..f0d5ecc177 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_interior_vehicle_data_request.cc @@ -0,0 +1,55 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_set_interior_vehicle_data_request.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCSetInteriorVehicleDataRequest::RCSetInteriorVehicleDataRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::RequestToHMI(message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} +RCSetInteriorVehicleDataRequest::~RCSetInteriorVehicleDataRequest() {} + +void RCSetInteriorVehicleDataRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + SendRequest(); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_interior_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_interior_vehicle_data_response.cc new file mode 100644 index 0000000000..56d924debe --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/hmi/rc_set_interior_vehicle_data_response.cc @@ -0,0 +1,61 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/hmi/rc_set_interior_vehicle_data_response.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +RCSetInteriorVehicleDataResponse::RCSetInteriorVehicleDataResponse( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::ResponseFromHMI( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} + +void RCSetInteriorVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + app_mngr::event_engine::Event event( + hmi_apis::FunctionID::RC_SetInteriorVehicleData); + event.set_smart_object(*message_); + event.raise(application_manager_.event_dispatcher()); +} + +RCSetInteriorVehicleDataResponse::~RCSetInteriorVehicleDataResponse() {} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc new file mode 100644 index 0000000000..5ce047071c --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2018, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/button_press_request.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "smart_objects/enum_schema_item.h" +#include "utils/macro.h" +#include "json/json.h" +#include "utils/helpers.h" +#include "interfaces/MOBILE_API.h" + +namespace rc_rpc_plugin { +namespace commands { + +using namespace json_keys; +using namespace message_params; + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +typedef std::map<std::string, mobile_apis::ButtonName::eType> ButtonsMap; + +ButtonPressRequest::ButtonPressRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : RCCommandRequest(message, params) {} + +ButtonPressRequest::~ButtonPressRequest() {} + +const std::vector<std::string> buttons_climate() { + std::vector<std::string> data; + data.push_back(enums_value::kACMax); + data.push_back(enums_value::kAC); + data.push_back(enums_value::kRecirculate); + data.push_back(enums_value::kFanUp); + data.push_back(enums_value::kFanDown); + data.push_back(enums_value::kTempUp); + data.push_back(enums_value::kTempDown); + data.push_back(enums_value::kDefrostMax); + data.push_back(enums_value::kDefrost); + data.push_back(enums_value::kDefrostRear); + data.push_back(enums_value::kUpperVent); + data.push_back(enums_value::kLowerVent); + return data; +} + +const std::vector<std::string> buttons_radio() { + std::vector<std::string> data; + data.push_back(enums_value::kVolumeUp); + data.push_back(enums_value::kVolumeDown); + data.push_back(enums_value::kEject); + data.push_back(enums_value::kSource); + data.push_back(enums_value::kShuffle); + data.push_back(enums_value::kRepeat); + return data; +} + +const ButtonsMap buttons_map() { + using namespace mobile_apis; + + ButtonsMap buttons_map; + buttons_map[enums_value::kACMax] = ButtonName::AC_MAX; + buttons_map[enums_value::kAC] = ButtonName::AC; + buttons_map[enums_value::kRecirculate] = ButtonName::RECIRCULATE; + buttons_map[enums_value::kFanUp] = ButtonName::FAN_UP; + buttons_map[enums_value::kFanDown] = ButtonName::FAN_DOWN; + buttons_map[enums_value::kTempUp] = ButtonName::TEMP_UP; + buttons_map[enums_value::kTempDown] = ButtonName::TEMP_DOWN; + buttons_map[enums_value::kDefrostMax] = ButtonName::DEFROST_MAX; + buttons_map[enums_value::kDefrost] = ButtonName::DEFROST; + buttons_map[enums_value::kDefrostRear] = ButtonName::DEFROST_REAR; + buttons_map[enums_value::kUpperVent] = ButtonName::UPPER_VENT; + buttons_map[enums_value::kLowerVent] = ButtonName::LOWER_VENT; + buttons_map[enums_value::kVolumeUp] = ButtonName::VOLUME_UP; + buttons_map[enums_value::kVolumeDown] = ButtonName::VOLUME_DOWN; + buttons_map[enums_value::kEject] = ButtonName::EJECT; + buttons_map[enums_value::kSource] = ButtonName::SOURCE; + buttons_map[enums_value::kShuffle] = ButtonName::SHUFFLE; + buttons_map[enums_value::kRepeat] = ButtonName::REPEAT; + + return buttons_map; +} + +bool CheckIfButtonExistInRCCaps( + const smart_objects::SmartObject& rc_capabilities, + const mobile_apis::ButtonName::eType button) { + if (rc_capabilities.keyExists(strings::kbuttonCapabilities)) { + const smart_objects::SmartObject& button_caps = + rc_capabilities[strings::kbuttonCapabilities]; + auto it = button_caps.asArray()->begin(); + for (; it != button_caps.asArray()->end(); ++it) { + smart_objects::SmartObject& so = *it; + int64_t current_id = so[message_params::kName].asInt(); + if (-1 == current_id) { + // capabilities received from HMI contains enum values + // capabilities loaded from file contains string values + // TODO : unificate capabilities storing + const std::string& bt_name = so[message_params::kName].asString(); + static ButtonsMap btn_map = buttons_map(); + current_id = btn_map[bt_name]; + } + const mobile_apis::ButtonName::eType current_button = + static_cast<mobile_apis::ButtonName::eType>(current_id); + if (current_button == button) { + LOG4CXX_TRACE(logger_, + "Button id " << current_button + << " exist in capabilities"); + return true; + } + } + } + LOG4CXX_TRACE(logger_, + "Button id " << button << " do not exist in capabilities"); + return false; +} + +bool CheckButtonName(const std::string& module_type, + const std::string& button_name, + const smart_objects::SmartObject* rc_capabilities) { + LOG4CXX_AUTO_TRACE(logger_); + if (rc_capabilities == NULL) { + LOG4CXX_ERROR(logger_, "No remote controll capabilities available"); + return false; + } + + if (enums_value::kRadio == module_type) { + if (!helpers::in_range(buttons_radio(), button_name)) { + LOG4CXX_WARN(logger_, + "Trying to acceess climate button with module type radio"); + return false; + } + } + + if (enums_value::kClimate == module_type) { + if (!helpers::in_range(buttons_climate(), button_name)) { + LOG4CXX_WARN(logger_, + "Trying to acceess radio button with module type climate"); + return false; + } + } + return true; +} + +void ButtonPressRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + const char* button_name; + ns_smart_device_link::ns_smart_objects:: + EnumConversionHelper<mobile_apis::ButtonName::eType>::EnumToCString( + static_cast<mobile_apis::ButtonName::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kButtonName].asUInt()), + &button_name); + + const std::string module_type = ModuleType(); + static ButtonsMap btn_map = buttons_map(); + mobile_apis::ButtonName::eType button_id = + mobile_apis::ButtonName::INVALID_ENUM; + if (btn_map.end() != btn_map.find(button_name)) { + button_id = btn_map[button_name]; + } + + const smart_objects::SmartObject* rc_capabilities = + hmi_capabilities_.rc_capability(); + const bool button_name_matches_module_type = + CheckButtonName(module_type, button_name, rc_capabilities); + const bool button_id_exist_in_caps = + rc_capabilities && + CheckIfButtonExistInRCCaps(*rc_capabilities, button_id); + + app_mngr::ApplicationSharedPtr app = + application_manager_.application(connection_key()); + + (*message_)[app_mngr::strings::msg_params][app_mngr::strings::app_id] = + app->app_id(); + + if (button_name_matches_module_type && button_id_exist_in_caps) { + SendHMIRequest(hmi_apis::FunctionID::Buttons_ButtonPress, + &(*message_)[app_mngr::strings::msg_params], + true); + } else if (!button_name_matches_module_type) { + LOG4CXX_WARN(logger_, "Request module type and button name mismatch!"); + SetResourceState(module_type, ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "Request module type and button name mismatch!"); + } else { + LOG4CXX_WARN(logger_, "Requested button is not exists in capabilities!"); + SetResourceState(module_type, ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Requested button is not exists in capabilities!"); + } +} + +AcquireResult::eType ButtonPressRequest::AcquireResource( + const app_mngr::commands::MessageSharedPtr& message) { + LOG4CXX_AUTO_TRACE(logger_); + const std::string module_type = ModuleType(); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + return resource_allocation_manager_.AcquireResource(module_type, + app->app_id()); +} + +bool ButtonPressRequest::IsResourceFree(const std::string& module_type) const { + LOG4CXX_AUTO_TRACE(logger_); + return resource_allocation_manager_.IsResourceFree(module_type); +} + +void ButtonPressRequest::SetResourceState(const std::string& module_type, + const ResourceState::eType state) { + LOG4CXX_AUTO_TRACE(logger_); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + resource_allocation_manager_.SetResourceState( + module_type, app->app_id(), state); +} + +void ButtonPressRequest::on_event(const app_mngr::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + RCCommandRequest::on_event(event); + + if (hmi_apis::FunctionID::Buttons_ButtonPress != event.id()) { + return; + } + + const smart_objects::SmartObject& message = event.smart_object(); + mobile_apis::Result::eType result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + message[app_mngr::strings::params][app_mngr::hmi_response::code] + .asUInt())); + + bool result = + helpers::Compare<mobile_apis::Result::eType, helpers::EQ, helpers::ONE>( + result_code, + mobile_apis::Result::SUCCESS, + mobile_apis::Result::WARNINGS); + + if (mobile_apis::Result::READ_ONLY == result_code) { + result = false; + result_code = mobile_apis::Result::GENERIC_ERROR; + } + std::string response_info; + GetInfo(message, response_info); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(result, result_code, response_info.c_str()); +} + +std::string ButtonPressRequest::ModuleType() { + mobile_apis::ModuleType::eType module_type = static_cast< + mobile_apis::ModuleType::eType>( + (*message_)[app_mngr::strings::msg_params][message_params::kModuleType] + .asUInt()); + const char* str; + const bool ok = ns_smart_device_link::ns_smart_objects::EnumConversionHelper< + mobile_apis::ModuleType::eType>::EnumToCString(module_type, &str); + return ok ? str : "unknown"; +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_response.cc new file mode 100644 index 0000000000..491b0363c9 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_response.cc @@ -0,0 +1,56 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/button_press_response.h" +#include "application_manager/rpc_service.h" + +namespace rc_rpc_plugin { +namespace commands { + +ButtonPressResponse::ButtonPressResponse( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::CommandResponseImpl( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} +ButtonPressResponse::~ButtonPressResponse() {} + +void ButtonPressResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc new file mode 100644 index 0000000000..4d12b4f375 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_request.cc @@ -0,0 +1,404 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the copyright holders nor the names of their contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_request.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "rc_rpc_plugin/rc_helpers.h" +#include "rc_rpc_plugin/rc_rpc_plugin.h" +#include "smart_objects/enum_schema_item.h" +#include "utils/macro.h" +#include "interfaces/MOBILE_API.h" + +namespace rc_rpc_plugin { +namespace commands { + +using namespace json_keys; +using namespace message_params; + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +GetInteriorVehicleDataRequest::GetInteriorVehicleDataRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : RCCommandRequest(message, params) + + , excessive_subscription_occured_(false) {} + +bool CheckIfModuleTypeExistInCapabilities( + const smart_objects::SmartObject& rc_capabilities, + const std::string& module_type) { + LOG4CXX_AUTO_TRACE(logger_); + const auto& mapping = RCHelpers::GetModuleTypeToCapabilitiesMapping(); + const auto& module_list = RCHelpers::GetModulesList(); + bool is_module_type_valid = false; + for (const auto& module : module_list) { + if (module == module_type) { + if (rc_capabilities.keyExists(mapping(module))) { + is_module_type_valid = true; + break; + } + } + } + return is_module_type_valid; +} + +bool GetInteriorVehicleDataRequest::ProcessCapabilities() { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject* rc_capabilities = + hmi_capabilities_.rc_capability(); + + const std::string module_type = ModuleType(); + if (rc_capabilities && + !CheckIfModuleTypeExistInCapabilities(*rc_capabilities, module_type)) { + LOG4CXX_WARN(logger_, "Accessing not supported module data"); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Accessing not supported module data"); + return false; + } + return true; +} + +void GetInteriorVehicleDataRequest::FilterDisabledModuleData( + smart_objects::SmartObject& module_data) { + // If radioEnable is false, remove all other radio parameters from the + // message. + if (module_data.keyExists(message_params::kRadioEnable) && + module_data[message_params::kRadioEnable].asBool() == false) { + for (auto data = module_data.map_begin(); data != module_data.map_end();) { + auto key = data->first; + ++data; + if (key != message_params::kRadioEnable) { + module_data.erase(key); + } + } + } + // If hdRadioEnable is false, find and remove the HDChannel if parameter is + // present. + if (module_data.keyExists(message_params::kHdRadioEnable) && + module_data[message_params::kHdRadioEnable].asBool() == false) { + module_data.erase(message_params::kHdChannel); + module_data.erase(message_params::kAvailableHDs); + module_data.erase(message_params::kSisData); + } +} + +void GetInteriorVehicleDataRequest::ProcessResponseToMobileFromCache( + app_mngr::ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); + auto data = interior_data_cache_.Retrieve(ModuleType()); + FilterDisabledModuleData(data); + auto response_msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + response_msg_params[message_params::kModuleData][data_mapping(ModuleType())] = + data; + response_msg_params[message_params::kModuleData] + [message_params::kModuleType] = ModuleType(); + + const auto& request_msg_params = (*message_)[app_mngr::strings::msg_params]; + LOG4CXX_DEBUG(logger_, + "kSubscribe exist" << request_msg_params.keyExists( + message_params::kSubscribe)); + if (request_msg_params.keyExists(message_params::kSubscribe)) { + response_msg_params[message_params::kIsSubscribed] = + request_msg_params[message_params::kSubscribe].asBool(); + if (request_msg_params[message_params::kSubscribe].asBool()) { + auto extension = RCHelpers::GetRCExtension(*app); + DCHECK(extension); + extension->SubscribeToInteriorVehicleData(ModuleType()); + } + } + SendResponse( + true, mobile_apis::Result::SUCCESS, nullptr, &response_msg_params); + if (AppShouldBeUnsubscribed()) { + auto extension = RCHelpers::GetRCExtension(*app); + DCHECK(extension); + extension->UnsubscribeFromInteriorVehicleData(ModuleType()); + } +} + +bool GetInteriorVehicleDataRequest::CheckRateLimits() { + LOG4CXX_AUTO_TRACE(logger_); + return interior_data_manager_.CheckRequestsToHMIFrequency(ModuleType()); +} + +bool GetInteriorVehicleDataRequest::AppShouldBeUnsubscribed() { + LOG4CXX_AUTO_TRACE(logger_); + const auto& msg_params = (*message_)[app_mngr::strings::msg_params]; + if (msg_params.keyExists(message_params::kSubscribe)) { + return !(msg_params[message_params::kSubscribe].asBool()); + } + return false; +} + +bool GetInteriorVehicleDataRequest::TheLastAppShouldBeUnsubscribed( + app_mngr::ApplicationSharedPtr app) { + LOG4CXX_AUTO_TRACE(logger_); + if (AppShouldBeUnsubscribed()) { + const auto subscribed_to_module_type = + RCHelpers::AppsSubscribedToModuleType(application_manager_, + ModuleType()); + if (subscribed_to_module_type.size() == 1 && + subscribed_to_module_type.front() == app) { + LOG4CXX_DEBUG(logger_, + "The last application unsubscribes from " << ModuleType()); + return true; + } + } + return false; +} + +void GetInteriorVehicleDataRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + if (!ProcessCapabilities()) { + return; + } + + app_mngr::ApplicationSharedPtr app = + application_manager_.application(connection_key()); + + if (TheLastAppShouldBeUnsubscribed(app) || + !interior_data_cache_.Contains(ModuleType())) { + if (HasRequestExcessiveSubscription()) { + excessive_subscription_occured_ = true; + is_subscribed = + (*message_)[app_mngr::strings::msg_params][message_params::kSubscribe] + .asBool(); + RemoveExcessiveSubscription(); + } + if (!CheckRateLimits()) { + LOG4CXX_WARN(logger_, "GetInteriorVehicleData frequency is too high."); + SendResponse(false, mobile_apis::Result::REJECTED); + return; + } + interior_data_manager_.StoreRequestToHMITime(ModuleType()); + SendHMIRequest(hmi_apis::FunctionID::RC_GetInteriorVehicleData, + &(*message_)[app_mngr::strings::msg_params], + true); + return; + } + ProcessResponseToMobileFromCache(app); +} + +void GetInteriorVehicleDataRequest::on_event( + const app_mngr::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + RCCommandRequest::on_event(event); + + if (hmi_apis::FunctionID::RC_GetInteriorVehicleData != event.id()) { + return; + } + + smart_objects::SmartObject& hmi_response = + const_cast<smart_objects::SmartObject&>(event.smart_object()); + + mobile_apis::Result::eType result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + hmi_response[app_mngr::strings::params][app_mngr::hmi_response::code] + .asUInt())); + + bool result = + helpers::Compare<mobile_apis::Result::eType, helpers::EQ, helpers::ONE>( + result_code, + mobile_apis::Result::SUCCESS, + mobile_apis::Result::WARNINGS); + + if (mobile_apis::Result::READ_ONLY == result_code) { + result = false; + result_code = mobile_apis::Result::GENERIC_ERROR; + } + + if (result) { + app_mngr::ApplicationSharedPtr app = + application_manager_.application(connection_key()); + + DCHECK_OR_RETURN_VOID(app); + if (TheLastAppShouldBeUnsubscribed(app)) { + interior_data_cache_.Remove(ModuleType()); + } + ProccessSubscription(hmi_response); + if (is_subscribed) { + const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); + const auto module_data = + hmi_response[app_mngr::strings::msg_params] + [message_params::kModuleData][data_mapping(ModuleType())]; + interior_data_cache_.Add(ModuleType(), module_data); + } + } else { + hmi_response[app_mngr::strings::msg_params].erase( + message_params::kIsSubscribed); + } + std::string response_info; + GetInfo(hmi_response, response_info); + SetResourceState(ModuleType(), ResourceState::FREE); + + SendResponse(result, + result_code, + response_info.c_str(), + &hmi_response[app_mngr::strings::msg_params]); +} + +GetInteriorVehicleDataRequest::~GetInteriorVehicleDataRequest() {} + +void GetInteriorVehicleDataRequest::ProccessSubscription( + const ns_smart_device_link::ns_smart_objects::SmartObject& hmi_response) { + LOG4CXX_AUTO_TRACE(logger_); + + const bool is_subscribe_present_in_request = + (*message_)[app_mngr::strings::msg_params].keyExists( + message_params::kSubscribe) || + excessive_subscription_occured_; + + const bool isSubscribed_present_in_response = + hmi_response[app_mngr::strings::msg_params].keyExists( + message_params::kIsSubscribed); + + smart_objects::SmartObject& temp_hmi_response = + const_cast<smart_objects::SmartObject&>(hmi_response); + + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + const auto extension = RCHelpers::GetRCExtension(*app); + const char* module_type; + ns_smart_device_link::ns_smart_objects:: + EnumConversionHelper<mobile_apis::ModuleType::eType>::EnumToCString( + static_cast<mobile_apis::ModuleType::eType>( + hmi_response[app_mngr::strings::msg_params] + [message_params::kModuleData] + [message_params::kModuleType].asUInt()), + &module_type); + if (excessive_subscription_occured_) { + is_subscribed = extension->IsSubscibedToInteriorVehicleData(module_type); + temp_hmi_response[app_mngr::strings::msg_params] + [message_params::kIsSubscribed] = is_subscribed; + return; + } + if (!is_subscribe_present_in_request && !isSubscribed_present_in_response) { + return; + } + + if (is_subscribe_present_in_request && !isSubscribed_present_in_response) { + LOG4CXX_WARN(logger_, + "conditional mandatory parameter " + << message_params::kIsSubscribed + << " missed in hmi response"); + + is_subscribed = extension->IsSubscibedToInteriorVehicleData(module_type); + temp_hmi_response[app_mngr::strings::msg_params] + [message_params::kIsSubscribed] = is_subscribed; + return; + } + + if (!is_subscribe_present_in_request && isSubscribed_present_in_response) { + LOG4CXX_WARN(logger_, + "Parameter " << message_params::kIsSubscribed + << " is ignored due to absence '" + << message_params::kSubscribe + << "' parameter in request"); + smart_objects::SmartObject& temp_hmi_response = + const_cast<smart_objects::SmartObject&>(hmi_response); + temp_hmi_response[app_mngr::strings::msg_params].erase( + message_params::kIsSubscribed); + return; + } + + const bool request_subscribe = + (*message_)[app_mngr::strings::msg_params][message_params::kSubscribe] + .asBool(); + const bool response_subscribe = + hmi_response[app_mngr::strings::msg_params][message_params::kIsSubscribed] + .asBool(); + is_subscribed = response_subscribe; + + LOG4CXX_TRACE(logger_, "request_subscribe = " << request_subscribe); + LOG4CXX_TRACE(logger_, "response_subscribe = " << response_subscribe); + if (request_subscribe == response_subscribe) { + const std::string module_type = ModuleType(); + if (response_subscribe) { + LOG4CXX_DEBUG(logger_, + "SubscribeToInteriorVehicleData " << app->app_id() << " " + << module_type); + extension->SubscribeToInteriorVehicleData(module_type); + } else { + LOG4CXX_DEBUG(logger_, + "UnsubscribeFromInteriorVehicleData " + << app->app_id() << " " << module_type); + extension->UnsubscribeFromInteriorVehicleData(module_type); + } + } +} + +bool GetInteriorVehicleDataRequest::HasRequestExcessiveSubscription() { + LOG4CXX_AUTO_TRACE(logger_); + const bool is_subscribe_present_in_request = + (*message_)[app_mngr::strings::msg_params].keyExists( + message_params::kSubscribe); + + if (is_subscribe_present_in_request) { + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + const auto extension = RCHelpers::GetRCExtension(*app); + + const bool is_app_already_subscribed = + extension->IsSubscibedToInteriorVehicleData(ModuleType()); + const bool app_wants_to_subscribe = + (*message_)[app_mngr::strings::msg_params][message_params::kSubscribe] + .asBool(); + if (!app_wants_to_subscribe && !is_app_already_subscribed) { + return true; + } + return app_wants_to_subscribe && is_app_already_subscribed; + } + return false; +} + +void GetInteriorVehicleDataRequest::RemoveExcessiveSubscription() { + LOG4CXX_AUTO_TRACE(logger_); + (*message_)[app_mngr::strings::msg_params].erase(message_params::kSubscribe); +} + +std::string GetInteriorVehicleDataRequest::ModuleType() { + mobile_apis::ModuleType::eType module_type = static_cast< + mobile_apis::ModuleType::eType>( + (*message_)[app_mngr::strings::msg_params][message_params::kModuleType] + .asUInt()); + const char* str; + const bool ok = ns_smart_device_link::ns_smart_objects::EnumConversionHelper< + mobile_apis::ModuleType::eType>::EnumToCString(module_type, &str); + return ok ? str : "unknown"; +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_response.cc new file mode 100644 index 0000000000..a7572f1d62 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/get_interior_vehicle_data_response.cc @@ -0,0 +1,56 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/get_interior_vehicle_data_response.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +GetInteriorVehicleDataResponse::GetInteriorVehicleDataResponse( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::CommandResponseImpl( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} +GetInteriorVehicleDataResponse::~GetInteriorVehicleDataResponse() {} + +void GetInteriorVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc new file mode 100644 index 0000000000..37890b7979 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/on_interior_vehicle_data_notification.cc @@ -0,0 +1,108 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the copyright holders nor the names of their contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/on_interior_vehicle_data_notification.h" +#include "rc_rpc_plugin/rc_rpc_plugin.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "rc_rpc_plugin/rc_helpers.h" +#include "smart_objects/enum_schema_item.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +OnInteriorVehicleDataNotification::OnInteriorVehicleDataNotification( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : app_mngr::commands::CommandNotificationImpl(message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) + , interior_data_cache_(params.interior_data_cache_) {} + +OnInteriorVehicleDataNotification::~OnInteriorVehicleDataNotification() {} + +void OnInteriorVehicleDataNotification::AddDataToCache( + const std::string& module_type) { + const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); + const auto module_data = + (*message_)[app_mngr::strings::msg_params][message_params::kModuleData] + [data_mapping(module_type)]; + interior_data_cache_.Add(module_type, module_data); +} + +void OnInteriorVehicleDataNotification::Run() { + LOG4CXX_AUTO_TRACE(logger_); + + const std::string module_type = ModuleType(); + auto apps_subscribed = + RCHelpers::AppsSubscribedToModuleType(application_manager_, module_type); + if (!apps_subscribed.empty()) { + AddDataToCache(module_type); + } + typedef std::vector<application_manager::ApplicationSharedPtr> AppPtrs; + AppPtrs apps = RCRPCPlugin::GetRCApplications(application_manager_); + + for (AppPtrs::iterator it = apps.begin(); it != apps.end(); ++it) { + DCHECK(*it); + application_manager::Application& app = **it; + + const auto extension = RCHelpers::GetRCExtension(app); + DCHECK(extension); + LOG4CXX_TRACE(logger_, + "Check subscription for " + << app.app_id() << "and module type " << module_type); + if (extension->IsSubscibedToInteriorVehicleData(module_type)) { + (*message_)[app_mngr::strings::params] + [app_mngr::strings::connection_key] = app.app_id(); + SendNotification(); + } + } +} + +std::string OnInteriorVehicleDataNotification::ModuleType() { + mobile_apis::ModuleType::eType module_type = + static_cast<mobile_apis::ModuleType::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kModuleData][message_params::kModuleType] + .asUInt()); + const char* str; + const bool ok = ns_smart_device_link::ns_smart_objects::EnumConversionHelper< + mobile_apis::ModuleType::eType>::EnumToCString(module_type, &str); + return ok ? str : "unknown"; +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc new file mode 100644 index 0000000000..edc45670ce --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_request.cc @@ -0,0 +1,787 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_request.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "rc_rpc_plugin/rc_rpc_plugin.h" +#include "rc_rpc_plugin/rc_helpers.h" +#include "smart_objects/enum_schema_item.h" +#include "utils/macro.h" +#include "json/json.h" +#include "utils/helpers.h" +#include "interfaces/MOBILE_API.h" + +namespace rc_rpc_plugin { +namespace commands { + +using namespace json_keys; +using namespace message_params; + +namespace { +std::vector<std::string> GetModuleReadOnlyParams( + const std::string& module_type) { + std::vector<std::string> module_ro_params; + if (enums_value::kClimate == module_type) { + module_ro_params.push_back(kCurrentTemperature); + } else if (enums_value::kRadio == module_type) { + module_ro_params.push_back(kRdsData); + module_ro_params.push_back(kAvailableHDs); + module_ro_params.push_back(kSignalStrength); + module_ro_params.push_back(kSignalChangeThreshold); + module_ro_params.push_back(kState); + module_ro_params.push_back(kSisData); + } else if (enums_value::kLight == module_type) { + module_ro_params.push_back(kLightStatus); + } + + return module_ro_params; +} + +const std::map<std::string, std::string> GetLightCapabilitiesMapping() { + std::map<std::string, std::string> mapping = { + {message_params::kId, strings::kName}, + {message_params::kLightStatus, strings::kStatusAvailable}, + {message_params::kLightDensity, strings::kDensityAvailable}, + {message_params::kLightColor, strings::kRGBColorSpaceAvailable}}; + return mapping; +} + +const std::map<std::string, std::string> GetModuleDataToCapabilitiesMapping() { + std::map<std::string, std::string> mapping; + // climate + mapping["fanSpeed"] = "fanSpeedAvailable"; + mapping["currentTemperature"] = "currentTemperatureAvailable"; + mapping["desiredTemperature"] = "desiredTemperatureAvailable"; + mapping["acEnable"] = "acEnableAvailable"; + mapping["circulateAirEnable"] = "circulateAirEnableAvailable"; + mapping["autoModeEnable"] = "autoModeEnableAvailable"; + mapping["defrostZone"] = "defrostZoneAvailable"; + mapping["dualModeEnable"] = "dualModeEnableAvailable"; + mapping["acMaxEnable"] = "acMaxEnableAvailable"; + mapping["ventilationMode"] = "ventilationModeAvailable"; + mapping["heatedSteeringWheelEnable"] = "heatedSteeringWheelAvailable"; + mapping["heatedWindshieldEnable"] = "heatedWindshieldAvailable"; + mapping["heatedMirrorsEnable"] = "heatedMirrorsAvailable"; + mapping["heatedRearWindowEnable"] = "heatedRearWindowAvailable"; + + // radio + mapping["band"] = "radioBandAvailable"; + mapping["frequencyInteger"] = "radioFrequencyAvailable"; + mapping["frequencyFraction"] = "radioFrequencyAvailable"; + mapping["rdsData"] = "rdsDataAvailable"; + mapping["availableHDs"] = "availableHDsAvailable"; + mapping["hdChannel"] = "availableHDsAvailable"; + mapping["hdRadioEnable"] = "hdRadioEnableAvailable"; + mapping["signalStrength"] = "signalStrengthAvailable"; + mapping["signalChangeThreshold"] = "signalChangeThresholdAvailable"; + mapping["radioEnable"] = "radioEnableAvailable"; + mapping["state"] = "stateAvailable"; + mapping["sisData"] = "sisDataAvailable"; + + // seat + mapping["heatingEnabled"] = "heatingEnabledAvailable"; + mapping["coolingEnabled"] = "coolingEnabledAvailable"; + mapping["heatingLevel"] = "heatingLevelAvailable"; + mapping["coolingLevel"] = "coolingLevelAvailable"; + mapping["horizontalPosition"] = "horizontalPositionAvailable"; + mapping["verticalPosition"] = "verticalPositionAvailable"; + mapping["frontVerticalPosition"] = "frontVerticalPositionAvailable"; + mapping["backVerticalPosition"] = "backVerticalPositionAvailable"; + mapping["backTiltAngle"] = "backTiltAngleAvailable"; + mapping["headSupportHorizontalPosition"] = + "headSupportHorizontalPositionAvailable"; + mapping["headSupportVerticalPosition"] = + "headSupportVerticalPositionAvailable"; + mapping["massageEnabled"] = "massageEnabledAvailable"; + mapping["massageMode"] = "massageModeAvailable"; + mapping["massageCushionFirmness"] = "massageCushionFirmnessAvailable"; + mapping["memory"] = "memoryAvailable"; + + // audio + mapping["source"] = "sourceAvailable"; + mapping["keepContext"] = "keepContextAvailable"; + mapping["volume"] = "volumeAvailable"; + mapping["equalizerSettings"] = "equalizerAvailable"; + + // hmi settings + mapping["distanceUnit"] = "distanceUnitAvailable"; + mapping["temperatureUnit"] = "temperatureUnitAvailable"; + mapping["displayMode"] = "displayModeUnitAvailable"; + + return mapping; +} +} // namespace + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +SetInteriorVehicleDataRequest::SetInteriorVehicleDataRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : RCCommandRequest(message, params) {} + +SetInteriorVehicleDataRequest::~SetInteriorVehicleDataRequest() {} + +const std::string LightName(const smart_objects::SmartObject& light_name) { + const char* name; + const bool ok = ns_smart_device_link::ns_smart_objects:: + EnumConversionHelper<mobile_apis::LightName::eType>::EnumToCString( + static_cast<mobile_apis::LightName::eType>(light_name.asUInt()), + &name); + return ok ? name : "unknown"; +} + +/** + * @brief Check whether the parameter exist in capabilities + * @param smart object of capabilities + * @param mapping - map of module data and capabilities + * @param request_parameter - string + * @param switched_off_result - ref of mobile_apis::Result + * @return success if parameter exist in capabilities missedParam otherwise + */ +capabilitiesStatus GetItemCapability( + const smart_objects::SmartObject& capabilities, + const std::map<std::string, std::string>& mapping, + const std::string& request_parameter, + const mobile_apis::Result::eType& switched_off_result) { + const auto it = mapping.find(request_parameter); + + if (it == mapping.end()) { + LOG4CXX_DEBUG(logger_, + "Parameter " << request_parameter + << " doesn't exist in capabilities."); + return capabilitiesStatus::missedParam; + } + + const std::string& caps_key = it->second; + + LOG4CXX_DEBUG(logger_, + "Checking request parameter " + << request_parameter + << " with capabilities. Appropriate key is " << caps_key); + + if (!capabilities.keyExists(caps_key)) { + LOG4CXX_DEBUG(logger_, + "Capability " << caps_key + << " is missed in RemoteControl capabilities"); + return capabilitiesStatus::missedParam; + } + + if (!capabilities[caps_key].asBool()) { + LOG4CXX_DEBUG(logger_, + "Capability " + << caps_key + << " is switched off in RemoteControl capabilities"); + capabilitiesStatus status = capabilitiesStatus::missedParam; + if (mobile_apis::Result::READ_ONLY == switched_off_result) { + status = capabilitiesStatus::readOnly; + } + return status; + } + + return capabilitiesStatus::success; +} + +/** + * @brief Check whether the cpabilities for light allowed + * @param smart object of capabilities + * @param smart object of control_data + * @return pair of state and capability status - ModuleCapability + */ +ModuleCapability GetLightDataCapabilities( + const smart_objects::SmartObject& capabilities, + const smart_objects::SmartObject& control_data) { + LOG4CXX_AUTO_TRACE(logger_); + std::map<std::string, std::string> mapping = GetLightCapabilitiesMapping(); + + for (auto it = control_data.map_begin(); it != control_data.map_end(); ++it) { + const std::string& request_parameter = it->first; + + if (message_params::kId == request_parameter) { + continue; + } + + const capabilitiesStatus status_item_capability = + GetItemCapability(capabilities, + mapping, + request_parameter, + mobile_apis::Result::READ_ONLY); + + if (capabilitiesStatus::success != status_item_capability) { + return std::make_pair(message_params::kLightState, + status_item_capability); + } + } + + return std::make_pair("", capabilitiesStatus::success); +} + +/** + * @brief Check whether the light name exists in capabilities + * @param smart object of capabilities_status + * @param smart object of light_data + * @return pair of state and capability status - ModuleCapability + */ +ModuleCapability GetLightNameCapabilities( + const smart_objects::SmartObject& capabilities_status, + const smart_objects::SmartObject& light_data) { + LOG4CXX_AUTO_TRACE(logger_); + auto it = capabilities_status.asArray()->begin(); + for (; it != capabilities_status.asArray()->end(); ++it) { + const smart_objects::SmartObject& so = *it; + const int64_t current_id = so[message_params::kName].asInt(); + if (current_id == light_data[message_params::kId].asInt()) { + return GetLightDataCapabilities(so, light_data); + } + } + LOG4CXX_DEBUG(logger_, "There is no such light name in capabilities"); + return std::make_pair(message_params::kLightState, + capabilitiesStatus::missedLightName); +} + +ModuleCapability GetRadioBandByCapabilities( + const smart_objects::SmartObject& capabilities_status, + const smart_objects::SmartObject& request_parameter) { + mobile_apis::RadioBand::eType radio_band = + static_cast<mobile_apis::RadioBand::eType>(request_parameter.asUInt()); + if (mobile_apis::RadioBand::XM == radio_band) { + if (!capabilities_status.keyExists(strings::kSiriusxmRadioAvailable)) { + LOG4CXX_DEBUG(logger_, + "Capability " + << strings::kSiriusxmRadioAvailable + << " is missed in RemoteControl capabilities"); + return std::make_pair(strings::kSiriusxmRadioAvailable, + capabilitiesStatus::missedParam); + } + if (!capabilities_status[strings::kSiriusxmRadioAvailable].asBool()) { + LOG4CXX_DEBUG(logger_, + "Capability " + << strings::kSiriusxmRadioAvailable + << " is switched off in RemoteControl capabilities"); + return std::make_pair(strings::kSiriusxmRadioAvailable, + capabilitiesStatus::missedParam); + } + } + return std::make_pair("", capabilitiesStatus::success); +} + +/** + * @brief Check whether the exists light data related to correspondent + * capabilities + * @param smart object of capabilities + * @param smart object of control_data + * @return pair of state and capability status - ModuleCapability + */ +ModuleCapability GetControlDataCapabilities( + const smart_objects::SmartObject& capabilities, + const smart_objects::SmartObject& control_data) { + LOG4CXX_AUTO_TRACE(logger_); + std::map<std::string, std::string> mapping = + GetModuleDataToCapabilitiesMapping(); + + for (auto it = control_data.map_begin(); it != control_data.map_end(); ++it) { + const std::string& request_parameter = it->first; + if (message_params::kId == request_parameter) { + continue; + } + if (message_params::kLightState == request_parameter) { + auto light_data = control_data[request_parameter].asArray()->begin(); + ModuleCapability light_capability = + std::make_pair("", capabilitiesStatus::success); + + for (; light_data != control_data[request_parameter].asArray()->end(); + ++light_data) { + light_capability = GetLightNameCapabilities( + capabilities[strings::kSupportedLights], *light_data); + + if (capabilitiesStatus::success != light_capability.second) { + return light_capability; + } + } + + return light_capability; + } + if (message_params::kBand == request_parameter) { + ModuleCapability radio_capability = GetRadioBandByCapabilities( + capabilities, control_data[request_parameter]); + if (capabilitiesStatus::success != radio_capability.second) { + return radio_capability; + } + } + + const capabilitiesStatus status_item_capability = + GetItemCapability(capabilities, + mapping, + request_parameter, + mobile_apis::Result::UNSUPPORTED_RESOURCE); + + if (capabilitiesStatus::success != status_item_capability) { + return std::make_pair("", status_item_capability); + } + } + + return std::make_pair("", capabilitiesStatus::success); +} + +/** + * @brief Check whether rc module data capabilities are presented + * @param smart object of rc_capabilities + * @param smart object of module_data + * @return pair of state and capability status - ModuleCapability + */ +ModuleCapability GetModuleDataCapabilities( + const smart_objects::SmartObject& rc_capabilities, + const smart_objects::SmartObject& module_data) { + LOG4CXX_AUTO_TRACE(logger_); + + const auto& all_module_types = RCHelpers::GetModulesList(); + const auto& get_module_data_key = RCHelpers::GetModuleTypeToDataMapping(); + const auto& get_capabilities_key = + RCHelpers::GetModuleTypeToCapabilitiesMapping(); + ModuleCapability module_data_capabilities = + std::make_pair("", capabilitiesStatus::missedParam); + + for (const auto& module_type : all_module_types) { + const auto module_data_key = get_module_data_key(module_type); + const auto capabilities_key = get_capabilities_key(module_type); + if (module_data.keyExists(module_data_key)) { + if (!rc_capabilities.keyExists(capabilities_key)) { + LOG4CXX_DEBUG(logger_, module_data_key << " capabilities not present"); + return module_data_capabilities; + } + const smart_objects::SmartObject& caps = + rc_capabilities[capabilities_key]; + + if (message_params::kHmiSettingsControlData == module_data_key || + message_params::kLightControlData == module_data_key) { + module_data_capabilities = + GetControlDataCapabilities(caps, module_data[module_data_key]); + } else { + module_data_capabilities = + GetControlDataCapabilities(caps[0], module_data[module_data_key]); + } + } + } + + return module_data_capabilities; +} + +/** + * @brief Clears unrelated module data parameters + * @param module type in request + * @param smart object of module_data + * @return true if the correct module parameter is present, false otherwise + */ +bool ClearUnrelatedModuleData(const std::string& module_type, + smart_objects::SmartObject& module_data) { + LOG4CXX_AUTO_TRACE(logger_); + const auto& all_module_types = RCHelpers::GetModulesList(); + const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); + bool module_type_and_data_match = false; + for (const auto& type : all_module_types) { + const std::string module_key = data_mapping(type); + if (type == module_type) { + module_type_and_data_match = module_data.keyExists(module_key); + } else if (module_data.keyExists(module_key)) { + // Cutting unrelated module data + module_data.erase(module_key); + } + } + return module_type_and_data_match; +} + +mobile_apis::Result::eType PrepareResultCodeAndInfo( + const ModuleCapability module_data_capabilities, std::string& info) { + mobile_apis::Result::eType result_code = + mobile_apis::Result::UNSUPPORTED_RESOURCE; + if (message_params::kLightState == module_data_capabilities.first) { + switch (module_data_capabilities.second) { + case capabilitiesStatus::missedLightName: + info = "The requested LightName is not supported by the vehicle."; + break; + case capabilitiesStatus::missedParam: + info = + "The requested parameter of the given LightName is not supported " + "by the vehicle."; + break; + case capabilitiesStatus::readOnly: + info = "The requested parameter is read-only."; + result_code = mobile_apis::Result::READ_ONLY; + break; + default: + break; + } + + } else { + info = "Accessing not supported module data."; + } + return result_code; + LOG4CXX_WARN(logger_, info); +} + +void SetInteriorVehicleDataRequest::Execute() { + LOG4CXX_AUTO_TRACE(logger_); + + smart_objects::SmartObject& module_data = + (*message_)[app_mngr::strings::msg_params][message_params::kModuleData]; + const std::string module_type = ModuleType(); + + if (ClearUnrelatedModuleData(module_type, module_data)) { + const smart_objects::SmartObject* rc_capabilities = + hmi_capabilities_.rc_capability(); + ModuleCapability module_data_capabilities; + + if (rc_capabilities) { + module_data_capabilities = + GetModuleDataCapabilities(*rc_capabilities, module_data); + + if (capabilitiesStatus::success != module_data_capabilities.second) { + SetResourceState(ModuleType(), ResourceState::FREE); + std::string info; + mobile_apis::Result::eType result = + PrepareResultCodeAndInfo(module_data_capabilities, info); + SendResponse(false, result, info.c_str()); + return; + } + } + + if (AreAllParamsReadOnly(module_data)) { + LOG4CXX_WARN(logger_, "All request params in module type are READ ONLY!"); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::READ_ONLY, + "All request params in module type are READ ONLY!"); + return; + } + + module_data_capabilities = std::make_pair("", capabilitiesStatus::success); + + if (AreReadOnlyParamsPresent(module_data, module_data_capabilities)) { + LOG4CXX_DEBUG(logger_, "Request module type has READ ONLY parameters"); + + if (enums_value::kLight == module_data_capabilities.first && + capabilitiesStatus::success != module_data_capabilities.second) { + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse( + false, + mobile_apis::Result::READ_ONLY, + "The LightStatus enum passed is READ ONLY and cannot be written."); + return; + } + + LOG4CXX_DEBUG(logger_, "Cutting-off READ ONLY parameters... "); + + CutOffReadOnlyParams(module_data); + } + + application_manager_.RemoveHMIFakeParameters( + message_, hmi_apis::FunctionID::RC_SetInteriorVehicleData); + + app_mngr::ApplicationSharedPtr app = + application_manager_.application(connection_key()); + (*message_)[app_mngr::strings::msg_params][app_mngr::strings::app_id] = + app->app_id(); + + const bool app_wants_to_set_audio_src = + module_data.keyExists(message_params::kAudioControlData) && + module_data[message_params::kAudioControlData].keyExists( + message_params::kSource); + + if (app_wants_to_set_audio_src) { + if (!app->IsAllowedToChangeAudioSource()) { + LOG4CXX_WARN(logger_, "App is not allowed to change audio source"); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::REJECTED, + "App is not allowed to change audio source"); + return; + } else if (module_data[message_params::kAudioControlData].keyExists( + message_params::kKeepContext)) { + app->set_keep_context( + module_data[message_params::kAudioControlData] + [message_params::kKeepContext].asBool()); + } + } + + SendHMIRequest(hmi_apis::FunctionID::RC_SetInteriorVehicleData, + &(*message_)[app_mngr::strings::msg_params], + true); + } else { + LOG4CXX_WARN(logger_, "Request module type & data mismatch!"); + SendResponse(false, + mobile_apis::Result::INVALID_DATA, + "Request module type & data mismatch!"); + } +} + +void SetInteriorVehicleDataRequest::on_event( + const app_mngr::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + RCCommandRequest::on_event(event); + + if (hmi_apis::FunctionID::RC_SetInteriorVehicleData != event.id()) { + return; + } + + const smart_objects::SmartObject& hmi_response = event.smart_object(); + mobile_apis::Result::eType result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + hmi_response[app_mngr::strings::params][app_mngr::hmi_response::code] + .asUInt())); + + bool result = + helpers::Compare<mobile_apis::Result::eType, helpers::EQ, helpers::ONE>( + result_code, + mobile_apis::Result::SUCCESS, + mobile_apis::Result::WARNINGS); + + smart_objects::SmartObject response_params; + if (result) { + response_params = hmi_response[app_mngr::strings::msg_params]; + if (enums_value::kAudio == ModuleType()) { + CheckAudioSource(( + *message_)[app_mngr::strings::msg_params][message_params::kModuleData] + [message_params::kAudioControlData]); + } + } else { + app_mngr::ApplicationSharedPtr app = + application_manager_.application(connection_key()); + app->set_keep_context(false); + } + std::string info; + GetInfo(hmi_response, info); + SendResponse( + result, result_code, info.c_str(), result ? &response_params : nullptr); +} + +const smart_objects::SmartObject& SetInteriorVehicleDataRequest::ControlData( + const smart_objects::SmartObject& module_data) { + const std::string module_type = ModuleType(); + + const auto& all_module_types = RCHelpers::GetModulesList(); + const auto& data_mapping = RCHelpers::GetModuleTypeToDataMapping(); + for (const auto& type : all_module_types) { + if (type == module_type) { + return module_data[data_mapping(type)]; + } + } + NOTREACHED(); + return module_data[0]; +} + +void SetInteriorVehicleDataRequest::CheckAudioSource( + const smart_objects::SmartObject& audio_data) { + LOG4CXX_AUTO_TRACE(logger_); + if (audio_data.keyExists(message_params::kSource)) { + application_manager_.set_current_audio_source( + audio_data[message_params::kSource].asUInt()); + } +} + +bool SetInteriorVehicleDataRequest::AreAllParamsReadOnly( + const smart_objects::SmartObject& module_data) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& module_type_params = + ControlData(module_data); + auto it = module_type_params.map_begin(); + std::vector<std::string> ro_params = GetModuleReadOnlyParams(ModuleType()); + for (; it != module_type_params.map_end(); ++it) { + if (!helpers::in_range(ro_params, it->first)) { + return false; + } + } + + LOG4CXX_DEBUG(logger_, "All params are ReadOnly"); + return true; +} + +bool CheckReadOnlyParamsForAudio( + const smart_objects::SmartObject& module_type_params) { + if (module_type_params.keyExists(message_params::kEqualizerSettings)) { + const auto& equalizer_settings = + module_type_params[message_params::kEqualizerSettings]; + auto it = equalizer_settings.asArray()->begin(); + + for (; it != equalizer_settings.asArray()->end(); ++it) { + if (it->keyExists(message_params::kChannelName)) { + LOG4CXX_DEBUG(logger_, + "READ ONLY parameter. ChannelName = " + << (*it)[message_params::kChannelName].asString()); + return true; + } + } + } + + return false; +} + +bool CheckReadOnlyParamsForLight( + const smart_objects::SmartObject& module_type_params) { + if (module_type_params.keyExists(message_params::kLightState)) { + const auto& light_state = module_type_params[message_params::kLightState]; + auto it = light_state.asArray()->begin(); + + for (; it != light_state.asArray()->end(); ++it) { + if (it->keyExists(message_params::kLightStatus)) { + const mobile_apis::LightStatus::eType light_status = + static_cast<mobile_apis::LightStatus::eType>( + (*it)[message_params::kLightStatus].asUInt()); + + if (helpers::Compare<mobile_apis::LightStatus::eType, + helpers::EQ, + helpers::ONE>(light_status, + mobile_apis::LightStatus::RAMP_UP, + mobile_apis::LightStatus::RAMP_DOWN, + mobile_apis::LightStatus::UNKNOWN, + mobile_apis::LightStatus::INVALID)) { + LOG4CXX_DEBUG(logger_, + "READ ONLY parameter. Status = " + << (*it)[message_params::kLightStatus].asInt()); + return true; + } + } + } + } + + return false; +} + +bool SetInteriorVehicleDataRequest::AreReadOnlyParamsPresent( + const smart_objects::SmartObject& module_data, + ModuleCapability& module_data_capabilities) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& module_type_params = + ControlData(module_data); + const std::string module_type = ModuleType(); + + if (enums_value::kAudio == module_type) { + return CheckReadOnlyParamsForAudio(module_type_params); + } + + if (enums_value::kLight == module_type) { + const bool result = CheckReadOnlyParamsForLight(module_type_params); + + if (result) { + module_data_capabilities = + std::make_pair(module_type, capabilitiesStatus::readOnly); + } + + return result; + } + + const std::vector<std::string> ro_params = + GetModuleReadOnlyParams(module_type); + auto it = module_type_params.map_begin(); + + for (; it != module_type_params.map_end(); ++it) { + if (helpers::in_range(ro_params, it->first)) { + return true; + } + } + + return false; +} + +void SetInteriorVehicleDataRequest::CutOffReadOnlyParams( + smart_objects::SmartObject& module_data) { + LOG4CXX_AUTO_TRACE(logger_); + const smart_objects::SmartObject& module_type_params = + ControlData(module_data); + const std::string module_type = ModuleType(); + std::vector<std::string> ro_params = GetModuleReadOnlyParams(module_type); + + for (auto& it : ro_params) { + if (module_type_params.keyExists(it)) { + if (enums_value::kClimate == module_type) { + module_data[message_params::kClimateControlData].erase(it); + } else if (enums_value::kRadio == module_type) { + module_data[message_params::kRadioControlData].erase(it); + } else { + continue; + } + + LOG4CXX_DEBUG(logger_, "Cutting-off READ ONLY parameter: " << it); + } + } + + if (enums_value::kAudio == module_type) { + auto& equalizer_settings = module_data[message_params::kAudioControlData] + [message_params::kEqualizerSettings]; + auto it = equalizer_settings.asArray()->begin(); + for (; it != equalizer_settings.asArray()->end(); ++it) { + if (it->keyExists(message_params::kChannelName)) { + it->erase(message_params::kChannelName); + LOG4CXX_DEBUG(logger_, + "Cutting-off READ ONLY parameter: " + << message_params::kChannelName); + } + } + } +} + +std::string SetInteriorVehicleDataRequest::ModuleType() { + mobile_apis::ModuleType::eType module_type = + static_cast<mobile_apis::ModuleType::eType>( + (*message_)[app_mngr::strings::msg_params] + [message_params::kModuleData][message_params::kModuleType] + .asUInt()); + const char* str; + const bool ok = ns_smart_device_link::ns_smart_objects::EnumConversionHelper< + mobile_apis::ModuleType::eType>::EnumToCString(module_type, &str); + return ok ? str : "unknown"; +} + +AcquireResult::eType SetInteriorVehicleDataRequest::AcquireResource( + const app_mngr::commands::MessageSharedPtr& message) { + LOG4CXX_AUTO_TRACE(logger_); + const std::string module_type = ModuleType(); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + return resource_allocation_manager_.AcquireResource(module_type, + app->app_id()); +} + +bool SetInteriorVehicleDataRequest::IsResourceFree( + const std::string& module_type) const { + return resource_allocation_manager_.IsResourceFree(module_type); +} + +void SetInteriorVehicleDataRequest::SetResourceState( + const std::string& module_type, const ResourceState::eType state) { + LOG4CXX_AUTO_TRACE(logger_); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + resource_allocation_manager_.SetResourceState( + module_type, app->app_id(), state); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_response.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_response.cc new file mode 100644 index 0000000000..4dedd4b5a2 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/set_interior_vehicle_data_response.cc @@ -0,0 +1,25 @@ +#include "rc_rpc_plugin/commands/mobile/set_interior_vehicle_data_response.h" +#include "rc_rpc_plugin/interior_data_cache.h" +#include "utils/macro.h" + +namespace rc_rpc_plugin { +namespace commands { + +SetInteriorVehicleDataResponse::SetInteriorVehicleDataResponse( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::CommandResponseImpl( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) {} +SetInteriorVehicleDataResponse::~SetInteriorVehicleDataResponse() {} + +void SetInteriorVehicleDataResponse::Run() { + LOG4CXX_AUTO_TRACE(logger_); + application_manager_.GetRPCService().SendMessageToMobile(message_); +} + +} // namespace commands +} // namespace rc_rpc_plugin diff --git a/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc new file mode 100644 index 0000000000..c24529d720 --- /dev/null +++ b/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/rc_command_request.cc @@ -0,0 +1,268 @@ +/* + Copyright (c) 2018, Ford Motor Company + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. + + Neither the name of the Ford Motor Company nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#include "rc_rpc_plugin/commands/rc_command_request.h" +#include "rc_rpc_plugin/rc_module_constants.h" +#include "application_manager/message_helper.h" +#include "application_manager/hmi_interfaces.h" +#include "smart_objects/enum_schema_item.h" +#include "rc_rpc_plugin/interior_data_cache.h" + +CREATE_LOGGERPTR_GLOBAL(logger_, "RemoteControlModule") + +namespace rc_rpc_plugin { +namespace commands { + +RCCommandRequest::RCCommandRequest( + const app_mngr::commands::MessageSharedPtr& message, + const RCCommandParams& params) + : application_manager::commands::CommandRequestImpl( + message, + params.application_manager_, + params.rpc_service_, + params.hmi_capabilities_, + params.policy_handler_) + , is_subscribed(false) + , auto_allowed_(false) + , resource_allocation_manager_(params.resource_allocation_manager_) + , interior_data_cache_(params.interior_data_cache_) + , interior_data_manager_(params.interior_data_manager_) {} + +RCCommandRequest::~RCCommandRequest() {} + +bool RCCommandRequest::IsInterfaceAvailable( + const app_mngr::HmiInterfaces::InterfaceID interface) const { + app_mngr::HmiInterfaces& hmi_interfaces = + application_manager_.hmi_interfaces(); + const app_mngr::HmiInterfaces::InterfaceState state = + hmi_interfaces.GetInterfaceState(interface); + return app_mngr::HmiInterfaces::STATE_NOT_AVAILABLE != state; +} + +void RCCommandRequest::onTimeOut() { + LOG4CXX_AUTO_TRACE(logger_); + const std::string module_type = ModuleType(); + SetResourceState(module_type, ResourceState::FREE); + SendResponse( + false, mobile_apis::Result::GENERIC_ERROR, "Request timeout expired"); +} + +bool RCCommandRequest::CheckDriverConsent() { + LOG4CXX_AUTO_TRACE(logger_); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + + const std::string module_type = ModuleType(); + rc_rpc_plugin::TypeAccess access = CheckModule(module_type, app); + + if (rc_rpc_plugin::kAllowed == access) { + set_auto_allowed(true); + return true; + } + SendDisallowed(access); + return false; +} + +rc_rpc_plugin::TypeAccess RCCommandRequest::CheckModule( + const std::string& module_type, + application_manager::ApplicationSharedPtr app) { + return policy_handler_.CheckModule(app->policy_app_id(), module_type) + ? rc_rpc_plugin::TypeAccess::kAllowed + : rc_rpc_plugin::TypeAccess::kDisallowed; +} + +void RCCommandRequest::SendDisallowed(rc_rpc_plugin::TypeAccess access) { + LOG4CXX_AUTO_TRACE(logger_); + std::string info; + if (rc_rpc_plugin::kDisallowed == access) { + info = disallowed_info_.empty() + ? "The RPC is disallowed by vehicle settings" + : disallowed_info_; + } else { + return; + } + LOG4CXX_ERROR(logger_, info); + SendResponse(false, mobile_apis::Result::DISALLOWED, info.c_str()); +} + +void RCCommandRequest::Run() { + LOG4CXX_AUTO_TRACE(logger_); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + + if (!IsInterfaceAvailable(app_mngr::HmiInterfaces::HMI_INTERFACE_RC)) { + LOG4CXX_WARN(logger_, "HMI interface RC is not available"); + SendResponse(false, + mobile_apis::Result::UNSUPPORTED_RESOURCE, + "Remote control is not supported by system"); + return; + } + LOG4CXX_TRACE(logger_, "RC interface is available!"); + if (!policy_handler_.CheckHMIType( + app->policy_app_id(), + mobile_apis::AppHMIType::eType::REMOTE_CONTROL, + app->app_types())) { + LOG4CXX_WARN(logger_, "Application has no remote control functions"); + SendResponse(false, mobile_apis::Result::DISALLOWED, ""); + return; + } + if (!resource_allocation_manager_.is_rc_enabled()) { + LOG4CXX_WARN(logger_, "Remote control is disabled by user"); + SetResourceState(ModuleType(), ResourceState::FREE); + SendResponse(false, + mobile_apis::Result::USER_DISALLOWED, + "Remote control is disabled by user"); + return; + } + + if (CheckDriverConsent()) { + if (AcquireResources()) { + Execute(); // run child's logic + } + // If resource is not aqcuired, AcquireResources method will either + // send response to mobile or + // send additional request to HMI to ask driver consent + } +} + +bool RCCommandRequest::AcquireResources() { + LOG4CXX_AUTO_TRACE(logger_); + const std::string module_type = ModuleType(); + + if (!IsResourceFree(module_type)) { + LOG4CXX_WARN(logger_, "Resource is busy."); + SendResponse(false, mobile_apis::Result::IN_USE, ""); + return false; + } + + AcquireResult::eType acquire_result = AcquireResource(message_); + switch (acquire_result) { + case AcquireResult::ALLOWED: { + SetResourceState(module_type, ResourceState::BUSY); + return true; + } + case AcquireResult::IN_USE: { + SendResponse(false, mobile_apis::Result::IN_USE, ""); + return false; + } + case AcquireResult::ASK_DRIVER: { + SendGetUserConsent(module_type); + return false; + } + case AcquireResult::REJECTED: { + SendResponse(false, mobile_apis::Result::REJECTED, ""); + return false; + } + } + return false; +} + +void RCCommandRequest::on_event(const app_mngr::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + + if (event.id() == hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent) { + ProcessAccessResponse(event); + } else { + const std::string module_type = ModuleType(); + SetResourceState(module_type, ResourceState::FREE); + } +} + +void RCCommandRequest::ProcessAccessResponse( + const app_mngr::event_engine::Event& event) { + LOG4CXX_AUTO_TRACE(logger_); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + const std::string module_type = ModuleType(); + if (!app) { + LOG4CXX_ERROR(logger_, "NULL pointer."); + SendResponse(false, mobile_apis::Result::APPLICATION_NOT_REGISTERED, ""); + return; + } + + const smart_objects::SmartObject& message = event.smart_object(); + + mobile_apis::Result::eType result_code = + GetMobileResultCode(static_cast<hmi_apis::Common_Result::eType>( + message[app_mngr::strings::params][app_mngr::hmi_response::code] + .asUInt())); + + const bool result = + helpers::Compare<mobile_apis::Result::eType, helpers::EQ, helpers::ONE>( + result_code, + mobile_apis::Result::SUCCESS, + mobile_apis::Result::WARNINGS); + + bool is_allowed = false; + if (result) { + if (message[app_mngr::strings::msg_params].keyExists( + message_params::kAllowed)) { + is_allowed = + message[app_mngr::strings::msg_params][message_params::kAllowed] + .asBool(); + } + if (is_allowed) { + resource_allocation_manager_.ForceAcquireResource(module_type, + app->app_id()); + SetResourceState(module_type, ResourceState::BUSY); + Execute(); // run child's logic + } else { + resource_allocation_manager_.OnDriverDisallowed(module_type, + app->app_id()); + SendResponse( + false, + mobile_apis::Result::REJECTED, + "The resource is in use and the driver disallows this remote " + "control RPC"); + } + } else { + std::string response_info; + GetInfo(message, response_info); + SendResponse(false, result_code, response_info.c_str()); + } +} + +void RCCommandRequest::SendGetUserConsent(const std::string& module_type) { + LOG4CXX_AUTO_TRACE(logger_); + app_mngr::ApplicationSharedPtr app = + application_manager_.application(CommandRequestImpl::connection_key()); + DCHECK(app); + smart_objects::SmartObject msg_params = + smart_objects::SmartObject(smart_objects::SmartType_Map); + msg_params[app_mngr::strings::app_id] = app->app_id(); + msg_params[message_params::kModuleType] = module_type; + SendHMIRequest(hmi_apis::FunctionID::RC_GetInteriorVehicleDataConsent, + &msg_params, + true); +} +} +} |