diff options
author | Sho Amano <samano@xevo.com> | 2017-07-29 14:28:36 +0900 |
---|---|---|
committer | Sho Amano <samano@xevo.com> | 2017-08-11 10:44:34 +0900 |
commit | 394a1a6b46eb19010448e8c9dad6e49186e38b32 (patch) | |
tree | 3bf4f3a1885ff45c98812de64dd21dd179dbd37e /src | |
parent | a51cf183feed320093acd4a471e9eeec77c4a437 (diff) | |
download | sdl_core-394a1a6b46eb19010448e8c9dad6e49186e38b32.tar.gz |
Add implementation for video streaming parameters
Diffstat (limited to 'src')
24 files changed, 869 insertions, 160 deletions
diff --git a/src/components/application_manager/CMakeLists.txt b/src/components/application_manager/CMakeLists.txt index a5fcd469ef..0d532c9a5c 100644 --- a/src/components/application_manager/CMakeLists.txt +++ b/src/components/application_manager/CMakeLists.txt @@ -57,6 +57,7 @@ include_directories ( ${ENCRYPTION_INCLUDE_DIRECTORY} ${MESSAGE_BROKER_INCLUDE_DIRECTORY} ${LOG4CXX_INCLUDE_DIRECTORY} + ${BSON_INCLUDE_DIRECTORY} ) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -399,6 +400,8 @@ set(LIBRARIES formatters dbms Utils + bson -L${BSON_LIBS_DIRECTORY} + emhashmap -L${EMHASHMAP_LIBS_DIRECTORY} ) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -437,6 +440,7 @@ if(ENABLE_LOG) list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() +add_dependencies("ApplicationManager" libbson) target_link_libraries("ApplicationManager" ${LIBRARIES}) if(BUILD_TESTS) diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h index 9543193ff9..4dfb8dbf7a 100644 --- a/src/components/application_manager/include/application_manager/application.h +++ b/src/components/application_manager/include/application_manager/application.h @@ -37,6 +37,7 @@ #include <map> #include <set> #include <list> +#include <vector> #include "utils/shared_ptr.h" #include "utils/data_accessor.h" #include "interfaces/MOBILE_API.h" @@ -441,6 +442,25 @@ class Application : public virtual InitialApplicationData, virtual void set_audio_streaming_allowed(bool state) = 0; /** + * @brief Sends SetVideoConfig request to HMI to configure streaming + * @param service_type Type of streaming service, should be kMobileNav + * @param params parameters of video streaming in key-value format + * @return true if SetVideoConfig is sent, false otherwise + */ + virtual bool SetVideoConfig(protocol_handler::ServiceType service_type, + const smart_objects::SmartObject& params) = 0; + + /** + * @brief Callback when SetVideoConfig response is received + * @param result true if HMI accepts video streaming parameters, + * false otherwise + * @param rejected_params list of rejected parameters' names. Only + * valid when result is false + */ + virtual void OnNaviSetVideoConfigDone( + bool result, std::vector<std::string>& rejected_params) = 0; + + /** * @brief Starts streaming service for application * @param service_type Type of streaming service */ diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h index 9ef2fb936c..f5db389c7f 100644 --- a/src/components/application_manager/include/application_manager/application_impl.h +++ b/src/components/application_manager/include/application_manager/application_impl.h @@ -110,6 +110,10 @@ class ApplicationImpl : public virtual InitialApplicationDataImpl, bool audio_streaming_allowed() const; void set_audio_streaming_allowed(bool state); + bool SetVideoConfig(protocol_handler::ServiceType service_type, + const smart_objects::SmartObject& params); + void OnNaviSetVideoConfigDone(bool result, + std::vector<std::string>& rejected_params); void StartStreaming(protocol_handler::ServiceType service_type); void StopStreamingForce(protocol_handler::ServiceType service_type); void StopStreaming(protocol_handler::ServiceType service_type); 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 313219116d..47a77a1f97 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 @@ -93,6 +93,8 @@ #include "utils/timer.h" #include "smart_objects/smart_object.h" +struct BsonObject; + namespace threads { class Thread; } @@ -792,10 +794,11 @@ class ApplicationManagerImpl void OnFindNewApplicationsRequest() OVERRIDE; void RemoveDevice( const connection_handler::DeviceHandle& device_handle) OVERRIDE; - bool OnServiceStartedCallback( + void OnServiceStartedCallback( const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, - const protocol_handler::ServiceType& type) OVERRIDE; + const protocol_handler::ServiceType& type, + const BsonObject* params) OVERRIDE; void OnServiceEndedCallback( const int32_t& session_key, const protocol_handler::ServiceType& type, @@ -886,6 +889,19 @@ class ApplicationManagerImpl void ForbidStreaming(uint32_t app_id) OVERRIDE; /** + * @brief Called when application completes streaming configuration + * @param app_id Streaming application id + * @param service_type Streaming service type + * @param result true if configuration is successful, false otherwise + * @param rejected_params list of rejected parameters' name. Valid + * only when result is false. + */ + void OnStreamingConfigured(uint32_t app_id, + protocol_handler::ServiceType service_type, + bool result, + std::vector<std::string>& rejected_params); + + /** * @brief Callback calls when application starts/stops data streaming * @param app_id Streaming application id * @param service_type Streaming service type @@ -1325,10 +1341,13 @@ class ApplicationManagerImpl * @brief Starts specified navi service for application * @param app_id Application to proceed * @param service_type Type of service to start - * @return True on success, false on fail + * @param params configuration parameters specified by mobile + * @return True if service is immediately started or configuration + * parameters are sent to HMI, false on other cases */ bool StartNaviService(uint32_t app_id, - protocol_handler::ServiceType service_type); + protocol_handler::ServiceType service_type, + const BsonObject* params); /** * @brief Stops specified navi service for application @@ -1399,6 +1418,24 @@ class ApplicationManagerImpl void ClearTTSGlobalPropertiesList(); + /** + * @brief Converts BSON object containing video parameters to + * smart object's map object + * @param output the smart object to add video parameters + * @param input BSON object to read parameters from + */ + static void ConvertVideoParamsToSO(smart_objects::SmartObject& output, + const BsonObject* input); + + /** + * @brief Converts rejected parameters' names acquired from HMI to + * SDL protocol's parameter names + * @param list of rejected parameters' names + * @return converted parameters' names + */ + static std::vector<std::string> ConvertRejectedParamList( + const std::vector<std::string>& input); + private: const ApplicationManagerSettings& settings_; /** diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc index 7e9215b0be..7d9025050a 100644 --- a/src/components/application_manager/src/application_impl.cc +++ b/src/components/application_manager/src/application_impl.cc @@ -416,6 +416,33 @@ bool ApplicationImpl::audio_streaming_allowed() const { return audio_streaming_allowed_; } +bool ApplicationImpl::SetVideoConfig(protocol_handler::ServiceType service_type, + const smart_objects::SmartObject& params) { + using namespace protocol_handler; + LOG4CXX_AUTO_TRACE(logger_); + + if (ServiceType::kMobileNav == service_type) { + // See StartStreaming(). We issue SetVideoConfig and StartStream + // only when streaming is not approved yet + if (!video_streaming_approved()) { + LOG4CXX_TRACE(logger_, "Video streaming not approved"); + MessageHelper::SendNaviSetVideoConfig( + app_id(), application_manager_, params); + return true; + } + } + return false; +} + +void ApplicationImpl::OnNaviSetVideoConfigDone( + bool result, std::vector<std::string>& rejected_params) { + using namespace protocol_handler; + LOG4CXX_AUTO_TRACE(logger_); + + application_manager_.OnStreamingConfigured( + app_id(), ServiceType::kMobileNav, result, rejected_params); +} + void ApplicationImpl::StartStreaming( protocol_handler::ServiceType service_type) { using namespace protocol_handler; diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 85c3469324..a76edc2747 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -36,6 +36,7 @@ #include <string> #include <fstream> #include <utility> +#include <bson_object.h> #include "application_manager/application_manager_impl.h" #include "application_manager/mobile_command_factory.h" @@ -1138,7 +1139,9 @@ void ApplicationManagerImpl::ReplaceHMIByMobileAppId( } bool ApplicationManagerImpl::StartNaviService( - uint32_t app_id, protocol_handler::ServiceType service_type) { + uint32_t app_id, + protocol_handler::ServiceType service_type, + const BsonObject* params) { using namespace protocol_handler; LOG4CXX_AUTO_TRACE(logger_); @@ -1155,6 +1158,56 @@ bool ApplicationManagerImpl::StartNaviService( } it = res.first; } + + if (service_type == ServiceType::kMobileNav) { + smart_objects::SmartObject converted_params(smart_objects::SmartType_Map); + ConvertVideoParamsToSO(converted_params, params); + + if (!converted_params.empty()) { + LOG4CXX_INFO(logger_, "Sending video configuration params"); +#ifdef DEBUG + MessageHelper::PrintSmartObject(converted_params); +#endif + bool request_sent = + application(app_id)->SetVideoConfig(service_type, converted_params); + if (request_sent) { + return true; + } + } + } + // no configuration is needed, or SetVideoConfig is not sent + std::vector<std::string> empty; + OnStreamingConfigured(app_id, service_type, true, empty); + return true; + + } else { + LOG4CXX_WARN(logger_, "Refused navi service by HMI level"); + } + return false; +} + +void ApplicationManagerImpl::OnStreamingConfigured( + uint32_t app_id, + protocol_handler::ServiceType service_type, + bool result, + std::vector<std::string>& rejected_params) { + using namespace protocol_handler; + LOG4CXX_AUTO_TRACE(logger_); + + std::vector<std::string> empty; + + LOG4CXX_INFO(logger_, + "OnStreamingConfigured called for service " + << service_type << ", result=" << result); + + if (result) { + NaviServiceStatusMap::iterator it = navi_service_status_.find(app_id); + if (navi_service_status_.end() == it) { + LOG4CXX_WARN(logger_, "Application not found in navi status map"); + connection_handler().NotifyServiceStartedResult(false, empty); + return; + } + // Fill NaviServices map. Set true to first value of pair if // we've started video service or to second value if we've // started audio service @@ -1162,11 +1215,12 @@ bool ApplicationManagerImpl::StartNaviService( : it->second.second = true; application(app_id)->StartStreaming(service_type); - return true; + connection_handler().NotifyServiceStartedResult(true, empty); } else { - LOG4CXX_WARN(logger_, "Refused navi service by HMI level"); + std::vector<std::string> converted_params = + ConvertRejectedParamList(rejected_params); + connection_handler().NotifyServiceStartedResult(false, converted_params); } - return false; } void ApplicationManagerImpl::StopNaviService( @@ -1194,40 +1248,47 @@ void ApplicationManagerImpl::StopNaviService( app->StopStreaming(service_type); } -bool ApplicationManagerImpl::OnServiceStartedCallback( +void ApplicationManagerImpl::OnServiceStartedCallback( const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, - const protocol_handler::ServiceType& type) { + const protocol_handler::ServiceType& type, + const BsonObject* params) { using namespace helpers; using namespace protocol_handler; LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "ServiceType = " << type << ". Session = " << std::hex << session_key); + std::vector<std::string> empty; if (type == kRpc) { LOG4CXX_DEBUG(logger_, "RPC service is about to be started."); - return true; + connection_handler().NotifyServiceStartedResult(true, empty); + return; } ApplicationSharedPtr app = application(session_key); if (!app) { LOG4CXX_WARN(logger_, "The application with id:" << session_key << " doesn't exists."); - return false; + connection_handler().NotifyServiceStartedResult(false, empty); + return; } if (Compare<ServiceType, EQ, ONE>( type, ServiceType::kMobileNav, ServiceType::kAudio)) { if (app->is_navi() || app->mobile_projection_enabled()) { - return StartNaviService(session_key, type); + if (!StartNaviService(session_key, type, params)) { + connection_handler().NotifyServiceStartedResult(false, empty); + } + return; } else { LOG4CXX_WARN(logger_, "Refuse not navi/projection application"); } } else { LOG4CXX_WARN(logger_, "Refuse unknown service"); } - return false; + connection_handler().NotifyServiceStartedResult(false, empty); } void ApplicationManagerImpl::OnServiceEndedCallback( @@ -3606,4 +3667,90 @@ const std::set<int32_t> ApplicationManagerImpl::GetAppsSubscribedForWayPoints() return subscribed_way_points_apps_list_; } +static hmi_apis::Common_VideoStreamingProtocol::eType ConvertVideoProtocol( + const char* str) { + if (strcmp(str, "RAW") == 0) { + return hmi_apis::Common_VideoStreamingProtocol::RAW; + } else if (strcmp(str, "RTP") == 0) { + return hmi_apis::Common_VideoStreamingProtocol::RTP; + } else if (strcmp(str, "RTSP") == 0) { + return hmi_apis::Common_VideoStreamingProtocol::RTSP; + } else if (strcmp(str, "RTMP") == 0) { + return hmi_apis::Common_VideoStreamingProtocol::RTMP; + } else if (strcmp(str, "WEBM") == 0) { + return hmi_apis::Common_VideoStreamingProtocol::WEBM; + } + return hmi_apis::Common_VideoStreamingProtocol::INVALID_ENUM; +} + +static hmi_apis::Common_VideoStreamingCodec::eType ConvertVideoCodec( + const char* str) { + if (strcmp(str, "H264") == 0) { + return hmi_apis::Common_VideoStreamingCodec::H264; + } else if (strcmp(str, "H265") == 0) { + return hmi_apis::Common_VideoStreamingCodec::H265; + } else if (strcmp(str, "Theora") == 0) { + return hmi_apis::Common_VideoStreamingCodec::Theora; + } else if (strcmp(str, "VP8") == 0) { + return hmi_apis::Common_VideoStreamingCodec::VP8; + } else if (strcmp(str, "VP9") == 0) { + return hmi_apis::Common_VideoStreamingCodec::VP9; + } + return hmi_apis::Common_VideoStreamingCodec::INVALID_ENUM; +} + +// static +void ApplicationManagerImpl::ConvertVideoParamsToSO( + smart_objects::SmartObject& output, const BsonObject* input) { + if (input == NULL) { + return; + } + BsonObject* obj = const_cast<BsonObject*>(input); + + const char* protocol = bson_object_get_string(obj, "videoProtocol"); + if (protocol != NULL) { + hmi_apis::Common_VideoStreamingProtocol::eType protocol_enum = + ConvertVideoProtocol(protocol); + if (protocol_enum != + hmi_apis::Common_VideoStreamingProtocol::INVALID_ENUM) { + output["protocol"] = protocol_enum; + } + } + const char* codec = bson_object_get_string(obj, "videoCodec"); + if (codec != NULL) { + hmi_apis::Common_VideoStreamingCodec::eType codec_enum = + ConvertVideoCodec(codec); + if (codec_enum != hmi_apis::Common_VideoStreamingCodec::INVALID_ENUM) { + output["codec"] = codec_enum; + } + } + BsonElement* element = bson_object_get(obj, "desiredHeight"); + if (element != NULL && element->type == TYPE_INT32) { + output["height"] = bson_object_get_int32(obj, "desiredHeight"); + } + element = bson_object_get(obj, "desiredWidth"); + if (element != NULL && element->type == TYPE_INT32) { + output["width"] = bson_object_get_int32(obj, "desiredWidth"); + } +} + +// static +std::vector<std::string> ApplicationManagerImpl::ConvertRejectedParamList( + const std::vector<std::string>& input) { + std::vector<std::string> output; + for (unsigned int i = 0; i < input.size(); i++) { + if (input[i] == "protocol") { + output.push_back("videoProtocol"); + } else if (input[i] == "codec") { + output.push_back("videoCodec"); + } else if (input[i] == "height") { + output.push_back("desiredHeight"); + } else if (input[i] == "width") { + output.push_back("desiredWidth"); + } + // ignore unknown parameters + } + return output; +} + } // namespace application_manager diff --git a/src/components/application_manager/src/commands/hmi/navi_set_video_config_request.cc b/src/components/application_manager/src/commands/hmi/navi_set_video_config_request.cc index 3a832e0255..8a51133b36 100644 --- a/src/components/application_manager/src/commands/hmi/navi_set_video_config_request.cc +++ b/src/components/application_manager/src/commands/hmi/navi_set_video_config_request.cc @@ -110,7 +110,7 @@ void NaviSetVideoConfigRequest::on_event(const event_engine::Event& event) { } } } -// app->OnNaviSetVideoConfigDone(result, rejected_params); + app->OnNaviSetVideoConfigDone(result, rejected_params); break; } default: @@ -129,8 +129,8 @@ void NaviSetVideoConfigRequest::onTimeOut() { return; } -// std::vector<std::string> empty; -// app->OnNaviSetVideoConfigDone(false, empty); + std::vector<std::string> empty; + app->OnNaviSetVideoConfigDone(false, empty); application_manager_.TerminateRequest( connection_key(), correlation_id(), function_id()); diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h index ae9b05bb92..53c4be1c77 100644 --- a/src/components/application_manager/test/include/application_manager/mock_application.h +++ b/src/components/application_manager/test/include/application_manager/mock_application.h @@ -70,6 +70,11 @@ class MockApplication : public ::application_manager::Application { MOCK_CONST_METHOD0(audio_streaming_allowed, bool()); MOCK_METHOD1(set_audio_streaming_allowed, void(bool state)); MOCK_CONST_METHOD0(is_audio, bool()); + MOCK_METHOD2(SetVideoConfig, + bool(protocol_handler::ServiceType service_type, + const smart_objects::SmartObject& params)); + MOCK_METHOD2(OnNaviSetVideoConfigDone, + void(bool result, std::vector<std::string>& rejected_params)); MOCK_METHOD1(StartStreaming, void(protocol_handler::ServiceType service_type)); MOCK_METHOD1(StopStreaming, void(protocol_handler::ServiceType service_type)); diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h index a6651a6466..32a4086bc4 100644 --- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h +++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h @@ -49,6 +49,7 @@ #include "utils/logger.h" #include "utils/macro.h" +#include "utils/message_queue.h" #include "utils/lock.h" #include "utils/stl_utils.h" #include "utils/rwlock.h" @@ -174,20 +175,21 @@ class ConnectionHandlerImpl /** * \brief Callback function used by ProtocolHandler * when Mobile Application initiates start of new session. - * \param connection_handle Connection identifier within which session has to - * be started. - * \param session_id Identifier of the session to be started + * Result must be notified through NotifySessionStartedResult(). + * \param connection_handle Connection identifier within which session + * has to be started. + * \param sessionId Identifier of the session to be start * \param service_type Type of service + * \param protocol_version Version of protocol * \param is_protected would be service protected - * \param hash_id pointer for session hash identifier - * \return uint32_t Id (number) of new session if successful, otherwise 0. + * \param params configuration parameters specified by mobile */ - virtual uint32_t OnSessionStartedCallback( + virtual void OnSessionStartedCallback( const transport_manager::ConnectionUID connection_handle, const uint8_t session_id, const protocol_handler::ServiceType& service_type, const bool is_protected, - uint32_t* hash_id); + const BsonObject* params); // DEPRECATED uint32_t OnSessionEndedCallback( @@ -441,8 +443,68 @@ class ConnectionHandlerImpl const protocol_handler::SessionObserver& get_session_observer(); DevicesDiscoveryStarter& get_device_discovery_starter(); + /** + * \brief Invoked when observer's OnServiceStartedCallback is completed + * \param result true if observer accepts starting service, false otherwise + * \param rejected_params list of rejected parameters' name. Only valid when + * result is false. Note that even if result is false, this may be empty. + * + * \note This is invoked only once but can be invoked by multiple threads. + * Also it can be invoked before OnServiceStartedCallback() returns. + **/ + virtual void NotifyServiceStartedResult( + bool result, std::vector<std::string>& rejected_params); + private: /** + * \brief Struct to keep variables between OnSessionStartedCallback() and + * NotifyServiceStartedResult() + **/ + struct ServiceStartedContext { + transport_manager::ConnectionUID connection_handle_; + uint8_t session_id_; + uint32_t new_session_id_; + protocol_handler::ServiceType service_type_; + uint32_t hash_id_; + bool is_protected_; + + /** + * \brief Constructor + */ + ServiceStartedContext() + : connection_handle_(0) + , session_id_(0) + , new_session_id_(0) + , service_type_(protocol_handler::kInvalidServiceType) + , hash_id_(0) + , is_protected_(0) {} + + /** + * \brief Constructor + * \param connection_handle Connection identifier within which session is + * started. + * \param session_id Session ID specified to OnSessionStartedCallback() + * \param new_session_id Session ID generated + * \param service_type Type of service + * \param hash_id Hash ID generated from connection_handle and + * new_session_id + * \param is_protected Whether service will be protected + **/ + ServiceStartedContext(transport_manager::ConnectionUID connection_handle, + uint8_t session_id, + uint32_t new_session_id, + protocol_handler::ServiceType service_type, + uint32_t hash_id, + bool is_protected) + : connection_handle_(connection_handle) + , session_id_(session_id) + , new_session_id_(new_session_id) + , service_type_(service_type) + , hash_id_(hash_id) + , is_protected_(is_protected) {} + }; + + /** * \brief Disconnect application. * * \param device_handle DeviceHandle of disconnected device. @@ -452,6 +514,13 @@ class ConnectionHandlerImpl void OnConnectionEnded(const transport_manager::ConnectionUID connection_id); + /** + * \brief Convenient method to call NotifySessionStartedResult() with + * negative result. + * \param is_protected whether the service would be protected + **/ + void NotifySessionStartedFailure(bool is_protected); + const ConnectionHandlerSettings& settings_; /** * \brief Pointer to observer @@ -486,6 +555,9 @@ class ConnectionHandlerImpl */ utils::StlMapDeleter<ConnectionList> connection_list_deleter_; + // we need thread-safe queue + utils::MessageQueue<ServiceStartedContext> start_service_context_queue_; + #ifdef BUILD_TESTS // Methods for test usage public: diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 125a6cd769..735140e24f 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -69,7 +69,8 @@ ConnectionHandlerImpl::ConnectionHandlerImpl( , protocol_handler_(NULL) , connection_list_lock_() , connection_handler_observer_lock_() - , connection_list_deleter_(&connection_list_) {} + , connection_list_deleter_(&connection_list_) + , start_service_context_queue_() {} ConnectionHandlerImpl::~ConnectionHandlerImpl() { LOG4CXX_AUTO_TRACE(logger_); @@ -279,40 +280,42 @@ bool AllowProtection(const ConnectionHandlerSettings& settings, } #endif // ENABLE_SECURITY -uint32_t ConnectionHandlerImpl::OnSessionStartedCallback( +void ConnectionHandlerImpl::OnSessionStartedCallback( const transport_manager::ConnectionUID connection_handle, const uint8_t session_id, const protocol_handler::ServiceType& service_type, const bool is_protected, - uint32_t* hash_id) { + const BsonObject* params) { LOG4CXX_AUTO_TRACE(logger_); - if (hash_id) { - *hash_id = protocol_handler::HASH_ID_WRONG; - } + uint32_t new_session_id = 0; + uint32_t hash_id = protocol_handler::HASH_ID_WRONG; + #ifdef ENABLE_SECURITY if (!AllowProtection(get_settings(), service_type, is_protected)) { - return 0; + std::vector<std::string> empty; + protocol_handler_->NotifySessionStartedResult( + new_session_id, hash_id, is_protected, empty); + return; } #endif // ENABLE_SECURITY sync_primitives::AutoReadLock lock(connection_list_lock_); ConnectionList::iterator it = connection_list_.find(connection_handle); if (connection_list_.end() == it) { LOG4CXX_ERROR(logger_, "Unknown connection!"); - return 0; + NotifySessionStartedFailure(is_protected); + return; } - uint32_t new_session_id = 0; Connection* connection = it->second; if ((0 == session_id) && (protocol_handler::kRpc == service_type)) { new_session_id = connection->AddNewSession(); if (0 == new_session_id) { LOG4CXX_ERROR(logger_, "Couldn't start new session!"); - return 0; - } - if (hash_id) { - *hash_id = KeyFromPair(connection_handle, new_session_id); + NotifySessionStartedFailure(is_protected); + return; } + hash_id = KeyFromPair(connection_handle, new_session_id); } else { // Could be create new service or protected exists one if (!connection->AddNewService(session_id, service_type, is_protected)) { LOG4CXX_ERROR(logger_, @@ -322,30 +325,87 @@ uint32_t ConnectionHandlerImpl::OnSessionStartedCallback( #endif // ENABLE_SECURITY << " service " << static_cast<int>(service_type) << " for session " << static_cast<int>(session_id)); - return 0; + NotifySessionStartedFailure(is_protected); + return; } new_session_id = session_id; - if (hash_id) { - *hash_id = protocol_handler::HASH_ID_NOT_SUPPORTED; - } + hash_id = protocol_handler::HASH_ID_NOT_SUPPORTED; } sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_); if (connection_handler_observer_) { const uint32_t session_key = KeyFromPair(connection_handle, new_session_id); - const bool success = connection_handler_observer_->OnServiceStartedCallback( - connection->connection_device_handle(), session_key, service_type); - if (!success) { - LOG4CXX_WARN(logger_, - "Service starting forbidden by connection_handler_observer"); - if (protocol_handler::kRpc == service_type) { - connection->RemoveSession(new_session_id); - } else { - connection->RemoveService(session_id, service_type); - } - return 0; + + ServiceStartedContext context(connection_handle, + session_id, + new_session_id, + service_type, + hash_id, + is_protected); + start_service_context_queue_.push(context); + + connection_handler_observer_->OnServiceStartedCallback( + connection->connection_device_handle(), + session_key, + service_type, + params); + } else { + if (protocol_handler_) { + std::vector<std::string> empty; + protocol_handler_->NotifySessionStartedResult( + new_session_id, hash_id, is_protected, empty); + } + } +} + +void ConnectionHandlerImpl::NotifyServiceStartedResult( + bool result, std::vector<std::string>& rejected_params) { + LOG4CXX_AUTO_TRACE(logger_); + + ServiceStartedContext context; + bool available = start_service_context_queue_.pop(context); + if (!available) { + LOG4CXX_ERROR(logger_, "context for start service not found!"); + return; + } + + Connection* connection = NULL; + { + sync_primitives::AutoReadLock lock(connection_list_lock_); + ConnectionList::iterator it = + connection_list_.find(context.connection_handle_); + if (connection_list_.end() == it) { + LOG4CXX_ERROR(logger_, "connection not found"); + return; } + connection = it->second; + } + + if (!result) { + LOG4CXX_WARN(logger_, + "Service starting forbidden by connection_handler_observer"); + if (protocol_handler::kRpc == context.service_type_) { + connection->RemoveSession(context.new_session_id_); + } else { + connection->RemoveService(context.session_id_, context.service_type_); + } + context.new_session_id_ = 0; + } + + if (protocol_handler_ != NULL) { + protocol_handler_->NotifySessionStartedResult(context.new_session_id_, + context.hash_id_, + context.is_protected_, + rejected_params); + } +} + +void ConnectionHandlerImpl::NotifySessionStartedFailure(bool is_protected) { + LOG4CXX_AUTO_TRACE(logger_); + if (protocol_handler_) { + std::vector<std::string> empty; + protocol_handler_->NotifySessionStartedResult( + 0, protocol_handler::HASH_ID_WRONG, is_protected, empty); } - return new_session_id; } void ConnectionHandlerImpl::OnApplicationFloodCallBack( diff --git a/src/components/connection_handler/test/connection_handler_impl_test.cc b/src/components/connection_handler/test/connection_handler_impl_test.cc index 7f4429500d..a8254af646 100644 --- a/src/components/connection_handler/test/connection_handler_impl_test.cc +++ b/src/components/connection_handler/test/connection_handler_impl_test.cc @@ -54,10 +54,18 @@ using namespace ::connection_handler; using ::protocol_handler::ServiceType; using namespace ::protocol_handler; using ::testing::_; +using ::testing::ByRef; +using ::testing::DoAll; using ::testing::InSequence; using ::testing::Mock; using ::testing::Return; using ::testing::ReturnRefOfCopy; +using ::testing::SaveArg; + +// custom action to call a member function with 4 arguments +ACTION_P4(InvokeMemberFuncWithArg2, ptr, memberFunc, a, b) { + (ptr->*memberFunc)(a, b); +} namespace { const uint32_t kAsyncExpectationsTimeout = 10000u; @@ -108,8 +116,15 @@ class ConnectionHandlerTest : public ::testing::Test { // Remove all specific services } void AddTestSession() { - start_session_id_ = connection_handler_->OnSessionStartedCallback( - uid_, 0, kRpc, PROTECTION_OFF, &out_hash_id_); + protocol_handler_test::MockProtocolHandler temp_protocol_handler; + connection_handler_->set_protocol_handler(&temp_protocol_handler); + EXPECT_CALL(temp_protocol_handler, NotifySessionStartedResult(_, _, _, _)) + .WillOnce( + DoAll(SaveArg<0>(&start_session_id_), SaveArg<1>(&out_hash_id_))); + + connection_handler_->OnSessionStartedCallback( + uid_, 0, kRpc, PROTECTION_OFF, NULL); + connection_handler_->set_protocol_handler(NULL); EXPECT_NE(0u, start_session_id_); EXPECT_EQ(SessionHash(uid_, start_session_id_), out_hash_id_); connection_key_ = connection_handler_->KeyFromPair(uid_, start_session_id_); @@ -123,8 +138,16 @@ class ConnectionHandlerTest : public ::testing::Test { EXPECT_EQ(SessionHash(uid_, start_session_id_), out_hash_id_); connection_key_ = connection_handler_->KeyFromPair(uid_, start_session_id_); CheckSessionExists(uid_, start_session_id_); - uint32_t session_id = connection_handler_->OnSessionStartedCallback( + + uint32_t session_id = 0; + protocol_handler_test::MockProtocolHandler temp_protocol_handler; + connection_handler_->set_protocol_handler(&temp_protocol_handler); + EXPECT_CALL(temp_protocol_handler, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id)); + + connection_handler_->OnSessionStartedCallback( uid_, start_session_id_, service_type, PROTECTION_OFF, 0); + connection_handler_->set_protocol_handler(NULL); EXPECT_EQ(session_id, start_session_id_); } @@ -267,8 +290,13 @@ TEST_F(ConnectionHandlerTest, StartSession_NoConnection) { // Null sessionId for start new session const uint8_t sessionID = 0; // Start new session with RPC service - const uint32_t result_fail = connection_handler_->OnSessionStartedCallback( - uid_, sessionID, kRpc, PROTECTION_ON, &out_hash_id_); + uint32_t result_fail = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(DoAll(SaveArg<0>(&result_fail), SaveArg<1>(&out_hash_id_))); + + connection_handler_->OnSessionStartedCallback( + uid_, sessionID, kRpc, PROTECTION_ON, NULL); // Unknown connection error is '0' EXPECT_EQ(0u, result_fail); EXPECT_EQ(protocol_handler::HASH_ID_WRONG, out_hash_id_); @@ -1013,19 +1041,28 @@ TEST_F(ConnectionHandlerTest, StartService_withServices) { AddTestDeviceConnection(); AddTestSession(); + uint32_t start_audio = 0; + uint32_t start_video = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(DoAll(SaveArg<0>(&start_audio), SaveArg<1>(&out_hash_id_))) + .WillOnce(DoAll(SaveArg<0>(&start_video), SaveArg<1>(&out_hash_id_))); + // Start Audio service - const uint32_t start_audio = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_OFF, NULL); EXPECT_EQ(start_session_id_, start_audio); CheckServiceExists(uid_, start_session_id_, kAudio, true); EXPECT_EQ(protocol_handler::HASH_ID_NOT_SUPPORTED, out_hash_id_); // Start Audio service - const uint32_t start_video = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kMobileNav, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kMobileNav, PROTECTION_OFF, NULL); EXPECT_EQ(start_session_id_, start_video); CheckServiceExists(uid_, start_session_id_, kMobileNav, true); EXPECT_EQ(protocol_handler::HASH_ID_NOT_SUPPORTED, out_hash_id_); + + connection_handler_->set_protocol_handler(NULL); } TEST_F(ConnectionHandlerTest, ServiceStop_UnExistSession) { @@ -1052,11 +1089,18 @@ TEST_F(ConnectionHandlerTest, ServiceStop_UnExistService) { TEST_F(ConnectionHandlerTest, ServiceStop) { AddTestDeviceConnection(); AddTestSession(); + + uint32_t start_audio = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillRepeatedly( + DoAll(SaveArg<0>(&start_audio), SaveArg<1>(&out_hash_id_))); + // Check ignoring hash_id on stop non-rpc service for (uint32_t some_hash_id = 0; some_hash_id < 0xFF; ++some_hash_id) { // Start audio service - const uint32_t start_audio = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_OFF, NULL); EXPECT_EQ(start_session_id_, start_audio); EXPECT_EQ(protocol_handler::HASH_ID_NOT_SUPPORTED, out_hash_id_); @@ -1122,13 +1166,23 @@ TEST_F(ConnectionHandlerTest, SessionStarted_WithRpc) { &mock_connection_handler_observer); uint32_t session_key = connection_handler_->KeyFromPair(uid_, start_session_id_); + std::vector<std::string> empty; EXPECT_CALL(mock_connection_handler_observer, - OnServiceStartedCallback(device_handle_, session_key, kRpc)) - .WillOnce(Return(true)); + OnServiceStartedCallback(device_handle_, session_key, kRpc, NULL)) + .WillOnce(InvokeMemberFuncWithArg2( + connection_handler_, + &ConnectionHandler::NotifyServiceStartedResult, + true, + ByRef(empty))); + + uint32_t new_session_id = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(DoAll(SaveArg<0>(&new_session_id), SaveArg<1>(&out_hash_id_))); // Start new session with RPC service - uint32_t new_session_id = connection_handler_->OnSessionStartedCallback( - uid_, 0, kRpc, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, 0, kRpc, PROTECTION_OFF, NULL); EXPECT_NE(0u, new_session_id); } @@ -1142,10 +1196,17 @@ TEST_F(ConnectionHandlerTest, // Forbid start kRPC without encryption protected_services_.push_back(kRpc); SetSpecificServices(); + + uint32_t session_id_fail = 0; + uint32_t session_id = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(DoAll(SaveArg<0>(&session_id_fail), SaveArg<1>(&out_hash_id_))) + .WillOnce(DoAll(SaveArg<0>(&session_id), SaveArg<1>(&out_hash_id_))); + // Start new session with RPC service - const uint32_t session_id_fail = - connection_handler_->OnSessionStartedCallback( - uid_, 0, kRpc, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, 0, kRpc, PROTECTION_OFF, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(0u, session_id_fail); EXPECT_EQ(protocol_handler::HASH_ID_WRONG, out_hash_id_); @@ -1159,8 +1220,8 @@ TEST_F(ConnectionHandlerTest, protected_services_.push_back(kControl); SetSpecificServices(); // Start new session with RPC service - const uint32_t session_id = connection_handler_->OnSessionStartedCallback( - uid_, 0, kRpc, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, 0, kRpc, PROTECTION_OFF, NULL); EXPECT_NE(0u, session_id); CheckService(uid_, session_id, kRpc, NULL, PROTECTION_OFF); EXPECT_EQ(SessionHash(uid_, session_id), out_hash_id_); @@ -1176,10 +1237,17 @@ TEST_F(ConnectionHandlerTest, unprotected_services_.push_back(UnnamedService::kServedService2); unprotected_services_.push_back(kControl); SetSpecificServices(); + + uint32_t session_id_fail = 0; + uint32_t session_id = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id_fail)) + .WillOnce(DoAll(SaveArg<0>(&session_id), SaveArg<1>(&out_hash_id_))); + // Start new session with RPC service - const uint32_t session_id_fail = - connection_handler_->OnSessionStartedCallback( - uid_, 0, kRpc, PROTECTION_ON, NULL); + connection_handler_->OnSessionStartedCallback( + uid_, 0, kRpc, PROTECTION_ON, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(0u, session_id_fail); #else @@ -1191,8 +1259,8 @@ TEST_F(ConnectionHandlerTest, unprotected_services_.push_back(kControl); SetSpecificServices(); // Start new session with RPC service - const uint32_t session_id = connection_handler_->OnSessionStartedCallback( - uid_, 0, kRpc, PROTECTION_ON, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, 0, kRpc, PROTECTION_ON, NULL); EXPECT_NE(0u, session_id); EXPECT_EQ(SessionHash(uid_, session_id), out_hash_id_); @@ -1211,8 +1279,16 @@ TEST_F(ConnectionHandlerTest, protected_services_.push_back(UnnamedService::kServedService2); protected_services_.push_back(kControl); SetSpecificServices(); + + uint32_t session_id2 = 0; + uint32_t session_id3 = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id2)) + .WillOnce(DoAll(SaveArg<0>(&session_id3), SaveArg<1>(&out_hash_id_))); + // Start new session with Audio service - const uint32_t session_id2 = connection_handler_->OnSessionStartedCallback( + connection_handler_->OnSessionStartedCallback( uid_, start_session_id_, kAudio, PROTECTION_OFF, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(0u, session_id2); @@ -1226,8 +1302,8 @@ TEST_F(ConnectionHandlerTest, protected_services_.push_back(UnnamedService::kServedService2); protected_services_.push_back(kControl); SetSpecificServices(); - const uint32_t session_id3 = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_OFF, NULL); // Returned original session id #ifdef ENABLE_SECURITY EXPECT_EQ(start_session_id_, session_id3); @@ -1250,10 +1326,17 @@ TEST_F(ConnectionHandlerTest, unprotected_services_.push_back(UnnamedService::kServedService2); unprotected_services_.push_back(kControl); SetSpecificServices(); + + uint32_t session_id_reject = 0; + uint32_t session_id3 = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id_reject)) + .WillOnce(DoAll(SaveArg<0>(&session_id3), SaveArg<1>(&out_hash_id_))); + // Start new session with Audio service - const uint32_t session_id_reject = - connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_ON, NULL); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_ON, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(0u, session_id_reject); #else @@ -1262,8 +1345,8 @@ TEST_F(ConnectionHandlerTest, // Allow start kAudio with encryption unprotected_services_.clear(); SetSpecificServices(); - const uint32_t session_id3 = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_ON, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_ON, NULL); // Returned original session id #ifdef ENABLE_SECURITY EXPECT_EQ(start_session_id_, session_id3); @@ -1280,9 +1363,18 @@ TEST_F(ConnectionHandlerTest, SessionStarted_DealyProtect) { AddTestDeviceConnection(); AddTestSession(); + uint32_t session_id_new = 0; + uint32_t session_id2 = 0; + uint32_t session_id3 = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(DoAll(SaveArg<0>(&session_id_new), SaveArg<1>(&out_hash_id_))) + .WillOnce(DoAll(SaveArg<0>(&session_id2), SaveArg<1>(&out_hash_id_))) + .WillOnce(DoAll(SaveArg<0>(&session_id3), SaveArg<1>(&out_hash_id_))); + // Start RPC protection - const uint32_t session_id_new = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kRpc, PROTECTION_ON, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kRpc, PROTECTION_ON, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(start_session_id_, session_id_new); // Post protection nedd no hash @@ -1296,15 +1388,15 @@ TEST_F(ConnectionHandlerTest, SessionStarted_DealyProtect) { #endif // ENABLE_SECURITY // Start Audio session without protection - const uint32_t session_id2 = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_OFF, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_OFF, NULL); EXPECT_EQ(start_session_id_, session_id2); EXPECT_EQ(protocol_handler::HASH_ID_NOT_SUPPORTED, out_hash_id_); CheckService(uid_, start_session_id_, kAudio, NULL, PROTECTION_OFF); // Start Audio protection - const uint32_t session_id3 = connection_handler_->OnSessionStartedCallback( - uid_, start_session_id_, kAudio, PROTECTION_ON, &out_hash_id_); + connection_handler_->OnSessionStartedCallback( + uid_, start_session_id_, kAudio, PROTECTION_ON, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(start_session_id_, session_id3); EXPECT_EQ(protocol_handler::HASH_ID_NOT_SUPPORTED, out_hash_id_); @@ -1320,7 +1412,11 @@ TEST_F(ConnectionHandlerTest, SessionStarted_DealyProtectBulk) { AddTestDeviceConnection(); AddTestSession(); - const uint32_t session_id_new = connection_handler_->OnSessionStartedCallback( + uint32_t session_id_new = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id_new)); + connection_handler_->OnSessionStartedCallback( uid_, start_session_id_, kBulk, PROTECTION_ON, NULL); #ifdef ENABLE_SECURITY EXPECT_EQ(start_session_id_, session_id_new); @@ -1416,8 +1512,14 @@ TEST_F(ConnectionHandlerTest, GetSSLContext_ByProtectedService) { // kAudio is not exists yet EXPECT_EQ(connection_handler_->GetSSLContext(connection_key_, kAudio), reinterpret_cast<security_manager::SSLContext*>(NULL)); + + uint32_t session_id = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id)); + // Open kAudio service - const uint32_t session_id = connection_handler_->OnSessionStartedCallback( + connection_handler_->OnSessionStartedCallback( uid_, start_session_id_, kAudio, PROTECTION_ON, NULL); EXPECT_EQ(session_id, start_session_id_); CheckService(uid_, session_id, kAudio, &mock_ssl_context, PROTECTION_ON); @@ -1441,8 +1543,13 @@ TEST_F(ConnectionHandlerTest, GetSSLContext_ByDealyProtectedRPC) { EXPECT_EQ(connection_handler_->GetSSLContext(connection_key_, kRpc), reinterpret_cast<security_manager::SSLContext*>(NULL)); + uint32_t session_id = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id)); + // Protect kRpc (Bulk will be protect also) - const uint32_t session_id = connection_handler_->OnSessionStartedCallback( + connection_handler_->OnSessionStartedCallback( uid_, start_session_id_, kRpc, PROTECTION_ON, NULL); EXPECT_EQ(start_session_id_, session_id); CheckService(uid_, session_id, kRpc, &mock_ssl_context, PROTECTION_ON); @@ -1469,8 +1576,13 @@ TEST_F(ConnectionHandlerTest, GetSSLContext_ByDealyProtectedBulk) { EXPECT_EQ(connection_handler_->GetSSLContext(connection_key_, kRpc), reinterpret_cast<security_manager::SSLContext*>(NULL)); + uint32_t session_id = 0; + connection_handler_->set_protocol_handler(&mock_protocol_handler_); + EXPECT_CALL(mock_protocol_handler_, NotifySessionStartedResult(_, _, _, _)) + .WillOnce(SaveArg<0>(&session_id)); + // Protect Bulk (kRpc will be protected also) - const uint32_t session_id = connection_handler_->OnSessionStartedCallback( + connection_handler_->OnSessionStartedCallback( uid_, start_session_id_, kBulk, PROTECTION_ON, NULL); EXPECT_EQ(start_session_id_, session_id); CheckService(uid_, session_id, kRpc, &mock_ssl_context, PROTECTION_ON); diff --git a/src/components/include/application_manager/application_manager.h b/src/components/include/application_manager/application_manager.h index 98bb341657..7875c12ff5 100644 --- a/src/components/include/application_manager/application_manager.h +++ b/src/components/include/application_manager/application_manager.h @@ -592,6 +592,20 @@ class ApplicationManager { */ virtual void ForbidStreaming(uint32_t app_id) = 0; + /** + * @brief Called when application completes streaming configuration + * @param app_id Streaming application id + * @param service_type Streaming service type + * @param result true if configuration is successful, false otherwise + * @param rejected_params list of rejected parameters' name. Valid + * only when result is false. + */ + virtual void OnStreamingConfigured( + uint32_t app_id, + protocol_handler::ServiceType service_type, + bool result, + std::vector<std::string>& rejected_params) = 0; + virtual const ApplicationManagerSettings& get_settings() const = 0; virtual event_engine::EventDispatcher& event_dispatcher() = 0; diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h index e8e1af715a..ca1a0314c6 100644 --- a/src/components/include/connection_handler/connection_handler.h +++ b/src/components/include/connection_handler/connection_handler.h @@ -198,6 +198,18 @@ class ConnectionHandler { virtual DevicesDiscoveryStarter& get_device_discovery_starter() = 0; + /** + * \brief Invoked when observer's OnServiceStartedCallback is completed + * \param result true if observer accepts starting service, false otherwise + * \param rejected_params list of rejected parameters' name. Only valid when + * result is false. Note that even if result is false, this may be empty. + * + * \note This is invoked only once but can be invoked by multiple threads. + * Also it can be invoked before OnServiceStartedCallback() returns. + **/ + virtual void NotifyServiceStartedResult( + bool result, std::vector<std::string>& rejected_params) = 0; + protected: /** * \brief Destructor diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h index e25b0aaea5..706f338d60 100644 --- a/src/components/include/connection_handler/connection_handler_observer.h +++ b/src/components/include/connection_handler/connection_handler_observer.h @@ -42,6 +42,8 @@ #include "security_manager/ssl_context.h" #endif // ENABLE_SECURITY +struct BsonObject; + /** * \namespace connection_handler * \brief SmartDeviceLink connection_handler namespace. @@ -83,15 +85,18 @@ class ConnectionHandlerObserver { /** * \brief Callback function used by connection_handler * when Mobile Application initiates start of new service. + * Result must be notified through NotifyServiceStartedResult(). * \param deviceHandle Device identifier within which session has to be * started. * \param sessionKey Key of started session. * \param type Established service type + * \param params Configuration parameters for this service */ - virtual bool OnServiceStartedCallback( + virtual void OnServiceStartedCallback( const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, - const protocol_handler::ServiceType& type) = 0; + const protocol_handler::ServiceType& type, + const BsonObject* params) = 0; /** * \brief Callback function used by connection_handler diff --git a/src/components/include/protocol_handler/protocol_handler.h b/src/components/include/protocol_handler/protocol_handler.h index 183db21532..5a3a2754cb 100644 --- a/src/components/include/protocol_handler/protocol_handler.h +++ b/src/components/include/protocol_handler/protocol_handler.h @@ -108,6 +108,23 @@ class ProtocolHandler { virtual const ProtocolHandlerSettings& get_settings() const = 0; virtual SessionObserver& get_session_observer() = 0; + /** + * \brief Called by connection handler to notify the result of + * OnSessionStartedCallback(). + * \param session_id Generated session ID, will be 0 if session is not + * started + * \param hash_id Generated Hash ID + * \param protection whether the service will be protected + * \param rejected_params list of parameters' name that are rejected. + * Only valid when session_id is 0. Note, even if session_id is 0, the + * list may be empty. + */ + virtual void NotifySessionStartedResult( + uint8_t session_id, + uint32_t hash_id, + bool protection, + std::vector<std::string>& rejected_params) = 0; + protected: /** * \brief Destructor diff --git a/src/components/include/protocol_handler/session_observer.h b/src/components/include/protocol_handler/session_observer.h index a5901baf0b..70035b5a3c 100644 --- a/src/components/include/protocol_handler/session_observer.h +++ b/src/components/include/protocol_handler/session_observer.h @@ -39,6 +39,9 @@ #ifdef ENABLE_SECURITY #include "security_manager/ssl_context.h" #endif // ENABLE_SECURITY + +struct BsonObject; + /** *\namespace protocol_handlerHandler *\brief Namespace for SmartDeviceLink ProtocolHandler related functionality. @@ -64,21 +67,21 @@ class SessionObserver { /** * \brief Callback function used by ProtocolHandler * when Mobile Application initiates start of new session. + * Result must be notified through NotifySessionStartedResult(). * \param connection_handle Connection identifier within which session * has to be started. * \param sessionId Identifier of the session to be start * \param service_type Type of service * \param protocol_version Version of protocol * \param is_protected would be service protected - * \param hash_id pointer for session hash identifier, uint32_t* hash_id - * \return uint32_t Id (number) of new session if successful, otherwise 0. + * \param params configuration parameters specified by mobile */ - virtual uint32_t OnSessionStartedCallback( + virtual void OnSessionStartedCallback( const transport_manager::ConnectionUID connection_handle, const uint8_t sessionId, const protocol_handler::ServiceType& service_type, const bool is_protected, - uint32_t* hash_id) = 0; + const BsonObject *params) = 0; // DEPRECATED virtual uint32_t OnSessionEndedCallback( diff --git a/src/components/include/test/application_manager/mock_application_manager.h b/src/components/include/test/application_manager/mock_application_manager.h index fb15435ca0..8d1bb756c2 100644 --- a/src/components/include/test/application_manager/mock_application_manager.h +++ b/src/components/include/test/application_manager/mock_application_manager.h @@ -261,6 +261,11 @@ class MockApplicationManager : public application_manager::ApplicationManager { MOCK_METHOD0(OnTimerSendTTSGlobalProperties, void()); MOCK_METHOD0(OnLowVoltage, void()); MOCK_METHOD0(OnWakeUp, void()); + MOCK_METHOD4(OnStreamingConfigured, + void(uint32_t app_id, + protocol_handler::ServiceType service_type, + bool result, + std::vector<std::string>& rejected_params)); }; } // namespace application_manager_test diff --git a/src/components/include/test/connection_handler/mock_connection_handler.h b/src/components/include/test/connection_handler/mock_connection_handler.h index e17224b097..b6af1e1f15 100644 --- a/src/components/include/test/connection_handler/mock_connection_handler.h +++ b/src/components/include/test/connection_handler/mock_connection_handler.h @@ -96,6 +96,8 @@ class MockConnectionHandler : public connection_handler::ConnectionHandler { MOCK_METHOD0(get_device_discovery_starter, DevicesDiscoveryStarter&()); MOCK_CONST_METHOD1(GetConnectedDevicesMAC, void(std::vector<std::string>& macs)); + MOCK_METHOD2(NotifyServiceStartedResult, + void(bool result, std::vector<std::string>& rejected_params)); }; } // namespace connection_handler_test diff --git a/src/components/include/test/connection_handler/mock_connection_handler_observer.h b/src/components/include/test/connection_handler/mock_connection_handler_observer.h index 6ca4557b35..d9a12d35c2 100644 --- a/src/components/include/test/connection_handler/mock_connection_handler_observer.h +++ b/src/components/include/test/connection_handler/mock_connection_handler_observer.h @@ -48,10 +48,11 @@ class MockConnectionHandlerObserver MOCK_METHOD0(OnFindNewApplicationsRequest, void()); MOCK_METHOD1(RemoveDevice, void(const connection_handler::DeviceHandle& device_handle)); - MOCK_METHOD3(OnServiceStartedCallback, - bool(const connection_handler::DeviceHandle& device_handle, + MOCK_METHOD4(OnServiceStartedCallback, + void(const connection_handler::DeviceHandle& device_handle, const int32_t& session_key, - const protocol_handler::ServiceType& type)); + const protocol_handler::ServiceType& type, + const BsonObject* params)); MOCK_METHOD3( OnServiceEndedCallback, void(const int32_t& session_key, diff --git a/src/components/include/test/protocol_handler/mock_protocol_handler.h b/src/components/include/test/protocol_handler/mock_protocol_handler.h index 44287edd4d..acb06ea6df 100644 --- a/src/components/include/test/protocol_handler/mock_protocol_handler.h +++ b/src/components/include/test/protocol_handler/mock_protocol_handler.h @@ -62,6 +62,11 @@ class MockProtocolHandler : public ::protocol_handler::ProtocolHandler { MOCK_CONST_METHOD0(get_settings, const ::protocol_handler::ProtocolHandlerSettings&()); MOCK_METHOD0(get_session_observer, protocol_handler::SessionObserver&()); + MOCK_METHOD4(NotifySessionStartedResult, + void(uint8_t session_id, + uint32_t hash_id, + bool protection, + std::vector<std::string>& rejected_params)); }; } // namespace protocol_handler_test } // namespace components diff --git a/src/components/include/test/protocol_handler/mock_session_observer.h b/src/components/include/test/protocol_handler/mock_session_observer.h index 0a86a29db5..40137c2e00 100644 --- a/src/components/include/test/protocol_handler/mock_session_observer.h +++ b/src/components/include/test/protocol_handler/mock_session_observer.h @@ -46,13 +46,12 @@ namespace protocol_handler_test { */ class MockSessionObserver : public ::protocol_handler::SessionObserver { public: - MOCK_METHOD5( - OnSessionStartedCallback, - uint32_t(const transport_manager::ConnectionUID connection_handle, - const uint8_t sessionId, - const protocol_handler::ServiceType& service_type, - const bool is_protected, - uint32_t* hash_id)); + MOCK_METHOD5(OnSessionStartedCallback, + void(const transport_manager::ConnectionUID connection_handle, + const uint8_t sessionId, + const protocol_handler::ServiceType& service_type, + const bool is_protected, + const BsonObject* params)); MOCK_METHOD4( OnSessionEndedCallback, uint32_t(const transport_manager::ConnectionUID connection_handle, diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h index bb6483dd82..2370fd730f 100644 --- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h +++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h @@ -349,6 +349,23 @@ class ProtocolHandlerImpl SessionObserver& get_session_observer() OVERRIDE; + /** + * \brief Called by connection handler to notify the result of + * OnSessionStartedCallback(). + * \param session_id Generated session ID, will be 0 if session is not + * started + * \param hash_id Generated Hash ID + * \param protection whether the service will be protected + * \param rejected_params list of parameters' name that are rejected. + * Only valid when session_id is 0. Note, even if session_id is 0, the + * list may be empty. + */ + void NotifySessionStartedResult( + uint8_t session_id, + uint32_t hash_id, + bool protection, + std::vector<std::string>& rejected_params) OVERRIDE; + #ifdef BUILD_TESTS const impl::FromMobileQueue& get_from_mobile_queue() const { return raw_ford_messages_from_mobile_; @@ -505,7 +522,7 @@ class ProtocolHandlerImpl RESULT_CODE HandleControlMessageEndServiceACK(const ProtocolPacket& packet); - RESULT_CODE HandleControlMessageStartSession(const ProtocolPacket& packet); + RESULT_CODE HandleControlMessageStartSession(const ProtocolFramePtr packet); RESULT_CODE HandleControlMessageHeartBeat(const ProtocolPacket& packet); @@ -618,6 +635,9 @@ class ProtocolHandlerImpl sync_primitives::Lock protocol_observers_lock_; + // we need thread-safe queue + utils::MessageQueue<ProtocolFramePtr> start_session_frame_queue_; + #ifdef TELEMETRY_MONITOR PHTelemetryObserver* metric_observer_; #endif // TELEMETRY_MONITOR diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc index 938583125d..3592ce692d 100644 --- a/src/components/protocol_handler/src/protocol_handler_impl.cc +++ b/src/components/protocol_handler/src/protocol_handler_impl.cc @@ -81,6 +81,7 @@ ProtocolHandlerImpl::ProtocolHandlerImpl( "PH FromMobile", this, threads::ThreadOptions(kStackSize)) , raw_ford_messages_to_mobile_( "PH ToMobile", this, threads::ThreadOptions(kStackSize)) + , start_session_frame_queue_() #ifdef TELEMETRY_MONITOR , metric_observer_(NULL) #endif // TELEMETRY_MONITOR @@ -1029,7 +1030,7 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessage( switch (packet->frame_data()) { case FRAME_DATA_START_SERVICE: { LOG4CXX_TRACE(logger_, "FrameData: StartService"); - return HandleControlMessageStartSession(*packet); + return HandleControlMessageStartSession(packet); } case FRAME_DATA_END_SERVICE: { LOG4CXX_TRACE(logger_, "FrameData: StopService"); @@ -1253,37 +1254,63 @@ class StartSessionHandler : public security_manager::SecurityManagerListener { #endif // ENABLE_SECURITY RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( - const ProtocolPacket& packet) { + const ProtocolFramePtr packet) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG( logger_, - "Protocol version:" << static_cast<int>(packet.protocol_version())); - const ServiceType service_type = ServiceTypeFromByte(packet.service_type()); - const uint8_t protocol_version = packet.protocol_version(); + "Protocol version:" << static_cast<int>(packet->protocol_version())); + const ServiceType service_type = ServiceTypeFromByte(packet->service_type()); + const uint8_t protocol_version = packet->protocol_version(); + BsonObject bson_obj = bson_object_from_bytes(packet->data()); #ifdef ENABLE_SECURITY const bool protection = // Protocolo version 1 is not support protection - (protocol_version > PROTOCOL_VERSION_1) ? packet.protection_flag() + (protocol_version > PROTOCOL_VERSION_1) ? packet->protection_flag() : false; #else const bool protection = false; #endif // ENABLE_SECURITY - uint32_t hash_id; - const ConnectionID connection_id = packet.connection_id(); - const uint32_t session_id = session_observer_.OnSessionStartedCallback( - connection_id, packet.session_id(), service_type, protection, &hash_id); + const ConnectionID connection_id = packet->connection_id(); + + start_session_frame_queue_.push(packet); + + session_observer_.OnSessionStartedCallback( + connection_id, packet->session_id(), service_type, protection, &bson_obj); + bson_object_deinitialize(&bson_obj); + + return RESULT_OK; +} + +void ProtocolHandlerImpl::NotifySessionStartedResult( + uint8_t session_id, + uint32_t hash_id, + bool protection, + std::vector<std::string>& rejected_params) { + + ProtocolFramePtr packet; + bool available = start_session_frame_queue_.pop(packet); + if (!available) { + LOG4CXX_ERROR(logger_, + "Cannot find Session Started packet"); + return; + } + + const ServiceType service_type = ServiceTypeFromByte(packet->service_type()); + const uint8_t protocol_version = packet->protocol_version(); + const ConnectionID connection_id = packet->connection_id(); if (0 == session_id) { LOG4CXX_WARN(logger_, "Refused by session_observer to create service " << static_cast<int32_t>(service_type) << " type."); SendStartSessionNAck(connection_id, - packet.session_id(), + session_id, protocol_version, - packet.service_type()); - return RESULT_OK; + packet->service_type(), + rejected_params); + return; } #ifdef ENABLE_SECURITY @@ -1304,19 +1331,19 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( // Start service without protection SendStartSessionAck(connection_id, session_id, - packet.protocol_version(), + packet->protocol_version(), hash_id, - packet.service_type(), + packet->service_type(), PROTECTION_OFF); - return RESULT_OK; + return; } ProtocolPacket::ProtocolVersion* fullVersion; std::vector<std::string> rejectedParams; // Can't check protocol_version because the first packet is v1, but there // could still be a payload, in which case we can get the real protocol // version - if (packet.service_type() == kRpc && packet.data_size() != 0) { - BsonObject obj = bson_object_from_bytes(packet.data()); + if (packet->service_type() == kRpc && packet->data_size() != 0) { + BsonObject obj = bson_object_from_bytes(packet->data()); fullVersion = new ProtocolPacket::ProtocolVersion( std::string(bson_object_get_string(&obj, strings::protocol_version))); bson_object_deinitialize(&obj); @@ -1329,9 +1356,9 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( } if (!rejectedParams.empty()) { SendStartSessionNAck(connection_id, - packet.session_id(), + packet->session_id(), protocol_version, - packet.service_type(), + packet->service_type(), rejectedParams); } else if (ssl_context->IsInitCompleted()) { // mark service as protected @@ -1339,9 +1366,9 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( // Start service as protected with current SSLContext SendStartSessionAck(connection_id, session_id, - packet.protocol_version(), + packet->protocol_version(), hash_id, - packet.service_type(), + packet->service_type(), PROTECTION_ON, *fullVersion); } else { @@ -1351,7 +1378,7 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( session_observer_, connection_id, session_id, - packet.protocol_version(), + packet->protocol_version(), hash_id, service_type, get_settings().force_protected_service(), @@ -1365,11 +1392,11 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( LOG4CXX_DEBUG(logger_, "Protection establishing for connection " << connection_key << " is in progress"); - return RESULT_OK; + return; } #endif // ENABLE_SECURITY - if (packet.service_type() == kRpc && packet.data_size() != 0) { - BsonObject obj = bson_object_from_bytes(packet.data()); + if (packet->service_type() == kRpc && packet->data_size() != 0) { + BsonObject obj = bson_object_from_bytes(packet->data()); ProtocolPacket::ProtocolVersion fullVersion( bson_object_get_string(&obj, strings::protocol_version)); bson_object_deinitialize(&obj); @@ -1378,18 +1405,18 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( // Start service without protection SendStartSessionAck(connection_id, session_id, - packet.protocol_version(), + packet->protocol_version(), hash_id, - packet.service_type(), + packet->service_type(), PROTECTION_OFF, fullVersion); } else { std::vector<std::string> rejectedParams( 1, std::string(strings::protocol_version)); SendStartSessionNAck(connection_id, - packet.session_id(), + packet->session_id(), protocol_version, - packet.service_type(), + packet->service_type(), rejectedParams); } @@ -1397,12 +1424,11 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession( // Start service without protection SendStartSessionAck(connection_id, session_id, - packet.protocol_version(), + packet->protocol_version(), hash_id, - packet.service_type(), + packet->service_type(), PROTECTION_OFF); } - return RESULT_OK; } RESULT_CODE ProtocolHandlerImpl::HandleControlMessageHeartBeat( diff --git a/src/components/protocol_handler/test/protocol_handler_tm_test.cc b/src/components/protocol_handler/test/protocol_handler_tm_test.cc index 66226825ba..2729254869 100644 --- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc +++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc @@ -98,6 +98,7 @@ using ::testing::ReturnRefOfCopy; using ::testing::ReturnNull; using ::testing::An; using ::testing::AnyOf; +using ::testing::ByRef; using ::testing::DoAll; using ::testing::_; using ::testing::Invoke; @@ -106,6 +107,11 @@ using ::testing::SetArgPointee; typedef std::vector<uint8_t> UCharDataVector; +// custom action to call a member function with 4 arguments +ACTION_P6(InvokeMemberFuncWithArg4, ptr, memberFunc, a, b, c, d) { + (ptr->*memberFunc)(a, b, c, d); +} + namespace { const uint32_t kAsyncExpectationsTimeout = 10000u; } @@ -179,6 +185,7 @@ class ProtocolHandlerImplTest : public ::testing::Test { void AddSession(const ::utils::SharedPtr<TestAsyncWaiter>& waiter, uint32_t& times) { + using namespace protocol_handler; ASSERT_TRUE(NULL != waiter.get()); AddConnection(); @@ -192,6 +199,7 @@ class ProtocolHandlerImplTest : public ::testing::Test { // use protection OFF const bool callback_protection_flag = PROTECTION_OFF; #endif // ENABLE_SECURITY + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL(session_observer_mock, @@ -202,7 +210,14 @@ class ProtocolHandlerImplTest : public ::testing::Test { _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(waiter), Return(session_id))); + WillOnce(DoAll(NotifyTestAsyncWaiter(waiter), + InvokeMemberFuncWithArg4( + protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + callback_protection_flag, + ByRef(empty)))); times++; // Expect send Ack with PROTECTION_OFF (on no Security Manager) @@ -342,11 +357,13 @@ TEST_F(ProtocolHandlerImplTest, RecieveOnUnknownConnection) { */ TEST_F(ProtocolHandlerImplTest, StartSession_Unprotected_SessionObserverReject) { + using namespace protocol_handler; const int call_times = 5; AddConnection(); TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -358,8 +375,14 @@ TEST_F(ProtocolHandlerImplTest, .Times(call_times) . // Return sessions start rejection - WillRepeatedly( - DoAll(NotifyTestAsyncWaiter(&waiter), Return(SESSION_START_REJECT))); + WillRepeatedly(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + SESSION_START_REJECT, + HASH_ID_WRONG, + PROTECTION_OFF, + ByRef(empty)))); times += call_times; // Expect send NAck @@ -390,6 +413,7 @@ TEST_F(ProtocolHandlerImplTest, * OFF */ TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) { + using namespace protocol_handler; const int call_times = 5; AddConnection(); #ifdef ENABLE_SECURITY @@ -403,6 +427,7 @@ TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) { TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -414,8 +439,14 @@ TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) { .Times(call_times) . // Return sessions start rejection - WillRepeatedly( - DoAll(NotifyTestAsyncWaiter(&waiter), Return(SESSION_START_REJECT))); + WillRepeatedly(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + SESSION_START_REJECT, + HASH_ID_WRONG, + callback_protection_flag, + ByRef(empty)))); times += call_times; // Expect send NAck with encryption OFF @@ -445,11 +476,13 @@ TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverReject) { */ TEST_F(ProtocolHandlerImplTest, StartSession_Unprotected_SessionObserverAccept) { + using namespace protocol_handler; AddConnection(); const ServiceType start_service = kRpc; TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -457,7 +490,14 @@ TEST_F(ProtocolHandlerImplTest, connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_OFF, + ByRef(empty)))); times++; SetProtocolVersion2(); @@ -567,6 +607,7 @@ TEST_F(ProtocolHandlerImplTest, EndSession_Success) { * Check session_observer with PROTECTION_OFF and Ack with PROTECTION_OFF */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) { + using namespace protocol_handler; ::utils::SharedPtr<TestAsyncWaiter> waiter = utils::MakeShared<TestAsyncWaiter>(); uint32_t times = 0; @@ -576,6 +617,7 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) { // Add security manager AddSecurityManager(); const ServiceType start_service = kRpc; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -583,7 +625,14 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) { connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_OFF, + ByRef(empty)))); times++; SetProtocolVersion2(); @@ -612,6 +661,7 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) { * PROTECTION_OFF */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) { + using namespace protocol_handler; AddConnection(); // Add security manager AddSecurityManager(); @@ -619,6 +669,7 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) { TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -626,7 +677,14 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) { connection_id, NEW_SESSION_ID, start_service, PROTECTION_OFF, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_OFF, + ByRef(empty)))); times++; SetProtocolVersion2(); @@ -646,12 +704,14 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionUnprotected) { * ProtocolHandler shall send Ack with PROTECTION_OFF on fail SLL creation */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { + using namespace protocol_handler; AddConnection(); AddSecurityManager(); const ServiceType start_service = kRpc; TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -659,7 +719,14 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_ON, + ByRef(empty)))); times++; SetProtocolVersion2(); @@ -688,12 +755,14 @@ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_Fail) { */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_SSLInitialized) { + using namespace protocol_handler; AddConnection(); AddSecurityManager(); const ServiceType start_service = kRpc; TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -701,7 +770,14 @@ TEST_F(ProtocolHandlerImplTest, connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_ON, + ByRef(empty)))); times++; SetProtocolVersion2(); @@ -743,12 +819,14 @@ TEST_F(ProtocolHandlerImplTest, */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeFail) { + using namespace protocol_handler; AddConnection(); AddSecurityManager(); const ServiceType start_service = kRpc; TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -756,7 +834,14 @@ TEST_F(ProtocolHandlerImplTest, connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_ON, + ByRef(empty)))); times++; std::vector<int> services; @@ -818,6 +903,7 @@ TEST_F(ProtocolHandlerImplTest, */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeSuccess) { + using namespace protocol_handler; AddConnection(); AddSecurityManager(); const ServiceType start_service = kRpc; @@ -829,6 +915,7 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -836,7 +923,14 @@ TEST_F(ProtocolHandlerImplTest, connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_ON, + ByRef(empty)))); times++; // call new SSLContext creation @@ -904,6 +998,7 @@ TEST_F(ProtocolHandlerImplTest, TEST_F( ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeSuccess_ServiceProtectedBefore) { + using namespace protocol_handler; AddConnection(); AddSecurityManager(); const ServiceType start_service = kRpc; @@ -914,6 +1009,7 @@ TEST_F( TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -921,7 +1017,14 @@ TEST_F( connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_ON, + ByRef(empty)))); times++; // call new SSLContext creation @@ -987,6 +1090,7 @@ TEST_F( */ TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtected_HandshakeSuccess_SSLIsNotPending) { + using namespace protocol_handler; AddConnection(); AddSecurityManager(); const ServiceType start_service = kRpc; @@ -997,6 +1101,7 @@ TEST_F(ProtocolHandlerImplTest, TestAsyncWaiter waiter; uint32_t times = 0; + std::vector<std::string> empty; // Expect ConnectionHandler check EXPECT_CALL( session_observer_mock, @@ -1004,7 +1109,14 @@ TEST_F(ProtocolHandlerImplTest, connection_id, NEW_SESSION_ID, start_service, PROTECTION_ON, _)) . // Return sessions start success - WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(session_id))); + WillOnce(DoAll( + NotifyTestAsyncWaiter(&waiter), + InvokeMemberFuncWithArg4(protocol_handler_impl.get(), + &ProtocolHandler::NotifySessionStartedResult, + session_id, + HASH_ID_WRONG, + PROTECTION_ON, + ByRef(empty)))); times++; // call new SSLContext creation |