summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSho Amano <samano@xevo.com>2017-07-29 14:28:36 +0900
committerSho Amano <samano@xevo.com>2017-08-11 10:44:34 +0900
commit394a1a6b46eb19010448e8c9dad6e49186e38b32 (patch)
tree3bf4f3a1885ff45c98812de64dd21dd179dbd37e /src
parenta51cf183feed320093acd4a471e9eeec77c4a437 (diff)
downloadsdl_core-394a1a6b46eb19010448e8c9dad6e49186e38b32.tar.gz
Add implementation for video streaming parameters
Diffstat (limited to 'src')
-rw-r--r--src/components/application_manager/CMakeLists.txt4
-rw-r--r--src/components/application_manager/include/application_manager/application.h20
-rw-r--r--src/components/application_manager/include/application_manager/application_impl.h4
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h45
-rw-r--r--src/components/application_manager/src/application_impl.cc27
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc167
-rw-r--r--src/components/application_manager/src/commands/hmi/navi_set_video_config_request.cc6
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_application.h5
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_impl.h86
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc118
-rw-r--r--src/components/connection_handler/test/connection_handler_impl_test.cc198
-rw-r--r--src/components/include/application_manager/application_manager.h14
-rw-r--r--src/components/include/connection_handler/connection_handler.h12
-rw-r--r--src/components/include/connection_handler/connection_handler_observer.h9
-rw-r--r--src/components/include/protocol_handler/protocol_handler.h17
-rw-r--r--src/components/include/protocol_handler/session_observer.h11
-rw-r--r--src/components/include/test/application_manager/mock_application_manager.h5
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler.h2
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler_observer.h7
-rw-r--r--src/components/include/test/protocol_handler/mock_protocol_handler.h5
-rw-r--r--src/components/include/test/protocol_handler/mock_session_observer.h13
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h22
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc92
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc140
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