summaryrefslogtreecommitdiff
path: root/src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc')
-rw-r--r--src/components/application_manager/rpc_plugins/rc_rpc_plugin/src/commands/mobile/button_press_request.cc290
1 files changed, 290 insertions, 0 deletions
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