diff options
author | agaliuzov <agaliuzov@luxoft.com> | 2016-04-23 06:36:28 -0700 |
---|---|---|
committer | agaliuzov <agaliuzov@luxoft.com> | 2016-04-23 06:44:17 -0700 |
commit | 2d288fbefa3c6ec00debf84d8ea192be3a5b3042 (patch) | |
tree | f94075c21508417c52f71ea78d62511b72f930a5 | |
parent | 301bd6dc13653009553fbedfbc0eabb0c710e195 (diff) | |
parent | 60726ea9c1fbcd094d443149230704c38a2c62da (diff) | |
download | sdl_core-2d288fbefa3c6ec00debf84d8ea192be3a5b3042.tar.gz |
Merge branch 'master' into develop
14 files changed, 206 insertions, 89 deletions
@@ -1,4 +1,4 @@ -##### Note: Please use the [develop](https://github.com/smartdevicelink/sdl_core/tree/develop) or [release candidate](https://github.com/smartdevicelink/sdl_core/tree/release/4.0.0) branches of sdl_core for the most stable versions. +##### Note: Please use the [develop](https://github.com/smartdevicelink/sdl_core/tree/develop) or [master](https://github.com/smartdevicelink/sdl_core) branches of sdl_core for the most stable versions. # SmartDeviceLink (SDL) diff --git a/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp b/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp index 095fffc542..f2b5de61c7 100644 --- a/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp +++ b/src/3rd_party/apache-log4cxx-0.10.0/src/main/cpp/serversocket.cpp @@ -128,6 +128,13 @@ SocketPtr ServerSocket::accept() { throw SocketException(status); } + // Added 5 seconds timeout to fix endless blocking on write() when the client is not reading + status = apr_socket_timeout_set(newSocket, 5000000); + if (status != APR_SUCCESS) { + apr_pool_destroy(newPool); + throw SocketException(status); + } + return new Socket(newSocket, newPool); } diff --git a/src/appMain/main_test.cc b/src/appMain/main_test.cc deleted file mode 100644 index 26da24ce1f..0000000000 --- a/src/appMain/main_test.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014, 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 <stdlib.h> -#include <stdio.h> - -#include "gtest/gtest.h" -#include "gmock/gmock.h" - -#include "config_profile/profile.h" -#include "utils/logger.h" - -#ifdef __cplusplus -extern "C" void __gcov_flush(); -#endif - -int main(int argc, char **argv) { - ::testing::InitGoogleMock(&argc, argv); - - profile::Profile::instance()->config_file_name("smartDeviceLink.ini"); - INIT_LOGGER("log4cxx.properties"); - - int result = RUN_ALL_TESTS(); - -#if defined(__cplusplus) and defined(GCOV_ENABLED) - __gcov_flush(); -#endif - - sleep(2); - DEINIT_LOGGER(); - return result; -} diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index 289ab920e8..f7c5751419 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -1464,6 +1464,7 @@ class ApplicationManagerImpl : public ApplicationManager, std::vector<ApplicationManagerTimerPtr> timer_pool_; sync_primitives::Lock timer_pool_lock_; + sync_primitives::Lock stopping_flag_lock_; StateController state_ctrl_; @@ -1484,8 +1485,7 @@ class ApplicationManagerImpl : public ApplicationManager, timer::TimerThread<ApplicationManagerImpl> tts_global_properties_timer_; bool is_low_voltage_; - - bool is_stopping_; + volatile bool is_stopping_; DISALLOW_COPY_AND_ASSIGN(ApplicationManagerImpl); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 2f4a3b6b0e..2ddd6b8859 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -112,6 +112,7 @@ ApplicationManagerImpl::ApplicationManagerImpl() unregister_reason_(mobile_api::AppInterfaceUnregisteredReason::INVALID_ENUM), navi_close_app_timeout_(profile::Profile::instance()->stop_streaming_timeout()), navi_end_stream_timeout_(profile::Profile::instance()->stop_streaming_timeout()), + stopping_flag_lock_(true), #ifdef TIME_TESTER metric_observer_(NULL), #endif // TIME_TESTER @@ -171,7 +172,9 @@ ApplicationManagerImpl::~ApplicationManagerImpl() { bool ApplicationManagerImpl::Stop() { LOG4CXX_INFO(logger_, "Stop ApplicationManager."); + stopping_flag_lock_.Acquire(); is_stopping_ = true; + stopping_flag_lock_.Release(); application_list_update_timer_->stop(); try { UnregisterAllApplications(); @@ -2206,6 +2209,9 @@ void ApplicationManagerImpl::SetUnregisterAllApplicationsReason( void ApplicationManagerImpl::HeadUnitReset( mobile_api::AppInterfaceUnregisteredReason::eType reason) { + stopping_flag_lock_.Acquire(); + is_stopping_ = true; + stopping_flag_lock_.Release(); switch (reason) { case mobile_api::AppInterfaceUnregisteredReason::MASTER_RESET: { UnregisterAllApplications(); @@ -2292,19 +2298,16 @@ void ApplicationManagerImpl::UnregisterAllApplications() { bool is_unexpected_disconnect = Compare<eType, NEQ, ALL>(unregister_reason_, IGNITION_OFF, MASTER_RESET, FACTORY_DEFAULTS); + + { // A local scope to limit accessor's lifetime and release app list lock. ApplicationListAccessor accessor; ApplictionSetConstIt it = accessor.begin(); while (it != accessor.end()) { ApplicationSharedPtr app_to_remove = *it; -#ifdef CUSTOMER_PASA - if (!is_ignition_off) { -#endif // CUSTOMER_PASA MessageHelper::SendOnAppInterfaceUnregisteredNotificationToMobile( app_to_remove->app_id(), unregister_reason_); -#ifdef CUSTOMER_PASA - } -#endif // CUSTOMER_PASA + UnregisterApplication(app_to_remove->app_id(), mobile_apis::Result::INVALID_ENUM, is_ignition_off, @@ -2312,6 +2315,7 @@ void ApplicationManagerImpl::UnregisterAllApplications() { connection_handler_->CloseSession(app_to_remove->app_id(), connection_handler::kCommon); it = accessor.begin(); + } } if (is_ignition_off) { resume_controller().OnSuspend(); @@ -2438,6 +2442,12 @@ void ApplicationManagerImpl::Handle(const impl::MessageFromMobile message) { LOG4CXX_ERROR(logger_, "Null-pointer message received."); return; } + + sync_primitives::AutoLock lock(stopping_flag_lock_); + if (is_stopping_) { + LOG4CXX_INFO(logger_, "Application manager is stopping"); + return; + } ProcessMessageFromMobile(message); } diff --git a/src/components/application_manager/src/message_helper.cc b/src/components/application_manager/src/message_helper.cc index 6cf6e53512..70ebb2fb6c 100644 --- a/src/components/application_manager/src/message_helper.cc +++ b/src/components/application_manager/src/message_helper.cc @@ -1123,11 +1123,11 @@ smart_objects::SmartObjectList MessageHelper::CreateAddCommandRequestToHMI( msg_params[strings::menu_params] = (*i->second)[strings::menu_params]; msg_params[strings::app_id] = app->app_id(); - if (((*i->second)[strings::cmd_icon].keyExists(strings::value)) + if (((*i->second).keyExists(strings::cmd_icon)) && (0 < (*i->second)[strings::cmd_icon][strings::value].length())) { msg_params[strings::cmd_icon] = (*i->second)[strings::cmd_icon]; msg_params[strings::cmd_icon][strings::value] = - (*i->second)[strings::cmd_icon][strings::value].asString(); + (*i->second)[strings::cmd_icon][strings::value].asString(); } (*ui_command)[strings::msg_params] = msg_params; requests.push_back(ui_command); diff --git a/src/components/policy/src/policy/policy_table/table_struct/types.cc b/src/components/policy/src/policy/policy_table/table_struct/types.cc index 5d12f652b2..893f175917 100644 --- a/src/components/policy/src/policy/policy_table/table_struct/types.cc +++ b/src/components/policy/src/policy/policy_table/table_struct/types.cc @@ -491,6 +491,24 @@ ModuleConfig::ModuleConfig(const Json::Value* value__) preloaded_date(impl::ValueMember(value__, "preloaded_date")), certificate(impl::ValueMember(value__, "certificate")){ } + +void ModuleConfig::SafeCopyFrom(const ModuleConfig& from) { +// device_certificates = from.device_certificates; // According to the requirements this is optional. + exchange_after_x_ignition_cycles = from.exchange_after_x_ignition_cycles; + exchange_after_x_kilometers = from.exchange_after_x_kilometers; + exchange_after_x_days = from.exchange_after_x_days; + timeout_after_x_seconds = from.timeout_after_x_seconds; + seconds_between_retries = from.seconds_between_retries; + endpoints = from.endpoints; + notifications_per_minute_by_priority = from.notifications_per_minute_by_priority; + + vehicle_make.assign_if_valid(from.vehicle_make); + vehicle_model.assign_if_valid(from.vehicle_model); + vehicle_year.assign_if_valid(from.vehicle_year); + certificate .assign_if_valid(from.certificate); + +} + Json::Value ModuleConfig::ToJsonValue() const { Json::Value result__(Json::objectValue); impl::WriteJsonField("device_certificates", device_certificates, &result__); diff --git a/src/components/policy/src/policy/policy_table/table_struct/types.h b/src/components/policy/src/policy/policy_table/table_struct/types.h index 2f5f275f0a..7e24dba99e 100644 --- a/src/components/policy/src/policy/policy_table/table_struct/types.h +++ b/src/components/policy/src/policy/policy_table/table_struct/types.h @@ -190,6 +190,7 @@ struct ModuleConfig : CompositeType { ModuleConfig(uint8_t exchange_after_x_ignition_cycles, int64_t exchange_after_x_kilometers, uint8_t exchange_after_x_days, uint16_t timeout_after_x_seconds, const SecondsBetweenRetries& seconds_between_retries, const ServiceEndpoints& endpoints, const NumberOfNotificationsPerMinute& notifications_per_minute_by_priority); ~ModuleConfig(); explicit ModuleConfig(const Json::Value* value__); + void SafeCopyFrom(const ModuleConfig& from); Json::Value ToJsonValue() const; bool is_valid() const; bool is_initialized() const; diff --git a/src/components/policy/src/policy/src/cache_manager.cc b/src/components/policy/src/policy/src/cache_manager.cc index 7730146f56..04a02b2e17 100644 --- a/src/components/policy/src/policy/src/cache_manager.cc +++ b/src/components/policy/src/policy/src/cache_manager.cc @@ -229,8 +229,13 @@ bool CacheManager::ApplyUpdate(const policy_table::Table& update_pt) { pt_->policy_table.app_policies_section.apps[iter->first].set_to_null(); pt_->policy_table.app_policies_section.apps[iter->first].set_to_string(""); } else if (policy::kDefaultId == (iter->second).get_string()) { - pt_->policy_table.app_policies_section.apps[iter->first] = - pt_->policy_table.app_policies_section.apps[kDefaultId]; + policy_table::ApplicationPolicies::const_iterator iter_default = + update_pt.policy_table.app_policies_section.apps.find(kDefaultId); + if (update_pt.policy_table.app_policies_section.apps.end() == iter_default) { + LOG4CXX_ERROR(logger_, "The default section was not found in PTU"); + continue; + } + pt_->policy_table.app_policies_section.apps[iter->first] = iter_default->second; } else { pt_->policy_table.app_policies_section.apps[iter->first] = iter->second; } @@ -239,10 +244,11 @@ bool CacheManager::ApplyUpdate(const policy_table::Table& update_pt) { pt_->policy_table.app_policies_section.device = update_pt.policy_table.app_policies_section.device; - if (update_pt.policy_table.consumer_friendly_messages.is_initialized()) { - pt_->policy_table.consumer_friendly_messages = - update_pt.policy_table.consumer_friendly_messages; - } + pt_->policy_table.module_config.SafeCopyFrom(update_pt.policy_table.module_config); + + pt_->policy_table.consumer_friendly_messages.assign_if_valid( + update_pt.policy_table.consumer_friendly_messages); + ResetCalculatedPermissions(); Backup(); return true; diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h index 5e0caa22e8..d764979fbd 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h @@ -81,6 +81,13 @@ class ThreadedSocketConnection : public Connection { TransportAdapter::Error Start(); /** + * @brief Checks is queue with frames to send empty or not. + * + * @return Information about queue is empty or not. + */ + bool IsFramesToSendQueueEmpty() const; + + /** * @brief Set variable that hold socket No. */ void set_socket(int socket) { diff --git a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc index 67e41cec2b..f520841a47 100644 --- a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc +++ b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc @@ -30,6 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <algorithm> #include <errno.h> #include <fcntl.h> #include <memory.h> @@ -183,14 +184,23 @@ void ThreadedSocketConnection::threadMain() { } } +bool ThreadedSocketConnection::IsFramesToSendQueueEmpty() const { + // Check Frames queue is empty or not + sync_primitives::AutoLock auto_lock(frames_to_send_mutex_); + return frames_to_send_.empty(); +} + void ThreadedSocketConnection::Transmit() { LOG4CXX_AUTO_TRACE(logger_); const nfds_t kPollFdsSize = 2; pollfd poll_fds[kPollFdsSize]; poll_fds[0].fd = socket_; + + const bool is_queue_empty_on_poll = IsFramesToSendQueueEmpty(); + poll_fds[0].events = POLLIN | POLLPRI - | (frames_to_send_.empty() ? 0 : POLLOUT); + | (is_queue_empty_on_poll ? 0 : POLLOUT); poll_fds[1].fd = read_fd_; poll_fds[1].events = POLLIN | POLLPRI; @@ -231,8 +241,10 @@ void ThreadedSocketConnection::Transmit() { return; } - // send data if possible - if (!frames_to_send_.empty() && (poll_fds[0].revents | POLLOUT)) { + const bool is_queue_empty = IsFramesToSendQueueEmpty(); + + // Send data if possible + if (!is_queue_empty && (poll_fds[0].revents | POLLOUT)) { LOG4CXX_DEBUG(logger_, "frames_to_send_ not empty() "); // send data @@ -288,15 +300,17 @@ bool ThreadedSocketConnection::Receive() { bool ThreadedSocketConnection::Send() { LOG4CXX_AUTO_TRACE(logger_); - FrameQueue frames_to_send; - frames_to_send_mutex_.Acquire(); - std::swap(frames_to_send, frames_to_send_); - frames_to_send_mutex_.Release(); + FrameQueue frames_to_send_local; + + { + sync_primitives::AutoLock auto_lock(frames_to_send_mutex_); + std::swap(frames_to_send_local, frames_to_send_); + } size_t offset = 0; - while (!frames_to_send.empty()) { + while (!frames_to_send_local.empty()) { LOG4CXX_INFO(logger_, "frames_to_send is not empty"); - ::protocol_handler::RawMessagePtr frame = frames_to_send.front(); + ::protocol_handler::RawMessagePtr frame = frames_to_send_local.front(); const ssize_t bytes_sent = ::send(socket_, frame->data() + offset, frame->data_size() - offset, 0); @@ -304,14 +318,14 @@ bool ThreadedSocketConnection::Send() { LOG4CXX_DEBUG(logger_, "bytes_sent >= 0"); offset += bytes_sent; if (offset == frame->data_size()) { - frames_to_send.pop(); + frames_to_send_local.pop(); offset = 0; controller_->DataSendDone(device_handle(), application_handle(), frame); } } else { LOG4CXX_DEBUG(logger_, "bytes_sent < 0"); LOG4CXX_ERROR_WITH_ERRNO(logger_, "Send failed for connection " << this); - frames_to_send.pop(); + frames_to_send_local.pop(); offset = 0; controller_->DataSendFailed(device_handle(), application_handle(), frame, DataSendError()); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 2834dce387..557c23f4e7 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -20,3 +20,8 @@ ExternalProject_Add_Step(intergen forcebuild COMMAND ${CMAKE_COMMAND} -E echo "Force intergen build" DEPENDEES update DEPENDERS build ALWAYS 1) + +if(BUILD_TESTS) + add_subdirectory(intergen/test) +endif() +add_subdirectory(policy_table_validator) diff --git a/tools/policy_table_validator/CMakeLists.txt b/tools/policy_table_validator/CMakeLists.txt new file mode 100644 index 0000000000..2a372d7ffa --- /dev/null +++ b/tools/policy_table_validator/CMakeLists.txt @@ -0,0 +1,27 @@ +#set( CMAKE_VERBOSE_MAKEFILE on ) + +include_directories( + ${CMAKE_SOURCE_DIR}/src/components/policy/src/policy/ + ${CMAKE_SOURCE_DIR}/src/components/rpc_base/include/ + ${CMAKE_SOURCE_DIR}/src/components/utils/include/ + ${JSONCPP_INCLUDE_DIRECTORY} +) + + +link_directories ( + ${CMAKE_BINARY_DIR}/src/components/policy/src/policy/policy_table/table_struct/ + ${CMAKE_BINARY_DIR}/src/components/rpc_base/ +) + + +set(LIBRARIES + policy_struct + rpc_base +) + +set (SOURCES + main.cpp +) + +add_executable(policyValidator ${SOURCES}) +target_link_libraries(policyValidator ${LIBRARIES}) diff --git a/tools/policy_table_validator/main.cpp b/tools/policy_table_validator/main.cpp new file mode 100644 index 0000000000..16454ca128 --- /dev/null +++ b/tools/policy_table_validator/main.cpp @@ -0,0 +1,83 @@ +#include <iostream> +#include <cstdlib> +#include "policy_table/table_struct/types.h" + +#include "json/reader.h" +#include "utils/file_system.h" + +namespace policy_table = rpc::policy_table_interface_base; + +enum ResultCode { + SUCCES = 0, + MISSED_FILE_NAME, + READ_ERROR, + PARSE_ERROR, + PT_TYPE_ERROR +}; + +rpc::policy_table_interface_base::PolicyTableType StringToPolicyTableType(const std::string& str_pt_type) { + if (str_pt_type == "PT_PRELOADED") { + return rpc::policy_table_interface_base::PT_PRELOADED; + } + if (str_pt_type == "PT_SNAPSHOT") { + return rpc::policy_table_interface_base::PT_SNAPSHOT; + } + if (str_pt_type == "PT_UPDATE") { + return rpc::policy_table_interface_base::PT_UPDATE; + } + return rpc::policy_table_interface_base::INVALID_PT_TYPE; +} + +void help() { + std::cout << "Usage:" << std::endl << + "./policy_validator {Policy table type} {file_name}" << std::endl; + std::cout << "Policy table types:" + "\t PT_PRELOADED , PT_UPDATE , PT_SNAPSHOT" <<std::endl; +} + +int main(int argc, char** argv) { + if (argc != 3) { + // TODO(AKutsan): No filename + help(); + exit(MISSED_FILE_NAME); + } + std::string pt_type_str = argv[1]; + std::string file_name = argv[2]; + std::string json_string; + rpc::policy_table_interface_base::PolicyTableType pt_type; + pt_type = StringToPolicyTableType(pt_type_str); + if (rpc::policy_table_interface_base::PolicyTableType::INVALID_PT_TYPE + == pt_type) { + std::cout << "Invalid policy table type: " << pt_type_str << std::endl; + exit(PT_TYPE_ERROR); + } + bool read_result = file_system::ReadFile(file_name, json_string); + if (false == read_result) { + std::cout << "Read file error: " << file_name << std::endl; + exit(READ_ERROR); + } + + Json::Reader reader; + Json::Value value; + + bool parce_result = reader.parse(json_string, value); + if (false == parce_result) { + std::cout << "Json parce fails" << std::endl; + exit(PARSE_ERROR); + } + std::cout << "DEFAULT_POLICY" << std::endl; + policy_table::Table table(&value); + table.SetPolicyTableType(pt_type); + bool is_valid = table.is_valid(); + if (true == is_valid ) { + std::cout << "Table is valid" << std::endl; + exit(SUCCES); + } + + std::cout << "Table is not valid" << std::endl; + rpc::ValidationReport report("policy_table"); + table.ReportErrors(&report); + std::cout << "Errors: " << std::endl << rpc::PrettyFormat(report) << std::endl; + + return SUCCES; +} |