summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/connection_handler/include/connection_handler/connection.h49
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_impl.h9
-rw-r--r--src/components/connection_handler/src/connection.cc71
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc92
-rw-r--r--src/components/include/connection_handler/connection_handler.h6
5 files changed, 195 insertions, 32 deletions
diff --git a/src/components/connection_handler/include/connection_handler/connection.h b/src/components/connection_handler/include/connection_handler/connection.h
index ca8e550de4..07df9bd943 100644
--- a/src/components/connection_handler/include/connection_handler/connection.h
+++ b/src/components/connection_handler/include/connection_handler/connection.h
@@ -72,13 +72,18 @@ typedef std::map<int32_t, Connection*> ConnectionList;
*/
struct Service {
protocol_handler::ServiceType service_type;
+ transport_manager::ConnectionUID connection_id;
bool is_protected_;
Service()
: service_type(protocol_handler::kInvalidServiceType)
+ , connection_id(0)
, is_protected_(false) {}
- explicit Service(protocol_handler::ServiceType service_type)
- : service_type(service_type), is_protected_(false) {}
+ explicit Service(protocol_handler::ServiceType service_type,
+ transport_manager::ConnectionUID connection_id)
+ : service_type(service_type)
+ , connection_id(connection_id)
+ , is_protected_(false) {}
bool operator==(const protocol_handler::ServiceType service_type) const {
return this->service_type == service_type;
@@ -175,7 +180,8 @@ class Connection {
*/
bool AddNewService(uint8_t session_id,
protocol_handler::ServiceType service_type,
- const bool is_protected);
+ const bool is_protected,
+ transport_manager::ConnectionUID connection_id);
/**
* @brief Removes service from session
* @param session_id session ID
@@ -184,6 +190,16 @@ class Connection {
*/
bool RemoveService(uint8_t session_id,
protocol_handler::ServiceType service_type);
+
+ /**
+ * @brief Removes secondary service from session
+ * @param secondary_connection_handle connection identifying services to be removed
+ * \param removed_services_list Returned: List of service types removed
+ * @return the session ID associated with the services removed
+ */
+ uint8_t RemoveSecondaryServices(transport_manager::ConnectionUID secondary_connection_handle,
+ std::list<protocol_handler::ServiceType>& removed_services_list);
+
#ifdef ENABLE_SECURITY
/**
* @brief Sets crypto context of service
@@ -213,10 +229,10 @@ class Connection {
const protocol_handler::ServiceType& service_type);
#endif // ENABLE_SECURITY
- /**
- * @brief Returns map of sessions which have been opened in
- * current connection.
- */
+ /**
+ * @brief Returns map of sessions which have been opened in
+ * current connection.
+ */
const SessionMap session_map() const;
/**
@@ -283,6 +299,20 @@ class Connection {
*/
bool ProtocolVersion(uint8_t session_id, uint8_t& protocol_version);
+ /**
+ * @brief Returns the primary connection handle associated with this connection
+ * @return ConnectionHandle
+ */
+ ConnectionHandle primary_connection_handle() const;
+
+ /**
+ * \brief Sets the primary connection handle
+ * \param primary_connection_handle the primary connection handle to
+ * associate with this connection
+ */
+ void SetPrimaryConnectionHandle(
+ ConnectionHandle primary_connection_handle);
+
private:
/**
* @brief Current connection handler.
@@ -307,6 +337,11 @@ class Connection {
mutable sync_primitives::Lock session_map_lock_;
/**
+ * @brief primary connection handle for secondary connections
+ */
+ ConnectionHandle primary_connection_handle_;
+
+ /**
* @brief monitor that closes connection if there is no traffic over it
*/
HeartBeatMonitor* heartbeat_monitor_;
diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
index abd814932b..b6109b59c0 100644
--- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
+++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
@@ -572,13 +572,13 @@ class ConnectionHandlerImpl
const uint8_t session_id);
/**
- * \brief Called when secondary transport with given session ID is removed
+ * \brief Called when secondary transport shuts down
* \param primary_connection_handle Identifier of primary connection
- * \param sessionid session ID taken from Register Secondary Transport frame
+ * \param secondary_connection_handle Identifier of secondary connection transport
**/
void OnSecondaryTransportEnded(
const transport_manager::ConnectionUID primary_connection_handle,
- const uint8_t session_id);
+ const transport_manager::ConnectionUID secondary_connection_handle);
private:
/**
@@ -591,6 +591,9 @@ class ConnectionHandlerImpl
void OnConnectionEnded(const transport_manager::ConnectionUID connection_id);
+ uint8_t GetSessionIdFromSecondaryTransport(
+ transport_manager::ConnectionUID secondary_transport_id);
+
const ConnectionHandlerSettings& settings_;
/**
* \brief Pointer to observer
diff --git a/src/components/connection_handler/src/connection.cc b/src/components/connection_handler/src/connection.cc
index cf430aceed..f7a4996e02 100644
--- a/src/components/connection_handler/src/connection.cc
+++ b/src/components/connection_handler/src/connection.cc
@@ -82,6 +82,7 @@ Connection::Connection(ConnectionHandle connection_handle,
, connection_handle_(connection_handle)
, connection_device_handle_(connection_device_handle)
, session_map_lock_(true)
+ , primary_connection_handle_(0)
, heartbeat_timeout_(heartbeat_timeout) {
LOG4CXX_AUTO_TRACE(logger_);
DCHECK(connection_handler_);
@@ -147,8 +148,8 @@ uint32_t Connection::AddNewSession(
sync_primitives::AutoLock lock(session_map_lock_);
Session& new_session = session_map_[session_id];
new_session.protocol_version = ::protocol_handler::PROTOCOL_VERSION_2;
- new_session.service_list.push_back(Service(protocol_handler::kRpc));
- new_session.service_list.push_back(Service(protocol_handler::kBulk));
+ new_session.service_list.push_back(Service(protocol_handler::kRpc, connection_handle));
+ new_session.service_list.push_back(Service(protocol_handler::kBulk, connection_handle));
} else {
LOG4CXX_WARN(logger_, "Session/Connection Map could not create a new session ID!!!");
}
@@ -182,7 +183,8 @@ uint32_t Connection::RemoveSession(uint8_t session_id) {
bool Connection::AddNewService(uint8_t session_id,
protocol_handler::ServiceType service_type,
- const bool request_protection) {
+ const bool request_protection,
+ transport_manager::ConnectionUID connection_id) {
// Ignore wrong services
if (protocol_handler::kControl == service_type ||
protocol_handler::kInvalidServiceType == service_type) {
@@ -192,7 +194,9 @@ bool Connection::AddNewService(uint8_t session_id,
LOG4CXX_DEBUG(logger_,
"Add service " << service_type << " for session "
- << static_cast<uint32_t>(session_id));
+ << static_cast<uint32_t>(session_id)
+ << " using connection ID "
+ << static_cast<uint32_t>(connection_id));
sync_primitives::AutoLock lock(session_map_lock_);
SessionMap::iterator session_it = session_map_.find(session_id);
@@ -241,7 +245,7 @@ bool Connection::AddNewService(uint8_t session_id,
#endif // ENABLE_SECURITY
}
// id service is not exists
- session.service_list.push_back(Service(service_type));
+ session.service_list.push_back(Service(service_type, connection_id));
return true;
}
@@ -286,6 +290,54 @@ bool Connection::RemoveService(uint8_t session_id,
return true;
}
+uint8_t Connection::RemoveSecondaryServices(transport_manager::ConnectionUID secondary_connection_handle,
+ std::list<protocol_handler::ServiceType>& removed_services_list) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ uint8_t found_session_id = 0;
+ sync_primitives::AutoLock lock(session_map_lock_);
+
+ LOG4CXX_INFO(logger_, "RemoveSecondaryServices looking for services on Connection ID " << static_cast<int>(secondary_connection_handle));
+
+ // Walk the SessionMap in the primary connection, and for each
+ // Session, we walk its ServiceList, looking for all the services
+ // that were running on the now-closed Secondary Connection.
+ for (SessionMap::iterator session_it = session_map_.begin();
+ session_map_.end() != session_it;
+ ++session_it) {
+
+ LOG4CXX_INFO(logger_, "RemoveSecondaryServices found session ID " << static_cast<int>(session_it->first));
+
+ // Now, for each session, walk the its ServiceList, looking for services
+ // that were using secondary)_connection_handle. If we find such a service,
+ // set session_found and break out of the outer loop.
+ ServiceList& service_list = session_it->second.service_list;
+ ServiceList::iterator service_it = service_list.begin();
+ for ( ; service_it != service_list.end() ; ) {
+ LOG4CXX_INFO(logger_, "RemoveSecondaryServices found service ID " << static_cast<int>(service_it->service_type));
+ if (service_it->connection_id == secondary_connection_handle) {
+ found_session_id = session_it->first;
+
+ LOG4CXX_INFO(logger_, "RemoveSecondaryServices removing Service " <<
+ static_cast<int>(service_it->service_type) <<
+ " in session " << static_cast<int>(found_session_id));
+
+ removed_services_list.push_back(service_it->service_type);
+ service_it = service_list.erase(service_it);
+ } else {
+ service_it++;
+ }
+ }
+
+ // If we found a session that had services running on the secondary connection, we're done.
+ if (found_session_id != 0) {
+ break;
+ }
+ }
+
+ return found_session_id;
+}
+
#ifdef ENABLE_SECURITY
int Connection::SetSSLContext(uint8_t session_id,
security_manager::SSLContext* context) {
@@ -445,6 +497,15 @@ bool Connection::ProtocolVersion(uint8_t session_id,
return true;
}
+ConnectionHandle Connection::primary_connection_handle() const {
+ return primary_connection_handle_;
+}
+
+void Connection::SetPrimaryConnectionHandle(
+ ConnectionHandle primary_connection_handle) {
+ primary_connection_handle_ = primary_connection_handle;
+}
+
void Connection::StartHeartBeat(uint8_t session_id) {
heartbeat_monitor_->AddSession(session_id);
}
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index c4865ccd53..f69ee0bd00 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -372,7 +372,7 @@ uint32_t ConnectionHandlerImpl::OnSessionStartedCallback(
*hash_id = KeyFromPair(connection_handle, new_session_id);
}
} else { // Could be create new service or protected exists one
- if (!connection->AddNewService(session_id, service_type, is_protected)) {
+ if (!connection->AddNewService(session_id, service_type, is_protected, connection_handle)) {
LOG4CXX_ERROR(logger_,
"Couldn't establish "
#ifdef ENABLE_SECURITY
@@ -471,7 +471,7 @@ void ConnectionHandlerImpl::OnSessionStartedCallback(
}
context.hash_id_ = KeyFromPair(primary_connection_handle, context.new_session_id_);
} else { // Could be create new service or protected exists one
- if (!connection->AddNewService(session_id, service_type, is_protected)) {
+ if (!connection->AddNewService(session_id, service_type, is_protected, connection_handle)) {
LOG4CXX_ERROR(logger_,
"Couldn't establish "
#ifdef ENABLE_SECURITY
@@ -724,6 +724,7 @@ bool ConnectionHandlerImpl::OnSecondaryTransportStarted(
}
DeviceHandle device_handle;
+ Connection* connection;
{
sync_primitives::AutoReadLock lock(connection_list_lock_);
ConnectionList::iterator it =
@@ -734,7 +735,7 @@ bool ConnectionHandlerImpl::OnSecondaryTransportStarted(
return false;
}
- Connection* connection = it->second;
+ connection = it->second;
device_handle = connection->connection_device_handle();
}
@@ -742,14 +743,18 @@ bool ConnectionHandlerImpl::OnSecondaryTransportStarted(
SessionTransports st = SetSecondaryTransportID(session_id, secondary_connection_handle);
primary_connection_handle = st.primary_transport;
if (st.secondary_transport != secondary_connection_handle) {
+ LOG4CXX_WARN(logger_, "Failed setting the session's secondary transport ID");
return false;
}
+ connection->SetPrimaryConnectionHandle(primary_connection_handle);
+
const uint32_t session_key =
KeyFromPair(primary_connection_handle, session_id);
sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
if (connection_handler_observer_valid_ && connection_handler_observer_) {
+ LOG4CXX_TRACE(logger_, "Calling Connection Handler Observer's OnSecondaryTransportStartedCallback");
connection_handler_observer_->OnSecondaryTransportStartedCallback(
device_handle, session_key);
}
@@ -759,21 +764,55 @@ bool ConnectionHandlerImpl::OnSecondaryTransportStarted(
void ConnectionHandlerImpl::OnSecondaryTransportEnded(
const transport_manager::ConnectionUID primary_connection_handle,
- const uint8_t session_id) {
+ const transport_manager::ConnectionUID secondary_connection_handle) {
LOG4CXX_AUTO_TRACE(logger_);
- if (session_id == 0) {
- LOG4CXX_WARN(logger_, "Session id for secondary transport is invalid");
+ LOG4CXX_INFO(logger_,
+ "Secondary Transport: " << static_cast<int32_t>(secondary_connection_handle) <<
+ " ended. Cleaning up services from primary connection ID " << static_cast<int32_t>(primary_connection_handle));
+ connection_list_lock_.AcquireForReading();
+ ConnectionList::iterator itr = connection_list_.find(primary_connection_handle);
+ if (connection_list_.end() == itr) {
+ LOG4CXX_ERROR(logger_, "Primary Connection not found!");
+ connection_list_lock_.Release();
return;
}
+ Connection *connection = itr->second;
+ connection_list_lock_.Release();
- const uint32_t session_key =
- KeyFromPair(primary_connection_handle, session_id);
+ if (connection != NULL) {
+ std::list<protocol_handler::ServiceType> removed_services_list;
+ uint8_t session_id = connection->RemoveSecondaryServices(secondary_connection_handle, removed_services_list);
- sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
- if (connection_handler_observer_valid_ && connection_handler_observer_) {
- connection_handler_observer_->OnSecondaryTransportEndedCallback(
- session_key);
+ if (session_id == 0) {
+ // The secondary services have already been removed from the primary connection, so we
+ // find the session associated with this secondary transport in the SessionConnectionMap
+ session_id = GetSessionIdFromSecondaryTransport(secondary_connection_handle);
+ }
+
+ if (session_id != 0) {
+
+ {
+ sync_primitives::AutoReadLock read_lock(connection_handler_observer_lock_);
+ if (connection_handler_observer_valid_ && connection_handler_observer_) {
+ const uint32_t session_key =
+ KeyFromPair(primary_connection_handle, session_id);
+
+ // Walk the returned list of services and call the ServiceEnded callback for each
+ std::list<protocol_handler::ServiceType>::const_iterator it = removed_services_list.begin();
+ for ( ; removed_services_list.end() != it; ++it) {
+ connection_handler_observer_->OnServiceEndedCallback(
+ session_key, *it, CloseSessionReason::kCommon);
+ }
+
+ connection_handler_observer_->OnSecondaryTransportEndedCallback(
+ session_key);
+ }
+ }
+
+ // Clear the secondary connection from the Session/Connection map entry associated with this session
+ SetSecondaryTransportID(session_id, 0);
+ }
}
}
@@ -902,8 +941,9 @@ SessionTransports ConnectionHandlerImpl::SetSecondaryTransportID(
st = it->second;
// The only time we overwrite an existing entry in the map is if the new secondary transport ID
- // is 0xFFFFFFFF, which effectively DISABLES the secondary transport feature for the session
- if (st.secondary_transport != 0 && secondary_transport_id != 0xFFFFFFFF) {
+ // is 0xFFFFFFFF, which effectively DISABLES the secondary transport feature for the session,
+ // or if the new secondary transport ID is 0, which means a secondary transport has shut down
+ if (st.secondary_transport != 0 && secondary_transport_id != 0xFFFFFFFF && secondary_transport_id != 0) {
LOG4CXX_WARN(logger_, "SetSecondaryTransportID: session ID " << static_cast<int>(session_id) <<
" already has a secondary connection " << static_cast<int>(st.secondary_transport) <<
" in the Session/Connection map");
@@ -931,6 +971,25 @@ SessionTransports ConnectionHandlerImpl::GetSessionTransports(uint8_t session_id
return st;
}
+uint8_t ConnectionHandlerImpl::GetSessionIdFromSecondaryTransport(
+ transport_manager::ConnectionUID secondary_transport_id) {
+ NonConstDataAccessor<SessionConnectionMap> session_connection_map_accessor = session_connection_map();
+ SessionConnectionMap& session_connection_map = session_connection_map_accessor.GetData();
+ SessionConnectionMap::iterator it = session_connection_map.begin();
+ for ( ; session_connection_map.end() != it ; it++) {
+ SessionTransports st = it->second;
+ if (st.secondary_transport == secondary_transport_id) {
+ return it->first;
+ }
+ }
+
+ LOG4CXX_ERROR(logger_, "Could not find secondary transport ID " <<
+ static_cast<int>(secondary_transport_id) <<
+ " in the Session/Connection map");
+ return 0;
+}
+
+
struct CompareMAC {
explicit CompareMAC(const std::string& mac) : mac_(mac) {}
bool operator()(const DeviceMap::value_type& device) {
@@ -1406,6 +1465,11 @@ void ConnectionHandlerImpl::OnConnectionEnded(
}
ending_connection_ = NULL;
}
+
+ ConnectionHandle primary_connection_handle = connection->primary_connection_handle();
+ if (primary_connection_handle != 0) {
+ OnSecondaryTransportEnded(primary_connection_handle, connection_id);
+ }
}
void ConnectionHandlerImpl::BindProtocolVersionWithSession(
diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h
index c39949d12c..336dfe89bf 100644
--- a/src/components/include/connection_handler/connection_handler.h
+++ b/src/components/include/connection_handler/connection_handler.h
@@ -273,13 +273,13 @@ class ConnectionHandler {
const uint8_t session_id) = 0;
/**
- * \brief Called when secondary transport with given session ID is removed
+ * \brief Called when secondary transport shuts down
* \param primary_connection_handle Identifier of primary connection
- * \param sessionid session ID taken from Register Secondary Transport frame
+ * \param secondary_connection_handle Identifier of secondary connection transport
**/
virtual void OnSecondaryTransportEnded(
const transport_manager::ConnectionUID primary_connection_handle,
- const uint8_t session_id) = 0;
+ const transport_manager::ConnectionUID secondary_connection_handle) = 0;
protected:
/**