summaryrefslogtreecommitdiff
path: root/src/components/protocol_handler
diff options
context:
space:
mode:
authorConlain Kelly <conlain.k@gmail.com>2018-08-10 11:04:43 -0400
committerConlain Kelly <conlain.k@gmail.com>2018-08-10 11:04:43 -0400
commit72a64f7419d20bc379d1e050fdaac90b2a6d097f (patch)
treef5be0f57b4699b2fd30a459c105cfb44c6903508 /src/components/protocol_handler
parent3b5ddfdacb94f4e3f5752bb7165ca668f62f4a5d (diff)
parent43e53192045daeff8e9e2887c8b67894725240b5 (diff)
downloadsdl_core-72a64f7419d20bc379d1e050fdaac90b2a6d097f.tar.gz
Merge branch 'develop' of https://github.com/smartdevicelink/sdl_core into feature/boost_datetime_implementation
Diffstat (limited to 'src/components/protocol_handler')
-rw-r--r--src/components/protocol_handler/CMakeLists.txt1
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h117
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_packet.h7
-rw-r--r--src/components/protocol_handler/src/multiframe_builder.cc2
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc648
-rw-r--r--src/components/protocol_handler/src/protocol_packet.cc12
-rw-r--r--src/components/protocol_handler/test/include/protocol_handler/mock_telemetry_observer.h2
-rw-r--r--src/components/protocol_handler/test/incoming_data_handler_test.cc445
-rw-r--r--src/components/protocol_handler/test/multiframe_builder_test.cc12
-rw-r--r--src/components/protocol_handler/test/protocol_handler_tm_test.cc1254
-rw-r--r--src/components/protocol_handler/test/protocol_header_validator_test.cc8
11 files changed, 2201 insertions, 307 deletions
diff --git a/src/components/protocol_handler/CMakeLists.txt b/src/components/protocol_handler/CMakeLists.txt
index ed3aaaf24c..ff8678b826 100644
--- a/src/components/protocol_handler/CMakeLists.txt
+++ b/src/components/protocol_handler/CMakeLists.txt
@@ -65,7 +65,6 @@ endforeach()
add_library(ProtocolHandler ${SOURCES})
-add_dependencies(ProtocolHandler libbson)
target_link_libraries(ProtocolHandler ${LIBRARIES})
if(BUILD_TESTS)
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 99f03b1c04..58877ac611 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
@@ -42,8 +42,9 @@
#include "utils/prioritized_queue.h"
#include "utils/message_queue.h"
#include "utils/threads/message_loop_thread.h"
-#include "utils/shared_ptr.h"
+
#include "utils/messagemeter.h"
+#include "utils/custom_string.h"
#include "protocol_handler/protocol_handler.h"
#include "protocol_handler/protocol_packet.h"
@@ -55,6 +56,7 @@
#include "transport_manager/common.h"
#include "transport_manager/transport_manager.h"
#include "transport_manager/transport_manager_listener_empty.h"
+#include "transport_manager/transport_adapter/transport_adapter.h"
#include "connection_handler/connection_handler.h"
#include "application_manager/policies/policy_handler_observer.h"
@@ -131,6 +133,30 @@ typedef threads::MessageLoopThread<
utils::PrioritizedQueue<RawFordMessageFromMobile> > FromMobileQueue;
typedef threads::MessageLoopThread<
utils::PrioritizedQueue<RawFordMessageToMobile> > ToMobileQueue;
+
+// Type to allow easy mapping between a device type and transport
+// characteristics
+typedef enum {
+ TT_NONE = -1,
+ TT_USB = 0,
+ TT_BLUETOOTH = 1,
+ TT_WIFI = 2
+} TransportType;
+
+struct TransportDescription {
+ TransportDescription(const TransportType transport_type,
+ const bool ios_transport,
+ const bool android_transport)
+ : transport_type_(transport_type)
+ , ios_transport_(ios_transport)
+ , android_transport_(android_transport) {}
+
+ TransportType transport_type_;
+ bool ios_transport_;
+ bool android_transport_;
+};
+
+typedef std::map<std::string, TransportDescription> TransportTypes;
} // namespace impl
/**
@@ -231,7 +257,15 @@ class ProtocolHandlerImpl
*/
void SendEndSession(int32_t connection_id, uint8_t session_id);
- void SendEndService(int32_t connection_id,
+ /**
+ * \brief Sends ending session to mobile application
+ * \param primary_connection_id Identifier of connection within which
+ * service exists
+ * \param connection_id Identifier of the actual transport for the service
+ * \param session_id ID of session to be ended
+ */
+ void SendEndService(int32_t primary_connection_id,
+ int32_t connection_id,
uint8_t session_id,
uint8_t service_type);
@@ -422,10 +456,19 @@ class ProtocolHandlerImpl
const impl::ToMobileQueue& get_to_mobile_queue() const {
return raw_ford_messages_to_mobile_;
}
+
+ void set_tcp_config(bool tcp_enabled,
+ std::string tcp_address,
+ std::string tcp_port) {
+ tcp_enabled_ = tcp_enabled;
+ tcp_ip_address_ = tcp_address;
+ tcp_port_ = tcp_port;
+ }
#endif
private:
- void SendEndServicePrivate(int32_t connection_id,
+ void SendEndServicePrivate(int32_t primary_connection_id,
+ int32_t connection_id,
uint8_t session_id,
uint8_t service_type);
@@ -436,6 +479,28 @@ class ProtocolHandlerImpl
uint8_t session_id,
uint32_t message_id);
+ /*
+ * Prepare and send TransportUpdateEvent message
+ */
+ void SendTransportUpdateEvent(ConnectionID connection_id, uint8_t session_id);
+
+ /*
+ * Prepare and send RegisterSecondaryTransportAck message
+ */
+ RESULT_CODE SendRegisterSecondaryTransportAck(
+ ConnectionID connection_id,
+ ConnectionID primary_transport_connection_id,
+ uint8_t session_id);
+
+ /*
+ * Prepare and send RegisterSecondaryTransportNAck message
+ */
+ RESULT_CODE SendRegisterSecondaryTransportNAck(
+ ConnectionID connection_id,
+ ConnectionID primary_transport_connection_id,
+ uint8_t session_id,
+ BsonObject* reason = NULL);
+
/**
* @brief Notifies about receiving message from TM.
*
@@ -474,6 +539,19 @@ class ProtocolHandlerImpl
void OnConnectionClosed(
const transport_manager::ConnectionUID connection_id) OVERRIDE;
+ void OnUnexpectedDisconnect(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::CommunicationError& error) OVERRIDE;
+
+ /**
+ * @brief Notifies that configuration of a transport has been updated.
+ *
+ * @param configs pairs of key and value that represent configuration.
+ */
+ void OnTransportConfigUpdated(
+ const transport_manager::transport_adapter::TransportConfig& configs)
+ OVERRIDE;
+
/**
* @brief Notifies subscribers about message
* received from mobile device.
@@ -575,6 +653,9 @@ class ProtocolHandlerImpl
RESULT_CODE HandleControlMessageStartSession(const ProtocolFramePtr packet);
+ RESULT_CODE HandleControlMessageRegisterSecondaryTransport(
+ const ProtocolFramePtr packet);
+
RESULT_CODE HandleControlMessageHeartBeat(const ProtocolPacket& packet);
void PopValideAndExpirateMultiframes();
@@ -603,6 +684,32 @@ class ProtocolHandlerImpl
*/
uint8_t SupportedSDLProtocolVersion() const;
+ const impl::TransportDescription GetTransportTypeFromConnectionType(
+ const std::string& device_type) const;
+
+ const bool ParseSecondaryTransportConfiguration(
+ const ConnectionID connection_id,
+ std::vector<std::string>& secondaryTransports,
+ std::vector<int32_t>& audioServiceTransports,
+ std::vector<int32_t>& videoServiceTransports) const;
+
+ void GenerateSecondaryTransportsForStartSessionAck(
+ const std::vector<std::string>& secondary_transport_types,
+ bool device_is_ios,
+ bool device_is_android,
+ std::vector<std::string>& secondaryTransports) const;
+
+ void GenerateServiceTransportsForStartSessionAck(
+ bool secondary_enabled,
+ const std::vector<std::string>& service_transports,
+ const std::string& primary_connection_type,
+ const impl::TransportType primary_transport_type,
+ const std::vector<std::string>& secondary_transport_types,
+ std::vector<int32_t>& serviceTransports) const;
+
+ const std::string TransportTypeFromTransport(
+ const utils::custom_string::CustomString& transport) const;
+
const ProtocolHandlerSettings& settings_;
/**
@@ -689,6 +796,10 @@ class ProtocolHandlerImpl
sync_primitives::Lock start_session_frame_map_lock_;
StartSessionFrameMap start_session_frame_map_;
+ bool tcp_enabled_;
+ std::string tcp_port_;
+ std::string tcp_ip_address_;
+
#ifdef TELEMETRY_MONITOR
PHTelemetryObserver* metric_observer_;
#endif // TELEMETRY_MONITOR
diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_packet.h b/src/components/protocol_handler/include/protocol_handler/protocol_packet.h
index b6c05d4c46..ff084beff8 100644
--- a/src/components/protocol_handler/include/protocol_handler/protocol_packet.h
+++ b/src/components/protocol_handler/include/protocol_handler/protocol_packet.h
@@ -332,6 +332,11 @@ class ProtocolPacket {
ConnectionID connection_id() const;
/**
+ * \brief Setter of Connection Identifier
+ */
+ void set_connection_id(ConnectionID connection_id);
+
+ /**
* \brief Getter for data payload size
*/
uint32_t payload_size() const;
@@ -370,7 +375,7 @@ class ProtocolPacket {
* @brief Type definition for variable that hold shared pointer to protocolol
* packet
*/
-typedef utils::SharedPtr<protocol_handler::ProtocolPacket> ProtocolFramePtr;
+typedef std::shared_ptr<protocol_handler::ProtocolPacket> ProtocolFramePtr;
typedef std::list<ProtocolFramePtr> ProtocolFramePtrList;
template <typename _CharT>
diff --git a/src/components/protocol_handler/src/multiframe_builder.cc b/src/components/protocol_handler/src/multiframe_builder.cc
index 487d1f8d73..c34e2ec640 100644
--- a/src/components/protocol_handler/src/multiframe_builder.cc
+++ b/src/components/protocol_handler/src/multiframe_builder.cc
@@ -35,7 +35,7 @@
#include <limits>
#include "utils/logger.h"
-#include "utils/make_shared.h"
+
#include "utils/lock.h"
#include "utils/date_time.h"
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index ee94f2f39b..b4b66f47be 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -31,6 +31,7 @@
*/
#include "protocol_handler/protocol_handler_impl.h"
+#include <arpa/inet.h> // for INET6_ADDRSTRLEN
#include <memory.h>
#include <algorithm> // std::find
#include <bson_object.h>
@@ -60,7 +61,8 @@ std::string ConvertPacketDataToString(const uint8_t* data,
const size_t kStackSize = 65536;
-ProtocolPacket::ProtocolVersion defaultProtocolVersion(5, 0, 0);
+ProtocolPacket::ProtocolVersion defaultProtocolVersion(5, 1, 0);
+ProtocolPacket::ProtocolVersion minMultipleTransportsVersion(5, 1, 0);
ProtocolHandlerImpl::ProtocolHandlerImpl(
const ProtocolHandlerSettings& settings,
@@ -84,6 +86,7 @@ ProtocolHandlerImpl::ProtocolHandlerImpl(
"PH ToMobile", this, threads::ThreadOptions(kStackSize))
, start_session_frame_map_lock_()
, start_session_frame_map_()
+ , tcp_enabled_(false)
#ifdef TELEMETRY_MONITOR
, metric_observer_(NULL)
#endif // TELEMETRY_MONITOR
@@ -242,6 +245,8 @@ void ProtocolHandlerImpl::SendStartSessionAck(
BsonObject& params) {
LOG4CXX_AUTO_TRACE(logger_);
+ bool send_transport_update_event = false;
+
uint8_t ack_protocol_version = SupportedSDLProtocolVersion();
const bool proxy_supports_v5_protocol =
@@ -317,6 +322,91 @@ void ProtocolHandlerImpl::SendStartSessionAck(
"Protocol version parameter was written to bson params: "
<< protocol_ver_written << "; Value: "
<< bson_object_get_string(&params, strings::protocol_version));
+
+ LOG4CXX_INFO(logger_,
+ "Protocol Version String " << protocolVersionString);
+
+ std::vector<std::string> secondaryTransports;
+ std::vector<int32_t> audioServiceTransports;
+ std::vector<int32_t> videoServiceTransports;
+ if (*minVersion >= minMultipleTransportsVersion) {
+ if (ParseSecondaryTransportConfiguration(connection_id,
+ secondaryTransports,
+ audioServiceTransports,
+ videoServiceTransports)) {
+ LOG4CXX_DEBUG(logger_, "Multiple transports are enabled.");
+ BsonArray secondaryTransportsArr;
+ bson_array_initialize(&secondaryTransportsArr,
+ secondaryTransports.size());
+ for (unsigned int i = 0; i < secondaryTransports.size(); i++) {
+ char secondaryTransport[255];
+ strncpy(secondaryTransport,
+ secondaryTransports[i].c_str(),
+ sizeof(secondaryTransport));
+ secondaryTransport[sizeof(secondaryTransport) - 1] = '\0';
+ LOG4CXX_DEBUG(
+ logger_,
+ "Adding "
+ << secondaryTransport
+ << " to secondaryTransports parameter of StartSessionAck");
+ bson_array_add_string(&secondaryTransportsArr, secondaryTransport);
+ }
+ bson_object_put_array(
+ &params, strings::secondary_transports, &secondaryTransportsArr);
+
+ BsonArray audioServiceTransportsArr;
+ bson_array_initialize(&audioServiceTransportsArr,
+ audioServiceTransports.size());
+ for (unsigned int i = 0; i < audioServiceTransports.size(); i++) {
+ LOG4CXX_DEBUG(logger_,
+ "Adding " << audioServiceTransports[i]
+ << " to audioServiceTransports parameter "
+ "of StartSessionAck");
+ bson_array_add_int32(&audioServiceTransportsArr,
+ audioServiceTransports[i]);
+ }
+ bson_object_put_array(&params,
+ strings::audio_service_transports,
+ &audioServiceTransportsArr);
+
+ BsonArray videoServiceTransportsArr;
+ bson_array_initialize(&videoServiceTransportsArr,
+ videoServiceTransports.size());
+ for (unsigned int i = 0; i < videoServiceTransports.size(); i++) {
+ LOG4CXX_DEBUG(logger_,
+ "Adding " << videoServiceTransports[i]
+ << " to videoServiceTransports parameter "
+ "of StartSessionAck");
+ bson_array_add_int32(&videoServiceTransportsArr,
+ videoServiceTransports[i]);
+ }
+ bson_object_put_array(&params,
+ strings::video_service_transports,
+ &videoServiceTransportsArr);
+
+ if (settings_.multiple_transports_enabled()) {
+ send_transport_update_event = true;
+ } else {
+ LOG4CXX_DEBUG(
+ logger_,
+ "Multiple transports feature is disabled by configuration");
+ // In this case, we must remember that this session will never have
+ // a secondary transport.
+ connection_handler_.SetSecondaryTransportID(session_id,
+ kDisabledSecondary);
+ }
+ } else {
+ LOG4CXX_WARN(
+ logger_,
+ "Failed to set up secondary transport and service type params");
+ connection_handler_.SetSecondaryTransportID(session_id,
+ kDisabledSecondary);
+ }
+ } else {
+ LOG4CXX_INFO(logger_, "Older protocol version. No multiple transports");
+ connection_handler_.SetSecondaryTransportID(session_id,
+ kDisabledSecondary);
+ }
}
uint8_t* payloadBytes = bson_object_to_bytes(&params);
ptr->set_data(payloadBytes, bson_object_size(&params));
@@ -334,6 +424,16 @@ void ProtocolHandlerImpl::SendStartSessionAck(
<< static_cast<int32_t>(service_type) << " session_id "
<< static_cast<int32_t>(session_id) << " protection "
<< (protection ? "ON" : "OFF"));
+
+ if (send_transport_update_event) {
+ // Wait until the StartService ACK has been processed for sending.
+ // The TransportUpdateEvent has a higher priority, being that it's
+ // a SERVICE_TYPE_CONTROL message. (The ACK is SERVICE_TYPE_RPC.)
+ LOG4CXX_DEBUG(logger_, "Waiting for the MessageToMobile queue to be empty");
+ raw_ford_messages_to_mobile_.WaitDumpQueue();
+ LOG4CXX_DEBUG(logger_, "Sending the TransportUpdate event");
+ SendTransportUpdateEvent(connection_id, session_id);
+ }
}
void ProtocolHandlerImpl::SendStartSessionNAck(ConnectionID connection_id,
@@ -491,14 +591,18 @@ void ProtocolHandlerImpl::SendEndSessionAck(ConnectionID connection_id,
<< static_cast<int32_t>(session_id));
}
-void ProtocolHandlerImpl::SendEndServicePrivate(int32_t connection_id,
+void ProtocolHandlerImpl::SendEndServicePrivate(int32_t primary_connection_id,
+ int32_t connection_id,
uint8_t session_id,
uint8_t service_type) {
LOG4CXX_AUTO_TRACE(logger_);
uint8_t protocol_version;
if (session_observer_.ProtocolVersionUsed(
- connection_id, session_id, protocol_version)) {
+ primary_connection_id, session_id, protocol_version)) {
+ LOG4CXX_TRACE(logger_,
+ "SendEndServicePrivate using protocol version "
+ << static_cast<int32_t>(protocol_version));
ProtocolFramePtr ptr(
new protocol_handler::ProtocolPacket(connection_id,
protocol_version,
@@ -513,25 +617,31 @@ void ProtocolHandlerImpl::SendEndServicePrivate(int32_t connection_id,
raw_ford_messages_to_mobile_.PostMessage(
impl::RawFordMessageToMobile(ptr, false));
LOG4CXX_DEBUG(logger_,
- "SendEndSession() for connection "
- << connection_id << " for service_type " << service_type
+ "SendEndServicePrivate() for connection "
+ << primary_connection_id << " for service_type "
+ << static_cast<int>(service_type)
+ << " service connection " << connection_id
<< " session_id " << static_cast<int32_t>(session_id));
} else {
LOG4CXX_WARN(
logger_,
- "SendEndSession is failed connection or session does not exist");
+ "SendEndServicePrivate is failed connection or session does not exist");
}
}
void ProtocolHandlerImpl::SendEndSession(int32_t connection_id,
uint8_t session_id) {
- SendEndServicePrivate(connection_id, session_id, SERVICE_TYPE_RPC);
+ // A session is always associated with a primary connection ID
+ SendEndServicePrivate(
+ connection_id, connection_id, session_id, SERVICE_TYPE_RPC);
}
-void ProtocolHandlerImpl::SendEndService(int32_t connection_id,
+void ProtocolHandlerImpl::SendEndService(int32_t primary_connection_id,
+ int32_t connection_id,
uint8_t session_id,
uint8_t service_type) {
- SendEndServicePrivate(connection_id, session_id, service_type);
+ SendEndServicePrivate(
+ primary_connection_id, connection_id, session_id, service_type);
}
RESULT_CODE ProtocolHandlerImpl::SendHeartBeatAck(ConnectionID connection_id,
@@ -563,6 +673,139 @@ RESULT_CODE ProtocolHandlerImpl::SendHeartBeatAck(ConnectionID connection_id,
return RESULT_FAIL;
}
+void ProtocolHandlerImpl::SendTransportUpdateEvent(ConnectionID connection_id,
+ uint8_t session_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ uint8_t protocol_version;
+ if (session_observer_.ProtocolVersionUsed(
+ connection_id, session_id, protocol_version)) {
+ ProtocolFramePtr ptr(
+ new protocol_handler::ProtocolPacket(connection_id,
+ protocol_version,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ SERVICE_TYPE_CONTROL,
+ FRAME_DATA_TRANSPORT_EVENT_UPDATE,
+ session_id,
+ 0,
+ message_counters_[session_id]++));
+
+ BsonObject payload_obj;
+ bson_object_initialize_default(&payload_obj);
+
+ int32_t tcp_port = atoi(tcp_port_.c_str());
+ char tcp_ip_address[INET6_ADDRSTRLEN + 1];
+ if (tcp_enabled_ && (tcp_port != 0)) {
+ strncpy(tcp_ip_address, tcp_ip_address_.c_str(), INET6_ADDRSTRLEN);
+ tcp_ip_address[INET6_ADDRSTRLEN] = '\0';
+ bson_object_put_string(
+ &payload_obj, strings::tcp_ip_address, tcp_ip_address);
+ bson_object_put_int32(&payload_obj, strings::tcp_port, tcp_port);
+ } else {
+ tcp_ip_address[0] = '\0';
+ bson_object_put_string(
+ &payload_obj, strings::tcp_ip_address, tcp_ip_address);
+ // omit TCP port number
+ }
+ LOG4CXX_INFO(logger_,
+ "SendTransportUpdateEvent IP address: "
+ << tcp_ip_address << " Port: " << tcp_port);
+
+ uint8_t* payloadBytes = bson_object_to_bytes(&payload_obj);
+ ptr->set_data(payloadBytes, bson_object_size(&payload_obj));
+ free(payloadBytes);
+ bson_object_deinitialize(&payload_obj);
+
+ raw_ford_messages_to_mobile_.PostMessage(
+ impl::RawFordMessageToMobile(ptr, false));
+
+ LOG4CXX_DEBUG(logger_,
+ "SendTransportUpdateEvent() for connection "
+ << connection_id << " for session "
+ << static_cast<int32_t>(session_id));
+ } else {
+ LOG4CXX_WARN(logger_,
+ "SendTransportUpdateEvent is failed connection or session "
+ "does not exist");
+ }
+}
+
+RESULT_CODE ProtocolHandlerImpl::SendRegisterSecondaryTransportAck(
+ ConnectionID connection_id,
+ ConnectionID primary_transport_connection_id,
+ uint8_t session_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // acquire the protocol version from primary transport
+ uint8_t protocol_version;
+ if (session_observer_.ProtocolVersionUsed(
+ primary_transport_connection_id, session_id, protocol_version)) {
+ ProtocolFramePtr ptr(new protocol_handler::ProtocolPacket(
+ connection_id,
+ protocol_version,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ SERVICE_TYPE_CONTROL,
+ FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_ACK,
+ session_id,
+ 0u,
+ 2));
+
+ raw_ford_messages_to_mobile_.PostMessage(
+ impl::RawFordMessageToMobile(ptr, false));
+ return RESULT_OK;
+ }
+ LOG4CXX_WARN(logger_,
+ "RegisterSecondaryTransportAck is failed connection or session "
+ "does not exist");
+ return RESULT_FAIL;
+}
+
+RESULT_CODE ProtocolHandlerImpl::SendRegisterSecondaryTransportNAck(
+ ConnectionID connection_id,
+ ConnectionID primary_transport_connection_id,
+ uint8_t session_id,
+ BsonObject* reason) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // If mobile sends an invalid session ID and we cannot find out the Connection
+ // ID of primary transport, then we use version 5. (The multiple-transports
+ // feature is added in 5.1.0.)
+ uint8_t protocol_version = PROTOCOL_VERSION_5;
+ if (primary_transport_connection_id > 0) {
+ // acquire the protocol version from primary transport
+ if (!session_observer_.ProtocolVersionUsed(
+ primary_transport_connection_id, session_id, protocol_version)) {
+ LOG4CXX_WARN(logger_,
+ "Failed to acquire protocol version for "
+ "RegisterSecondaryTransportNAck");
+ return RESULT_FAIL;
+ }
+ }
+
+ ProtocolFramePtr ptr(new protocol_handler::ProtocolPacket(
+ connection_id,
+ protocol_version,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ SERVICE_TYPE_CONTROL,
+ FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK,
+ session_id,
+ 0u,
+ 2));
+
+ if (reason) {
+ uint8_t* payloadBytes = bson_object_to_bytes(reason);
+ ptr->set_data(payloadBytes, bson_object_size(reason));
+ free(payloadBytes);
+ }
+
+ raw_ford_messages_to_mobile_.PostMessage(
+ impl::RawFordMessageToMobile(ptr, false));
+ return RESULT_OK;
+}
+
void ProtocolHandlerImpl::SendHeartBeat(int32_t connection_id,
uint8_t session_id) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -682,8 +925,7 @@ void ProtocolHandlerImpl::SendMessageToMobileApp(const RawMessagePtr message,
}
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
- PHTelemetryObserver::MessageMetric* metric =
- new PHTelemetryObserver::MessageMetric();
+ auto metric = std::make_shared<PHTelemetryObserver::MessageMetric>();
metric->message_id = message_id;
metric->connection_key = message->connection_key();
metric->raw_msg = message;
@@ -857,6 +1099,12 @@ void ProtocolHandlerImpl::OnConnectionClosed(
multiframe_builder_.RemoveConnection(connection_id);
}
+void ProtocolHandlerImpl::OnUnexpectedDisconnect(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::CommunicationError& error) {
+ OnConnectionClosed(connection_id);
+}
+
void ProtocolHandlerImpl::NotifyOnFailedHandshake() {
LOG4CXX_AUTO_TRACE(logger_);
#ifdef ENABLE_SECURITY
@@ -864,6 +1112,72 @@ void ProtocolHandlerImpl::NotifyOnFailedHandshake() {
#endif // ENABLE_SECURITY
}
+void ProtocolHandlerImpl::OnTransportConfigUpdated(
+ const transport_manager::transport_adapter::TransportConfig& configs) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ transport_manager::transport_adapter::TransportConfig::const_iterator it =
+ configs.find(transport_manager::transport_adapter::tc_enabled);
+ if (configs.end() == it) {
+ LOG4CXX_WARN(logger_, "No enabled field in OnTransportConfigUpdated");
+ return;
+ }
+
+ bool tcp_enabled = (0 == strcmp("true", it->second.c_str()));
+ std::string tcp_port;
+
+ if (tcp_enabled) {
+ it = configs.find(transport_manager::transport_adapter::tc_tcp_port);
+ if (configs.end() == it) {
+ LOG4CXX_WARN(logger_, "No port field in OnTransportConfigUpdated");
+ return;
+ }
+ tcp_port = it->second;
+
+ it = configs.find(transport_manager::transport_adapter::tc_tcp_ip_address);
+ if (configs.end() == it) {
+ LOG4CXX_WARN(logger_, "No IP address field in OnTransportConfigUpdated");
+ return;
+ }
+ tcp_enabled_ = true;
+ tcp_port_ = tcp_port;
+ tcp_ip_address_ = it->second;
+ } else {
+ tcp_enabled_ = false;
+ tcp_port_.clear();
+ tcp_ip_address_.clear();
+ }
+
+ LOG4CXX_INFO(logger_,
+ "OnTransportConfigUpdated: new config enabled is "
+ << tcp_enabled_ << ". Port is " << tcp_port_
+ << ". IP Address is " << tcp_ip_address_);
+
+ // Walk the SessionConnection map and find all sessions that need a
+ // TransportUpdate Event. Sessions flagged with kDisabledSecondary in their
+ // secondary transport are ineligible for secondary transport, and
+ // therefore don't get this event.
+ DataAccessor<connection_handler::SessionConnectionMap>
+ session_connection_map_accessor =
+ connection_handler_.session_connection_map();
+ const connection_handler::SessionConnectionMap& session_connection_map =
+ session_connection_map_accessor.GetData();
+ connection_handler::SessionConnectionMap::const_iterator itr =
+ session_connection_map.begin();
+ while (itr != session_connection_map.end()) {
+ const connection_handler::SessionTransports st = itr->second;
+ LOG4CXX_INFO(logger_,
+ "OnTransportConfigUpdated found session "
+ << itr->first << " with primary connection "
+ << st.primary_transport << " and secondary connection "
+ << st.secondary_transport);
+ if (st.secondary_transport != kDisabledSecondary) {
+ SendTransportUpdateEvent(st.primary_transport, itr->first);
+ }
+ itr++;
+ }
+}
+
RESULT_CODE ProtocolHandlerImpl::SendFrame(const ProtocolFramePtr packet) {
LOG4CXX_AUTO_TRACE(logger_);
if (!packet) {
@@ -1048,6 +1362,13 @@ RESULT_CODE ProtocolHandlerImpl::HandleSingleFrameMessage(
<< packet->data_size() << "; message "
<< ConvertPacketDataToString(packet->data(), packet->data_size()));
+ // Replace a potential secondary transport ID in the packet with the primary
+ // transport ID
+ const connection_handler::SessionTransports st =
+ connection_handler_.GetSessionTransports(packet->session_id());
+ if (st.primary_transport != 0) {
+ packet->set_connection_id(st.primary_transport);
+ }
const uint32_t connection_key = session_observer_.KeyFromPair(
packet->connection_id(), packet->session_id());
@@ -1062,8 +1383,7 @@ RESULT_CODE ProtocolHandlerImpl::HandleSingleFrameMessage(
}
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
- PHTelemetryObserver::MessageMetric* metric =
- new PHTelemetryObserver::MessageMetric();
+ auto metric = std::make_shared<PHTelemetryObserver::MessageMetric>();
metric->message_id = packet->message_id();
metric->connection_key = connection_key;
metric->raw_msg = rawMessage;
@@ -1080,6 +1400,14 @@ RESULT_CODE ProtocolHandlerImpl::HandleMultiFrameMessage(
const ProtocolFramePtr packet) {
LOG4CXX_AUTO_TRACE(logger_);
+ // Replace a potential secondary transport ID in the packet with the primary
+ // transport ID
+ const connection_handler::SessionTransports st =
+ connection_handler_.GetSessionTransports(packet->session_id());
+ if (st.primary_transport != 0) {
+ packet->set_connection_id(st.primary_transport);
+ }
+
if (multiframe_builder_.AddFrame(packet) != RESULT_OK) {
LOG4CXX_WARN(logger_, "Frame assembling issue");
}
@@ -1117,6 +1445,10 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessage(
<< packet->connection_id());
return RESULT_OK;
}
+ case FRAME_DATA_REGISTER_SECONDARY_TRANSPORT: {
+ LOG4CXX_TRACE(logger_, "FrameData: RegisterSecondaryTransport");
+ return HandleControlMessageRegisterSecondaryTransport(packet);
+ }
default:
LOG4CXX_WARN(logger_,
"Control message of type "
@@ -1401,6 +1733,11 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession(
const ConnectionID connection_id = packet->connection_id();
const uint8_t session_id = packet->session_id();
+ LOG4CXX_INFO(logger_,
+ "StartSession ID " << static_cast<int>(session_id)
+ << " and Connection ID "
+ << static_cast<int>(connection_id));
+
{
sync_primitives::AutoLock auto_lock(start_session_frame_map_lock_);
start_session_frame_map_[std::make_pair(connection_id, session_id)] =
@@ -1414,6 +1751,50 @@ RESULT_CODE ProtocolHandlerImpl::HandleControlMessageStartSession(
return RESULT_OK;
}
+RESULT_CODE ProtocolHandlerImpl::HandleControlMessageRegisterSecondaryTransport(
+ const ProtocolFramePtr packet) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const uint8_t session_id = packet->session_id();
+ const ConnectionID connection_id = packet->connection_id();
+ ConnectionID primary_connection_id = 0;
+
+ LOG4CXX_INFO(logger_,
+ "RegisterSecondaryTransport ID "
+ << static_cast<int>(session_id) << " and Connection ID "
+ << static_cast<int>(connection_id));
+
+ if (connection_handler_.OnSecondaryTransportStarted(
+ primary_connection_id, connection_id, session_id)) {
+ SendRegisterSecondaryTransportAck(
+ connection_id, primary_connection_id, session_id);
+ } else {
+ char reason[256];
+ BsonObject registerSecondaryTransportNackObj;
+ bson_object_initialize_default(&registerSecondaryTransportNackObj);
+ if (0 == session_id) {
+ strncpy(reason,
+ "RegisterSecondaryTransport MUST include a non-zero session ID",
+ 255);
+ } else if (primary_connection_id == 0) {
+ strncpy(reason, "RegisterSecondaryTransport session ID not found", 255);
+ } else {
+ strncpy(
+ reason,
+ "RegisterSecondaryTransport session ID has already been registered",
+ 255);
+ }
+ bson_object_put_string(
+ &registerSecondaryTransportNackObj, strings::reason, reason);
+ SendRegisterSecondaryTransportNAck(connection_id,
+ primary_connection_id,
+ session_id,
+ &registerSecondaryTransportNackObj);
+ bson_object_deinitialize(&registerSecondaryTransportNackObj);
+ }
+
+ return RESULT_OK;
+}
+
void ProtocolHandlerImpl::NotifySessionStartedResult(
int32_t connection_id,
uint8_t session_id,
@@ -1423,6 +1804,7 @@ void ProtocolHandlerImpl::NotifySessionStartedResult(
std::vector<std::string>& rejected_params) {
LOG4CXX_AUTO_TRACE(logger_);
protocol_handler::SessionContext context(connection_id,
+ connection_id,
session_id,
generated_session_id,
ServiceType::kInvalidServiceType,
@@ -1670,8 +2052,7 @@ void ProtocolHandlerImpl::PopValideAndExpirateMultiframes() {
#ifdef TELEMETRY_MONITOR
if (metric_observer_) {
- PHTelemetryObserver::MessageMetric* metric =
- new PHTelemetryObserver::MessageMetric();
+ auto metric = std::make_shared<PHTelemetryObserver::MessageMetric>();
metric->raw_msg = rawMessage;
metric_observer_->EndMessageProcess(metric);
}
@@ -1989,4 +2370,241 @@ uint8_t ProtocolHandlerImpl::SupportedSDLProtocolVersion() const {
LOG4CXX_AUTO_TRACE(logger_);
return get_settings().max_supported_protocol_version();
}
+
+const impl::TransportTypes transportTypes = {
+ std::make_pair(
+ std::string("AOA_USB"),
+ impl::TransportDescription(impl::TransportType::TT_USB, false, true)),
+ std::make_pair(std::string("SPP_BLUETOOTH"),
+ impl::TransportDescription(
+ impl::TransportType::TT_BLUETOOTH, false, true)),
+ std::make_pair(std::string("IAP_BLUETOOTH"),
+ impl::TransportDescription(
+ impl::TransportType::TT_BLUETOOTH, true, false)),
+ std::make_pair(
+ std::string("IAP_USB"),
+ impl::TransportDescription(impl::TransportType::TT_USB, true, false)),
+ std::make_pair(
+ std::string("TCP_WIFI"),
+ impl::TransportDescription(impl::TransportType::TT_WIFI, true, true)),
+ std::make_pair(
+ std::string("IAP_USB_HOST_MODE"),
+ impl::TransportDescription(impl::TransportType::TT_USB, true, false)),
+ std::make_pair(
+ std::string("IAP_USB_DEVICE_MODE"),
+ impl::TransportDescription(impl::TransportType::TT_USB, true, false)),
+ std::make_pair(
+ std::string("IAP_CARPLAY"),
+ impl::TransportDescription(impl::TransportType::TT_WIFI, true, false))};
+
+const impl::TransportDescription
+ProtocolHandlerImpl::GetTransportTypeFromConnectionType(
+ const std::string& connection_type) const {
+ impl::TransportDescription result =
+ impl::TransportDescription(impl::TransportType::TT_NONE, false, false);
+ impl::TransportTypes::const_iterator it =
+ transportTypes.find(connection_type);
+ if (it != transportTypes.end()) {
+ result = it->second;
+ } else {
+ LOG4CXX_ERROR(logger_, "Unknown connection type " << connection_type);
+ }
+
+ return result;
+}
+
+const bool ProtocolHandlerImpl::ParseSecondaryTransportConfiguration(
+ const ConnectionID connection_id,
+ std::vector<std::string>& secondaryTransports,
+ std::vector<int32_t>& audioServiceTransports,
+ std::vector<int32_t>& videoServiceTransports) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ std::vector<std::string> secondary_transport_types;
+
+ // First discover what the connection type of the primary transport is
+ // and look up the allowed secondary transports for that primary transport
+ const std::string connection_type =
+ session_observer_.TransportTypeProfileStringFromConnHandle(connection_id);
+ const impl::TransportDescription td =
+ GetTransportTypeFromConnectionType(connection_type);
+ if (settings_.multiple_transports_enabled()) {
+ if (td.transport_type_ == impl::TransportType::TT_USB) {
+ secondary_transport_types = settings_.secondary_transports_for_usb();
+ } else if (td.transport_type_ == impl::TransportType::TT_BLUETOOTH) {
+ secondary_transport_types =
+ settings_.secondary_transports_for_bluetooth();
+ } else if (td.transport_type_ == impl::TransportType::TT_WIFI) {
+ secondary_transport_types = settings_.secondary_transports_for_wifi();
+ } else {
+ LOG4CXX_ERROR(
+ logger_,
+ "Bad or unknown device type in ParseSecondaryTransportConfiguration");
+ return false;
+ }
+ }
+ // note: even if settings_.multiple_transports_enabled() is false, we still
+ // send out an empty "secondaryTransports" parameter, along with
+ // "videoServiceTransports" and "audioServiceTransports" params which are
+ // useful without secondary transport.
+
+ // Then, generate the "secondaryTransports" array for the StartSession ACK
+ GenerateSecondaryTransportsForStartSessionAck(secondary_transport_types,
+ td.ios_transport_,
+ td.android_transport_,
+ secondaryTransports);
+
+ // Next, figure out which connections audio or video services are allowed on
+ GenerateServiceTransportsForStartSessionAck(
+ settings_.multiple_transports_enabled(),
+ settings_.audio_service_transports(),
+ connection_type,
+ td.transport_type_,
+ secondary_transport_types,
+ audioServiceTransports);
+
+ GenerateServiceTransportsForStartSessionAck(
+ settings_.multiple_transports_enabled(),
+ settings_.video_service_transports(),
+ connection_type,
+ td.transport_type_,
+ secondary_transport_types,
+ videoServiceTransports);
+
+ return true;
+}
+
+void ProtocolHandlerImpl::GenerateSecondaryTransportsForStartSessionAck(
+ const std::vector<std::string>& secondary_transport_types,
+ bool device_is_ios,
+ bool device_is_android,
+ std::vector<std::string>& secondaryTransports) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // Parse the "secondary_transport_types" vector (which comes from
+ // smartDeviceLink.ini). For each entry in the vector, add an
+ // appropriate string to the secondaryTransports
+ std::vector<std::string>::const_iterator it =
+ secondary_transport_types.begin();
+ while (it != secondary_transport_types.end()) {
+ const utils::custom_string::CustomString transport_type(*it);
+ if (transport_type.CompareIgnoreCase("USB")) {
+ if (device_is_ios) {
+ LOG4CXX_TRACE(
+ logger_,
+ "Adding IAP_USB to secondaryTransports for StartSessionAck");
+ secondaryTransports.push_back("IAP_USB");
+ }
+ if (device_is_android) {
+ LOG4CXX_TRACE(
+ logger_,
+ "Adding AOA_USB to secondaryTransports for StartSessionAck");
+ secondaryTransports.push_back("AOA_USB");
+ }
+ } else if (transport_type.CompareIgnoreCase("Bluetooth")) {
+ if (device_is_ios) {
+ LOG4CXX_TRACE(
+ logger_,
+ "Adding IAP_BLUETOOTH to secondaryTransports for StartSessionAck");
+ secondaryTransports.push_back("IAP_BLUETOOTH");
+ }
+ if (device_is_android) {
+ LOG4CXX_TRACE(
+ logger_,
+ "Adding SPP_BLUETOOTH to secondaryTransports for StartSessionAck");
+ secondaryTransports.push_back("SPP_BLUETOOTH");
+ }
+ }
+ if (transport_type.CompareIgnoreCase("WiFi")) {
+ LOG4CXX_TRACE(
+ logger_,
+ "Adding TCP_WIFI to secondaryTransports for StartSessionAck");
+ secondaryTransports.push_back("TCP_WIFI");
+ }
+
+ it++;
+ }
+}
+
+void ProtocolHandlerImpl::GenerateServiceTransportsForStartSessionAck(
+ bool secondary_enabled,
+ const std::vector<std::string>& service_transports,
+ const std::string& primary_connection_type,
+ const impl::TransportType primary_transport_type,
+ const std::vector<std::string>& secondary_transport_types,
+ std::vector<int32_t>& serviceTransports) const {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (service_transports.size() == 0) {
+ if (secondary_enabled && !secondary_transport_types.empty()) {
+ LOG4CXX_TRACE(logger_,
+ "Empty Service Transports. Allowing service to run on both "
+ "connections");
+ serviceTransports.push_back(1);
+ serviceTransports.push_back(2);
+ } else {
+ serviceTransports.push_back(1);
+ }
+ } else {
+ bool fPrimaryAdded = false;
+ bool fSecondaryAdded = false;
+ std::vector<std::string>::const_iterator it = service_transports.begin();
+ for (; it != service_transports.end(); it++) {
+ const utils::custom_string::CustomString transport(*it);
+ LOG4CXX_TRACE(logger_,
+ "Service Allowed to run on " << transport.c_str()
+ << " transport");
+
+ if (!fPrimaryAdded &&
+ (transport.CompareIgnoreCase(primary_connection_type.c_str()) ||
+ (transport.CompareIgnoreCase("IAP_USB") &&
+ primary_transport_type == impl::TransportType::TT_USB))) {
+ LOG4CXX_TRACE(logger_, "Service allowed on primary transport");
+ serviceTransports.push_back(1);
+ fPrimaryAdded = true;
+ }
+
+ if (!fSecondaryAdded) {
+ const utils::custom_string::CustomString transport_type(
+ TransportTypeFromTransport(transport));
+ std::vector<std::string>::const_iterator found =
+ std::find_if(secondary_transport_types.begin(),
+ secondary_transport_types.end(),
+ [&](const std::string& secondary_transport_type) {
+ return transport_type.CompareIgnoreCase(
+ secondary_transport_type.c_str());
+ });
+ if (found != secondary_transport_types.end()) {
+ LOG4CXX_TRACE(logger_, "Service allowed on secondary transport");
+ serviceTransports.push_back(2);
+ fSecondaryAdded = true;
+ }
+ }
+
+ if (fPrimaryAdded && fSecondaryAdded) {
+ break;
+ }
+ }
+ }
+}
+
+const std::string ProtocolHandlerImpl::TransportTypeFromTransport(
+ const utils::custom_string::CustomString& transport) const {
+ std::string transport_type;
+
+ if (transport.CompareIgnoreCase("IAP_BLUETOOTH") ||
+ transport.CompareIgnoreCase("SPP_BLUETOOTH")) {
+ transport_type = "Bluetooth";
+ } else if (transport.CompareIgnoreCase("IAP_USB") ||
+ transport.CompareIgnoreCase("AOA_USB") ||
+ transport.CompareIgnoreCase("IAP_USB_HOST_MODE") ||
+ transport.CompareIgnoreCase("IAP_USB_DEVICE_MODE")) {
+ transport_type = "USB";
+ } else if (transport.CompareIgnoreCase("TCP_WIFI") ||
+ transport.CompareIgnoreCase("IAP_CARPLAY")) {
+ transport_type = "WiFi";
+ }
+
+ return transport_type;
+}
+
} // namespace protocol_handler
diff --git a/src/components/protocol_handler/src/protocol_packet.cc b/src/components/protocol_handler/src/protocol_packet.cc
index a490916c99..3cd9e7f781 100644
--- a/src/components/protocol_handler/src/protocol_packet.cc
+++ b/src/components/protocol_handler/src/protocol_packet.cc
@@ -304,8 +304,8 @@ RESULT_CODE ProtocolPacket::ProtocolHeaderValidator::validate(
// Check frame info for each frame type
// Frame type shall be 0x00 (Control), 0x01 (Single), 0x02 (First), 0x03
// (Consecutive)
- // For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data
- // Ack), 0xFF(HB Ack)
+ // For Control frames Frame info value shall be from 0x00 to 0x09 or
+ // 0xFD(Transport Event Update), 0xFE(Data Ack), 0xFF(HB Ack)
// For Single and First frames Frame info value shall be equal 0x00
switch (header.frameType) {
case FRAME_TYPE_CONTROL: {
@@ -317,6 +317,10 @@ RESULT_CODE ProtocolPacket::ProtocolHeaderValidator::validate(
case FRAME_DATA_END_SERVICE:
case FRAME_DATA_END_SERVICE_ACK:
case FRAME_DATA_END_SERVICE_NACK:
+ case FRAME_DATA_REGISTER_SECONDARY_TRANSPORT:
+ case FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_ACK:
+ case FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK:
+ case FRAME_DATA_TRANSPORT_EVENT_UPDATE:
case FRAME_DATA_SERVICE_DATA_ACK:
case FRAME_DATA_HEART_BEAT_ACK:
break;
@@ -642,6 +646,10 @@ ConnectionID ProtocolPacket::connection_id() const {
return connection_id_;
}
+void ProtocolPacket::set_connection_id(ConnectionID connection_id) {
+ connection_id_ = connection_id;
+}
+
uint32_t ProtocolPacket::payload_size() const {
return payload_size_;
}
diff --git a/src/components/protocol_handler/test/include/protocol_handler/mock_telemetry_observer.h b/src/components/protocol_handler/test/include/protocol_handler/mock_telemetry_observer.h
index 3296d716fa..9a91a5d1f7 100644
--- a/src/components/protocol_handler/test/include/protocol_handler/mock_telemetry_observer.h
+++ b/src/components/protocol_handler/test/include/protocol_handler/mock_telemetry_observer.h
@@ -45,7 +45,7 @@ class MockPHTelemetryObserver : public ::protocol_handler::PHTelemetryObserver {
public:
MOCK_METHOD2(StartMessageProcess,
void(uint32_t, const date_time::TimeDuration&));
- MOCK_METHOD2(EndMessageProcess, void(utils::SharedPtr<MessageMetric>));
+ MOCK_METHOD2(EndMessageProcess, void(std::shared_ptr<MessageMetric>));
};
} // namespace protocol_handler_test
diff --git a/src/components/protocol_handler/test/incoming_data_handler_test.cc b/src/components/protocol_handler/test/incoming_data_handler_test.cc
index d0a311583c..9abf5d69af 100644
--- a/src/components/protocol_handler/test/incoming_data_handler_test.cc
+++ b/src/components/protocol_handler/test/incoming_data_handler_test.cc
@@ -74,7 +74,7 @@ class IncomingDataHandlerTest : public ::testing::Test {
void AppendPacketToTMData(const ProtocolPacket& packet) {
const RawMessagePtr msg = packet.serializePacket();
- EXPECT_TRUE(msg.valid());
+ EXPECT_TRUE(msg.use_count() != 0);
EXPECT_GT(msg->data_size(), 0u);
tm_data.insert(tm_data.end(), msg->data(), msg->data() + msg->data_size());
}
@@ -192,49 +192,51 @@ TEST_F(IncomingDataHandlerTest, Heartbeat_pack) {
TEST_F(IncomingDataHandlerTest, MixedPayloadData_TwoConnections) {
FrameList mobile_packets;
// single packet RPC
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_1,
- PROTECTION_OFF,
- FRAME_TYPE_SINGLE,
- kRpc,
- FRAME_DATA_SINGLE,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_1,
+ PROTECTION_OFF,
+ FRAME_TYPE_SINGLE,
+ kRpc,
+ FRAME_DATA_SINGLE,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
// consecutive packet Audio
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_2,
- PROTECTION_ON,
- FRAME_TYPE_CONSECUTIVE,
- kAudio,
- FRAME_DATA_LAST_CONSECUTIVE,
- ++some_session_id,
- some_data2_size,
- some_message_id,
- some_data2));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_2,
+ PROTECTION_ON,
+ FRAME_TYPE_CONSECUTIVE,
+ kAudio,
+ FRAME_DATA_LAST_CONSECUTIVE,
+ ++some_session_id,
+ some_data2_size,
+ some_message_id,
+ some_data2));
// single packet Nav
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_ON,
- FRAME_TYPE_SINGLE,
- kMobileNav,
- FRAME_DATA_SINGLE,
- ++some_session_id,
- some_data_size,
- ++some_message_id,
- some_data));
+ mobile_packets.push_back(std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_ON,
+ FRAME_TYPE_SINGLE,
+ kMobileNav,
+ FRAME_DATA_SINGLE,
+ ++some_session_id,
+ some_data_size,
+ ++some_message_id,
+ some_data));
// consecutive packet Bulk
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_ON,
- FRAME_TYPE_CONSECUTIVE,
- kBulk,
- FRAME_DATA_LAST_CONSECUTIVE,
- ++some_session_id,
- some_data2_size,
- ++some_message_id,
- some_data2));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_ON,
+ FRAME_TYPE_CONSECUTIVE,
+ kBulk,
+ FRAME_DATA_LAST_CONSECUTIVE,
+ ++some_session_id,
+ some_data2_size,
+ ++some_message_id,
+ some_data2));
for (FrameList::iterator it = mobile_packets.begin();
it != mobile_packets.end();
++it) {
@@ -268,16 +270,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_Version) {
malformed_versions.push_back(version);
}
for (size_t i = 0; i < malformed_versions.size(); ++i) {
- malformed_packets.push_back(new ProtocolPacket(uid1,
- malformed_versions[i],
- PROTECTION_OFF,
- FRAME_TYPE_CONTROL,
- kControl,
- FRAME_DATA_HEART_BEAT,
- some_session_id,
- 0u,
- some_message_id,
- NULL));
+ malformed_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ malformed_versions[i],
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ kControl,
+ FRAME_DATA_HEART_BEAT,
+ some_session_id,
+ 0u,
+ some_message_id,
+ nullptr));
}
// We count malformed only first time when it occurs after correct message
@@ -316,16 +319,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_ServiceType) {
malformed_serv_types.push_back(0x0D);
malformed_serv_types.push_back(0x0E);
for (size_t i = 0; i < malformed_serv_types.size(); ++i) {
- malformed_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_OFF,
- FRAME_TYPE_CONTROL,
- malformed_serv_types[i],
- FRAME_DATA_HEART_BEAT,
- some_session_id,
- 0u,
- some_message_id,
- NULL));
+ malformed_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ malformed_serv_types[i],
+ FRAME_DATA_HEART_BEAT,
+ some_session_id,
+ 0u,
+ some_message_id,
+ nullptr));
}
// We count malformed only first time when it occurs after correct message
@@ -360,16 +364,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_FrameType) {
malformed_frame_types.push_back(frame_type);
}
for (size_t i = 0; i < malformed_frame_types.size(); ++i) {
- malformed_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_OFF,
- malformed_frame_types[i],
- kControl,
- FRAME_DATA_HEART_BEAT,
- some_session_id,
- 0u,
- some_message_id,
- NULL));
+ malformed_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_OFF,
+ malformed_frame_types[i],
+ kControl,
+ FRAME_DATA_HEART_BEAT,
+ some_session_id,
+ 0u,
+ some_message_id,
+ nullptr));
}
// We count malformed only first time when it occurs after correct message
@@ -393,27 +398,28 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_FrameType) {
}
}
-// For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data
-// Ack), 0xFF(HB Ack)
+// For Control frames Frame info value shall be from 0x00 to 0x09 or 0xFD
+// (Transport Update Event), 0xFE(Data Ack), 0xFF(HB Ack)
TEST_F(IncomingDataHandlerTest, MalformedPacket_ControlFrame) {
FrameList malformed_packets;
std::vector<uint8_t> malformed_frame_data;
- for (uint8_t frame_type = FRAME_DATA_END_SERVICE_NACK + 1;
- frame_type < FRAME_DATA_SERVICE_DATA_ACK;
+ for (uint8_t frame_type = FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK + 1;
+ frame_type < FRAME_DATA_TRANSPORT_EVENT_UPDATE;
++frame_type) {
malformed_frame_data.push_back(frame_type);
}
for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
- malformed_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_OFF,
- FRAME_TYPE_CONTROL,
- kControl,
- malformed_frame_data[i],
- some_session_id,
- 0u,
- some_message_id,
- NULL));
+ malformed_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ kControl,
+ malformed_frame_data[i],
+ some_session_id,
+ 0u,
+ some_message_id,
+ nullptr));
}
// We count malformed only first time when it occurs after correct message
@@ -448,16 +454,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_SingleFrame) {
}
malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
- malformed_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_OFF,
- FRAME_TYPE_SINGLE,
- kControl,
- malformed_frame_data[i],
- some_session_id,
- 0u,
- some_message_id,
- NULL));
+ malformed_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_OFF,
+ FRAME_TYPE_SINGLE,
+ kControl,
+ malformed_frame_data[i],
+ some_session_id,
+ 0u,
+ some_message_id,
+ nullptr));
}
// We count malformed only first time when it occurs after correct message
@@ -492,16 +499,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_FirstFrame) {
}
malformed_frame_data.push_back(FRAME_DATA_MAX_VALUE);
for (size_t i = 0; i < malformed_frame_data.size(); ++i) {
- malformed_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_OFF,
- FRAME_TYPE_SINGLE,
- kControl,
- malformed_frame_data[i],
- some_session_id,
- 0u,
- some_message_id,
- NULL));
+ malformed_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_OFF,
+ FRAME_TYPE_SINGLE,
+ kControl,
+ malformed_frame_data[i],
+ some_session_id,
+ 0u,
+ some_message_id,
+ nullptr));
}
// We count malformed only first time when it occurs after correct message
@@ -529,106 +537,110 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_FirstFrame) {
TEST_F(IncomingDataHandlerTest, MalformedPacket_AdditionalByte) {
FrameList mobile_packets;
// single packet RPC
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_1,
- PROTECTION_OFF,
- FRAME_TYPE_SINGLE,
- kRpc,
- FRAME_DATA_SINGLE,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_1,
+ PROTECTION_OFF,
+ FRAME_TYPE_SINGLE,
+ kRpc,
+ FRAME_DATA_SINGLE,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
// Add malformed byte
tm_data.insert(tm_data.end(), 1, 0x1);
// consecutive packet Audio
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_2,
- PROTECTION_ON,
- FRAME_TYPE_CONSECUTIVE,
- kAudio,
- FRAME_DATA_LAST_CONSECUTIVE,
- ++some_session_id,
- some_data2_size,
- some_message_id,
- some_data2));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_2,
+ PROTECTION_ON,
+ FRAME_TYPE_CONSECUTIVE,
+ kAudio,
+ FRAME_DATA_LAST_CONSECUTIVE,
+ ++some_session_id,
+ some_data2_size,
+ some_message_id,
+ some_data2));
AppendPacketToTMData(*mobile_packets.back());
// Add malformed bytes
tm_data.insert(tm_data.end(), 2, 0x2);
// single packet Nav
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_ON,
- FRAME_TYPE_SINGLE,
- kMobileNav,
- FRAME_DATA_SINGLE,
- ++some_session_id,
- some_data_size,
- ++some_message_id,
- some_data));
+ mobile_packets.push_back(std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_ON,
+ FRAME_TYPE_SINGLE,
+ kMobileNav,
+ FRAME_DATA_SINGLE,
+ ++some_session_id,
+ some_data_size,
+ ++some_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
// Add malformed bytes
tm_data.insert(tm_data.end(), 3, 0x3);
// consecutive packet Bulk
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_ON,
- FRAME_TYPE_CONSECUTIVE,
- kBulk,
- FRAME_DATA_LAST_CONSECUTIVE,
- ++some_session_id,
- some_data2_size,
- ++some_message_id,
- some_data2));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_ON,
+ FRAME_TYPE_CONSECUTIVE,
+ kBulk,
+ FRAME_DATA_LAST_CONSECUTIVE,
+ ++some_session_id,
+ some_data2_size,
+ ++some_message_id,
+ some_data2));
AppendPacketToTMData(*mobile_packets.back());
// Add malformed bytes
tm_data.insert(tm_data.end(), 4, 0x4);
// single packet RPC
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_1,
- PROTECTION_OFF,
- FRAME_TYPE_CONTROL,
- kRpc,
- FRAME_DATA_HEART_BEAT,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_1,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ kRpc,
+ FRAME_DATA_HEART_BEAT,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
// Add malformed bytes
tm_data.insert(tm_data.end(), 5, 0x5);
// single packet Audio
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_1,
- PROTECTION_OFF,
- FRAME_TYPE_CONTROL,
- kAudio,
- FRAME_DATA_HEART_BEAT,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_1,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ kAudio,
+ FRAME_DATA_HEART_BEAT,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
// Add malformed bytes
tm_data.insert(tm_data.end(), 6, 0x6);
// single packet RPC
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_1,
- PROTECTION_OFF,
- FRAME_TYPE_SINGLE,
- kRpc,
- FRAME_DATA_SINGLE,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_1,
+ PROTECTION_OFF,
+ FRAME_TYPE_SINGLE,
+ kRpc,
+ FRAME_DATA_SINGLE,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
ProcessData(uid1, &tm_data[0], tm_data.size());
@@ -651,29 +663,30 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_AdditionalByte) {
TEST_F(IncomingDataHandlerTest, MalformedPacket_Mix) {
FrameList mobile_packets;
// single packet RPC
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_1,
- PROTECTION_OFF,
- FRAME_TYPE_SINGLE,
- kRpc,
- FRAME_DATA_SINGLE,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_1,
+ PROTECTION_OFF,
+ FRAME_TYPE_SINGLE,
+ kRpc,
+ FRAME_DATA_SINGLE,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
// consecutive packet Audio
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_2,
- PROTECTION_ON,
- FRAME_TYPE_CONSECUTIVE,
- kAudio,
- FRAME_DATA_LAST_CONSECUTIVE,
- ++some_session_id,
- some_data2_size,
- some_message_id,
- some_data2));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_2,
+ PROTECTION_ON,
+ FRAME_TYPE_CONSECUTIVE,
+ kAudio,
+ FRAME_DATA_LAST_CONSECUTIVE,
+ ++some_session_id,
+ some_data2_size,
+ some_message_id,
+ some_data2));
AppendPacketToTMData(*mobile_packets.back());
// Malformed packet 1
@@ -691,16 +704,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_Mix) {
AppendPacketToTMData(malformed_packet1);
// consecutive packet Bulk
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_ON,
- FRAME_TYPE_CONSECUTIVE,
- kBulk,
- FRAME_DATA_LAST_CONSECUTIVE,
- ++some_session_id,
- some_data2_size,
- ++some_message_id,
- some_data2));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_ON,
+ FRAME_TYPE_CONSECUTIVE,
+ kBulk,
+ FRAME_DATA_LAST_CONSECUTIVE,
+ ++some_session_id,
+ some_data2_size,
+ ++some_message_id,
+ some_data2));
AppendPacketToTMData(*mobile_packets.back());
// Malformed packet 2
@@ -718,16 +732,17 @@ TEST_F(IncomingDataHandlerTest, MalformedPacket_Mix) {
AppendPacketToTMData(malformed_packet2);
// Audio packet
- mobile_packets.push_back(new ProtocolPacket(uid1,
- PROTOCOL_VERSION_3,
- PROTECTION_OFF,
- FRAME_TYPE_CONTROL,
- kAudio,
- FRAME_DATA_HEART_BEAT,
- some_session_id,
- some_data_size,
- protov1_message_id,
- some_data));
+ mobile_packets.push_back(
+ std::make_shared<ProtocolPacket>(uid1,
+ PROTOCOL_VERSION_3,
+ PROTECTION_OFF,
+ FRAME_TYPE_CONTROL,
+ kAudio,
+ FRAME_DATA_HEART_BEAT,
+ some_session_id,
+ some_data_size,
+ protov1_message_id,
+ some_data));
AppendPacketToTMData(*mobile_packets.back());
ProcessData(uid1, &tm_data[0], tm_data.size());
diff --git a/src/components/protocol_handler/test/multiframe_builder_test.cc b/src/components/protocol_handler/test/multiframe_builder_test.cc
index ad8a39f79a..f919ec92af 100644
--- a/src/components/protocol_handler/test/multiframe_builder_test.cc
+++ b/src/components/protocol_handler/test/multiframe_builder_test.cc
@@ -35,7 +35,7 @@
#include <algorithm>
#include <utility>
#include <limits>
-#include "utils/make_shared.h"
+
#include "protocol_handler/multiframe_builder.h"
namespace test {
@@ -149,7 +149,7 @@ class MultiFrameBuilderTest : public ::testing::Test {
const ProtocolFramePtrList::const_iterator it_last = --(multiframes.end());
while (it != it_last) {
const ProtocolFramePtr frame = *it;
- ASSERT_TRUE(frame);
+ ASSERT_TRUE((bool)frame);
EXPECT_EQ(RESULT_OK, multiframe_builder_.AddFrame(frame))
<< "Non final CONSECUTIVE frame: " << frame;
EXPECT_EQ(ProtocolFramePtrList(), multiframe_builder_.PopMultiframes())
@@ -331,7 +331,7 @@ TEST_F(MultiFrameBuilderTest, Add_FirstFrames_NoConnections) {
const ProtocolFramePtrList& multiframes = multiframe_data.multiframes;
ASSERT_FALSE(multiframes.empty());
const ProtocolFramePtr first_frame = multiframes.front();
- ASSERT_TRUE(first_frame);
+ ASSERT_TRUE((bool)first_frame);
EXPECT_EQ(RESULT_FAIL, multiframe_builder_.AddFrame(first_frame))
<< "Non-existed connection " << connection_id
<< "- to be skipped first frame: " << first_frame;
@@ -365,7 +365,7 @@ TEST_F(MultiFrameBuilderTest, Add_FirstFrames_only) {
const ProtocolFramePtrList& multiframes = multiframe_data.multiframes;
ASSERT_FALSE(multiframes.empty());
const ProtocolFramePtr first_frame = multiframes.front();
- ASSERT_TRUE(first_frame);
+ ASSERT_TRUE((bool)first_frame);
EXPECT_EQ(RESULT_OK, multiframe_builder_.AddFrame(first_frame))
<< "First frame: " << first_frame;
@@ -440,7 +440,7 @@ TEST_F(MultiFrameBuilderTest, Add_ConsecutiveFrames_per1) {
ASSERT_FALSE(multiframes.empty());
const ProtocolFramePtr frame = multiframes.front();
- ASSERT_TRUE(frame);
+ ASSERT_TRUE((bool)frame);
EXPECT_EQ(RESULT_OK, multiframe_builder_.AddFrame(frame))
<< "Frame: " << frame;
@@ -501,7 +501,7 @@ TEST_F(MultiFrameBuilderTest, FrameExpired_OneMSec) {
const ProtocolFramePtrList& multiframes = multiframe_data.multiframes;
ASSERT_FALSE(multiframes.empty());
const ProtocolFramePtr first_frame = multiframes.front();
- ASSERT_TRUE(first_frame);
+ ASSERT_TRUE((bool)first_frame);
EXPECT_EQ(RESULT_OK, multiframe_builder_.AddFrame(first_frame))
<< "First frame: " << first_frame;
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 0cb8e155d0..cfda0a550a 100644
--- a/src/components/protocol_handler/test/protocol_handler_tm_test.cc
+++ b/src/components/protocol_handler/test/protocol_handler_tm_test.cc
@@ -41,16 +41,26 @@
#include "protocol_handler/mock_protocol_handler_settings.h"
#include "protocol_handler/mock_session_observer.h"
#include "connection_handler/mock_connection_handler.h"
+#include "connection_handler/connection_handler_impl.h"
#ifdef ENABLE_SECURITY
#include "security_manager/mock_security_manager.h"
#include "security_manager/mock_ssl_context.h"
#endif // ENABLE_SECURITY
#include "transport_manager/mock_transport_manager.h"
#include "utils/mock_system_time_handler.h"
-#include "utils/make_shared.h"
+
#include "utils/test_async_waiter.h"
#include <bson_object.h>
+namespace transport_manager {
+namespace transport_adapter {
+// taken from transport_adapter_impl.cc
+const char* tc_enabled = "enabled";
+const char* tc_tcp_port = "tcp_port";
+const char* tc_tcp_ip_address = "tcp_ip_address";
+}
+}
+
namespace test {
namespace components {
namespace protocol_handler_test {
@@ -88,6 +98,10 @@ using protocol_handler::FRAME_DATA_SERVICE_DATA_ACK;
using protocol_handler::FRAME_DATA_SINGLE;
using protocol_handler::FRAME_DATA_FIRST;
using protocol_handler::FRAME_DATA_LAST_CONSECUTIVE;
+using protocol_handler::FRAME_DATA_REGISTER_SECONDARY_TRANSPORT;
+using protocol_handler::FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_ACK;
+using protocol_handler::FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK;
+using protocol_handler::FRAME_DATA_TRANSPORT_EVENT_UPDATE;
using protocol_handler::kRpc;
using protocol_handler::kControl;
using protocol_handler::kAudio;
@@ -108,10 +122,12 @@ using ContextCreationStrategy =
using connection_handler::DeviceHandle;
// Google Testing Framework Entities
using ::testing::Return;
+using ::testing::ReturnRef;
using ::testing::ReturnRefOfCopy;
using ::testing::ReturnNull;
using ::testing::An;
using ::testing::AnyOf;
+using ::testing::AtLeast;
using ::testing::ByRef;
using ::testing::DoAll;
using ::testing::SaveArg;
@@ -190,6 +206,9 @@ class ProtocolHandlerImplTest : public ::testing::Test {
.
// Return false to avoid call KeepConnectionAlive
WillRepeatedly(Return(false));
+
+ session_connection_map_lock_ptr_ =
+ std::make_shared<sync_primitives::Lock>();
}
void TearDown() OVERRIDE {
@@ -216,6 +235,7 @@ class ProtocolHandlerImplTest : public ::testing::Test {
const uint32_t hash_id,
const bool protection_flag) {
return protocol_handler::SessionContext(connection_id,
+ connection_id,
initial_session_id,
new_session_id,
service_type,
@@ -223,7 +243,7 @@ class ProtocolHandlerImplTest : public ::testing::Test {
protection_flag);
}
- void AddSession(const ::utils::SharedPtr<TestAsyncWaiter>& waiter,
+ void AddSession(const std::shared_ptr<TestAsyncWaiter>& waiter,
uint32_t& times) {
using namespace protocol_handler;
ASSERT_TRUE(NULL != waiter.get());
@@ -320,10 +340,11 @@ class ProtocolHandlerImplTest : public ::testing::Test {
uint8_t service_type,
uint8_t sessionId,
uint32_t frame_data,
+ uint8_t protocol_version = PROTOCOL_VERSION_3,
uint32_t dataSize = 0u,
const uint8_t* data = NULL) {
SendTMMessage(connection_id,
- PROTOCOL_VERSION_3,
+ protocol_version,
protection,
FRAME_TYPE_CONTROL,
service_type,
@@ -334,8 +355,20 @@ class ProtocolHandlerImplTest : public ::testing::Test {
data);
}
+ void VerifySecondaryTransportParamsInStartSessionAck(
+ bool config_multiple_transports_enabled,
+ const std::vector<std::string>& config_secondary_transports_for_usb,
+ const std::vector<std::string>& config_secondary_transports_for_bluetooth,
+ const std::vector<std::string>& config_secondary_transports_for_wifi,
+ const std::vector<std::string>& config_audio_service_transports,
+ const std::vector<std::string>& config_video_service_transports,
+ const std::string& connection_type_string,
+ const std::vector<std::string>& expected_transport_strings,
+ const std::vector<int32_t>& expected_audio_service_transports,
+ const std::vector<int32_t>& expected_video_service_transports);
+
testing::NiceMock<MockProtocolHandlerSettings> protocol_handler_settings_mock;
- ::utils::SharedPtr<ProtocolHandlerImpl> protocol_handler_impl;
+ std::shared_ptr<ProtocolHandlerImpl> protocol_handler_impl;
TransportManagerListener* tm_listener;
// Uniq connection
::transport_manager::ConnectionUID connection_id;
@@ -360,6 +393,10 @@ class ProtocolHandlerImplTest : public ::testing::Test {
std::vector<int> force_unprotected_services;
#endif // ENABLE_SECURITY
std::vector<std::string> empty_rejected_param_;
+ // Used by OnTransportConfigUpdated() tests. The lifetime of these objects
+ // should be longer than that of a test case.
+ connection_handler::SessionConnectionMap session_connection_map_;
+ std::shared_ptr<sync_primitives::Lock> session_connection_map_lock_ptr_;
};
#ifdef ENABLE_SECURITY
@@ -584,8 +621,7 @@ TEST_F(ProtocolHandlerImplTest,
TEST_F(ProtocolHandlerImplTest, StartSession_Protected_SessionObserverAccept) {
SetProtocolVersion2();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -799,8 +835,7 @@ TEST_F(ProtocolHandlerImplTest,
* ProtocolHandler shall send NAck on session_observer rejection
*/
TEST_F(ProtocolHandlerImplTest, EndSession_SessionObserverReject) {
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -833,8 +868,7 @@ TEST_F(ProtocolHandlerImplTest, EndSession_SessionObserverReject) {
* ProtocolHandler shall send NAck on wrong hash code
*/
TEST_F(ProtocolHandlerImplTest, EndSession_Success) {
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -867,8 +901,7 @@ TEST_F(ProtocolHandlerImplTest, EndSession_Success) {
#ifdef ENABLE_SECURITY
TEST_F(ProtocolHandlerImplTest, SecurityEnable_StartSessionProtocoloV1) {
using namespace protocol_handler;
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1485,14 +1518,1138 @@ TEST_F(ProtocolHandlerImplTest,
}
#endif // ENABLE_SECURITY
+void ProtocolHandlerImplTest::VerifySecondaryTransportParamsInStartSessionAck(
+ bool config_multiple_transports_enabled,
+ const std::vector<std::string>& config_secondary_transports_for_usb,
+ const std::vector<std::string>& config_secondary_transports_for_bluetooth,
+ const std::vector<std::string>& config_secondary_transports_for_wifi,
+ const std::vector<std::string>& config_audio_service_transports,
+ const std::vector<std::string>& config_video_service_transports,
+ const std::string& connection_type_string,
+ const std::vector<std::string>& expected_transport_strings,
+ const std::vector<int32_t>& expected_audio_service_transports,
+ const std::vector<int32_t>& expected_video_service_transports) {
+ const size_t maximum_rpc_payload_size = 1500;
+ EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size())
+ .WillRepeatedly(Return(maximum_rpc_payload_size));
+ InitProtocolHandlerImpl(0u, 0u);
+
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ const uint8_t input_protocol_version = 5;
+ const uint32_t hash_id = 123456;
+ ProtocolPacket::ProtocolVersion full_version(5, 1, 0);
+ char full_version_string[] = "5.1.0";
+
+ // configuration setup
+ EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version())
+ .WillRepeatedly(Return(PROTOCOL_VERSION_5));
+ EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled())
+ .WillRepeatedly(Return(config_multiple_transports_enabled));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb));
+ EXPECT_CALL(protocol_handler_settings_mock,
+ secondary_transports_for_bluetooth())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi));
+ EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports())
+ .WillOnce(ReturnRef(config_audio_service_transports));
+ EXPECT_CALL(protocol_handler_settings_mock, video_service_transports())
+ .WillOnce(ReturnRef(config_video_service_transports));
+
+ EXPECT_CALL(session_observer_mock,
+ TransportTypeProfileStringFromConnHandle(connection_id))
+ .WillRepeatedly(Return(connection_type_string));
+
+ // Prepare expected BSON parameters. When we add another param in Start
+ // Service ACK frame in future, it should be also added here.
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // mtu
+ bson_object_put_int64(&expected_obj,
+ protocol_handler::strings::mtu,
+ static_cast<int64_t>(maximum_rpc_payload_size));
+ // hashId
+ bson_object_put_int32(&expected_obj,
+ protocol_handler::strings::hash_id,
+ static_cast<int32_t>(hash_id));
+ // protocolVersion
+ bson_object_put_string(&expected_obj,
+ protocol_handler::strings::protocol_version,
+ full_version_string);
+ // secondaryTransports
+ BsonArray secondary_transports;
+ bson_array_initialize(&secondary_transports,
+ expected_transport_strings.size());
+ for (std::vector<std::string>::const_iterator it =
+ expected_transport_strings.begin();
+ it != expected_transport_strings.end();
+ ++it) {
+ // note: if there is no transport allowed, we can either make the array
+ // empty, or completely omit the array. (The spec allows both cases.) In
+ // this test case we make the array empty.
+ bson_array_add_string(&secondary_transports,
+ const_cast<char*>(it->c_str()));
+ }
+ bson_object_put_array(&expected_obj,
+ protocol_handler::strings::secondary_transports,
+ &secondary_transports);
+ // audioServiceTransports
+ BsonArray audio_service_transports;
+ if (expected_audio_service_transports.size() > 0) {
+ bson_array_initialize(&audio_service_transports,
+ expected_audio_service_transports.size());
+ for (std::vector<int32_t>::const_iterator it =
+ expected_audio_service_transports.begin();
+ it != expected_audio_service_transports.end();
+ ++it) {
+ bson_array_add_int32(&audio_service_transports, *it);
+ }
+ bson_object_put_array(&expected_obj,
+ protocol_handler::strings::audio_service_transports,
+ &audio_service_transports);
+ }
+ // videoServiceTransports
+ BsonArray video_service_transports;
+ if (expected_video_service_transports.size() > 0) {
+ bson_array_initialize(&video_service_transports,
+ expected_video_service_transports.size());
+ for (std::vector<int32_t>::const_iterator it =
+ expected_video_service_transports.begin();
+ it != expected_video_service_transports.end();
+ ++it) {
+ bson_array_add_int32(&video_service_transports, *it);
+ }
+ bson_object_put_array(&expected_obj,
+ protocol_handler::strings::video_service_transports,
+ &video_service_transports);
+ }
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK,
+ PROTECTION_OFF,
+ connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+#ifdef ENABLE_SECURITY
+ AddSecurityManager();
+
+ EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id))
+ .WillOnce(Return(connection_key));
+
+ EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc))
+ .WillOnce(ReturnNull());
+#endif // ENABLE_SECURITY
+
+ protocol_handler_impl->SendStartSessionAck(connection_id,
+ session_id,
+ input_protocol_version,
+ hash_id,
+ protocol_handler::SERVICE_TYPE_RPC,
+ false /* protection */,
+ full_version);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_Enabled) {
+ // config allows secondary transport only when connected through Bluetooth,
+ // and the secondary is Wi-Fi
+ std::vector<std::string> secondary_transports_for_usb; // empty
+ std::vector<std::string> secondary_transports_for_bluetooth;
+ secondary_transports_for_bluetooth.push_back("WiFi");
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config allows video and audio services to run on all transports except
+ // Bluetooth
+ std::vector<std::string> audio_service_transports;
+ audio_service_transports.push_back("IAP_USB");
+ audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ audio_service_transports.push_back("IAP_CARPLAY");
+ audio_service_transports.push_back("AOA_USB");
+ audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> video_service_transports;
+ video_service_transports.push_back("IAP_USB");
+ video_service_transports.push_back("IAP_USB_HOST_MODE");
+ video_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ video_service_transports.push_back("IAP_CARPLAY");
+ video_service_transports.push_back("AOA_USB");
+ video_service_transports.push_back("TCP_WIFI");
+
+ // assume the device is Android and is connected through Bluetooth SPP
+ std::string connection_type_string("SPP_BLUETOOTH");
+
+ // Core should specify WiFi for secondary transport, and should allow video
+ // and audio services only on secondary transport
+ std::vector<std::string> expected_transport_strings;
+ expected_transport_strings.push_back("TCP_WIFI");
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(2);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(2);
+
+ // A TransportUpdateEvent is also issued after Start Service ACK. We don't
+ // check it in this test case.
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ true,
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_NoSecondaryTransport) {
+ // config allows secondary transport only when connected through Bluetooth,
+ // and the secondary is Wi-Fi
+ std::vector<std::string> secondary_transports_for_usb; // empty
+ std::vector<std::string> secondary_transports_for_bluetooth;
+ secondary_transports_for_bluetooth.push_back("WiFi");
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config allows video and audio services to run on all transports except
+ // Bluetooth
+ std::vector<std::string> audio_service_transports;
+ audio_service_transports.push_back("IAP_USB");
+ audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ audio_service_transports.push_back("IAP_CARPLAY");
+ audio_service_transports.push_back("AOA_USB");
+ audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> video_service_transports;
+ video_service_transports.push_back("IAP_USB");
+ video_service_transports.push_back("IAP_USB_HOST_MODE");
+ video_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ video_service_transports.push_back("IAP_CARPLAY");
+ video_service_transports.push_back("AOA_USB");
+ video_service_transports.push_back("TCP_WIFI");
+
+ // assume the device is iOS and is connected through iAP over USB
+ std::string connection_type_string("IAP_USB");
+
+ // Core should not offer any secondary transport. It will allow both video
+ // and audio services on primary transport.
+ std::vector<std::string> expected_transport_strings; // empty
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(1);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(1);
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ true,
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_MultipleSecondaryTransports) {
+ // config allows secondary transport only when connected through Bluetooth,
+ // and the secondary is Wi-Fi and USB
+ std::vector<std::string> secondary_transports_for_usb; // empty
+ std::vector<std::string> secondary_transports_for_bluetooth;
+ secondary_transports_for_bluetooth.push_back("WiFi");
+ secondary_transports_for_bluetooth.push_back("USB");
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config allows video and audio services to run on all transports except
+ // Bluetooth
+ std::vector<std::string> audio_service_transports;
+ audio_service_transports.push_back("IAP_USB");
+ audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ audio_service_transports.push_back("IAP_CARPLAY");
+ audio_service_transports.push_back("AOA_USB");
+ audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> video_service_transports;
+ video_service_transports.push_back("IAP_USB");
+ video_service_transports.push_back("IAP_USB_HOST_MODE");
+ video_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ video_service_transports.push_back("IAP_CARPLAY");
+ video_service_transports.push_back("AOA_USB");
+ video_service_transports.push_back("TCP_WIFI");
+
+ // assume the device is iOS and is connected through iAP over Bluetooth
+ std::string connection_type_string("IAP_BLUETOOTH");
+
+ // Core should offer both Wi-Fi and USB for secondary transport. Since the
+ // device is iOS, Core should specify "IAP_USB".
+ std::vector<std::string> expected_transport_strings;
+ expected_transport_strings.push_back("TCP_WIFI");
+ expected_transport_strings.push_back("IAP_USB");
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(2);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(2);
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ true,
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(
+ ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_ServiceAllowedOnBothTransports) {
+ std::vector<std::string> secondary_transports_for_usb;
+ secondary_transports_for_usb.push_back("WiFi");
+ std::vector<std::string> secondary_transports_for_bluetooth;
+ secondary_transports_for_bluetooth.push_back("USB");
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config allows video service to run on Wi-Fi transports only, and audio
+ // service to run on all transports
+ std::vector<std::string> audio_service_transports;
+ audio_service_transports.push_back("IAP_BLUETOOTH");
+ audio_service_transports.push_back("IAP_USB");
+ audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ audio_service_transports.push_back("IAP_CARPLAY");
+ audio_service_transports.push_back("SPP_BLUETOOTH");
+ audio_service_transports.push_back("AOA_USB");
+ audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> video_service_transports;
+ video_service_transports.push_back("IAP_CARPLAY");
+ video_service_transports.push_back("TCP_WIFI");
+
+ // assume the device is Android and is connected through AOA
+ std::string connection_type_string("AOA_USB");
+
+ // Core should offer Wi-Fi for secondary transport. It should allow audio
+ // service to run on both primary and secondary, while video service to run
+ // on secondary only. Since the list specifies AOA_USB then TCP_WIFI, the
+ // priority is primary > secondary.
+ std::vector<std::string> expected_transport_strings;
+ expected_transport_strings.push_back("TCP_WIFI");
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(1); // primary preferred
+ expected_audio_service_transports.push_back(2);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(2);
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ true,
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_SecondaryDisabled) {
+ std::vector<std::string> secondary_transports_for_usb; // empty
+ std::vector<std::string> secondary_transports_for_bluetooth; // empty
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config allows video and audio services to run on all transports
+ std::vector<std::string> audio_service_transports;
+ audio_service_transports.push_back("IAP_BLUETOOTH");
+ audio_service_transports.push_back("IAP_USB");
+ audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ audio_service_transports.push_back("IAP_CARPLAY");
+ audio_service_transports.push_back("SPP_BLUETOOTH");
+ audio_service_transports.push_back("AOA_USB");
+ audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> video_service_transports;
+ video_service_transports.push_back("IAP_BLUETOOTH");
+ video_service_transports.push_back("IAP_USB");
+ video_service_transports.push_back("IAP_USB_HOST_MODE");
+ video_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ video_service_transports.push_back("IAP_CARPLAY");
+ video_service_transports.push_back("SPP_BLUETOOTH");
+ video_service_transports.push_back("AOA_USB");
+ video_service_transports.push_back("TCP_WIFI");
+
+ // assume the device is iOS and is connected through iAP over Bluetooth
+ std::string connection_type_string("IAP_BLUETOOTH");
+
+ // Core should not offer any secondary transport. It should still send
+ // the video/audio service transport lists.
+ std::vector<std::string> expected_transport_strings; // empty
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(1);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(1);
+
+ connection_handler::SessionTransports dummy_st = {0, 0};
+ EXPECT_CALL(connection_handler_mock,
+ SetSecondaryTransportID(_, kDisabledSecondary))
+ .WillOnce(Return(dummy_st));
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ false, /* disabled */
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_ServicesMapEmpty) {
+ std::vector<std::string> secondary_transports_for_usb; // empty
+ std::vector<std::string> secondary_transports_for_bluetooth;
+ secondary_transports_for_bluetooth.push_back("USB");
+ std::vector<std::string> secondary_transports_for_wifi;
+ secondary_transports_for_wifi.push_back("USB");
+ // config does not specify video and audio services
+ std::vector<std::string> audio_service_transports; // empty
+ std::vector<std::string> video_service_transports; // empty
+
+ // assume the device is connected through Wi-Fi (so not sure if it's iOS or
+ // Android)
+ std::string connection_type_string("TCP_WIFI");
+
+ // Core should offer USB transport for secondary transport. (Since the OS type
+ // is unknown, it will offer both IAP_USB and AOA_USB.) Also, it should allow
+ // video/audio services on all transports.
+ std::vector<std::string> expected_transport_strings;
+ expected_transport_strings.push_back("IAP_USB");
+ expected_transport_strings.push_back("AOA_USB");
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(1);
+ expected_audio_service_transports.push_back(2);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(1);
+ expected_video_service_transports.push_back(2);
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ true,
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(
+ ProtocolHandlerImplTest,
+ StartSessionAck_SecondaryTransportParams_SecondaryDisabled_ServicesMapEmpty) {
+ std::vector<std::string> secondary_transports_for_usb; // empty
+ std::vector<std::string> secondary_transports_for_bluetooth; // empty
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config does not specify video and audio services
+ std::vector<std::string> audio_service_transports; // empty
+ std::vector<std::string> video_service_transports; // empty
+
+ std::string connection_type_string("IAP_BLUETOOTH");
+
+ // Core should not offer any secondary transport. It should still send
+ // the video/audio service transport lists.
+ std::vector<std::string> expected_transport_strings; // empty
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(1);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(1);
+
+ connection_handler::SessionTransports dummy_st = {0, 0};
+ EXPECT_CALL(connection_handler_mock,
+ SetSecondaryTransportID(_, kDisabledSecondary))
+ .WillOnce(Return(dummy_st));
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ false, /* disabled */
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+// Secondary transport param should not be included for apps with v5.0.0
+TEST_F(ProtocolHandlerImplTest,
+ StartSessionAck_Unprotected_NoSecondaryTransportParamsForV5) {
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ const uint8_t input_protocol_version = 5;
+ const uint32_t hash_id = 123456;
+ ProtocolPacket::ProtocolVersion full_version(5, 0, 0);
+ char full_version_string[] = "5.0.0";
+
+ const size_t maximum_rpc_payload_size = 1500;
+ EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size())
+ .WillRepeatedly(Return(maximum_rpc_payload_size));
+ InitProtocolHandlerImpl(0u, 0u);
+
+ // configuration
+ std::vector<std::string> config_secondary_transports_for_usb; // empty
+ std::vector<std::string> config_secondary_transports_for_bluetooth;
+ config_secondary_transports_for_bluetooth.push_back("USB");
+ std::vector<std::string> config_secondary_transports_for_wifi;
+ config_secondary_transports_for_wifi.push_back("USB");
+
+ // assume the device is iOS and is connected through iAP over Bluetooth
+ std::string connection_type_string("IAP_BLUETOOTH");
+
+ // configuration setup
+ EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version())
+ .WillRepeatedly(Return(PROTOCOL_VERSION_5));
+ EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb));
+ EXPECT_CALL(protocol_handler_settings_mock,
+ secondary_transports_for_bluetooth())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi));
+
+ EXPECT_CALL(session_observer_mock,
+ TransportTypeProfileStringFromConnHandle(connection_id))
+ .WillRepeatedly(Return(connection_type_string));
+
+ // BSON params should not include any of "secondaryTransports",
+ // "audioServiceTransports" and "videoServiceTransports" since v5.0.0 app
+ // does not understand them
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // mtu
+ bson_object_put_int64(&expected_obj,
+ protocol_handler::strings::mtu,
+ static_cast<int64_t>(maximum_rpc_payload_size));
+ // hashId
+ bson_object_put_int32(&expected_obj,
+ protocol_handler::strings::hash_id,
+ static_cast<int32_t>(hash_id));
+ // protocolVersion
+ bson_object_put_string(&expected_obj,
+ protocol_handler::strings::protocol_version,
+ full_version_string);
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_START_SERVICE_ACK,
+ PROTECTION_OFF,
+ connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ connection_handler::SessionTransports dummy_st = {0, 0};
+ EXPECT_CALL(connection_handler_mock,
+ SetSecondaryTransportID(_, kDisabledSecondary))
+ .WillOnce(Return(dummy_st));
+
+ // Since the protocol version is less than 5.1.0, Core should not issue
+ // TransportEventUpdate frame. Enable ProtocolVersionUsed() call and verify
+ // that transport_manager_mock will NOT receive another SendMessageToDevice()
+ // call.
+ ON_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillByDefault(Return(true));
+
+#ifdef ENABLE_SECURITY
+ AddSecurityManager();
+
+ EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id))
+ .WillOnce(Return(connection_key));
+
+ EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc))
+ .WillOnce(ReturnNull());
+#endif // ENABLE_SECURITY
+
+ protocol_handler_impl->SendStartSessionAck(connection_id,
+ session_id,
+ input_protocol_version,
+ hash_id,
+ protocol_handler::SERVICE_TYPE_RPC,
+ false /* protection */,
+ full_version);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest, StartSessionAck_PrimaryTransportUSBHostMode) {
+ // config allows secondary transport only when connected through Bluetooth,
+ // and the secondary is Wi-Fi
+ std::vector<std::string> secondary_transports_for_usb;
+ secondary_transports_for_usb.push_back("WiFi");
+ std::vector<std::string> secondary_transports_for_bluetooth; // empty
+ std::vector<std::string> secondary_transports_for_wifi; // empty
+ // config allows video and audio services to run on all transports except
+ // Bluetooth
+ std::vector<std::string> audio_service_transports;
+ audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ audio_service_transports.push_back("IAP_CARPLAY");
+ audio_service_transports.push_back("AOA_USB");
+ audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> video_service_transports;
+ video_service_transports.push_back("IAP_USB");
+ video_service_transports.push_back("IAP_CARPLAY");
+ video_service_transports.push_back("AOA_USB");
+ video_service_transports.push_back("TCP_WIFI");
+
+ // assume the device is IOS and is connected through USB Host Mode
+ std::string connection_type_string("IAP_USB_HOST_MODE");
+
+ // Core should specify WiFi for secondary transport, and should allow video
+ // services on both transports, and audio only on secondary transport
+ std::vector<std::string> expected_transport_strings;
+ expected_transport_strings.push_back("TCP_WIFI");
+ std::vector<int32_t> expected_audio_service_transports;
+ expected_audio_service_transports.push_back(2);
+ std::vector<int32_t> expected_video_service_transports;
+ expected_video_service_transports.push_back(1);
+ expected_video_service_transports.push_back(2);
+
+ // A TransportUpdateEvent is also issued after Start Service ACK. We don't
+ // check it in this test case.
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(Return(false));
+
+ VerifySecondaryTransportParamsInStartSessionAck(
+ true,
+ secondary_transports_for_usb,
+ secondary_transports_for_bluetooth,
+ secondary_transports_for_wifi,
+ audio_service_transports,
+ video_service_transports,
+ connection_type_string,
+ expected_transport_strings,
+ expected_audio_service_transports,
+ expected_video_service_transports);
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ TransportEventUpdate_afterVersionNegotiation_TCPEnabled) {
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ const uint8_t input_protocol_version = 5;
+ const uint32_t hash_id = 123456;
+ ProtocolPacket::ProtocolVersion full_version(5, 1, 0);
+
+ const size_t maximum_rpc_payload_size = 1500;
+ EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size())
+ .WillRepeatedly(Return(maximum_rpc_payload_size));
+ InitProtocolHandlerImpl(0u, 0u);
+
+ // TCP configuration setup
+ bool tcp_enabled = true;
+ char tcp_address[] = "192.168.1.1";
+ int32_t tcp_port = 12345;
+ std::string tcp_port_str = "12345";
+ protocol_handler_impl->set_tcp_config(
+ tcp_enabled, std::string(tcp_address), tcp_port_str);
+
+ // configuration setup
+ std::vector<std::string> config_secondary_transports_for_usb; // empty
+ std::vector<std::string> config_secondary_transports_for_bluetooth;
+ config_secondary_transports_for_bluetooth.push_back("WiFi");
+ std::vector<std::string> config_secondary_transports_for_wifi; // empty
+ std::vector<std::string> config_audio_service_transports;
+ config_audio_service_transports.push_back("IAP_USB");
+ config_audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ config_audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ config_audio_service_transports.push_back("IAP_CARPLAY");
+ config_audio_service_transports.push_back("AOA_USB");
+ config_audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> config_video_service_transports;
+ config_video_service_transports.push_back("IAP_USB");
+ config_video_service_transports.push_back("IAP_USB_HOST_MODE");
+ config_video_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ config_video_service_transports.push_back("IAP_CARPLAY");
+ config_video_service_transports.push_back("AOA_USB");
+ config_video_service_transports.push_back("TCP_WIFI");
+
+ EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version())
+ .WillRepeatedly(Return(PROTOCOL_VERSION_5));
+ EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb));
+ EXPECT_CALL(protocol_handler_settings_mock,
+ secondary_transports_for_bluetooth())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi));
+ EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports())
+ .WillOnce(ReturnRef(config_audio_service_transports));
+ EXPECT_CALL(protocol_handler_settings_mock, video_service_transports())
+ .WillOnce(ReturnRef(config_video_service_transports));
+
+ // assume the device is iOS and is connected through iAP over Bluetooth
+ std::string connection_type_string("IAP_BLUETOOTH");
+
+ EXPECT_CALL(session_observer_mock,
+ TransportTypeProfileStringFromConnHandle(connection_id))
+ .WillRepeatedly(Return(connection_type_string));
+
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(
+ FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF, connection_id, _)))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true)));
+
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // IP address
+ bson_object_put_string(
+ &expected_obj, protocol_handler::strings::tcp_ip_address, tcp_address);
+ // TCP port number
+ bson_object_put_int32(
+ &expected_obj, protocol_handler::strings::tcp_port, tcp_port);
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE,
+ PROTECTION_OFF,
+ connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+#ifdef ENABLE_SECURITY
+ AddSecurityManager();
+
+ EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id))
+ .WillOnce(Return(connection_key));
+
+ EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc))
+ .WillOnce(ReturnNull());
+#endif // ENABLE_SECURITY
+
+ protocol_handler_impl->SendStartSessionAck(connection_id,
+ session_id,
+ input_protocol_version,
+ hash_id,
+ protocol_handler::SERVICE_TYPE_RPC,
+ false /* protection */,
+ full_version);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ TransportEventUpdate_afterVersionNegotiation_TCPDisabled) {
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ const uint8_t input_protocol_version = 5;
+ const uint32_t hash_id = 123456;
+ ProtocolPacket::ProtocolVersion full_version(5, 1, 0);
+
+ const size_t maximum_rpc_payload_size = 1500;
+ EXPECT_CALL(protocol_handler_settings_mock, maximum_rpc_payload_size())
+ .WillRepeatedly(Return(maximum_rpc_payload_size));
+ InitProtocolHandlerImpl(0u, 0u);
+
+ // TCP configuration setup
+ bool tcp_enabled = false;
+ char tcp_address[] = "192.168.2.3";
+ std::string tcp_port_str = "12345";
+ protocol_handler_impl->set_tcp_config(
+ tcp_enabled, std::string(tcp_address), tcp_port_str);
+
+ std::vector<std::string> config_secondary_transports_for_usb; // empty
+ std::vector<std::string> config_secondary_transports_for_bluetooth;
+ config_secondary_transports_for_bluetooth.push_back("WiFi");
+ std::vector<std::string> config_secondary_transports_for_wifi; // empty
+ std::vector<std::string> config_audio_service_transports;
+ config_audio_service_transports.push_back("IAP_USB");
+ config_audio_service_transports.push_back("IAP_USB_HOST_MODE");
+ config_audio_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ config_audio_service_transports.push_back("IAP_CARPLAY");
+ config_audio_service_transports.push_back("AOA_USB");
+ config_audio_service_transports.push_back("TCP_WIFI");
+ std::vector<std::string> config_video_service_transports;
+ config_video_service_transports.push_back("IAP_USB");
+ config_video_service_transports.push_back("IAP_USB_HOST_MODE");
+ config_video_service_transports.push_back("IAP_USB_DEVICE_MODE");
+ config_video_service_transports.push_back("IAP_CARPLAY");
+ config_video_service_transports.push_back("AOA_USB");
+ config_video_service_transports.push_back("TCP_WIFI");
+
+ EXPECT_CALL(protocol_handler_settings_mock, max_supported_protocol_version())
+ .WillRepeatedly(Return(PROTOCOL_VERSION_5));
+ EXPECT_CALL(protocol_handler_settings_mock, multiple_transports_enabled())
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_usb())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_usb));
+ EXPECT_CALL(protocol_handler_settings_mock,
+ secondary_transports_for_bluetooth())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_bluetooth));
+ EXPECT_CALL(protocol_handler_settings_mock, secondary_transports_for_wifi())
+ .Times(AtLeast(0))
+ .WillRepeatedly(ReturnRef(config_secondary_transports_for_wifi));
+ EXPECT_CALL(protocol_handler_settings_mock, audio_service_transports())
+ .WillOnce(ReturnRef(config_audio_service_transports));
+ EXPECT_CALL(protocol_handler_settings_mock, video_service_transports())
+ .WillOnce(ReturnRef(config_video_service_transports));
+
+ // assume the device is iOS and is connected through iAP over Bluetooth
+ std::string connection_type_string("IAP_BLUETOOTH");
+
+ EXPECT_CALL(session_observer_mock,
+ TransportTypeProfileStringFromConnHandle(connection_id))
+ .WillRepeatedly(Return(connection_type_string));
+
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(
+ FRAME_DATA_START_SERVICE_ACK, PROTECTION_OFF, connection_id, _)))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true)));
+
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // IP address
+ char empty_ip_address[] = "";
+ bson_object_put_string(&expected_obj,
+ protocol_handler::strings::tcp_ip_address,
+ empty_ip_address);
+ // TCP port number should be omitted
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE,
+ PROTECTION_OFF,
+ connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+#ifdef ENABLE_SECURITY
+ AddSecurityManager();
+
+ EXPECT_CALL(session_observer_mock, KeyFromPair(connection_id, session_id))
+ .WillOnce(Return(connection_key));
+
+ EXPECT_CALL(session_observer_mock, GetSSLContext(connection_key, kRpc))
+ .WillOnce(ReturnNull());
+#endif // ENABLE_SECURITY
+
+ protocol_handler_impl->SendStartSessionAck(connection_id,
+ session_id,
+ input_protocol_version,
+ hash_id,
+ protocol_handler::SERVICE_TYPE_RPC,
+ false /* protection */,
+ full_version);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ OnTransportConfigUpdated_TransportEventUpdate_TCPEnabled) {
+ using connection_handler::SessionConnectionMap;
+ using connection_handler::SessionTransports;
+
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ char tcp_address[] = "172.16.2.3";
+ int32_t tcp_port = 23456;
+ std::string tcp_port_str = "23456";
+
+ transport_manager::transport_adapter::TransportConfig configs;
+ configs[transport_manager::transport_adapter::tc_enabled] =
+ std::string("true");
+ configs[transport_manager::transport_adapter::tc_tcp_port] = tcp_port_str;
+ configs[transport_manager::transport_adapter::tc_tcp_ip_address] =
+ std::string(tcp_address);
+
+ transport_manager::ConnectionUID device1_primary_connection_id = 100;
+ transport_manager::ConnectionUID device2_primary_connection_id = 101;
+ transport_manager::ConnectionUID device2_secondary_connection_id = 150;
+
+ SessionTransports st1 = {device1_primary_connection_id, kDisabledSecondary};
+ SessionTransports st2 = {device2_primary_connection_id,
+ device2_secondary_connection_id};
+ session_connection_map_[0x11] = st1;
+ session_connection_map_[0x22] = st2;
+
+ EXPECT_CALL(connection_handler_mock, session_connection_map())
+ .WillOnce(Return(DataAccessor<SessionConnectionMap>(
+ session_connection_map_, session_connection_map_lock_ptr_)));
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true)));
+
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // IP address
+ bson_object_put_string(
+ &expected_obj, protocol_handler::strings::tcp_ip_address, tcp_address);
+ // TCP port number
+ bson_object_put_int32(
+ &expected_obj, protocol_handler::strings::tcp_port, tcp_port);
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ // since device 1 doesn't support secondary transport feature,
+ // TransportEvetUpdate should be delivered only to device 2
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE,
+ PROTECTION_OFF,
+ device2_primary_connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ tm_listener->OnTransportConfigUpdated(configs);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest,
+ OnTransportConfigUpdated_TransportEventUpdate_TCPDisabled) {
+ using connection_handler::SessionConnectionMap;
+ using connection_handler::SessionTransports;
+
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ char tcp_address[] = "172.16.2.3";
+ std::string tcp_port_str = "23456";
+
+ transport_manager::transport_adapter::TransportConfig configs;
+ configs[transport_manager::transport_adapter::tc_enabled] =
+ std::string("false");
+ configs[transport_manager::transport_adapter::tc_tcp_port] = tcp_port_str;
+ configs[transport_manager::transport_adapter::tc_tcp_ip_address] =
+ std::string(tcp_address);
+
+ transport_manager::ConnectionUID device1_primary_connection_id = 100;
+ transport_manager::ConnectionUID device1_secondary_connection_id = 150;
+ transport_manager::ConnectionUID device2_primary_connection_id = 101;
+ transport_manager::ConnectionUID device3_primary_connection_id = 102;
+ transport_manager::ConnectionUID device3_secondary_connection_id = 151;
+
+ SessionTransports st1 = {device1_primary_connection_id,
+ device1_secondary_connection_id};
+ SessionTransports st2 = {device2_primary_connection_id, kDisabledSecondary};
+ SessionTransports st3 = {device3_primary_connection_id,
+ device3_secondary_connection_id};
+ session_connection_map_[0x11] = st1;
+ session_connection_map_[0x22] = st2;
+ session_connection_map_[0x33] = st3;
+
+ EXPECT_CALL(connection_handler_mock, session_connection_map())
+ .WillOnce(Return(DataAccessor<SessionConnectionMap>(
+ session_connection_map_, session_connection_map_lock_ptr_)));
+
+ EXPECT_CALL(session_observer_mock, ProtocolVersionUsed(_, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true)));
+
+ BsonObject expected_obj;
+ bson_object_initialize_default(&expected_obj);
+ // IP address
+ char empty_ip_address[] = "";
+ bson_object_put_string(&expected_obj,
+ protocol_handler::strings::tcp_ip_address,
+ empty_ip_address);
+ // TCP port number should be omitted
+
+ std::vector<uint8_t> expected_param =
+ CreateVectorFromBsonObject(&expected_obj);
+
+ bson_object_deinitialize(&expected_obj);
+
+ // both device 1 and device 3 should receive TransportEventUpdate frames
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE,
+ PROTECTION_OFF,
+ device1_primary_connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+ EXPECT_CALL(
+ transport_manager_mock,
+ SendMessageToDevice(ControlMessage(FRAME_DATA_TRANSPORT_EVENT_UPDATE,
+ PROTECTION_OFF,
+ device3_primary_connection_id,
+ Eq(expected_param))))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ tm_listener->OnTransportConfigUpdated(configs);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest, RegisterSecondaryTransport_SUCCESS) {
+ AddConnection();
+
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ transport_manager::ConnectionUID primary_connection_id = 123;
+
+ EXPECT_CALL(session_observer_mock,
+ ProtocolVersionUsed(primary_connection_id, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true)));
+
+ EXPECT_CALL(connection_handler_mock,
+ OnSecondaryTransportStarted(_, connection_id, session_id))
+ .WillOnce(DoAll(SetArgReferee<0>(primary_connection_id), Return(true)));
+
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(
+ ControlMessage(FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_ACK,
+ PROTECTION_OFF,
+ connection_id,
+ _)))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ SendControlMessage(PROTECTION_OFF,
+ kControl,
+ session_id,
+ FRAME_DATA_REGISTER_SECONDARY_TRANSPORT,
+ PROTOCOL_VERSION_5);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
+TEST_F(ProtocolHandlerImplTest, RegisterSecondaryTransport_FAILURE) {
+ AddConnection();
+
+ TestAsyncWaiter waiter;
+ uint32_t times = 0;
+
+ transport_manager::ConnectionUID primary_connection_id = 123;
+
+ EXPECT_CALL(session_observer_mock,
+ ProtocolVersionUsed(primary_connection_id, _, _))
+ .WillRepeatedly(
+ DoAll(SetArgReferee<2>(PROTOCOL_VERSION_5), Return(true)));
+
+ // check the behavior when OnSecondaryTransportStarted() returns false
+ EXPECT_CALL(connection_handler_mock,
+ OnSecondaryTransportStarted(_, connection_id, session_id))
+ .WillOnce(DoAll(SetArgReferee<0>(primary_connection_id), Return(false)));
+
+ EXPECT_CALL(transport_manager_mock,
+ SendMessageToDevice(
+ ControlMessage(FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK,
+ PROTECTION_OFF,
+ connection_id,
+ _)))
+ .WillOnce(DoAll(NotifyTestAsyncWaiter(&waiter), Return(E_SUCCESS)));
+ times++;
+
+ SendControlMessage(PROTECTION_OFF,
+ kControl,
+ session_id,
+ FRAME_DATA_REGISTER_SECONDARY_TRANSPORT,
+ PROTOCOL_VERSION_5);
+
+ EXPECT_TRUE(waiter.WaitFor(times, kAsyncExpectationsTimeout));
+}
+
TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification) {
const size_t period_msec = 10000;
const size_t max_messages = 1000;
InitProtocolHandlerImpl(period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1529,8 +2686,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification_ThresholdValue) {
InitProtocolHandlerImpl(period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1566,8 +2722,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification_VideoFrameSkip) {
InitProtocolHandlerImpl(period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1595,8 +2750,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerification_AudioFrameSkip) {
InitProtocolHandlerImpl(period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1624,8 +2778,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_FloodVerificationDisable) {
InitProtocolHandlerImpl(period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1653,8 +2806,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedVerificationDisable) {
InitProtocolHandlerImpl(0u, 0u, false, period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1686,8 +2838,7 @@ TEST_F(ProtocolHandlerImplTest, DISABLED_MalformedLimitVerification) {
InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1734,8 +2885,7 @@ TEST_F(ProtocolHandlerImplTest,
InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1806,8 +2956,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_MalformedOnly) {
InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1867,8 +3016,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_NullTimePeriod) {
InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1901,8 +3049,7 @@ TEST_F(ProtocolHandlerImplTest, MalformedLimitVerification_NullCount) {
InitProtocolHandlerImpl(0u, 0u, true, period_msec, max_messages);
AddConnection();
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1945,8 +3092,7 @@ TEST_F(ProtocolHandlerImplTest,
TEST_F(ProtocolHandlerImplTest,
DISABLED_SendEndServicePrivate_EndSession_MessageSent) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1970,8 +3116,7 @@ TEST_F(ProtocolHandlerImplTest,
TEST_F(ProtocolHandlerImplTest,
SendEndServicePrivate_ServiceTypeControl_MessageSent) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -1990,7 +3135,8 @@ TEST_F(ProtocolHandlerImplTest,
times++;
// Act
- protocol_handler_impl->SendEndService(connection_id, session_id, kControl);
+ protocol_handler_impl->SendEndService(
+ connection_id, connection_id, session_id, kControl);
EXPECT_TRUE(waiter->WaitFor(times, kAsyncExpectationsTimeout));
}
@@ -2009,8 +3155,7 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeat_NoConnection_NotSent) {
TEST_F(ProtocolHandlerImplTest, SendHeartBeat_Successful) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2035,8 +3180,7 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeat_Successful) {
TEST_F(ProtocolHandlerImplTest, SendHeartBeatAck_Successful) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2065,8 +3209,7 @@ TEST_F(ProtocolHandlerImplTest, SendHeartBeatAck_Successful) {
TEST_F(ProtocolHandlerImplTest,
DISABLED_SendHeartBeatAck_WrongProtocolVersion_NotSent) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2095,8 +3238,7 @@ TEST_F(ProtocolHandlerImplTest,
TEST_F(ProtocolHandlerImplTest,
SendMessageToMobileApp_SendSingleControlMessage) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2104,7 +3246,7 @@ TEST_F(ProtocolHandlerImplTest,
const bool is_final = true;
const uint32_t total_data_size = 1;
UCharDataVector data(total_data_size);
- RawMessagePtr message = utils::MakeShared<RawMessage>(
+ RawMessagePtr message = std::make_shared<RawMessage>(
connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kControl);
// Expect getting pair from key from session observer
EXPECT_CALL(session_observer_mock,
@@ -2134,8 +3276,7 @@ TEST_F(ProtocolHandlerImplTest,
TEST_F(ProtocolHandlerImplTest,
SendMessageToMobileApp_SendSingleNonControlMessage) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2143,7 +3284,7 @@ TEST_F(ProtocolHandlerImplTest,
const bool is_final = true;
const uint32_t total_data_size = 1;
UCharDataVector data(total_data_size);
- RawMessagePtr message = utils::MakeShared<RawMessage>(
+ RawMessagePtr message = std::make_shared<RawMessage>(
connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kRpc);
// Expect getting pair from key from session observer
EXPECT_CALL(session_observer_mock,
@@ -2177,8 +3318,7 @@ TEST_F(ProtocolHandlerImplTest,
TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) {
// Arrange
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2187,7 +3327,7 @@ TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) {
const uint32_t total_data_size = MAXIMUM_FRAME_DATA_V2_SIZE * 2;
UCharDataVector data(total_data_size);
const uint8_t first_consecutive_frame = 0x01;
- RawMessagePtr message = utils::MakeShared<RawMessage>(
+ RawMessagePtr message = std::make_shared<RawMessage>(
connection_key, PROTOCOL_VERSION_3, &data[0], total_data_size, kBulk);
// Expect getting pair from key from session observer
EXPECT_CALL(session_observer_mock,
@@ -2232,8 +3372,7 @@ TEST_F(ProtocolHandlerImplTest, SendMessageToMobileApp_SendMultiframeMessage) {
}
TEST_F(ProtocolHandlerImplTest, SendServiceDataAck_PreVersion5) {
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
@@ -2259,8 +3398,7 @@ TEST_F(ProtocolHandlerImplTest, SendServiceDataAck_PreVersion5) {
}
TEST_F(ProtocolHandlerImplTest, SendServiceDataAck_AfterVersion5) {
- ::utils::SharedPtr<TestAsyncWaiter> waiter =
- utils::MakeShared<TestAsyncWaiter>();
+ std::shared_ptr<TestAsyncWaiter> waiter = std::make_shared<TestAsyncWaiter>();
uint32_t times = 0;
AddSession(waiter, times);
diff --git a/src/components/protocol_handler/test/protocol_header_validator_test.cc b/src/components/protocol_handler/test/protocol_header_validator_test.cc
index e42ba96251..5554bfd280 100644
--- a/src/components/protocol_handler/test/protocol_header_validator_test.cc
+++ b/src/components/protocol_handler/test/protocol_header_validator_test.cc
@@ -230,12 +230,12 @@ TEST_F(ProtocolHeaderValidatorTest, Malformed_FrameType) {
}
}
-// For Control frames Frame info value shall be from 0x00 to 0x06 or 0xFE(Data
-// Ack), 0xFF(HB Ack)
+// For Control frames Frame info value shall be from 0x00 to 0x09 or 0xFD
+// (Transport Update Event), 0xFE(Data Ack), 0xFF(HB Ack)
TEST_F(ProtocolHeaderValidatorTest, Malformed_ControlFrame) {
std::vector<uint8_t> malformed_frame_data;
- for (uint8_t frame_type = FRAME_DATA_END_SERVICE_NACK + 1;
- frame_type < FRAME_DATA_SERVICE_DATA_ACK;
+ for (uint8_t frame_type = FRAME_DATA_REGISTER_SECONDARY_TRANSPORT_NACK + 1;
+ frame_type < FRAME_DATA_TRANSPORT_EVENT_UPDATE;
++frame_type) {
malformed_frame_data.push_back(frame_type);
}