summaryrefslogtreecommitdiff
path: root/src/components/transport_manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/transport_manager')
-rw-r--r--src/components/transport_manager/CMakeLists.txt103
-rw-r--r--src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_connection_factory.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device.h7
-rw-r--r--src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device_scanner.h6
-rw-r--r--src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_socket_connection.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_transport_adapter.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/dnssd_service_browser.h24
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h34
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/tcp_connection_factory.h13
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/tcp_device.h15
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/tcp_socket_connection.h10
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/tcp_transport_adapter.h10
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/client_connection_listener.h4
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/connection.h9
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/device_scanner.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/server_connection_factory.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h26
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h51
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_manager_impl.h23
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/libusb/platform_usb_device.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h20
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/qnx/platform_usb_device.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/qnx/usb_connection.h8
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/qnx/usb_handler.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/usb_aoa_adapter.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/usb_connection_factory.h4
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/usb_control_transfer.h2
-rw-r--r--src/components/transport_manager/include/transport_manager/usb/usb_device_scanner.h7
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc2
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_device.cc7
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc71
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_socket_connection.cc5
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc4
-rw-r--r--src/components/transport_manager/src/tcp/dnssd_service_browser.cc183
-rw-r--r--src/components/transport_manager/src/tcp/tcp_client_listener.cc184
-rw-r--r--src/components/transport_manager/src/tcp/tcp_connection_factory.cc35
-rw-r--r--src/components/transport_manager/src/tcp/tcp_device.cc88
-rw-r--r--src/components/transport_manager/src/tcp/tcp_socket_connection.cc52
-rw-r--r--src/components/transport_manager/src/tcp/tcp_transport_adapter.cc69
-rw-r--r--src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc234
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc209
-rw-r--r--src/components/transport_manager/src/transport_manager_default.cc4
-rw-r--r--src/components/transport_manager/src/transport_manager_impl.cc70
-rw-r--r--src/components/transport_manager/src/usb/libusb/platform_usb_device.cc2
-rw-r--r--src/components/transport_manager/src/usb/libusb/usb_connection.cc3
-rw-r--r--src/components/transport_manager/src/usb/libusb/usb_handler.cc52
-rw-r--r--src/components/transport_manager/src/usb/qnx/platform_usb_device.cc2
-rw-r--r--src/components/transport_manager/src/usb/qnx/usb_connection.cc15
-rw-r--r--src/components/transport_manager/src/usb/qnx/usb_handler.cc2
-rw-r--r--src/components/transport_manager/src/usb/usb_aoa_adapter.cc2
-rw-r--r--src/components/transport_manager/src/usb/usb_connection_factory.cc2
-rw-r--r--src/components/transport_manager/src/usb/usb_device_scanner.cc84
-rw-r--r--src/components/transport_manager/test/CMakeLists.txt85
-rw-r--r--src/components/transport_manager/test/dnssd_service_browser_test.cc122
-rw-r--r--src/components/transport_manager/test/include/mock_application.h80
-rw-r--r--src/components/transport_manager/test/include/mock_connection.h69
-rw-r--r--src/components/transport_manager/test/include/mock_connection_factory.h69
-rw-r--r--src/components/transport_manager/test/include/mock_device.h82
-rw-r--r--src/components/transport_manager/test/include/mock_device_scanner.h76
-rw-r--r--src/components/transport_manager/test/include/mock_transport_adapter.h62
-rw-r--r--src/components/transport_manager/test/include/mock_transport_adapter_listener.h93
-rw-r--r--src/components/transport_manager/test/include/mock_transport_manager_listener.h103
-rw-r--r--src/components/transport_manager/test/include/raw_message_matcher.h75
-rw-r--r--src/components/transport_manager/test/include/transport_manager_mock.h87
-rw-r--r--src/components/transport_manager/test/main.cc37
-rw-r--r--src/components/transport_manager/test/mock_application.cc147
-rw-r--r--src/components/transport_manager/test/mock_connection.cc78
-rw-r--r--src/components/transport_manager/test/mock_connection_factory.cc63
-rw-r--r--src/components/transport_manager/test/mock_device.cc85
-rw-r--r--src/components/transport_manager/test/mock_device_scanner.cc103
-rw-r--r--src/components/transport_manager/test/mock_transport_adapter.cc57
-rw-r--r--src/components/transport_manager/test/raw_message_matcher.cc65
-rw-r--r--src/components/transport_manager/test/tcp_transport_adapter_test.cc459
-rw-r--r--src/components/transport_manager/test/transport_manager_instance_test.cc73
-rw-r--r--src/components/transport_manager/test/transport_manager_test.cc394
77 files changed, 3521 insertions, 822 deletions
diff --git a/src/components/transport_manager/CMakeLists.txt b/src/components/transport_manager/CMakeLists.txt
index 15ecc91619..764f1cdafa 100644
--- a/src/components/transport_manager/CMakeLists.txt
+++ b/src/components/transport_manager/CMakeLists.txt
@@ -1,12 +1,43 @@
+# Copyright (c) 2014, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
set(target TransportManager)
+set(TM_SRC_DIR ${COMPONENTS_DIR}/transport_manager/src)
include_directories (
- ./include
- ../utils/include/
- ../protocol_handler/include
- ../connection_handler/include
- ../config_profile/include
- ../resumption/include
+ include
+ ${COMPONENTS_DIR}/utils/include/
+ ${COMPONENTS_DIR}/protocol_handler/include
+ ${COMPONENTS_DIR}/connection_handler/include
+ ${COMPONENTS_DIR}/config_profile/include
+ ${COMPONENTS_DIR}/resumption/include
${JSONCPP_INCLUDE_DIRECTORY}
${LIBUSB_INCLUDE_DIRECTORY}
${LOG4CXX_INCLUDE_DIRECTORY}
@@ -17,50 +48,50 @@ if (BUILD_BT_SUPPORT)
endif()
set (SOURCES
- ./src/transport_manager_impl.cc
- ./src/transport_manager_default.cc
- ./src/transport_adapter/transport_adapter_listener_impl.cc
- ./src/transport_adapter/transport_adapter_impl.cc
- ./src/tcp/tcp_transport_adapter.cc
- ./src/transport_adapter/threaded_socket_connection.cc
- ./src/tcp/tcp_client_listener.cc
- ./src/tcp/tcp_device.cc
- ./src/tcp/tcp_socket_connection.cc
- ./src/tcp/tcp_connection_factory.cc
+ ${TM_SRC_DIR}/transport_manager_impl.cc
+ ${TM_SRC_DIR}/transport_manager_default.cc
+ ${TM_SRC_DIR}/transport_adapter/transport_adapter_listener_impl.cc
+ ${TM_SRC_DIR}/transport_adapter/transport_adapter_impl.cc
+ ${TM_SRC_DIR}/tcp/tcp_transport_adapter.cc
+ ${TM_SRC_DIR}/transport_adapter/threaded_socket_connection.cc
+ ${TM_SRC_DIR}/tcp/tcp_client_listener.cc
+ ${TM_SRC_DIR}/tcp/tcp_device.cc
+ ${TM_SRC_DIR}/tcp/tcp_socket_connection.cc
+ ${TM_SRC_DIR}/tcp/tcp_connection_factory.cc
)
if (BUILD_AVAHI_SUPPORT)
list (APPEND SOURCES
- ./src/tcp/dnssd_service_browser.cc
+ ${TM_SRC_DIR}/tcp/dnssd_service_browser.cc
)
endif()
if (BUILD_BT_SUPPORT)
list (APPEND SOURCES
- ./src/bluetooth/bluetooth_device_scanner.cc
- ./src/bluetooth/bluetooth_transport_adapter.cc
- ./src/bluetooth/bluetooth_connection_factory.cc
- ./src/bluetooth/bluetooth_socket_connection.cc
- ./src/bluetooth/bluetooth_device.cc
+ ${TM_SRC_DIR}/bluetooth/bluetooth_device_scanner.cc
+ ${TM_SRC_DIR}/bluetooth/bluetooth_transport_adapter.cc
+ ${TM_SRC_DIR}/bluetooth/bluetooth_connection_factory.cc
+ ${TM_SRC_DIR}/bluetooth/bluetooth_socket_connection.cc
+ ${TM_SRC_DIR}/bluetooth/bluetooth_device.cc
)
endif()
if (BUILD_USB_SUPPORT)
list (APPEND SOURCES
- ./src/usb/usb_aoa_adapter.cc
- ./src/usb/usb_connection_factory.cc
- ./src/usb/usb_device_scanner.cc
+ ${TM_SRC_DIR}/usb/usb_aoa_adapter.cc
+ ${TM_SRC_DIR}/usb/usb_connection_factory.cc
+ ${TM_SRC_DIR}/usb/usb_device_scanner.cc
)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
list (APPEND SOURCES
- ./src/usb/libusb/usb_handler.cc
- ./src/usb/libusb/usb_connection.cc
- ./src/usb/libusb/platform_usb_device.cc
+ ${TM_SRC_DIR}/usb/libusb/usb_handler.cc
+ ${TM_SRC_DIR}/usb/libusb/usb_connection.cc
+ ${TM_SRC_DIR}/usb/libusb/platform_usb_device.cc
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
list(APPEND SOURCES
- ./src/usb/qnx/usb_handler.cc
- ./src/usb/qnx/usb_connection.cc
- ./src/usb/qnx/platform_usb_device.cc
+ ${TM_SRC_DIR}/usb/qnx/usb_handler.cc
+ ${TM_SRC_DIR}/usb/qnx/usb_connection.cc
+ ${TM_SRC_DIR}/usb/qnx/platform_usb_device.cc
)
endif()
endif(BUILD_USB_SUPPORT)
@@ -92,4 +123,12 @@ if (BUILD_BT_SUPPORT)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL "QNX")
-endif() \ No newline at end of file
+endif()
+
+add_library("transport_manager" ${SOURCES}
+ ${TRANSPORT_MANAGER_SOURCES}
+)
+
+if(BUILD_TESTS)
+ add_subdirectory(test)
+endif()
diff --git a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_connection_factory.h b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_connection_factory.h
index 48d1f15538..4d1d474377 100644
--- a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_connection_factory.h
+++ b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_connection_factory.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_connection_factory.h
* \brief BluetoothConnectionFactory class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device.h b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device.h
index 4abef3c604..f28147a3b5 100644
--- a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device.h
+++ b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_device.h
* \brief BluetoothDevice class header file.
*
@@ -37,11 +37,6 @@
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_BLUETOOTH_BLUETOOTH_DEVICE_H_
#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <bluetooth/rfcomm.h>
#include <vector>
diff --git a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device_scanner.h b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device_scanner.h
index 0c68c67216..d1bed9b3dc 100644
--- a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device_scanner.h
+++ b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_device_scanner.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_device_scanner.h
* \brief BluetoothDeviceScanner class header file.
*
@@ -46,7 +46,9 @@
#include "transport_manager/transport_adapter/device_scanner.h"
#include "utils/conditional_variable.h"
#include "utils/lock.h"
-#include "utils/threads/thread.h"
+#include "utils/threads/thread_delegate.h"
+
+class Thread;
namespace transport_manager {
namespace transport_adapter {
diff --git a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_socket_connection.h b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_socket_connection.h
index e1606da878..3de77ab529 100644
--- a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_socket_connection.h
+++ b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_socket_connection.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_socket_connection.h
* \brief BluetoothSocketConnection class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_transport_adapter.h b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_transport_adapter.h
index 075b5da55f..69a588fd37 100644
--- a/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_transport_adapter.h
+++ b/src/components/transport_manager/include/transport_manager/bluetooth/bluetooth_transport_adapter.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_transport_adapter.h
* \brief BluetoothAdapter class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/tcp/dnssd_service_browser.h b/src/components/transport_manager/include/transport_manager/tcp/dnssd_service_browser.h
index cd319ca543..079494d035 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/dnssd_service_browser.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/dnssd_service_browser.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file dnssd_service_browser.h
* \brief DnssdServiceBrowser class header file.
*
@@ -36,14 +36,15 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_DNSSD_SERVICE_BROWSER_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_DNSSD_SERVICE_BROWSER_H_
-#include <string>
-#include <vector>
-#include <pthread.h>
#include <avahi-client/client.h>
#include <avahi-client/lookup.h>
#include <avahi-common/error.h>
#include <avahi-common/thread-watch.h>
+#include <string>
+#include <vector>
+
+#include "utils/lock.h"
#include "transport_manager/transport_adapter/device_scanner.h"
#include "transport_manager/transport_adapter/transport_adapter.h"
@@ -74,13 +75,15 @@ class DnssdServiceBrowser : public DeviceScanner {
*
* @param controller Pointer to the device adapter controller.
*/
- DnssdServiceBrowser(class TransportAdapterController* controller);
+ explicit DnssdServiceBrowser(class TransportAdapterController* controller);
virtual ~DnssdServiceBrowser();
+
protected:
virtual TransportAdapter::Error Init();
virtual TransportAdapter::Error Scan();
virtual void Terminate();
virtual bool IsInitialised() const;
+
private:
TransportAdapter::Error CreateAvahiClientAndBrowser();
void AddService(AvahiIfIndex interface, AvahiProtocol protocol,
@@ -121,13 +124,12 @@ class DnssdServiceBrowser : public DeviceScanner {
typedef std::vector<DnssdServiceRecord> ServiceRecords;
ServiceRecords service_records_;
- pthread_mutex_t mutex_;
+ sync_primitives::Lock mutex_;
bool initialised_;
-}
-;
+};
-} // namespace
-} // namespace
+} // namespace transport_adapter
+} // namespace transport_manager
-#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_DNSSD_SERVICE_BROWSER
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_DNSSD_SERVICE_BROWSER_H_
diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h
index 12eab5a1b5..d5a24f07eb 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_client_listener.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file tcp_client_listener.h
* \brief TcpClientListener class header file.
*
@@ -36,10 +36,10 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_CLIENT_LISTENER_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_CLIENT_LISTENER_H_
+#include "utils/threads/thread_delegate.h"
#include "transport_manager/transport_adapter/client_connection_listener.h"
-#include "utils/threads/thread_delegate.h"
-#include "utils/threads/thread.h"
+class Thread;
namespace transport_manager {
namespace transport_adapter {
@@ -49,8 +49,7 @@ class TransportAdapterController;
/**
* @brief Listener of device adapter that use TCP transport.
*/
-class TcpClientListener : public ClientConnectionListener,
- public threads::ThreadDelegate {
+class TcpClientListener : public ClientConnectionListener {
public:
/**
* @breaf Constructor.
@@ -64,14 +63,6 @@ class TcpClientListener : public ClientConnectionListener,
bool enable_keepalive);
/**
- * @brief Start TCP client listener thread.
- */
- void threadMain();
-
- bool exitThreadMain();
- protected:
-
- /**
* @brief Destructor.
*/
virtual ~TcpClientListener();
@@ -107,18 +98,29 @@ class TcpClientListener : public ClientConnectionListener,
* @brief Terminate TCP client listener thread.
*/
virtual TransportAdapter::Error StopListening();
+
private:
const uint16_t port_;
const bool enable_keepalive_;
TransportAdapterController* controller_;
- // TODO(Eamakhov): change to threads::Thread usage
threads::Thread* thread_;
int socket_;
- bool thread_started_;
bool thread_stop_requested_;
+
+ void Loop();
+ void StopLoop();
+
+ class ListeningThreadDelegate : public threads::ThreadDelegate {
+ public:
+ explicit ListeningThreadDelegate(TcpClientListener* parent);
+ virtual void threadMain();
+ void exitThreadMain();
+ private:
+ TcpClientListener* parent_;
+ };
};
} // namespace transport_adapter
} // namespace transport_manager
-#endif /* TCP_CLIENT_LISTENER_H_ */
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_CLIENT_LISTENER_H_
diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_connection_factory.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_connection_factory.h
index fba85aa601..7f238e91ec 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/tcp_connection_factory.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_connection_factory.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file tcp_connection_factory.h
* \brief TcpConnectionFactory class header file.
*
@@ -47,14 +47,12 @@ namespace transport_adapter {
*/
class TcpConnectionFactory : public ServerConnectionFactory {
public:
-
/**
* @brief Constructor.
*
* @param controller Pointer to the device adapter controller.
*/
- TcpConnectionFactory(TransportAdapterController* controller);
- protected:
+ explicit TcpConnectionFactory(TransportAdapterController* controller);
/**
* @brief Start TCP connection factory.
@@ -69,8 +67,8 @@ class TcpConnectionFactory : public ServerConnectionFactory {
*
* @return Error information about possible reason of failure.
*/
- virtual TransportAdapter::Error CreateConnection(const DeviceUID& device_uid,
- const ApplicationHandle& app_handle);
+ virtual TransportAdapter::Error CreateConnection(
+ const DeviceUID& device_uid, const ApplicationHandle& app_handle);
/**
* @brief
@@ -89,6 +87,7 @@ class TcpConnectionFactory : public ServerConnectionFactory {
* @brief Destructor.
*/
virtual ~TcpConnectionFactory();
+
private:
TransportAdapterController* controller_;
};
@@ -96,4 +95,4 @@ class TcpConnectionFactory : public ServerConnectionFactory {
} // namespace transport_adapter
} // namespace transport_manager
-#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_CONNECTION_FACTORY_H_
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_CONNECTION_FACTORY_H_
diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h
index 08821ab3c4..45bcc405d7 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file tcp_device.h
* \brief TcpDevice class header file.
*
@@ -36,9 +36,6 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_DEVICE_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_DEVICE_H_
-#include "transport_manager/transport_adapter/device.h"
-
-#include <map>
#include <memory.h>
#include <signal.h>
#include <errno.h>
@@ -47,6 +44,12 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <map>
+#include <string>
+
+#include "utils/lock.h"
+#include "transport_manager/transport_adapter/device.h"
+
namespace transport_manager {
namespace transport_adapter {
@@ -136,7 +139,7 @@ class TcpDevice : public Device {
uint16_t port;
};
std::map<ApplicationHandle, Application> applications_;
- mutable pthread_mutex_t applications_mutex_;
+ mutable sync_primitives::Lock applications_mutex_;
const in_addr_t in_addr_;
const std::string name_;
ApplicationHandle last_handle_;
@@ -145,4 +148,4 @@ class TcpDevice : public Device {
} // namespace transport_adapter
} // namespace transport_manager
-#endif /* TCP_DEVICE_H_ */
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_DEVICE_H_
diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_socket_connection.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_socket_connection.h
index 8fe7b8e837..432a0aa760 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/tcp_socket_connection.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_socket_connection.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file tcp_socket_connection.h
* \brief TcpSocketConnection class header file.
*
@@ -53,7 +53,6 @@ class TransportAdapterController;
*/
class TcpSocketConnection : public ThreadedSocketConnection {
public:
-
/**
* @brief Constructor.
*
@@ -69,8 +68,8 @@ class TcpSocketConnection : public ThreadedSocketConnection {
* @brief Destructor.
*/
virtual ~TcpSocketConnection();
- protected:
+ protected:
/**
* @brief
*/
@@ -82,7 +81,6 @@ class TcpSocketConnection : public ThreadedSocketConnection {
*/
class TcpServerOiginatedSocketConnection : public ThreadedSocketConnection {
public:
-
/**
* @brief Constructor.
*
@@ -98,8 +96,8 @@ class TcpServerOiginatedSocketConnection : public ThreadedSocketConnection {
* @brief Destructor.
*/
virtual ~TcpServerOiginatedSocketConnection();
- protected:
+ protected:
/**
* @brief
*/
@@ -109,4 +107,4 @@ class TcpServerOiginatedSocketConnection : public ThreadedSocketConnection {
} // namespace transport_adapter
} // namespace transport_manager
-#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_SOCKET_CONNECTION_H_
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_SOCKET_CONNECTION_H_
diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_transport_adapter.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_transport_adapter.h
index 1319c40eeb..5c1582230a 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/tcp_transport_adapter.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_transport_adapter.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file tcp_transport_adapter.h
* \brief TcpTransportAdapter class header file.
*
@@ -33,8 +33,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_ADAPTER_H_
-#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_ADAPTER_H_
+#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_TRANSPORT_ADAPTER_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_TRANSPORT_ADAPTER_H_
#include "transport_manager/transport_adapter/transport_adapter_impl.h"
@@ -55,8 +55,8 @@ class TcpTransportAdapter : public TransportAdapterImpl {
* @brief Destructor.
*/
virtual ~TcpTransportAdapter();
- protected:
+ protected:
/**
* @brief Return type of device.
*
@@ -80,4 +80,4 @@ class TcpTransportAdapter : public TransportAdapterImpl {
} // namespace transport_adapter
} // namespace transport_manager
-#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_ADAPTER
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_TRANSPORT_ADAPTER_H_
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/client_connection_listener.h b/src/components/transport_manager/include/transport_manager/transport_adapter/client_connection_listener.h
index 41658fb45f..018dd46810 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/client_connection_listener.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/client_connection_listener.h
@@ -1,6 +1,4 @@
-/**
- * \file client_connection_listener.h
- * \brief ClientConnectionListener class header file.
+/*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
*
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h b/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h
index 094cb51921..e3f0b3d1d7 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/connection.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file connection.h
* \brief Connection class header.
* Copyright (c) 2013, Ford Motor Company
@@ -39,7 +39,6 @@
#include "transport_manager/transport_adapter/transport_adapter.h"
namespace transport_manager {
-
namespace transport_adapter {
/**
@@ -48,10 +47,6 @@ namespace transport_adapter {
class Connection {
public:
/**
- * @brief Constructor.
- */
- Connection() {}
- /**
* @brief Destructor.
**/
virtual ~Connection() {}
@@ -71,6 +66,8 @@ class Connection {
virtual TransportAdapter::Error Disconnect() = 0;
};
+typedef utils::SharedPtr<Connection> ConnectionSPtr;
+
} // namespace transport_adapter
} // namespace transport_manager
#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_ADAPTER_CONNECTION_H_
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/device_scanner.h b/src/components/transport_manager/include/transport_manager/transport_adapter/device_scanner.h
index 5b09a726e5..36759a9385 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/device_scanner.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/device_scanner.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file device_scanner.h
* \brief DeviceScanner class header file.
* Copyright (c) 2013, Ford Motor Company
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/server_connection_factory.h b/src/components/transport_manager/include/transport_manager/transport_adapter/server_connection_factory.h
index d944594d88..19c37aa6a6 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/server_connection_factory.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/server_connection_factory.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file server_connection_factory.h
* \brief ServerConnectionFactory class header file.
* Copyright (c) 2013, Ford Motor Company
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h
index 851f250a88..5e0caa22e8 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/threaded_socket_connection.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file threaded_socket_connection.h
* \brief Header for classes responsible for communication over sockets.
* Copyright (c) 2013, Ford Motor Company
@@ -41,10 +41,12 @@
#include "transport_manager/transport_adapter/connection.h"
#include "protocol/common.h"
#include "utils/threads/thread_delegate.h"
-#include "utils/threads/thread.h"
+#include "utils/lock.h"
using ::transport_manager::transport_adapter::Connection;
+class Thread;
+
namespace transport_manager {
namespace transport_adapter {
@@ -53,10 +55,8 @@ class TransportAdapterController;
/**
* @brief Class responsible for communication over sockets.
*/
-class ThreadedSocketConnection : public Connection,
- public threads::ThreadDelegate {
+class ThreadedSocketConnection : public Connection {
public:
-
/**
* @brief Send data frame.
*
@@ -86,8 +86,8 @@ class ThreadedSocketConnection : public Connection,
void set_socket(int socket) {
socket_ = socket;
}
- protected:
+ protected:
/**
* @brief Constructor.
*
@@ -104,7 +104,6 @@ class ThreadedSocketConnection : public Connection,
*/
virtual ~ThreadedSocketConnection();
-
virtual bool Establish(ConnectError** error) = 0;
/**
@@ -129,11 +128,18 @@ class ThreadedSocketConnection : public Connection,
}
private:
+ class SocketConnectionDelegate : public threads::ThreadDelegate {
+ public:
+ explicit SocketConnectionDelegate(ThreadedSocketConnection* connection);
+ void threadMain() OVERRIDE;
+ void exitThreadMain() OVERRIDE;
+ private:
+ ThreadedSocketConnection* connection_;
+ };
int read_fd_;
int write_fd_;
void threadMain();
- bool exitThreadMain();
void Transmit();
void Finalize();
TransportAdapter::Error Notify() const;
@@ -147,7 +153,7 @@ class ThreadedSocketConnection : public Connection,
**/
typedef std::queue<protocol_handler::RawMessagePtr> FrameQueue;
FrameQueue frames_to_send_;
- mutable pthread_mutex_t frames_to_send_mutex_;
+ mutable sync_primitives::Lock frames_to_send_mutex_;
int socket_;
bool terminate_flag_;
@@ -159,4 +165,4 @@ class ThreadedSocketConnection : public Connection,
} // namespace transport_adapter
} // namespace transport_manager
-#endif //SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_transport_adapter_SOCKET_COMMUNICATION
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_ADAPTER_THREADED_SOCKET_CONNECTION_H_
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h
index aaa1139b9f..f0148ad1af 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h
@@ -95,7 +95,7 @@ class TransportAdapterController {
* @param device_handle Device unique identifier.
* @param app_handle Handle of application.
*/
- virtual void ConnectionCreated(Connection* connection,
+ virtual void ConnectionCreated(ConnectionSPtr connection,
const DeviceUID& device_handle,
const ApplicationHandle& app_handle) = 0;
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h
index 2c27e0d20f..5306a7af5a 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h
@@ -39,6 +39,8 @@
#include <memory>
#include <string>
+#include "utils/lock.h"
+#include "utils/rwlock.h"
#include "transport_manager/transport_adapter/transport_adapter.h"
#include "transport_manager/transport_adapter/transport_adapter_controller.h"
#include "transport_manager/transport_adapter/connection.h"
@@ -99,6 +101,12 @@ class TransportAdapterImpl : public TransportAdapter,
virtual TransportAdapter::Error Init();
/**
+ * @brief Stops device adapter
+ * Called from transport manager to stop device adapter
+ */
+ virtual void Terminate();
+
+ /**
* @brief Add listener to the container(list) of device adapter listeners.
*
* @param listener Pointer to the device adapter listener.
@@ -264,7 +272,7 @@ class TransportAdapterImpl : public TransportAdapter,
* @param device_handle Device unique identifier.
* @param app_handle Handle of application.
*/
- virtual void ConnectionCreated(Connection* connection,
+ virtual void ConnectionCreated(ConnectionSPtr connection,
const DeviceUID& device_handle,
const ApplicationHandle& app_handle);
@@ -405,9 +413,7 @@ class TransportAdapterImpl : public TransportAdapter,
virtual TMMetricObserver* GetTimeMetricObserver();
#endif // TIME_TESTER
-
protected:
-
/**
* @brief Store adapter state where applicable
*/
@@ -425,6 +431,13 @@ class TransportAdapterImpl : public TransportAdapter,
*/
virtual bool ToBeAutoConnected(DeviceSptr device) const;
+
+ /**
+ * @brief Returns true if \a device is to be disconnected automatically when
+ * all applications will be closed
+ */
+ virtual bool ToBeAutoDisconnected(DeviceSptr device) const;
+
/**
* @brief Find connection that has state - ESTABLISHED.
*
@@ -433,7 +446,7 @@ class TransportAdapterImpl : public TransportAdapter,
*
* @return pointer to the connection.
*/
- Connection* FindEstablishedConnection(const DeviceUID& device_handle,
+ ConnectionSPtr FindEstablishedConnection(const DeviceUID& device_handle,
const ApplicationHandle& app_handle) const;
private:
@@ -451,6 +464,15 @@ class TransportAdapterImpl : public TransportAdapter,
void RemoveDevice(const DeviceUID& device_handle);
/**
+ * Checks whether application is single active on device
+ * @param device_uid
+ * @param app_uid
+ * @return true if this application is the single application on device
+ */
+ bool IsSingleApplication(const DeviceUID& device_uid,
+ const ApplicationHandle& app_uid);
+
+ /**
* @brief Listener for device adapter notifications.
**/
TransportAdapterListenerList listeners_;
@@ -464,7 +486,7 @@ class TransportAdapterImpl : public TransportAdapter,
* @brief Structure that holds information about connection.
*/
struct ConnectionInfo {
- Connection* connection;
+ ConnectionSPtr connection;
DeviceUID device_id;
ApplicationHandle app_handle;
enum {
@@ -493,7 +515,7 @@ class TransportAdapterImpl : public TransportAdapter,
/**
* @brief Mutex restricting access to device map.
**/
- mutable pthread_mutex_t devices_mutex_;
+ mutable sync_primitives::Lock devices_mutex_;
/**
* @brief Container(map) of connections.
@@ -503,9 +525,16 @@ class TransportAdapterImpl : public TransportAdapter,
/**
* @brief Mutex restricting access to connections map.
**/
- mutable pthread_mutex_t connections_mutex_;
+ mutable sync_primitives::RWLock connections_lock_;
protected:
+#ifdef TIME_TESTER
+ /**
+ * @brief Pointer to time metric observer
+ */
+ TMMetricObserver* metric_observer_;
+#endif // TIME_TESTER
+
/**
* @brief Pointer to the device scanner.
*/
@@ -520,14 +549,8 @@ class TransportAdapterImpl : public TransportAdapter,
* @brief Pointer to the factory of connections initiated from client.
*/
ClientConnectionListener* client_connection_listener_;
-
-#ifdef TIME_TESTER
- /**
- * @brief Pointer to time metric observer
- */
- TMMetricObserver* metric_observer_;
-#endif // TIME_TESTER
};
+
} // namespace transport_adapter
} // namespace transport_manager
diff --git a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h
index 62fdb3fa2e..4c38716f3f 100644
--- a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h
+++ b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h
@@ -33,15 +33,12 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_IMPL_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_IMPL_H_
-#include <pthread.h>
-
#include <queue>
#include <map>
#include <list>
#include <algorithm>
#include "utils/timer_thread.h"
-#include "utils/rwlock.h"
#include "transport_manager/transport_manager.h"
#include "transport_manager/transport_manager_listener.h"
@@ -104,6 +101,12 @@ class TransportManagerImpl : public TransportManager,
virtual int Init();
/**
+ * Reinitializes transport manager
+ * @return Error code
+ */
+ virtual int Reinit();
+
+ /**
* @brief Start scanning for new devices.
*
* @return Code error.
@@ -250,12 +253,6 @@ class TransportManagerImpl : public TransportManager,
**/
void PostEvent(const TransportAdapterEvent& event);
- /**
- * @brief flag that indicates that thread is active
- * if it is false then threads exist main loop
- **/
- volatile bool all_thread_active_;
-
typedef std::list<TransportManagerListener*> TransportManagerListenerList;
/**
* @brief listener that would be called when TM's event happened.
@@ -263,11 +260,6 @@ class TransportManagerImpl : public TransportManager,
TransportManagerListenerList transport_manager_listener_;
/**
- * @brief Condition variable to wake up event
- **/
- pthread_cond_t device_listener_thread_wakeup_;
-
- /**
* @brief Flag that TM is initialized
*/
bool is_initialized_;
@@ -352,6 +344,9 @@ class TransportManagerImpl : public TransportManager,
unsigned char** frame);
void OnDeviceListUpdated(TransportAdapter* ta);
+ void DisconnectAllDevices();
+ void TerminateAllAdapters();
+ int InitAllAdapters();
static Connection convert(const ConnectionInternal& p);
};
// class ;
diff --git a/src/components/transport_manager/include/transport_manager/usb/libusb/platform_usb_device.h b/src/components/transport_manager/include/transport_manager/usb/libusb/platform_usb_device.h
index d1f485c9d5..b90c504a4b 100644
--- a/src/components/transport_manager/include/transport_manager/usb/libusb/platform_usb_device.h
+++ b/src/components/transport_manager/include/transport_manager/usb/libusb/platform_usb_device.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file platform_usb_device.h
* \brief libusb PlatformUsbDevice class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h
index fc6af46a47..7c1fbd4551 100644
--- a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h
+++ b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h
@@ -49,7 +49,7 @@ class UsbConnection : public Connection {
UsbConnection(const DeviceUID& device_uid,
const ApplicationHandle& app_handle,
TransportAdapterController* controller,
- const UsbHandlerSptr& usb_handler, PlatformUsbDevice* device);
+ const UsbHandlerSptr usb_handler, PlatformUsbDevice* device);
bool Init();
virtual ~UsbConnection();
diff --git a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h
index fd6e77013a..215b66f6e3 100644
--- a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h
+++ b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_handler.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_handler.h
* \brief libusb USB handler class header file.
*
@@ -36,16 +36,17 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_USB_LIBUSB_USB_HANDLER_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_USB_LIBUSB_USB_HANDLER_H_
-#include <pthread.h>
-
#include <libusb/libusb.h>
#include "transport_manager/transport_adapter/transport_adapter.h"
#include "transport_manager/usb/usb_control_transfer.h"
#include "transport_manager/usb/libusb/platform_usb_device.h"
-namespace transport_manager {
+#include "utils/threads/thread.h"
+
+class Thread;
+namespace transport_manager {
namespace transport_adapter {
class UsbHandler {
@@ -71,9 +72,16 @@ class UsbHandler {
friend void UsbTransferSequenceCallback(libusb_transfer* transfer);
private:
+ class UsbHandlerDelegate: public threads::ThreadDelegate {
+ public:
+ explicit UsbHandlerDelegate(UsbHandler* handler);
+ void threadMain() OVERRIDE;
+ private:
+ UsbHandler* handler_;
+ };
+
bool shutdown_requested_;
- // TODO(Eamakhov): change to threads::Thread usage
- pthread_t thread_;
+ threads::Thread* thread_;
friend class UsbDeviceListener;
std::list<class UsbDeviceListener*> usb_device_listeners_;
diff --git a/src/components/transport_manager/include/transport_manager/usb/qnx/platform_usb_device.h b/src/components/transport_manager/include/transport_manager/usb/qnx/platform_usb_device.h
index 939a8fcb3c..ab35f862c6 100644
--- a/src/components/transport_manager/include/transport_manager/usb/qnx/platform_usb_device.h
+++ b/src/components/transport_manager/include/transport_manager/usb/qnx/platform_usb_device.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file platform_usb_device.h
* \brief QNX PlatfromUsbDevice class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/usb/qnx/usb_connection.h b/src/components/transport_manager/include/transport_manager/usb/qnx/usb_connection.h
index 3a0d2f8a26..d55c887bd1 100644
--- a/src/components/transport_manager/include/transport_manager/usb/qnx/usb_connection.h
+++ b/src/components/transport_manager/include/transport_manager/usb/qnx/usb_connection.h
@@ -36,7 +36,7 @@
#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_USB_QNX_USB_CONNECTION_H_
#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_USB_QNX_USB_CONNECTION_H_
-#include <pthread.h>
+#include "utils/lock.h"
#include "transport_manager/transport_adapter/transport_adapter_controller.h"
#include "transport_manager/transport_adapter/connection.h"
@@ -51,7 +51,7 @@ class UsbConnection : public Connection {
UsbConnection(const DeviceUID& device_uid,
const ApplicationHandle& app_handle,
TransportAdapterController* controller,
- const UsbHandlerSptr& libusb_handler,
+ const UsbHandlerSptr libusb_handler,
PlatformUsbDevice* device);
bool Init();
@@ -82,13 +82,13 @@ class UsbConnection : public Connection {
unsigned char* in_buffer_;
void* out_buffer_;
-
+
usbd_urb* in_urb_;
usbd_urb* out_urb_;
std::list<protocol_handler::RawMessagePtr> out_messages_;
::protocol_handler::RawMessagePtr current_out_message_;
- pthread_mutex_t out_messages_mutex_;
+ sync_primitives::Lock out_messages_mutex_;
size_t bytes_sent_;
bool disconnecting_;
bool pending_in_transfer_;
diff --git a/src/components/transport_manager/include/transport_manager/usb/qnx/usb_handler.h b/src/components/transport_manager/include/transport_manager/usb/qnx/usb_handler.h
index 26b00087ff..c33e0f2361 100644
--- a/src/components/transport_manager/include/transport_manager/usb/qnx/usb_handler.h
+++ b/src/components/transport_manager/include/transport_manager/usb/qnx/usb_handler.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_handler.h
* \brief QNX USB handler class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/usb/usb_aoa_adapter.h b/src/components/transport_manager/include/transport_manager/usb/usb_aoa_adapter.h
index 55fb028ef7..b0d8c1e453 100644
--- a/src/components/transport_manager/include/transport_manager/usb/usb_aoa_adapter.h
+++ b/src/components/transport_manager/include/transport_manager/usb/usb_aoa_adapter.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_aoa_adapter.h
* \brief UsbAoaAdapter class header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/usb/usb_connection_factory.h b/src/components/transport_manager/include/transport_manager/usb/usb_connection_factory.h
index ed0fda91ee..ebd25bd37b 100644
--- a/src/components/transport_manager/include/transport_manager/usb/usb_connection_factory.h
+++ b/src/components/transport_manager/include/transport_manager/usb/usb_connection_factory.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_connection_factory.h
* \brief UsbConnectionFactory class header file.
*
@@ -46,7 +46,7 @@ namespace transport_adapter {
class UsbConnectionFactory : public ServerConnectionFactory {
public:
UsbConnectionFactory(TransportAdapterController* controller);
- void SetUsbHandler(const UsbHandlerSptr& usb_handler);
+ void SetUsbHandler(const UsbHandlerSptr usb_handler);
protected:
virtual TransportAdapter::Error Init();
diff --git a/src/components/transport_manager/include/transport_manager/usb/usb_control_transfer.h b/src/components/transport_manager/include/transport_manager/usb/usb_control_transfer.h
index 8c4f8a9d4c..c701a86e0a 100644
--- a/src/components/transport_manager/include/transport_manager/usb/usb_control_transfer.h
+++ b/src/components/transport_manager/include/transport_manager/usb/usb_control_transfer.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file aoa_common.h
* \brief Google AOA protocol header file.
*
diff --git a/src/components/transport_manager/include/transport_manager/usb/usb_device_scanner.h b/src/components/transport_manager/include/transport_manager/usb/usb_device_scanner.h
index 0937222155..9efb7ba58d 100644
--- a/src/components/transport_manager/include/transport_manager/usb/usb_device_scanner.h
+++ b/src/components/transport_manager/include/transport_manager/usb/usb_device_scanner.h
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_device_scanner.h
* \brief UsbDeviceScanner class header file.
*
@@ -38,8 +38,7 @@
#include <list>
-#include <pthread.h>
-
+#include "utils/lock.h"
#include "transport_manager/transport_adapter/device_scanner.h"
#include "transport_manager/usb/common.h"
@@ -69,7 +68,7 @@ class UsbDeviceScanner : public DeviceScanner, public UsbDeviceListener {
typedef std::list<PlatformUsbDevice*> Devices;
Devices devices_;
- pthread_mutex_t devices_mutex_;
+ sync_primitives::Lock devices_mutex_;
};
} // namespace
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc b/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc
index 421104422b..02224baf4e 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_connection_factory.cc
* \brief BluetoothConnectionFactory class source file.
*
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_device.cc b/src/components/transport_manager/src/bluetooth/bluetooth_device.cc
index 1a47f6c7ff..c8061a7ac5 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_device.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_device.cc
@@ -33,6 +33,13 @@
#include "transport_manager/bluetooth/bluetooth_device.h"
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+#include <bluetooth/rfcomm.h>
+
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc b/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc
index 547dc463b2..29be3cd219 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_device_scanner.cc
* \brief BluetoothDeviceScanner class header file.
*
@@ -52,6 +52,7 @@
#include "transport_manager/bluetooth/bluetooth_device.h"
#include "utils/logger.h"
+#include "utils/threads/thread.h"
namespace transport_manager {
namespace transport_adapter {
@@ -117,44 +118,45 @@ BluetoothDeviceScanner::BluetoothDeviceScanner(
};
sdp_uuid128_create(&smart_device_link_service_uuid_,
smart_device_link_service_uuid_data);
- thread_ = threads::CreateThread("BT Device Scaner", new BluetoothDeviceScannerDelegate(this));
+ thread_ = threads::CreateThread("BT Device Scaner",
+ new BluetoothDeviceScannerDelegate(this));
}
BluetoothDeviceScanner::~BluetoothDeviceScanner() {
+ thread_->join();
+ delete thread_->delegate();
+ threads::DeleteThread(thread_);
}
bool BluetoothDeviceScanner::IsInitialised() const {
- return thread_->is_running();
+ return thread_ && thread_->is_running();
}
void BluetoothDeviceScanner::UpdateTotalDeviceList() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
DeviceVector devices;
devices.insert(devices.end(), paired_devices_with_sdl_.begin(),
paired_devices_with_sdl_.end());
devices.insert(devices.end(), found_devices_with_sdl_.begin(),
found_devices_with_sdl_.end());
controller_->SearchDeviceDone(devices);
- LOG4CXX_TRACE(logger_, "exit");
}
void BluetoothDeviceScanner::DoInquiry() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
const int device_id = hci_get_route(0);
if (device_id < 0) {
LOG4CXX_INFO(logger_, "HCI device is not available");
shutdown_requested_ = true;
controller_->SearchDeviceFailed(SearchDeviceError());
- LOG4CXX_TRACE(logger_, "exit. Condition: device_id < 0");
return;
}
int device_handle = hci_open_dev(device_id);
if (device_handle < 0) {
controller_->SearchDeviceFailed(SearchDeviceError());
- LOG4CXX_TRACE(logger_, "exit. Condition: device_handle < 0");
return;
}
@@ -195,6 +197,7 @@ void BluetoothDeviceScanner::DoInquiry() {
&found_devices_with_sdl_);
}
UpdateTotalDeviceList();
+ controller_->FindNewApplicationsRequest();
close(device_handle);
delete[] inquiry_info_list;
@@ -203,8 +206,6 @@ void BluetoothDeviceScanner::DoInquiry() {
LOG4CXX_DEBUG(logger_, "number_of_devices < 0");
controller_->SearchDeviceFailed(SearchDeviceError());
}
-
- LOG4CXX_TRACE(logger_, "exit");
}
void BluetoothDeviceScanner::CheckSDLServiceOnDevices(
@@ -371,7 +372,7 @@ bool BluetoothDeviceScanner::DiscoverSmartDeviceLinkRFCOMMChannels(
}
void BluetoothDeviceScanner::Thread() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
ready_ = true;
if (auto_repeat_search_) {
while (!shutdown_requested_) {
@@ -394,12 +395,10 @@ void BluetoothDeviceScanner::Thread() {
device_scan_requested_ = false;
}
}
-
- LOG4CXX_TRACE(logger_, "exit");
}
void BluetoothDeviceScanner::TimedWaitForDeviceScanRequest() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if (auto_repeat_pause_sec_ == 0) {
LOG4CXX_TRACE(logger_, "exit. Condition: auto_repeat_pause_sec_ == 0");
@@ -417,26 +416,22 @@ void BluetoothDeviceScanner::TimedWaitForDeviceScanRequest() {
}
}
}
-
- LOG4CXX_TRACE(logger_, "exit");
}
TransportAdapter::Error BluetoothDeviceScanner::Init() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if(!thread_->start()) {
LOG4CXX_ERROR(logger_, "Bluetooth device scanner thread start failed");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter:Fail");
return TransportAdapter::FAIL;
}
LOG4CXX_INFO(logger_, "Bluetooth device scanner thread started");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter:OK");
return TransportAdapter::OK;
}
void BluetoothDeviceScanner::Terminate() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
shutdown_requested_ = true;
- if (thread_->is_running()) {
+ if (thread_) {
{
sync_primitives::AutoLock auto_lock(device_scan_requested_lock_);
device_scan_requested_ = false;
@@ -445,36 +440,30 @@ void BluetoothDeviceScanner::Terminate() {
LOG4CXX_INFO(logger_,
"Waiting for bluetooth device scanner thread termination");
thread_->stop();
- LOG4CXX_INFO(logger_, "PASA Bluetooth device scanner thread joined");
+ LOG4CXX_INFO(logger_, "Bluetooth device scanner thread stopped");
}
- LOG4CXX_TRACE(logger_, "exit");
}
TransportAdapter::Error BluetoothDeviceScanner::Scan() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if ((!IsInitialised()) || shutdown_requested_) {
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::BAD_STATE");
+ LOG4CXX_WARN(logger_, "BAD_STATE");
return TransportAdapter::BAD_STATE;
}
if (auto_repeat_pause_sec_ == 0) {
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
return TransportAdapter::OK;
}
TransportAdapter::Error ret = TransportAdapter::OK;
- {
- sync_primitives::AutoLock auto_lock(device_scan_requested_lock_);
- if (false == device_scan_requested_) {
- LOG4CXX_INFO(logger_, "Requesting device Scan");
- device_scan_requested_ = true;
- device_scan_requested_cv_.NotifyOne();
- } else {
- ret = TransportAdapter::BAD_STATE;
- LOG4CXX_INFO(logger_, "Device Scan is currently in progress");
- }
+ sync_primitives::AutoLock auto_lock(device_scan_requested_lock_);
+ if (!device_scan_requested_) {
+ LOG4CXX_TRACE(logger_, "Requesting device Scan");
+ device_scan_requested_ = true;
+ device_scan_requested_cv_.NotifyOne();
+ } else {
+ ret = TransportAdapter::BAD_STATE;
+ LOG4CXX_WARN(logger_, "BAD_STATE");
}
-
- LOG4CXX_TRACE(logger_, "exit with Error: " << ret);
return ret;
}
@@ -483,12 +472,10 @@ BluetoothDeviceScanner::BluetoothDeviceScannerDelegate::BluetoothDeviceScannerDe
: scanner_(scanner) {
}
-void BluetoothDeviceScanner::BluetoothDeviceScannerDelegate::threadMain()
-{
- LOG4CXX_TRACE_ENTER(logger_);
+void BluetoothDeviceScanner::BluetoothDeviceScannerDelegate::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
DCHECK(scanner_);
scanner_->Thread();
- LOG4CXX_TRACE_EXIT(logger_);
}
} // namespace transport_adapter
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_socket_connection.cc b/src/components/transport_manager/src/bluetooth/bluetooth_socket_connection.cc
index ac1ccecfb5..d6f9f26317 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_socket_connection.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_socket_connection.cc
@@ -1,4 +1,4 @@
-/**
+/*
*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
@@ -60,7 +60,8 @@ BluetoothSocketConnection::~BluetoothSocketConnection() {
}
bool BluetoothSocketConnection::Establish(ConnectError** error) {
- LOG4CXX_TRACE(logger_, "enter. (#" << pthread_self() << "), error: " << error);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "error: " << error);
DeviceSptr device = controller()->FindDevice(device_handle());
BluetoothDevice* bluetooth_device =
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc b/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc
index 7d60213b01..4d02e60896 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file bluetooth_transport_adapter.cc
* \brief BluetoothTransportAdapter class source file.
*
@@ -152,7 +152,7 @@ bool BluetoothTransportAdapter::Restore() {
if (result) {
LOG4CXX_TRACE(logger_, "exit with TRUE");
} else {
- LOG4CXX_TRACE(logger_, "exit with FALSE");
+ LOG4CXX_TRACE(logger_, "exit with FALSE");
}
return result;
}
diff --git a/src/components/transport_manager/src/tcp/dnssd_service_browser.cc b/src/components/transport_manager/src/tcp/dnssd_service_browser.cc
index 5580585766..3571ac8156 100644
--- a/src/components/transport_manager/src/tcp/dnssd_service_browser.cc
+++ b/src/components/transport_manager/src/tcp/dnssd_service_browser.cc
@@ -1,4 +1,4 @@
-/**
+/*
*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
@@ -33,37 +33,41 @@
#include <algorithm>
#include <map>
+#include "utils/logger.h"
#include "transport_manager/transport_adapter/transport_adapter_impl.h"
#include "transport_manager/tcp/tcp_device.h"
#include "transport_manager/tcp/dnssd_service_browser.h"
-#include "utils/logger.h"
+
namespace transport_manager {
namespace transport_adapter {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
bool operator==(const DnssdServiceRecord& a, const DnssdServiceRecord& b) {
return a.name == b.name && a.type == b.type && a.interface == b.interface
- && a.protocol == b.protocol && a.domain_name == b.domain_name;
+ && a.protocol == b.protocol && a.domain_name == b.domain_name;
}
void DnssdServiceBrowser::Terminate() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if (0 != avahi_threaded_poll_) {
avahi_threaded_poll_stop(avahi_threaded_poll_);
}
if (0 != avahi_service_browser_) {
avahi_service_browser_free(avahi_service_browser_);
+ avahi_service_browser_ = NULL;
}
if (0 != avahi_client_) {
avahi_client_free(avahi_client_);
+ avahi_client_ = NULL;
}
if (0 != avahi_threaded_poll_) {
avahi_threaded_poll_free(avahi_threaded_poll_);
+ avahi_threaded_poll_ = NULL;
}
- LOG4CXX_TRACE(logger_, "exit");
}
bool DnssdServiceBrowser::IsInitialised() const {
@@ -71,18 +75,16 @@ bool DnssdServiceBrowser::IsInitialised() const {
}
DnssdServiceBrowser::DnssdServiceBrowser(TransportAdapterController* controller)
- : controller_(controller),
- avahi_service_browser_(0),
- avahi_threaded_poll_(0),
- avahi_client_(0),
- service_records_(),
- mutex_(),
- initialised_(false) {
- pthread_mutex_init(&mutex_, 0);
+ : controller_(controller),
+ avahi_service_browser_(0),
+ avahi_threaded_poll_(0),
+ avahi_client_(0),
+ service_records_(),
+ mutex_(),
+ initialised_(false) {
}
DnssdServiceBrowser::~DnssdServiceBrowser() {
- pthread_mutex_destroy(&mutex_);
}
void DnssdServiceBrowser::OnClientConnected() {
@@ -91,7 +93,7 @@ void DnssdServiceBrowser::OnClientConnected() {
}
void DnssdServiceBrowser::OnClientFailure() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
const int avahi_errno = avahi_client_errno(avahi_client_);
if (avahi_errno == AVAHI_ERR_DISCONNECTED) {
LOG4CXX_DEBUG(logger_, "AvahiClient disconnected");
@@ -100,16 +102,16 @@ void DnssdServiceBrowser::OnClientFailure() {
LOG4CXX_ERROR(logger_,
"AvahiClient failure: " << avahi_strerror(avahi_errno));
}
- LOG4CXX_TRACE(logger_, "exit");
}
void AvahiClientCallback(AvahiClient* avahi_client,
AvahiClientState avahi_client_state, void* data) {
- LOG4CXX_TRACE(logger_,
- "enter. avahi_client " << avahi_client << "avahi_client_state " <<
- avahi_client_state << "data " << data);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(
+ logger_,
+ "avahi_client " << avahi_client << ", avahi_client_state " << avahi_client_state << ", data " << data);
DnssdServiceBrowser* dnssd_service_browser =
- static_cast<DnssdServiceBrowser*>(data);
+ static_cast<DnssdServiceBrowser*>(data);
switch (avahi_client_state) {
case AVAHI_CLIENT_S_RUNNING:
@@ -121,10 +123,10 @@ void AvahiClientCallback(AvahiClient* avahi_client,
LOG4CXX_DEBUG(logger_, "avahi_client_state: AVAHI_CLIENT_FAILURE");
break;
default: {
- LOG4CXX_ERROR(logger_, "Unknown avahi_client_state: " << avahi_client_state);
+ LOG4CXX_ERROR(logger_,
+ "Unknown avahi_client_state: " << avahi_client_state);
}
}
- LOG4CXX_TRACE(logger_, "exit");
}
void AvahiServiceBrowserCallback(AvahiServiceBrowser* avahi_service_browser,
@@ -132,21 +134,21 @@ void AvahiServiceBrowserCallback(AvahiServiceBrowser* avahi_service_browser,
AvahiBrowserEvent event, const char* name,
const char* type, const char* domain,
AvahiLookupResultFlags flags, void* data) {
- LOG4CXX_TRACE(logger_, "enter. avahi_service_browser " << avahi_service_browser <<
- " interface " << interface << " protocol " << protocol <<
- " event " << event << " name " << name << " type " << type << " domain " << domain <<
- " flags " << flags << " data " << data);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(
+ logger_,
+ "avahi_service_browser " << avahi_service_browser << " interface " << interface <<
+ " protocol " << protocol << " event " << event << " name " << name <<
+ " type " << type << " domain " << domain << " flags " << flags << " data " << data);
DnssdServiceBrowser* dnssd_service_browser =
- static_cast<DnssdServiceBrowser*>(data);
+ static_cast<DnssdServiceBrowser*>(data);
switch (event) {
case AVAHI_BROWSER_FAILURE:
LOG4CXX_ERROR(
logger_,
- "AvahiServiceBrowser failure: " << avahi_strerror(
- avahi_client_errno(
- avahi_service_browser_get_client(
- avahi_service_browser))));
+ "AvahiServiceBrowser failure: " << avahi_strerror(avahi_client_errno(
+ avahi_service_browser_get_client(avahi_service_browser))));
break;
case AVAHI_BROWSER_NEW:
@@ -163,6 +165,7 @@ void AvahiServiceBrowserCallback(AvahiServiceBrowser* avahi_service_browser,
case AVAHI_BROWSER_ALL_FOR_NOW:
LOG4CXX_DEBUG(logger_, "event: AVAHI_BROWSER_ALL_FOR_NOW");
+ break;
case AVAHI_BROWSER_CACHE_EXHAUSTED:
LOG4CXX_DEBUG(logger_, "event: AVAHI_BROWSER_CACHE_EXHAUSTED");
break;
@@ -171,33 +174,29 @@ void AvahiServiceBrowserCallback(AvahiServiceBrowser* avahi_service_browser,
}
void DnssdServiceBrowser::ServiceResolved(
- const DnssdServiceRecord& service_record) {
- LOG4CXX_TRACE(logger_, "enter");
- pthread_mutex_lock(&mutex_);
+ const DnssdServiceRecord& service_record) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock locker(mutex_);
ServiceRecords::iterator service_record_it = std::find(
- service_records_.begin(), service_records_.end(), service_record);
+ service_records_.begin(), service_records_.end(), service_record);
if (service_record_it != service_records_.end()) {
*service_record_it = service_record;
}
DeviceVector device_vector = PrepareDeviceVector();
controller_->SearchDeviceDone(device_vector);
- pthread_mutex_unlock(&mutex_);
- LOG4CXX_TRACE(logger_, "exit");
}
void DnssdServiceBrowser::ServiceResolveFailed(
- const DnssdServiceRecord& service_record) {
- LOG4CXX_TRACE(logger_, "enter");
- LOG4CXX_ERROR(logger_,
+ const DnssdServiceRecord& service_record) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_,
"AvahiServiceResolver failure for: " << service_record.name);
- pthread_mutex_lock(&mutex_);
+ sync_primitives::AutoLock locker(mutex_);
ServiceRecords::iterator service_record_it = std::find(
- service_records_.begin(), service_records_.end(), service_record);
+ service_records_.begin(), service_records_.end(), service_record);
if (service_record_it != service_records_.end()) {
service_records_.erase(service_record_it);
}
- pthread_mutex_unlock(&mutex_);
- LOG4CXX_TRACE(logger_, "exit");
}
void AvahiServiceResolverCallback(AvahiServiceResolver* avahi_service_resolver,
@@ -209,14 +208,16 @@ void AvahiServiceResolverCallback(AvahiServiceResolver* avahi_service_resolver,
const AvahiAddress* avahi_address,
uint16_t port, AvahiStringList* txt,
AvahiLookupResultFlags flags, void* data) {
- LOG4CXX_TRACE(logger_, "enter. avahi_service_resolver " << avahi_service_resolver <<
- " interface " << interface <<
- " protocol " << protocol << " event " << event << " name " << name << " type " << type <<
- " domain " << domain << " host_name " << host_name <<
- " avahi_address " << avahi_address << " port " << port << " txt " << txt << " flags " <<
- flags << " data " << data);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(
+ logger_,
+ "avahi_service_resolver " << avahi_service_resolver << " interface " << interface <<
+ " protocol " << protocol << " event " << event << " name " << name <<
+ " type " << type << " domain " << domain << " host_name " << host_name <<
+ " avahi_address " << avahi_address << " port " << port <<
+ " txt " << txt << " flags " << flags << " data " << data);
DnssdServiceBrowser* dnssd_service_browser =
- static_cast<DnssdServiceBrowser*>(data);
+ static_cast<DnssdServiceBrowser*>(data);
DnssdServiceRecord service_record;
service_record.interface = interface;
@@ -239,62 +240,60 @@ void AvahiServiceResolverCallback(AvahiServiceResolver* avahi_service_resolver,
}
avahi_service_resolver_free(avahi_service_resolver);
- LOG4CXX_TRACE(logger_, "exit");
}
TransportAdapter::Error DnssdServiceBrowser::CreateAvahiClientAndBrowser() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if (0 != avahi_service_browser_) {
avahi_service_browser_free(avahi_service_browser_);
+ avahi_service_browser_ = NULL;
}
if (0 != avahi_client_) {
avahi_client_free(avahi_client_);
+ avahi_client_ = NULL;
}
int avahi_error;
avahi_client_ = avahi_client_new(
- avahi_threaded_poll_get(avahi_threaded_poll_), AVAHI_CLIENT_NO_FAIL,
- AvahiClientCallback, this, &avahi_error);
+ avahi_threaded_poll_get(avahi_threaded_poll_), AVAHI_CLIENT_NO_FAIL,
+ AvahiClientCallback, this, &avahi_error);
if (0 == avahi_client_) {
- LOG4CXX_ERROR(logger_, "Failed to create AvahiClient: " << avahi_strerror(avahi_error));
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL");
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed to create AvahiClient: " << avahi_strerror(avahi_error));
return TransportAdapter::FAIL;
}
- pthread_mutex_lock(&mutex_);
+ mutex_.Acquire();
service_records_.clear();
- pthread_mutex_unlock(&mutex_);
+ mutex_.Release();
avahi_service_browser_ = avahi_service_browser_new(
- avahi_client_, AVAHI_IF_UNSPEC, /* TODO use only required iface */
- AVAHI_PROTO_INET, DNSSD_DEFAULT_SERVICE_TYPE, NULL, /* use default domain */
- static_cast<AvahiLookupFlags>(0), AvahiServiceBrowserCallback, this);
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
+ avahi_client_, AVAHI_IF_UNSPEC, /* TODO use only required iface */
+ AVAHI_PROTO_INET, DNSSD_DEFAULT_SERVICE_TYPE, NULL, /* use default domain */
+ static_cast<AvahiLookupFlags>(0), AvahiServiceBrowserCallback, this);
return TransportAdapter::OK;
}
TransportAdapter::Error DnssdServiceBrowser::Init() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
avahi_threaded_poll_ = avahi_threaded_poll_new();
if (0 == avahi_threaded_poll_) {
LOG4CXX_ERROR(logger_, "Failed to create AvahiThreadedPoll");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL");
return TransportAdapter::FAIL;
}
const TransportAdapter::Error err = CreateAvahiClientAndBrowser();
if (err != TransportAdapter::OK) {
- LOG4CXX_TRACE(logger_, "exit with error " << err);
+ LOG4CXX_ERROR(logger_, "Error " << err);
return err;
}
const int poll_start_status = avahi_threaded_poll_start(avahi_threaded_poll_);
if (0 != poll_start_status) {
LOG4CXX_ERROR(logger_, "Failed to start AvahiThreadedPoll");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL. Condition: 0 != poll_start_status");
return TransportAdapter::FAIL;
}
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
return TransportAdapter::OK;
}
@@ -305,8 +304,10 @@ TransportAdapter::Error DnssdServiceBrowser::Scan() {
void DnssdServiceBrowser::AddService(AvahiIfIndex interface,
AvahiProtocol protocol, const char* name,
const char* type, const char* domain) {
- LOG4CXX_TRACE(logger_, "enter: interface " << interface << " protocol " << protocol <<
- " name " << name << " type " << type << " domain " << domain);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(
+ logger_,
+ "interface " << interface << " protocol " << protocol << " name " << name << " type " << type << " domain " << domain);
DnssdServiceRecord record;
record.interface = interface;
record.protocol = protocol;
@@ -314,25 +315,25 @@ void DnssdServiceBrowser::AddService(AvahiIfIndex interface,
record.name = name;
record.type = type;
- pthread_mutex_lock(&mutex_);
+ sync_primitives::AutoLock locker(mutex_);
if (service_records_.end()
== std::find(service_records_.begin(), service_records_.end(), record)) {
service_records_.push_back(record);
- avahi_service_resolver_new(
- avahi_client_, interface, protocol, name, type, domain,
- AVAHI_PROTO_INET, static_cast<AvahiLookupFlags>(0),
- AvahiServiceResolverCallback, this);
+ avahi_service_resolver_new(avahi_client_, interface, protocol, name, type,
+ domain, AVAHI_PROTO_INET,
+ static_cast<AvahiLookupFlags>(0),
+ AvahiServiceResolverCallback, this);
}
- pthread_mutex_unlock(&mutex_);
- LOG4CXX_TRACE(logger_, "exit");
}
void DnssdServiceBrowser::RemoveService(AvahiIfIndex interface,
AvahiProtocol protocol,
const char* name, const char* type,
const char* domain) {
- LOG4CXX_TRACE(logger_, "enter: interface " << interface << " protocol " << protocol <<
- " name " << name << " type " << type << " domain " << domain);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(
+ logger_,
+ "interface " << interface << " protocol " << protocol << " name " << name << " type " << type << " domain " << domain);
DnssdServiceRecord record;
record.interface = interface;
record.protocol = protocol;
@@ -340,42 +341,38 @@ void DnssdServiceBrowser::RemoveService(AvahiIfIndex interface,
record.type = type;
record.domain_name = domain;
- pthread_mutex_lock(&mutex_);
+ sync_primitives::AutoLock locker(mutex_);
service_records_.erase(
- std::remove(service_records_.begin(), service_records_.end(), record),
- service_records_.end());
- pthread_mutex_unlock(&mutex_);
- LOG4CXX_TRACE(logger_, "exit");
+ std::remove(service_records_.begin(), service_records_.end(), record),
+ service_records_.end());
}
DeviceVector DnssdServiceBrowser::PrepareDeviceVector() const {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
std::map<uint32_t, TcpDevice*> devices;
for (ServiceRecords::const_iterator it = service_records_.begin();
- it != service_records_.end(); ++it) {
+ it != service_records_.end(); ++it) {
const DnssdServiceRecord& service_record = *it;
if (service_record.host_name.empty()) {
continue;
}
if (devices[service_record.addr] == 0) {
devices[service_record.addr] = new TcpDevice(service_record.addr,
- service_record.host_name);
+ service_record.host_name);
}
if (devices[service_record.addr] != 0) {
devices[service_record.addr]->AddDiscoveredApplication(
- service_record.port);
+ service_record.port);
}
}
DeviceVector device_vector;
device_vector.reserve(devices.size());
for (std::map<uint32_t, TcpDevice*>::const_iterator it = devices.begin();
- it != devices.end(); ++it) {
+ it != devices.end(); ++it) {
device_vector.push_back(DeviceSptr(it->second));
}
- LOG4CXX_TRACE(logger_, "exit");
return device_vector;
}
-} // namespace
-} // namespace
-
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/src/tcp/tcp_client_listener.cc b/src/components/transport_manager/src/tcp/tcp_client_listener.cc
index c0f39cc490..28a3c389da 100644
--- a/src/components/transport_manager/src/tcp/tcp_client_listener.cc
+++ b/src/components/transport_manager/src/tcp/tcp_client_listener.cc
@@ -53,7 +53,7 @@
#include <sstream>
#include "utils/logger.h"
-
+#include "utils/threads/thread.h"
#include "transport_manager/transport_adapter/transport_adapter_controller.h"
#include "transport_manager/tcp/tcp_device.h"
#include "transport_manager/tcp/tcp_socket_connection.h"
@@ -66,35 +66,78 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
TcpClientListener::TcpClientListener(TransportAdapterController* controller,
const uint16_t port,
const bool enable_keepalive)
- : port_(port),
- enable_keepalive_(enable_keepalive),
- controller_(controller),
- thread_(threads::CreateThread("TcpClientListener", this)),
- socket_(-1),
- thread_stop_requested_(false) { }
+ : port_(port),
+ enable_keepalive_(enable_keepalive),
+ controller_(controller),
+ thread_(0),
+ socket_(-1),
+ thread_stop_requested_(false) {
+ thread_ = threads::CreateThread("TcpClientListener",
+ new ListeningThreadDelegate(this));
+}
TransportAdapter::Error TcpClientListener::Init() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ thread_stop_requested_ = false;
+
+ socket_ = socket(AF_INET, SOCK_STREAM, 0);
+ if (-1 == socket_) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create socket");
+ return TransportAdapter::FAIL;
+ }
+
+ sockaddr_in server_address = { 0 };
+ server_address.sin_family = AF_INET;
+ server_address.sin_port = htons(port_);
+ server_address.sin_addr.s_addr = INADDR_ANY;
+
+ int optval = 1;
+ setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
+
+ if (bind(socket_, reinterpret_cast<sockaddr*>(&server_address),
+ sizeof(server_address)) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "bind() failed");
+ return TransportAdapter::FAIL;
+ }
+
+ const int kBacklog = 128;
+ if (0 != listen(socket_, kBacklog)) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "listen() failed");
+ return TransportAdapter::FAIL;
+ }
return TransportAdapter::OK;
}
void TcpClientListener::Terminate() {
- LOG4CXX_TRACE(logger_, "enter");
- if (TransportAdapter::OK != StopListening()) {
- LOG4CXX_ERROR(logger_, "Cannot stop listening TCP");
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (socket_ == -1) {
+ LOG4CXX_WARN(logger_, "Socket has been closed");
+ return;
}
- LOG4CXX_TRACE(logger_, "exit");
+ if (shutdown(socket_, SHUT_RDWR) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to shutdown socket");
+ }
+ if (close(socket_) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to close socket");
+ }
+ socket_ = -1;
}
bool TcpClientListener::IsInitialised() const {
- return true;
+ return thread_;
}
TcpClientListener::~TcpClientListener() {
- LOG4CXX_INFO(logger_, "destructor");
+ LOG4CXX_AUTO_TRACE(logger_);
+ StopListening();
+ delete thread_->delegate();
+ threads::DeleteThread(thread_);
+ Terminate();
}
void SetKeepaliveOptions(const int fd) {
- LOG4CXX_TRACE(logger_, "enter. fd: " << fd);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "fd: " << fd);
int yes = 1;
int keepidle = 3; // 3 seconds to disconnection detecting
int keepcnt = 5;
@@ -108,7 +151,7 @@ void SetKeepaliveOptions(const int fd) {
setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &user_timeout,
sizeof(user_timeout));
#elif defined(__QNX__) // __linux__
- // TODO (KKolodiy): Out of order!
+ // TODO(KKolodiy): Out of order!
const int kMidLength = 4;
int mib[kMidLength];
@@ -130,23 +173,24 @@ void SetKeepaliveOptions(const int fd) {
mib[3] = TCPCTL_KEEPINTVL;
sysctl(mib, kMidLength, NULL, NULL, &keepintvl, sizeof(keepintvl));
- struct timeval tval = { 0 };
+ struct timeval tval = {0};
tval.tv_sec = keepidle;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &tval, sizeof(tval));
#endif // __QNX__
- LOG4CXX_TRACE(logger_, "exit");
}
-void TcpClientListener::threadMain() {
- LOG4CXX_TRACE(logger_, "enter");
+void TcpClientListener::Loop() {
+ LOG4CXX_AUTO_TRACE(logger_);
while (!thread_stop_requested_) {
sockaddr_in client_address;
socklen_t client_address_size = sizeof(client_address);
- const int connection_fd = accept(socket_, (struct sockaddr*)&client_address,
+ const int connection_fd = accept(socket_,
+ (struct sockaddr*) &client_address,
&client_address_size);
if (thread_stop_requested_) {
LOG4CXX_DEBUG(logger_, "thread_stop_requested_");
+ close(connection_fd);
break;
}
@@ -157,6 +201,7 @@ void TcpClientListener::threadMain() {
if (AF_INET != client_address.sin_family) {
LOG4CXX_DEBUG(logger_, "Address of connected client is invalid");
+ close(connection_fd);
continue;
}
@@ -169,99 +214,78 @@ void TcpClientListener::threadMain() {
SetKeepaliveOptions(connection_fd);
}
- TcpDevice* tcp_device = new TcpDevice(client_address.sin_addr.s_addr, device_name);
+ TcpDevice* tcp_device = new TcpDevice(client_address.sin_addr.s_addr,
+ device_name);
DeviceSptr device = controller_->AddDevice(tcp_device);
tcp_device = static_cast<TcpDevice*>(device.get());
const ApplicationHandle app_handle = tcp_device->AddIncomingApplication(
- connection_fd);
+ connection_fd);
TcpSocketConnection* connection(
- new TcpSocketConnection(device->unique_device_id(), app_handle,
- controller_));
+ new TcpSocketConnection(device->unique_device_id(), app_handle,
+ controller_));
connection->set_socket(connection_fd);
const TransportAdapter::Error error = connection->Start();
if (error != TransportAdapter::OK) {
delete connection;
}
}
- LOG4CXX_TRACE(logger_, "exit");
}
-TransportAdapter::Error TcpClientListener::StartListening() {
- LOG4CXX_TRACE(logger_, "enter");
- if (thread_->is_running()) {
- LOG4CXX_TRACE(logger_,
- "exit with TransportAdapter::BAD_STATE. Condition: thread_started_");
- return TransportAdapter::BAD_STATE;
- }
-
- socket_ = socket(AF_INET, SOCK_STREAM, 0);
-
- if (-1 == socket_) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create socket");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL. Condition: -1 == socket_");
- return TransportAdapter::FAIL;
- }
-
+void TcpClientListener::StopLoop() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ thread_stop_requested_ = true;
+ // We need to connect to the listening socket to unblock accept() call
+ int byesocket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in server_address = { 0 };
server_address.sin_family = AF_INET;
server_address.sin_port = htons(port_);
server_address.sin_addr.s_addr = INADDR_ANY;
+ connect(byesocket, reinterpret_cast<sockaddr*>(&server_address),
+ sizeof(server_address));
+ shutdown(byesocket, SHUT_RDWR);
+ close(byesocket);
+}
- int optval = 1;
- setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
-
- if (0 != bind(socket_, (sockaddr*) &server_address, sizeof(server_address))) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "bind() failed");
- LOG4CXX_TRACE(logger_,
- "exit with TransportAdapter::FAIL. Condition: 0 != bind(socket_, (sockaddr*) &server_address, sizeof(server_address))");
- return TransportAdapter::FAIL;
- }
-
- if (0 != listen(socket_, 128)) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "listen() failed");
- LOG4CXX_TRACE(logger_,
- "exit with TransportAdapter::FAIL. Condition: 0 != listen(socket_, 128)");
- return TransportAdapter::FAIL;
+TransportAdapter::Error TcpClientListener::StartListening() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (thread_->is_running()) {
+ LOG4CXX_WARN(logger_,
+ "TransportAdapter::BAD_STATE. Listener has already been started");
+ return TransportAdapter::BAD_STATE;
}
- if (thread_->start()) {
- LOG4CXX_DEBUG(logger_, "Tcp client listener thread started");
- } else {
+ if (!thread_->start()) {
LOG4CXX_ERROR(logger_, "Tcp client listener thread start failed");
return TransportAdapter::FAIL;
}
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
+ LOG4CXX_INFO(logger_, "Tcp client listener has started successfully");
return TransportAdapter::OK;
}
-bool TcpClientListener::exitThreadMain() {
- StopListening();
- return true;
+void TcpClientListener::ListeningThreadDelegate::exitThreadMain() {
+ parent_->StopLoop();
+}
+
+void TcpClientListener::ListeningThreadDelegate::threadMain() {
+ parent_->Loop();
+}
+
+TcpClientListener::ListeningThreadDelegate::ListeningThreadDelegate(
+ TcpClientListener* parent)
+ : parent_(parent) {
}
TransportAdapter::Error TcpClientListener::StopListening() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if (!thread_->is_running()) {
- LOG4CXX_TRACE(logger_,
- "exit with TransportAdapter::BAD_STATE. Condition !thread_started_");
+ LOG4CXX_DEBUG(logger_, "TcpClientListener is not running now");
return TransportAdapter::BAD_STATE;
}
- thread_stop_requested_ = true;
- // We need to connect to the listening socket to unblock accept() call
- int byesocket = socket(AF_INET, SOCK_STREAM, 0);
- sockaddr_in server_address = { 0 };
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(port_);
- server_address.sin_addr.s_addr = INADDR_ANY;
- connect(byesocket, (sockaddr*)&server_address, sizeof(server_address));
- shutdown(byesocket, SHUT_RDWR);
- close(byesocket);
- LOG4CXX_DEBUG(logger_, "Tcp client listener thread terminated");
- close(socket_);
- socket_ = -1;
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
+ thread_->join();
+
+ LOG4CXX_INFO(logger_, "Tcp client listener has stopped successfully");
return TransportAdapter::OK;
}
diff --git a/src/components/transport_manager/src/tcp/tcp_connection_factory.cc b/src/components/transport_manager/src/tcp/tcp_connection_factory.cc
index 69173a0e06..7c6c06ddc0 100644
--- a/src/components/transport_manager/src/tcp/tcp_connection_factory.cc
+++ b/src/components/transport_manager/src/tcp/tcp_connection_factory.cc
@@ -1,6 +1,5 @@
-/**
- *
- * Copyright (c) 2013, Ford Motor Company
+/*
+ * Copyright (c) 2015, Ford Motor Company
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,8 +40,9 @@ namespace transport_adapter {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
-TcpConnectionFactory::TcpConnectionFactory(TransportAdapterController* controller)
- : controller_(controller) {
+TcpConnectionFactory::TcpConnectionFactory(
+ TransportAdapterController* controller)
+ : controller_(controller) {
}
TransportAdapter::Error TcpConnectionFactory::Init() {
@@ -50,19 +50,22 @@ TransportAdapter::Error TcpConnectionFactory::Init() {
}
TransportAdapter::Error TcpConnectionFactory::CreateConnection(
- const DeviceUID& device_uid, const ApplicationHandle& app_handle) {
- LOG4CXX_TRACE(logger_, "enter. DeviceUID: " << &device_uid << ", ApplicationHandle: " <<
- &app_handle);
+ const DeviceUID& device_uid, const ApplicationHandle& app_handle) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(
+ logger_,
+ "DeviceUID: " << &device_uid << ", ApplicationHandle: " << &app_handle);
TcpServerOiginatedSocketConnection* connection(
- new TcpServerOiginatedSocketConnection(device_uid, app_handle,
- controller_));
- TransportAdapter::Error error = connection->Start();
- if (TransportAdapter::OK != error) {
- LOG4CXX_ERROR(logger_, "Transport adapter error " << error);
- delete connection;
+ new TcpServerOiginatedSocketConnection(device_uid, app_handle,
+ controller_));
+ controller_->ConnectionCreated(connection, device_uid, app_handle);
+ if (connection->Start() == TransportAdapter::OK) {
+ LOG4CXX_DEBUG(logger_, "TCP connection initialised");
+ return TransportAdapter::OK;
+ } else {
+ LOG4CXX_ERROR(logger_, "Could not initialise TCP connection");
+ return TransportAdapter::FAIL;
}
- LOG4CXX_TRACE(logger_, "exit with error " << error);
- return error;
}
void TcpConnectionFactory::Terminate() {
diff --git a/src/components/transport_manager/src/tcp/tcp_device.cc b/src/components/transport_manager/src/tcp/tcp_device.cc
index 2540c26ed0..92848a4246 100644
--- a/src/components/transport_manager/src/tcp/tcp_device.cc
+++ b/src/components/transport_manager/src/tcp/tcp_device.cc
@@ -1,4 +1,4 @@
-/**
+/*
*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
@@ -30,31 +30,34 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-
+#include "utils/logger.h"
#include "transport_manager/tcp/tcp_device.h"
-#include "utils/logger.h"
namespace transport_manager {
namespace transport_adapter {
+//CREATE_LOGGERPTR_LOCAL(logger_, "TransportManager")
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
TcpDevice::TcpDevice(const in_addr_t& in_addr, const std::string& name)
- :
- Device(name, name),
- in_addr_(in_addr),
- last_handle_(0) {
- pthread_mutex_init(&applications_mutex_, 0);
+ : Device(name, name),
+ applications_mutex_(),
+ in_addr_(in_addr),
+ last_handle_(0) {
+ LOG4CXX_AUTO_TRACE(logger_);
}
bool TcpDevice::IsSameAs(const Device* other) const {
- LOG4CXX_TRACE(logger_, "enter. Device: " << other);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device: " << other);
const TcpDevice* other_tcp_device = static_cast<const TcpDevice*>(other);
if (other_tcp_device->in_addr_ == in_addr_) {
- LOG4CXX_TRACE(logger_,
- "exit with TRUE. Condition: other_tcp_device->in_addr_ == in_addr_");
+ LOG4CXX_TRACE(
+ logger_,
+ "exit with TRUE. Condition: other_tcp_device->in_addr_ == in_addr_");
return true;
} else {
LOG4CXX_TRACE(logger_, "exit with FALSE");
@@ -63,91 +66,88 @@ bool TcpDevice::IsSameAs(const Device* other) const {
}
ApplicationList TcpDevice::GetApplicationList() const {
- LOG4CXX_TRACE(logger_, "enter");
- pthread_mutex_lock(&applications_mutex_);
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock locker(applications_mutex_);
ApplicationList app_list;
for (std::map<ApplicationHandle, Application>::const_iterator it =
- applications_.begin(); it != applications_.end(); ++it) {
+ applications_.begin(); it != applications_.end(); ++it) {
app_list.push_back(it->first);
}
- pthread_mutex_unlock(&applications_mutex_);
- LOG4CXX_TRACE(logger_, "exit with app_list. It's size = " << app_list.size());
return app_list;
}
ApplicationHandle TcpDevice::AddIncomingApplication(int socket_fd) {
- LOG4CXX_TRACE(logger_, "enter. Socket_fd: " << socket_fd);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Socket_fd: " << socket_fd);
Application app;
app.incoming = true;
app.socket = socket_fd;
- app.port = 0; // this line removes compiler warning
- pthread_mutex_lock(&applications_mutex_);
+ app.port = 0; // this line removes compiler warning
+ sync_primitives::AutoLock locker(applications_mutex_);
const ApplicationHandle app_handle = ++last_handle_;
applications_[app_handle] = app;
- pthread_mutex_unlock(&applications_mutex_);
- LOG4CXX_TRACE(logger_, "exit with app_handle " << app_handle);
+ LOG4CXX_DEBUG(logger_, "App_handle " << app_handle);
return app_handle;
}
ApplicationHandle TcpDevice::AddDiscoveredApplication(int port) {
- LOG4CXX_TRACE(logger_, "enter. port " << port);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Port " << port);
Application app;
app.incoming = false;
app.socket = 0; // this line removes compiler warning
app.port = port;
- pthread_mutex_lock(&applications_mutex_);
+ sync_primitives::AutoLock locker(applications_mutex_);
const ApplicationHandle app_handle = ++last_handle_;
applications_[app_handle] = app;
- pthread_mutex_unlock(&applications_mutex_);
- LOG4CXX_TRACE(logger_, "exit with app_handle " << app_handle);
+ LOG4CXX_DEBUG(logger_, "App_handle " << app_handle);
return app_handle;
}
-
void TcpDevice::RemoveApplication(const ApplicationHandle app_handle) {
- LOG4CXX_TRACE(logger_, "enter. ApplicationHandle: " << app_handle);
- pthread_mutex_lock(&applications_mutex_);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "ApplicationHandle: " << app_handle);
+ sync_primitives::AutoLock locker(applications_mutex_);
applications_.erase(app_handle);
- pthread_mutex_unlock(&applications_mutex_);
- LOG4CXX_TRACE(logger_, "exit");
}
TcpDevice::~TcpDevice() {
- pthread_mutex_destroy(&applications_mutex_);
+ LOG4CXX_AUTO_TRACE(logger_);
}
int TcpDevice::GetApplicationSocket(const ApplicationHandle app_handle) const {
- LOG4CXX_TRACE(logger_, "enter. ApplicationHandle: " << app_handle);
- std::map<ApplicationHandle, Application>::const_iterator it = applications_.find(
- app_handle);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "ApplicationHandle: " << app_handle);
+ std::map<ApplicationHandle, Application>::const_iterator it = applications_
+ .find(app_handle);
if (applications_.end() == it) {
- LOG4CXX_TRACE(logger_, "exit with -1. Condition: applications_.end() == it");
+ LOG4CXX_WARN(logger_, "Application was not found");
return -1;
}
if (!it->second.incoming) {
- LOG4CXX_TRACE(logger_, "exit with -1. Condition: !it->second.incoming");
+ LOG4CXX_WARN(logger_, "Application is not incoming");
return -1;
}
- LOG4CXX_TRACE(logger_, "exit with socket " << it->second.socket);
+ LOG4CXX_DEBUG(logger_, "socket " << it->second.socket);
return it->second.socket;
}
int TcpDevice::GetApplicationPort(const ApplicationHandle app_handle) const {
- LOG4CXX_TRACE(logger_, "enter. ApplicationHandle: " << app_handle);
- std::map<ApplicationHandle, Application>::const_iterator it = applications_.find(
- app_handle);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "ApplicationHandle: " << app_handle);
+ std::map<ApplicationHandle, Application>::const_iterator it = applications_
+ .find(app_handle);
if (applications_.end() == it) {
- LOG4CXX_TRACE(logger_, "exit with -1. Condition: applications_.end() == it");
+ LOG4CXX_WARN(logger_, "Application was not found");
return -1;
}
if (it->second.incoming) {
- LOG4CXX_TRACE(logger_, "exit with -1. Condition: it->second.incoming");
+ LOG4CXX_WARN(logger_, "Application is incoming");
return -1;
}
- LOG4CXX_TRACE(logger_, "exit with port " << it->second.port);
+ LOG4CXX_DEBUG(logger_, "port " << it->second.port);
return it->second.port;
}
-
} // namespace transport_adapter
} // namespace transport_manager
diff --git a/src/components/transport_manager/src/tcp/tcp_socket_connection.cc b/src/components/transport_manager/src/tcp/tcp_socket_connection.cc
index 3b208d8a07..c5d0e88d84 100644
--- a/src/components/transport_manager/src/tcp/tcp_socket_connection.cc
+++ b/src/components/transport_manager/src/tcp/tcp_socket_connection.cc
@@ -1,4 +1,4 @@
-/**
+/*
*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
@@ -31,25 +31,27 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include "transport_manager/transport_adapter/transport_adapter_controller.h"
#include "transport_manager/tcp/tcp_socket_connection.h"
-#include "transport_manager/tcp/tcp_device.h"
-#include "utils/logger.h"
#include <memory.h>
#include <signal.h>
#include <errno.h>
+#include <unistd.h>
+
+#include "utils/logger.h"
+#include "utils/threads/thread.h"
+#include "transport_manager/tcp/tcp_device.h"
+#include "transport_manager/transport_adapter/transport_adapter_controller.h"
namespace transport_manager {
namespace transport_adapter {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
-
TcpSocketConnection::TcpSocketConnection(const DeviceUID& device_uid,
- const ApplicationHandle& app_handle,
- TransportAdapterController* controller)
- : ThreadedSocketConnection(device_uid, app_handle, controller) {
+ const ApplicationHandle& app_handle,
+ TransportAdapterController* controller)
+ : ThreadedSocketConnection(device_uid, app_handle, controller) {
}
TcpSocketConnection::~TcpSocketConnection() {
@@ -60,30 +62,32 @@ bool TcpSocketConnection::Establish(ConnectError** error) {
}
TcpServerOiginatedSocketConnection::TcpServerOiginatedSocketConnection(
- const DeviceUID& device_uid, const ApplicationHandle& app_handle,
- TransportAdapterController* controller)
- : ThreadedSocketConnection(device_uid, app_handle, controller) {
+ const DeviceUID& device_uid, const ApplicationHandle& app_handle,
+ TransportAdapterController* controller)
+ : ThreadedSocketConnection(device_uid, app_handle, controller) {
}
TcpServerOiginatedSocketConnection::~TcpServerOiginatedSocketConnection() {
}
bool TcpServerOiginatedSocketConnection::Establish(ConnectError** error) {
- LOG4CXX_TRACE(logger_, "enter. error " << error);
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(error);
+ LOG4CXX_DEBUG(logger_, "error " << error);
DeviceSptr device = controller()->FindDevice(device_handle());
if (!device.valid()) {
LOG4CXX_ERROR(logger_, "Device " << device_handle() << " not found");
*error = new ConnectError();
- LOG4CXX_TRACE(logger_, "exit with FALSE. Condition: !device.valid()");
return false;
}
TcpDevice* tcp_device = static_cast<TcpDevice*>(device.get());
- int port;
- if (-1 == (port = tcp_device->GetApplicationPort(application_handle()))) {
- LOG4CXX_ERROR(logger_, "Application port for " << application_handle() << " not found");
+ const int port = tcp_device->GetApplicationPort(application_handle());
+ if (-1 == port) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Application port for " << application_handle() << " not found");
*error = new ConnectError();
- LOG4CXX_TRACE(logger_, "exit with FALSE. Condition: port not found");
return false;
}
@@ -91,7 +95,6 @@ bool TcpServerOiginatedSocketConnection::Establish(ConnectError** error) {
if (socket < 0) {
LOG4CXX_ERROR(logger_, "Failed to create socket");
*error = new ConnectError();
- LOG4CXX_TRACE(logger_, "exit with FALSE. Condition: failed to create socket");
return false;
}
@@ -100,21 +103,20 @@ bool TcpServerOiginatedSocketConnection::Establish(ConnectError** error) {
addr.sin_addr.s_addr = tcp_device->in_addr();
addr.sin_port = htons(port);
- LOG4CXX_INFO(logger_, "Connecting " << inet_ntoa(addr.sin_addr) << ":"
- << port);
+ LOG4CXX_DEBUG(logger_,
+ "Connecting " << inet_ntoa(addr.sin_addr) << ":" << port);
if (::connect(socket, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
- LOG4CXX_ERROR(logger_, "Failed to connect for application "
- << application_handle() << ", error " << errno);
+ LOG4CXX_ERROR(
+ logger_,
+ "Failed to connect for application " << application_handle() << ", error " << errno);
*error = new ConnectError();
- LOG4CXX_TRACE(logger_, "exit with FALSE. Condition: failed to connect to application");
+ ::close(socket);
return false;
}
set_socket(socket);
- LOG4CXX_TRACE(logger_, "exit with TRUE");
return true;
}
} // namespace transport_adapter
} // namespace transport_manager
-
diff --git a/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc b/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc
index 3747225a89..ade69cba69 100644
--- a/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc
+++ b/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc
@@ -1,5 +1,4 @@
-/**
- *
+/*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
*
@@ -31,18 +30,19 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "transport_manager/tcp/tcp_transport_adapter.h"
+
#include <memory.h>
#include <signal.h>
#include <errno.h>
-#include <sstream>
-#include <cstdlib>
+#include <stdio.h>
-#include "resumption/last_state.h"
+#include <cstdlib>
+#include <sstream>
#include "utils/logger.h"
#include "utils/threads/thread_delegate.h"
-
-#include "transport_manager/tcp/tcp_transport_adapter.h"
+#include "resumption/last_state.h"
#include "transport_manager/tcp/tcp_client_listener.h"
#include "transport_manager/tcp/tcp_connection_factory.h"
#include "transport_manager/tcp/tcp_device.h"
@@ -57,14 +57,14 @@ namespace transport_adapter {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportAdapterImpl")
TcpTransportAdapter::TcpTransportAdapter(const uint16_t port)
- : TransportAdapterImpl(
+ : TransportAdapterImpl(
#ifdef AVAHI_SUPPORT
- new DnssdServiceBrowser(this),
+ new DnssdServiceBrowser(this),
#else
- NULL,
+ NULL,
#endif
- new TcpConnectionFactory(this),
- new TcpClientListener(this, port, false)) {
+ new TcpConnectionFactory(this),
+ new TcpClientListener(this, port, false)) {
}
TcpTransportAdapter::~TcpTransportAdapter() {
@@ -75,18 +75,19 @@ DeviceType TcpTransportAdapter::GetDeviceType() const {
}
void TcpTransportAdapter::Store() const {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
Json::Value tcp_adapter_dictionary;
Json::Value devices_dictionary;
DeviceList device_ids = GetDeviceList();
- for (DeviceList::const_iterator i = device_ids.begin(); i != device_ids.end(); ++i) {
+ for (DeviceList::const_iterator i = device_ids.begin(); i != device_ids.end();
+ ++i) {
DeviceUID device_id = *i;
DeviceSptr device = FindDevice(device_id);
- if (!device) { // device could have been disconnected
+ if (!device) { // device could have been disconnected
continue;
}
- utils::SharedPtr<TcpDevice> tcp_device =
- DeviceSptr::static_pointer_cast<TcpDevice>(device);
+ utils::SharedPtr<TcpDevice> tcp_device = DeviceSptr::static_pointer_cast<
+ TcpDevice>(device);
Json::Value device_dictionary;
device_dictionary["name"] = tcp_device->name();
struct in_addr address;
@@ -94,14 +95,16 @@ void TcpTransportAdapter::Store() const {
device_dictionary["address"] = std::string(inet_ntoa(address));
Json::Value applications_dictionary;
ApplicationList app_ids = tcp_device->GetApplicationList();
- for (ApplicationList::const_iterator j = app_ids.begin(); j != app_ids.end(); ++j) {
+ for (ApplicationList::const_iterator j = app_ids.begin();
+ j != app_ids.end(); ++j) {
ApplicationHandle app_handle = *j;
- if (FindEstablishedConnection(tcp_device->unique_device_id(), app_handle)) {
+ if (FindEstablishedConnection(tcp_device->unique_device_id(),
+ app_handle)) {
int port = tcp_device->GetApplicationPort(app_handle);
- if (port != -1) { // don't want to store incoming applications
+ if (port != -1) { // don't want to store incoming applications
Json::Value application_dictionary;
char port_record[12];
- sprintf(port_record, "%d", port);
+ snprintf(port_record, sizeof(port_record), "%d", port);
application_dictionary["port"] = std::string(port_record);
applications_dictionary.append(application_dictionary);
}
@@ -113,19 +116,18 @@ void TcpTransportAdapter::Store() const {
}
}
tcp_adapter_dictionary["devices"] = devices_dictionary;
- resumption::LastState::instance()->dictionary["TransportManager"]["TcpAdapter"] =
- tcp_adapter_dictionary;
- LOG4CXX_TRACE(logger_, "exit");
+ Json::Value& dictionary = resumption::LastState::instance()->dictionary;
+ dictionary["TransportManager"]["TcpAdapter"] = tcp_adapter_dictionary;
}
bool TcpTransportAdapter::Restore() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
bool errors_occurred = false;
- const Json::Value tcp_adapter_dictionary =
- resumption::LastState::instance()->dictionary["TransportManager"]["TcpAdapter"];
+ const Json::Value tcp_adapter_dictionary = resumption::LastState::instance()
+ ->dictionary["TransportManager"]["TcpAdapter"];
const Json::Value devices_dictionary = tcp_adapter_dictionary["devices"];
for (Json::Value::const_iterator i = devices_dictionary.begin();
- i != devices_dictionary.end(); ++i) {
+ i != devices_dictionary.end(); ++i) {
const Json::Value device_dictionary = *i;
std::string name = device_dictionary["name"].asString();
std::string address_record = device_dictionary["address"].asString();
@@ -133,9 +135,10 @@ bool TcpTransportAdapter::Restore() {
TcpDevice* tcp_device = new TcpDevice(address, name);
DeviceSptr device(tcp_device);
AddDevice(device);
- const Json::Value applications_dictionary = device_dictionary["applications"];
+ const Json::Value applications_dictionary =
+ device_dictionary["applications"];
for (Json::Value::const_iterator j = applications_dictionary.begin();
- j != applications_dictionary.end(); ++j) {
+ j != applications_dictionary.end(); ++j) {
const Json::Value application_dictionary = *j;
std::string port_record = application_dictionary["port"].asString();
int port = atoi(port_record.c_str());
@@ -146,11 +149,7 @@ bool TcpTransportAdapter::Restore() {
}
}
bool result = !errors_occurred;
- if (result) {
- LOG4CXX_TRACE(logger_, "exit with TRUE");
- } else {
- LOG4CXX_TRACE(logger_, "exit with FALSE");
- }
+ LOG4CXX_DEBUG(logger_, "result " << std::boolalpha << result);
return result;
}
diff --git a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc
index 1e189ed101..67e41cec2b 100644
--- a/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc
+++ b/src/components/transport_manager/src/transport_adapter/threaded_socket_connection.cc
@@ -1,4 +1,4 @@
-/**
+/*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
*
@@ -36,7 +36,9 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
+
#include "utils/logger.h"
+#include "utils/threads/thread.h"
#include "transport_manager/transport_adapter/threaded_socket_connection.h"
#include "transport_manager/transport_adapter/transport_adapter_controller.h"
@@ -46,197 +48,173 @@ namespace transport_adapter {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
ThreadedSocketConnection::ThreadedSocketConnection(
- const DeviceUID& device_id, const ApplicationHandle& app_handle,
- TransportAdapterController* controller)
- : read_fd_(-1), write_fd_(-1), controller_(controller),
- frames_to_send_(),
- frames_to_send_mutex_(),
- socket_(-1),
- terminate_flag_(false),
- unexpected_disconnect_(false),
- device_uid_(device_id),
- app_handle_(app_handle)
- {
- pthread_mutex_init(&frames_to_send_mutex_, 0);
+ const DeviceUID& device_id, const ApplicationHandle& app_handle,
+ TransportAdapterController* controller)
+ : read_fd_(-1),
+ write_fd_(-1),
+ controller_(controller),
+ frames_to_send_(),
+ frames_to_send_mutex_(),
+ socket_(-1),
+ terminate_flag_(false),
+ unexpected_disconnect_(false),
+ device_uid_(device_id),
+ app_handle_(app_handle),
+ thread_(NULL) {
+ const std::string thread_name = std::string("Socket ") + device_handle();
+ thread_ = threads::CreateThread(thread_name.c_str(),
+ new SocketConnectionDelegate(this));
}
ThreadedSocketConnection::~ThreadedSocketConnection() {
- terminate_flag_ = true;
- Notify();
- pthread_mutex_destroy(&frames_to_send_mutex_);
+ LOG4CXX_AUTO_TRACE(logger_);
+ Disconnect();
+ thread_->join();
+ delete thread_->delegate();
+ threads::DeleteThread(thread_);
+ if (-1 != read_fd_) {
+ close(read_fd_);
+ }
+ if (-1 != write_fd_) {
+ close(write_fd_);
+ }
}
void ThreadedSocketConnection::Abort() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
unexpected_disconnect_ = true;
terminate_flag_ = true;
- LOG4CXX_TRACE(logger_, "exit");
}
TransportAdapter::Error ThreadedSocketConnection::Start() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
int fds[2];
const int pipe_ret = pipe(fds);
if (0 == pipe_ret) {
- LOG4CXX_DEBUG(logger_, "pipe created(#" << pthread_self() << ")");
+ LOG4CXX_DEBUG(logger_, "pipe created");
read_fd_ = fds[0];
write_fd_ = fds[1];
} else {
- LOG4CXX_WARN(logger_, "pipe creation failed (#" << pthread_self() << ")");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL");
+ LOG4CXX_ERROR(logger_, "pipe creation failed");
return TransportAdapter::FAIL;
}
const int fcntl_ret = fcntl(read_fd_, F_SETFL,
fcntl(read_fd_, F_GETFL) | O_NONBLOCK);
if (0 != fcntl_ret) {
- LOG4CXX_WARN(logger_, "fcntl failed (#" << pthread_self() << ")");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL");
+ LOG4CXX_ERROR(logger_, "fcntl failed");
return TransportAdapter::FAIL;
}
- const std::string thread_name = std::string("Socket ") + device_handle();
- thread_ = threads::CreateThread(thread_name.c_str(), this);
-
if (!thread_->start()) {
- LOG4CXX_WARN(logger_, "thread creation failed (#" << pthread_self() << ")");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL");
+ LOG4CXX_ERROR(logger_, "thread creation failed");
return TransportAdapter::FAIL;
}
- LOG4CXX_DEBUG(logger_, "thread created (#" << pthread_self() << ")");
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
+ LOG4CXX_INFO(logger_, "thread created");
return TransportAdapter::OK;
}
void ThreadedSocketConnection::Finalize() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if (unexpected_disconnect_) {
- LOG4CXX_DEBUG(logger_, "unexpected_disconnect (#" << pthread_self() << ")");
+ LOG4CXX_DEBUG(logger_, "unexpected_disconnect");
controller_->ConnectionAborted(device_handle(), application_handle(),
CommunicationError());
} else {
- LOG4CXX_DEBUG(logger_, "not unexpected_disconnect (#" << pthread_self() << ")");
+ LOG4CXX_DEBUG(logger_, "not unexpected_disconnect");
controller_->ConnectionFinished(device_handle(), application_handle());
}
close(socket_);
- LOG4CXX_TRACE(logger_, "exit");
}
TransportAdapter::Error ThreadedSocketConnection::Notify() const {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
if (-1 == write_fd_) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_,
- "Failed to wake up connection thread for connection " << this);
+ LOG4CXX_ERROR_WITH_ERRNO(
+ logger_, "Failed to wake up connection thread for connection " << this);
LOG4CXX_TRACE(logger_, "exit with TransportAdapter::BAD_STATE");
return TransportAdapter::BAD_STATE;
}
uint8_t c = 0;
- if (1 == write(write_fd_, &c, 1)) {
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::OK");
- return TransportAdapter::OK;
- } else {
+ if (1 != write(write_fd_, &c, 1)) {
LOG4CXX_ERROR_WITH_ERRNO(
- logger_, "Failed to wake up connection thread for connection " << this);
- LOG4CXX_TRACE(logger_, "exit with TransportAdapter::FAIL");
+ logger_, "Failed to wake up connection thread for connection " << this);
return TransportAdapter::FAIL;
}
+ return TransportAdapter::OK;
}
TransportAdapter::Error ThreadedSocketConnection::SendData(
- ::protocol_handler::RawMessagePtr message) {
- LOG4CXX_TRACE(logger_, "enter");
- pthread_mutex_lock(&frames_to_send_mutex_);
+ ::protocol_handler::RawMessagePtr message) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(frames_to_send_mutex_);
frames_to_send_.push(message);
- pthread_mutex_unlock(&frames_to_send_mutex_);
- TransportAdapter::Error error = Notify();
- LOG4CXX_TRACE(logger_, "exit with error" << error);
- return error;
+ return Notify();
}
TransportAdapter::Error ThreadedSocketConnection::Disconnect() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
terminate_flag_ = true;
- TransportAdapter::Error error = Notify();
- LOG4CXX_TRACE(logger_, "exit with error" << error);
- return error;
-}
-
-bool ThreadedSocketConnection::exitThreadMain() {
- terminate_flag_ = true;
- Notify();
- return true;
+ return Notify();
}
void ThreadedSocketConnection::threadMain() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
controller_->ConnectionCreated(this, device_uid_, app_handle_);
ConnectError* connect_error = NULL;
- if (Establish(&connect_error)) {
- LOG4CXX_DEBUG(logger_, "Connection established (#" << pthread_self() << ")");
- controller_->ConnectDone(device_handle(), application_handle());
- while (!terminate_flag_) {
- Transmit();
- }
- LOG4CXX_DEBUG(logger_, "Connection is to finalize (#" << pthread_self() << ")");
- Finalize();
- while (!frames_to_send_.empty()) {
- LOG4CXX_INFO(logger_, "removing message (#" << pthread_self() << ")");
- ::protocol_handler::RawMessagePtr message = frames_to_send_.front();
- frames_to_send_.pop();
- controller_->DataSendFailed(device_handle(), application_handle(),
- message, DataSendError());
- }
- controller_->DisconnectDone(device_handle(), application_handle());
- } else {
- LOG4CXX_ERROR(logger_, "Connection Establish failed (#" << pthread_self() << ")");
- controller_->ConnectFailed(device_handle(), application_handle(),
- *connect_error);
+ if (!Establish(&connect_error)) {
+ LOG4CXX_ERROR(logger_, "Connection Establish failed");
delete connect_error;
}
- if (-1 != read_fd_) {
- close(read_fd_);
+ LOG4CXX_DEBUG(logger_, "Connection established");
+ controller_->ConnectDone(device_handle(), application_handle());
+ while (!terminate_flag_) {
+ Transmit();
}
- if (-1 != write_fd_) {
- close(write_fd_);
+ LOG4CXX_DEBUG(logger_, "Connection is to finalize");
+ Finalize();
+ sync_primitives::AutoLock auto_lock(frames_to_send_mutex_);
+ while (!frames_to_send_.empty()) {
+ LOG4CXX_INFO(logger_, "removing message");
+ ::protocol_handler::RawMessagePtr message = frames_to_send_.front();
+ frames_to_send_.pop();
+ controller_->DataSendFailed(device_handle(), application_handle(),
+ message, DataSendError());
}
- LOG4CXX_TRACE(logger_, "exit");
}
void ThreadedSocketConnection::Transmit() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
- const nfds_t poll_fds_size = 2;
- pollfd poll_fds[poll_fds_size];
+ const nfds_t kPollFdsSize = 2;
+ pollfd poll_fds[kPollFdsSize];
poll_fds[0].fd = socket_;
- poll_fds[0].events = POLLIN | POLLPRI | (frames_to_send_.empty() ? 0 : POLLOUT);
+ poll_fds[0].events = POLLIN | POLLPRI
+ | (frames_to_send_.empty() ? 0 : POLLOUT);
poll_fds[1].fd = read_fd_;
poll_fds[1].events = POLLIN | POLLPRI;
- LOG4CXX_DEBUG(logger_, "poll (#" << pthread_self() << ") " << this);
- if (-1 == poll(poll_fds, poll_fds_size, -1)) {
+ LOG4CXX_DEBUG(logger_, "poll " << this);
+ if (-1 == poll(poll_fds, kPollFdsSize, -1)) {
LOG4CXX_ERROR_WITH_ERRNO(logger_, "poll failed for connection " << this);
Abort();
- LOG4CXX_TRACE(logger_, "exit. Condition: -1 == poll(poll_fds, poll_fds_size, -1)");
return;
}
- LOG4CXX_DEBUG(logger_, "poll is ok (#" << pthread_self() << ") " << this << " revents0:"
- <<
- std::hex << poll_fds[0].revents << " revents1:" << std::hex << poll_fds[1].revents);
+ LOG4CXX_DEBUG(
+ logger_,
+ "poll is ok " << this << " revents0: " << std::hex << poll_fds[0].revents <<
+ " revents1:" << std::hex << poll_fds[1].revents);
// error check
if (0 != (poll_fds[1].revents & (POLLERR | POLLHUP | POLLNVAL))) {
LOG4CXX_ERROR(logger_,
"Notification pipe for connection " << this << " terminated");
Abort();
- LOG4CXX_TRACE(logger_,
- "exit. Condition: 0 != (poll_fds[1].revents & (POLLERR | POLLHUP | POLLNVAL))");
return;
}
if (poll_fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) {
LOG4CXX_WARN(logger_, "Connection " << this << " terminated");
Abort();
- LOG4CXX_TRACE(logger_,
- "exit. Condition: poll_fds[0].revents & (POLLERR | POLLHUP | POLLNVAL");
return;
}
@@ -250,20 +228,18 @@ void ThreadedSocketConnection::Transmit() {
LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to clear notification pipe");
LOG4CXX_ERROR_WITH_ERRNO(logger_, "poll failed for connection " << this);
Abort();
- LOG4CXX_TRACE(logger_, "exit. Condition: (bytes_read < 0) && (EAGAIN != errno)");
return;
}
// send data if possible
if (!frames_to_send_.empty() && (poll_fds[0].revents | POLLOUT)) {
- LOG4CXX_DEBUG(logger_, "frames_to_send_ not empty() (#" << pthread_self() << ")");
+ LOG4CXX_DEBUG(logger_, "frames_to_send_ not empty() ");
// send data
const bool send_ok = Send();
if (!send_ok) {
- LOG4CXX_ERROR(logger_, "Send() failed (#" << pthread_self() << ")");
+ LOG4CXX_ERROR(logger_, "Send() failed ");
Abort();
- LOG4CXX_TRACE(logger_, "exit. Condition: !send_ok");
return;
}
}
@@ -272,17 +248,15 @@ void ThreadedSocketConnection::Transmit() {
if (poll_fds[0].revents & (POLLIN | POLLPRI)) {
const bool receive_ok = Receive();
if (!receive_ok) {
- LOG4CXX_ERROR(logger_, "Receive() failed (#" << pthread_self() << ")");
+ LOG4CXX_ERROR(logger_, "Receive() failed ");
Abort();
- LOG4CXX_TRACE(logger_, "exit. Condition: !receive_ok");
return;
}
}
- LOG4CXX_TRACE(logger_, "exit");
}
bool ThreadedSocketConnection::Receive() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
uint8_t buffer[4096];
ssize_t bytes_read = -1;
@@ -291,8 +265,8 @@ bool ThreadedSocketConnection::Receive() {
if (bytes_read > 0) {
LOG4CXX_DEBUG(
- logger_,
- "Received " << bytes_read << " bytes for connection " << this);
+ logger_,
+ "Received " << bytes_read << " bytes for connection " << this);
::protocol_handler::RawMessagePtr frame(
new protocol_handler::RawMessage(0, 0, buffer, bytes_read));
controller_->DataReceiveDone(device_handle(), application_handle(),
@@ -301,36 +275,33 @@ bool ThreadedSocketConnection::Receive() {
if (EAGAIN != errno && EWOULDBLOCK != errno) {
LOG4CXX_ERROR_WITH_ERRNO(logger_,
"recv() failed for connection " << this);
- LOG4CXX_TRACE(logger_,
- "exit with FALSE. Condition: EAGAIN != errno && EWOULDBLOCK != errno");
return false;
}
} else {
LOG4CXX_WARN(logger_, "Connection " << this << " closed by remote peer");
- LOG4CXX_TRACE(logger_, "exit with FALSE. Condition: bytes_read >= 0");
return false;
}
} while (bytes_read > 0);
- LOG4CXX_TRACE(logger_, "exit with TRUE");
+
return true;
}
bool ThreadedSocketConnection::Send() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
FrameQueue frames_to_send;
- pthread_mutex_lock(&frames_to_send_mutex_);
+ frames_to_send_mutex_.Acquire();
std::swap(frames_to_send, frames_to_send_);
- pthread_mutex_unlock(&frames_to_send_mutex_);
+ frames_to_send_mutex_.Release();
size_t offset = 0;
while (!frames_to_send.empty()) {
- LOG4CXX_INFO(logger_, "frames_to_send is not empty" << pthread_self() << ")");
+ LOG4CXX_INFO(logger_, "frames_to_send is not empty");
::protocol_handler::RawMessagePtr frame = frames_to_send.front();
const ssize_t bytes_sent = ::send(socket_, frame->data() + offset,
frame->data_size() - offset, 0);
if (bytes_sent >= 0) {
- LOG4CXX_DEBUG(logger_, "bytes_sent >= 0" << pthread_self() << ")");
+ LOG4CXX_DEBUG(logger_, "bytes_sent >= 0");
offset += bytes_sent;
if (offset == frame->data_size()) {
frames_to_send.pop();
@@ -338,7 +309,7 @@ bool ThreadedSocketConnection::Send() {
controller_->DataSendDone(device_handle(), application_handle(), frame);
}
} else {
- LOG4CXX_DEBUG(logger_, "bytes_sent < 0" << pthread_self() << ")");
+ LOG4CXX_DEBUG(logger_, "bytes_sent < 0");
LOG4CXX_ERROR_WITH_ERRNO(logger_, "Send failed for connection " << this);
frames_to_send.pop();
offset = 0;
@@ -346,9 +317,24 @@ bool ThreadedSocketConnection::Send() {
DataSendError());
}
}
- LOG4CXX_TRACE(logger_, "exit with TRUE");
+
return true;
}
-} // namespace
-} // namespace
+ThreadedSocketConnection::SocketConnectionDelegate::SocketConnectionDelegate(
+ ThreadedSocketConnection* connection)
+ : connection_(connection) {
+}
+
+void ThreadedSocketConnection::SocketConnectionDelegate::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(connection_);
+ connection_->threadMain();
+}
+
+void ThreadedSocketConnection::SocketConnectionDelegate::exitThreadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
index 3330e93e31..d45143a900 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
@@ -53,56 +53,64 @@ TransportAdapterImpl::TransportAdapterImpl(
devices_(),
devices_mutex_(),
connections_(),
- connections_mutex_(),
- device_scanner_(device_scanner),
- server_connection_factory_(server_connection_factory),
- client_connection_listener_(client_connection_listener)
+ connections_lock_(),
#ifdef TIME_TESTER
- , metric_observer_(NULL)
+ metric_observer_(NULL),
#endif // TIME_TESTER
-{
- pthread_mutex_init(&devices_mutex_, 0);
- pthread_mutex_init(&connections_mutex_, 0);
+ device_scanner_(device_scanner),
+ server_connection_factory_(server_connection_factory),
+ client_connection_listener_(client_connection_listener) {
}
TransportAdapterImpl::~TransportAdapterImpl() {
+ Terminate();
+
+ if (device_scanner_) {
+ LOG4CXX_DEBUG(logger_, "Deleting device_scanner_ " << device_scanner_);
+ delete device_scanner_;
+ LOG4CXX_DEBUG(logger_, "device_scanner_ deleted.");
+ }
+ if (server_connection_factory_) {
+ LOG4CXX_DEBUG(logger_, "Deleting server_connection_factory " << server_connection_factory_);
+ delete server_connection_factory_;
+ LOG4CXX_DEBUG(logger_, "server_connection_factory deleted.");
+ }
+ if (client_connection_listener_) {
+ LOG4CXX_DEBUG(logger_, "Deleting client_connection_listener_ " << client_connection_listener_);
+ delete client_connection_listener_;
+ LOG4CXX_DEBUG(logger_, "client_connection_listener_ deleted.");
+ }
+}
+
+void TransportAdapterImpl::Terminate() {
if (device_scanner_) {
device_scanner_->Terminate();
LOG4CXX_DEBUG(logger_, "device_scanner_ " << device_scanner_ << " terminated.");
- delete device_scanner_;
- LOG4CXX_DEBUG(logger_, "device_scanner_ " << device_scanner_ << " deleted.");
}
if (server_connection_factory_) {
server_connection_factory_->Terminate();
LOG4CXX_DEBUG(logger_, "server_connection_factory " << server_connection_factory_ << " terminated.");
- delete server_connection_factory_;
- LOG4CXX_DEBUG(logger_, "server_connection_factory " << server_connection_factory_ << " deleted.");
}
if (client_connection_listener_) {
client_connection_listener_->Terminate();
LOG4CXX_DEBUG(logger_, "client_connection_listener_ " << client_connection_listener_ << " terminated.");
- delete client_connection_listener_;
- LOG4CXX_DEBUG(logger_, "client_connection_listener_ " << client_connection_listener_ << " deleted.");
}
- pthread_mutex_lock(&connections_mutex_);
ConnectionMap connections;
+ connections_lock_.AcquireForWriting();
std::swap(connections, connections_);
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
connections.clear();
LOG4CXX_DEBUG(logger_, "Connections deleted");
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
DeviceMap devices;
std::swap(devices, devices_);
- pthread_mutex_unlock(&devices_mutex_);
+ devices_mutex_.Release();
devices.clear();
LOG4CXX_DEBUG(logger_, "Devices deleted");
-
- pthread_mutex_destroy(&connections_mutex_);
- pthread_mutex_destroy(&devices_mutex_);
}
TransportAdapter::Error TransportAdapterImpl::Init() {
@@ -159,7 +167,7 @@ TransportAdapter::Error TransportAdapterImpl::Connect(
return BAD_STATE;
}
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForWriting();
const bool already_exists =
connections_.end() !=
connections_.find(std::make_pair(device_id, app_handle));
@@ -169,7 +177,7 @@ TransportAdapter::Error TransportAdapterImpl::Connect(
info.device_id = device_id;
info.state = ConnectionInfo::NEW;
}
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
if (already_exists) {
LOG4CXX_TRACE(logger_, "exit with ALREADY_EXISTS");
return ALREADY_EXISTS;
@@ -178,9 +186,9 @@ TransportAdapter::Error TransportAdapterImpl::Connect(
const TransportAdapter::Error err =
server_connection_factory_->CreateConnection(device_id, app_handle);
if (TransportAdapter::OK != err) {
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForWriting();
connections_.erase(std::make_pair(device_id, app_handle));
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
}
LOG4CXX_TRACE(logger_, "exit with error: " << err);
return err;
@@ -208,7 +216,7 @@ TransportAdapter::Error TransportAdapterImpl::Disconnect(
LOG4CXX_TRACE(logger_, "exit with BAD_STATE");
return BAD_STATE;
}
- Connection* connection = FindEstablishedConnection(device_id, app_handle);
+ ConnectionSPtr connection = FindEstablishedConnection(device_id, app_handle);
if (connection) {
TransportAdapter::Error err = connection->Disconnect();
LOG4CXX_TRACE(logger_, "exit with error: " << err);
@@ -228,21 +236,25 @@ TransportAdapter::Error TransportAdapterImpl::DisconnectDevice(
}
Error error = OK;
- pthread_mutex_lock(&connections_mutex_);
- for (ConnectionMap::iterator it = connections_.begin();
- it != connections_.end(); ++it) {
- ConnectionInfo& info = it->second;
- if (info.device_id == device_id &&
- info.state != ConnectionInfo::FINALISING) {
- if (OK != info.connection->Disconnect()) {
- error = FAIL;
- LOG4CXX_ERROR(logger_, "Error on disconnect" << error);
- }
+ std::vector<ConnectionInfo> to_disconnect;
+ connections_lock_.AcquireForReading();
+ for (ConnectionMap::const_iterator i = connections_.begin(); i != connections_.end(); ++i) {
+ ConnectionInfo info = i->second;
+ if (info.device_id == device_id && info.state != ConnectionInfo::FINALISING) {
+ to_disconnect.push_back(info);
}
}
- pthread_mutex_unlock(&connections_mutex_);
- LOG4CXX_TRACE(logger_, "exit with error " << error);
+ connections_lock_.Release();
+
+ for (std::vector<ConnectionInfo>::const_iterator j = to_disconnect.begin(); j != to_disconnect.end(); ++j) {
+ ConnectionInfo info = *j;
+ if (OK != info.connection->Disconnect()) {
+ error = FAIL;
+ LOG4CXX_ERROR(logger_, "Error on disconnect " << error);
+ }
+ }
+
return error;
}
@@ -256,7 +268,7 @@ TransportAdapter::Error TransportAdapterImpl::SendData(
return BAD_STATE;
}
- Connection* connection = FindEstablishedConnection(device_id, app_handle);
+ ConnectionSPtr connection = FindEstablishedConnection(device_id, app_handle);
if (connection) {
TransportAdapter::Error err = connection->SendData(data);
LOG4CXX_TRACE(logger_, "exit with error: " << err);
@@ -293,19 +305,23 @@ TransportAdapter::Error TransportAdapterImpl::StopClientListening() {
return BAD_STATE;
}
TransportAdapter::Error err = client_connection_listener_->StopListening();
+ for(DeviceMap::iterator it = devices_.begin();
+ it != devices_.end();
+ ++it) {
+ it->second->Stop();
+ }
LOG4CXX_TRACE(logger_, "exit with error: " << err);
return err;
}
DeviceList TransportAdapterImpl::GetDeviceList() const {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
DeviceList devices;
- pthread_mutex_lock(&devices_mutex_);
+ sync_primitives::AutoLock locker(devices_mutex_);
for (DeviceMap::const_iterator it = devices_.begin(); it != devices_.end();
++it) {
devices.push_back(it->first);
}
- pthread_mutex_unlock(&devices_mutex_);
LOG4CXX_TRACE(logger_, "exit with DeviceList. It's' size = " << devices.size());
return devices;
}
@@ -314,7 +330,7 @@ DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) {
LOG4CXX_TRACE(logger_, "enter. device: " << device);
DeviceSptr existing_device;
bool same_device_found = false;
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
for (DeviceMap::const_iterator i = devices_.begin(); i != devices_.end();
++i) {
existing_device = i->second;
@@ -327,7 +343,7 @@ DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) {
if (!same_device_found) {
devices_[device->unique_device_id()] = device;
}
- pthread_mutex_unlock(&devices_mutex_);
+ devices_mutex_.Release();
if (same_device_found) {
LOG4CXX_TRACE(logger_, "exit with TRUE. Condition: same_device_found");
return existing_device;
@@ -352,7 +368,7 @@ void TransportAdapterImpl::SearchDeviceDone(const DeviceVector& devices) {
DeviceSptr device = *it;
bool device_found = false;
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
for (DeviceMap::iterator it = devices_.begin(); it != devices_.end();
++it) {
DeviceSptr existing_device = it->second;
@@ -363,7 +379,7 @@ void TransportAdapterImpl::SearchDeviceDone(const DeviceVector& devices) {
break;
}
}
- pthread_mutex_unlock(&devices_mutex_);
+ devices_mutex_.Release();
if (!device_found) {
LOG4CXX_INFO(logger_, "Adding new device " << device->unique_device_id()
@@ -375,7 +391,7 @@ void TransportAdapterImpl::SearchDeviceDone(const DeviceVector& devices) {
new_devices[device->unique_device_id()] = device;
}
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForReading();
std::set<DeviceUID> connected_devices;
for (ConnectionMap::const_iterator it = connections_.begin();
it != connections_.end(); ++it) {
@@ -384,10 +400,10 @@ void TransportAdapterImpl::SearchDeviceDone(const DeviceVector& devices) {
connected_devices.insert(info.device_id);
}
}
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
DeviceMap all_devices = new_devices;
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
for (DeviceMap::iterator it = devices_.begin(); it != devices_.end(); ++it) {
DeviceSptr existing_device = it->second;
@@ -399,7 +415,7 @@ void TransportAdapterImpl::SearchDeviceDone(const DeviceVector& devices) {
}
}
devices_ = all_devices;
- pthread_mutex_unlock(&devices_mutex_);
+ devices_mutex_.Release();
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end(); ++it) {
@@ -453,24 +469,22 @@ bool TransportAdapterImpl::IsServerOriginatedConnectSupported() const {
}
bool TransportAdapterImpl::IsClientOriginatedConnectSupported() const {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_TRACE(logger_, "IsClientOriginatedConnectSupported");
return client_connection_listener_ != 0;
- LOG4CXX_TRACE(logger_, "exit");
}
void TransportAdapterImpl::ConnectionCreated(
- Connection* connection, const DeviceUID& device_id,
+ ConnectionSPtr connection, const DeviceUID& device_id,
const ApplicationHandle& app_handle) {
LOG4CXX_TRACE(logger_, "enter connection:" << connection << ", device_id: " << &device_id
<< ", app_handle: " << &app_handle);
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForReading();
ConnectionInfo& info = connections_[std::make_pair(device_id, app_handle)];
info.app_handle = app_handle;
info.device_id = device_id;
info.connection = connection;
info.state = ConnectionInfo::NEW;
- pthread_mutex_unlock(&connections_mutex_);
- LOG4CXX_TRACE(logger_, "exit");
+ connections_lock_.Release();
}
void TransportAdapterImpl::DeviceDisconnected(
@@ -488,42 +502,55 @@ void TransportAdapterImpl::DeviceDisconnected(
}
}
- pthread_mutex_lock(&connections_mutex_);
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end(); ++it) {
TransportAdapterListener* listener = *it;
listener->OnDisconnectDeviceDone(this, device_uid);
}
+
+ connections_lock_.AcquireForWriting();
for (ApplicationList::const_iterator i = app_list.begin(); i != app_list.end(); ++i) {
ApplicationHandle app_handle = *i;
connections_.erase(std::make_pair(device_uid, app_handle));
}
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
RemoveDevice(device_uid);
LOG4CXX_TRACE(logger_, "exit");
}
-void TransportAdapterImpl::DisconnectDone(
- const DeviceUID& device_handle, const ApplicationHandle& app_handle) {
- const DeviceUID device_uid = device_handle;
- const ApplicationHandle app_uid = app_handle;
- LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_uid << ", app_handle: " <<
- &app_uid);
- bool device_disconnected = true;
- pthread_mutex_lock(&connections_mutex_);
+bool TransportAdapterImpl::IsSingleApplication(const DeviceUID& device_uid,
+ const ApplicationHandle& app_uid) {
+ sync_primitives::AutoReadLock locker(connections_lock_);
for (ConnectionMap::const_iterator it = connections_.begin();
it != connections_.end(); ++it) {
const DeviceUID& current_device_id = it->first.first;
const ApplicationHandle& current_app_handle = it->first.second;
if (current_device_id == device_uid && current_app_handle != app_uid) {
- device_disconnected = false;
LOG4CXX_DEBUG(logger_,
"break. Condition: current_device_id == device_id && current_app_handle != app_handle");
- break;
+
+ return false;
}
}
- pthread_mutex_unlock(&connections_mutex_);
+ return true;
+}
+
+void TransportAdapterImpl::DisconnectDone(
+ const DeviceUID& device_handle, const ApplicationHandle& app_handle) {
+ const DeviceUID device_uid = device_handle;
+ const ApplicationHandle app_uid = app_handle;
+ LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_uid << ", app_handle: " <<
+ &app_uid);
+ DeviceSptr device = FindDevice(device_handle);
+ if (!device) {
+ LOG4CXX_WARN(logger_, "Device: uid " << &device_uid << " not found");
+ return;
+ }
+
+ bool device_disconnected = ToBeAutoDisconnected(device) &&
+ IsSingleApplication(device_uid, app_uid);
+
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end(); ++it) {
TransportAdapterListener* listener = *it;
@@ -532,9 +559,9 @@ void TransportAdapterImpl::DisconnectDone(
listener->OnDisconnectDeviceDone(this, device_uid);
}
}
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForWriting();
connections_.erase(std::make_pair(device_uid, app_uid));
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
if (device_disconnected) {
RemoveDevice(device_uid);
@@ -600,14 +627,13 @@ DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const {
LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id);
DeviceSptr ret;
LOG4CXX_DEBUG(logger_, "devices_.size() = " << devices_.size());
- pthread_mutex_lock(&devices_mutex_);
+ sync_primitives::AutoLock locker(devices_mutex_);
DeviceMap::const_iterator it = devices_.find(device_id);
if (it != devices_.end()) {
ret = it->second;
} else {
LOG4CXX_WARN(logger_, "Device " << device_id << " not found.");
}
- pthread_mutex_unlock(&devices_mutex_);
LOG4CXX_TRACE(logger_, "exit with DeviceSptr: " << ret);
return ret;
}
@@ -616,14 +642,14 @@ void TransportAdapterImpl::ConnectDone(const DeviceUID& device_id,
const ApplicationHandle& app_handle) {
LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id << ", app_handle: " <<
&app_handle);
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForReading();
ConnectionMap::iterator it_conn =
connections_.find(std::make_pair(device_id, app_handle));
if (it_conn != connections_.end()) {
ConnectionInfo& info = it_conn->second;
info.state = ConnectionInfo::ESTABLISHED;
}
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end(); ++it) {
@@ -640,9 +666,9 @@ void TransportAdapterImpl::ConnectFailed(const DeviceUID& device_handle,
const ApplicationHandle app_uid = app_handle;
LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_uid << ", app_handle: " <<
&app_uid << ", error: " << &error);
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForWriting();
connections_.erase(std::make_pair(device_uid, app_uid));
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end(); ++it) {
(*it)->OnConnectFailed(this, device_uid, app_uid, error);
@@ -674,15 +700,14 @@ void TransportAdapterImpl::ConnectionFinished(
const DeviceUID& device_id, const ApplicationHandle& app_handle) {
LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id << ", app_handle: " <<
&app_handle);
- pthread_mutex_lock(&connections_mutex_);
+ connections_lock_.AcquireForReading();
ConnectionMap::iterator it =
connections_.find(std::make_pair(device_id, app_handle));
if (it != connections_.end()) {
ConnectionInfo& info = it->second;
info.state = ConnectionInfo::FINALISING;
}
- pthread_mutex_unlock(&connections_mutex_);
- LOG4CXX_TRACE(logger_, "exit");
+ connections_lock_.Release();
}
void TransportAdapterImpl::ConnectionAborted(
@@ -763,12 +788,16 @@ bool TransportAdapterImpl::ToBeAutoConnected(DeviceSptr device) const {
return false;
}
-Connection* TransportAdapterImpl::FindEstablishedConnection(
+bool TransportAdapterImpl::ToBeAutoDisconnected(DeviceSptr device) const {
+ return true;
+}
+
+ConnectionSPtr TransportAdapterImpl::FindEstablishedConnection(
const DeviceUID& device_id, const ApplicationHandle& app_handle) const {
LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id << ", app_handle: " <<
&app_handle);
- Connection* connection = NULL;
- pthread_mutex_lock(&connections_mutex_);
+ ConnectionSPtr connection;
+ connections_lock_.AcquireForReading();
ConnectionMap::const_iterator it =
connections_.find(std::make_pair(device_id, app_handle));
if (it != connections_.end()) {
@@ -777,7 +806,7 @@ Connection* TransportAdapterImpl::FindEstablishedConnection(
connection = info.connection;
}
}
- pthread_mutex_unlock(&connections_mutex_);
+ connections_lock_.Release();
LOG4CXX_TRACE(logger_, "exit with Connection: " << connection);
return connection;
}
@@ -820,10 +849,10 @@ TransportAdapter::Error TransportAdapterImpl::ConnectDevice(DeviceSptr device) {
}
void TransportAdapterImpl::RemoveDevice(const DeviceUID& device_handle) {
- LOG4CXX_TRACE(logger_, "enter. device_handle: " << &device_handle);
- pthread_mutex_lock(&devices_mutex_);
- DeviceMap::iterator i = devices_.find(
- device_handle); //ykazakov: there is no erase for const iterator on QNX
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Device_handle: " << &device_handle);
+ sync_primitives::AutoLock locker(devices_mutex_);
+ DeviceMap::iterator i = devices_.find(device_handle);
if (i != devices_.end()) {
DeviceSptr device = i->second;
if (!device->keep_on_disconnect()) {
@@ -835,11 +864,7 @@ void TransportAdapterImpl::RemoveDevice(const DeviceUID& device_handle) {
}
}
}
- pthread_mutex_unlock(&devices_mutex_);
- LOG4CXX_TRACE(logger_, "exit");
}
-
} // namespace transport_adapter
-
} // namespace transport_manager
diff --git a/src/components/transport_manager/src/transport_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc
index ffd1b3d860..835c2c17ed 100644
--- a/src/components/transport_manager/src/transport_manager_default.cc
+++ b/src/components/transport_manager/src/transport_manager_default.cc
@@ -43,7 +43,6 @@
#include "transport_manager/bluetooth/bluetooth_transport_adapter.h"
#endif
-// CUSTOMER_PASA
#if defined(USB_SUPPORT)
#include "transport_manager/usb/usb_aoa_adapter.h"
@@ -72,6 +71,8 @@ int TransportManagerDefault::Init() {
#endif // TIME_TESTER
AddTransportAdapter(ta);
#endif
+
+
uint16_t port = profile::Profile::instance()->transport_manager_tcp_adapter_port();
ta = new transport_adapter::TcpTransportAdapter(port);
#ifdef TIME_TESTER
@@ -81,7 +82,6 @@ int TransportManagerDefault::Init() {
#endif // TIME_TESTER
AddTransportAdapter(ta);
-// CUSTOMER_PASA
#if defined(USB_SUPPORT)
ta = new transport_adapter::UsbAoaAdapter();
diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc
index 0ee1d3304d..6c3edd7b91 100644
--- a/src/components/transport_manager/src/transport_manager_impl.cc
+++ b/src/components/transport_manager/src/transport_manager_impl.cc
@@ -32,7 +32,6 @@
#include "transport_manager/transport_manager_impl.h"
-#include <pthread.h>
#include <stdint.h>
#include <cstring>
#include <queue>
@@ -70,22 +69,20 @@ TransportManagerImpl::Connection TransportManagerImpl::convert(
}
TransportManagerImpl::TransportManagerImpl()
- : all_thread_active_(false),
- device_listener_thread_wakeup_(),
- is_initialized_(false),
+ : is_initialized_(false),
#ifdef TIME_TESTER
metric_observer_(NULL),
#endif // TIME_TESTER
connection_id_counter_(0),
message_queue_("TM MessageQueue", this),
event_queue_("TM EventQueue", this) {
- LOG4CXX_INFO(logger_, "==============================================");
- pthread_cond_init(&device_listener_thread_wakeup_, NULL);
- LOG4CXX_DEBUG(logger_, "TransportManager object created");
+ LOG4CXX_TRACE(logger_, "TransportManager has created");
}
TransportManagerImpl::~TransportManagerImpl() {
LOG4CXX_DEBUG(logger_, "TransportManager object destroying");
+ message_queue_.Shutdown();
+ event_queue_.Shutdown();
for (std::vector<TransportAdapter*>::iterator it =
transport_adapters_.begin();
@@ -99,7 +96,6 @@ TransportManagerImpl::~TransportManagerImpl() {
delete it->second;
}
- pthread_cond_destroy(&device_listener_thread_wakeup_);
LOG4CXX_INFO(logger_, "TransportManager object destroyed");
}
@@ -226,18 +222,48 @@ int TransportManagerImpl::AddEventListener(TransportManagerListener* listener) {
return E_SUCCESS;
}
+void TransportManagerImpl::DisconnectAllDevices() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ for (DeviceInfoList::iterator i = device_list_.begin();
+ i != device_list_.end(); ++i) {
+ DeviceInfo& device = i->second;
+ DisconnectDevice(device.device_handle());
+ }
+}
+
+void TransportManagerImpl::TerminateAllAdapters() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ for (std::vector<TransportAdapter*>::iterator i = transport_adapters_.begin();
+ i != transport_adapters_.end(); ++i) {
+ (*i)->Terminate();
+ }
+}
+
+int TransportManagerImpl::InitAllAdapters() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ for (std::vector<TransportAdapter*>::iterator i = transport_adapters_.begin();
+ i != transport_adapters_.end(); ++i) {
+ if ((*i)->Init() != TransportAdapter::OK) {
+ return E_ADAPTERS_FAIL;
+ }
+ }
+ return E_SUCCESS;
+}
+
int TransportManagerImpl::Stop() {
- LOG4CXX_TRACE(logger_, "enter");
- if (!all_thread_active_) {
- LOG4CXX_TRACE(logger_,
- "exit with E_TM_IS_NOT_INITIALIZED. Condition: !all_thread_active_");
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (!is_initialized_) {
+ LOG4CXX_WARN(logger_, "TransportManager is not initialized_");
return E_TM_IS_NOT_INITIALIZED;
}
- all_thread_active_ = false;
- pthread_cond_signal(&device_listener_thread_wakeup_);
+ message_queue_.Shutdown();
+ event_queue_.Shutdown();
- LOG4CXX_TRACE(logger_, "exit with E_SUCCESS");
+ DisconnectAllDevices();
+ TerminateAllAdapters();
+
+ is_initialized_ = false;
return E_SUCCESS;
}
@@ -390,12 +416,19 @@ int TransportManagerImpl::SearchDevices() {
int TransportManagerImpl::Init() {
LOG4CXX_TRACE(logger_, "enter");
- all_thread_active_ = true;
is_initialized_ = true;
LOG4CXX_TRACE(logger_, "exit with E_SUCCESS");
return E_SUCCESS;
}
+int TransportManagerImpl::Reinit() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DisconnectAllDevices();
+ TerminateAllAdapters();
+ int ret = InitAllAdapters();
+ return ret;
+}
+
int TransportManagerImpl::Visibility(const bool& on_off) const {
LOG4CXX_TRACE(logger_, "enter. On_off: " << &on_off);
TransportAdapter::Error ret;
@@ -478,10 +511,9 @@ void TransportManagerImpl::PostMessage(const ::protocol_handler::RawMessagePtr m
}
void TransportManagerImpl::PostEvent(const TransportAdapterEvent& event) {
- LOG4CXX_TRACE(logger_, "enter. TransportAdapterEvent: " << &event);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "TransportAdapterEvent: " << &event);
event_queue_.PostMessage(event);
- pthread_cond_signal(&device_listener_thread_wakeup_);
- LOG4CXX_TRACE(logger_, "exit");
}
void TransportManagerImpl::AddConnection(const ConnectionInternal& c) {
diff --git a/src/components/transport_manager/src/usb/libusb/platform_usb_device.cc b/src/components/transport_manager/src/usb/libusb/platform_usb_device.cc
index 103e03a4f6..1ca1a54b32 100644
--- a/src/components/transport_manager/src/usb/libusb/platform_usb_device.cc
+++ b/src/components/transport_manager/src/usb/libusb/platform_usb_device.cc
@@ -1,4 +1,4 @@
-/**
+/*
*
* Copyright (c) 2013, Ford Motor Company
* All rights reserved.
diff --git a/src/components/transport_manager/src/usb/libusb/usb_connection.cc b/src/components/transport_manager/src/usb/libusb/usb_connection.cc
index 40891d3513..b8096514bc 100644
--- a/src/components/transport_manager/src/usb/libusb/usb_connection.cc
+++ b/src/components/transport_manager/src/usb/libusb/usb_connection.cc
@@ -30,6 +30,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <pthread.h>
#include <unistd.h>
#include <iomanip>
@@ -51,7 +52,7 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
UsbConnection::UsbConnection(const DeviceUID& device_uid,
const ApplicationHandle& app_handle,
TransportAdapterController* controller,
- const UsbHandlerSptr& usb_handler,
+ const UsbHandlerSptr usb_handler,
PlatformUsbDevice* device)
: device_uid_(device_uid),
app_handle_(app_handle),
diff --git a/src/components/transport_manager/src/usb/libusb/usb_handler.cc b/src/components/transport_manager/src/usb/libusb/usb_handler.cc
index eb0ffdb4dc..776bb56c5d 100644
--- a/src/components/transport_manager/src/usb/libusb/usb_handler.cc
+++ b/src/components/transport_manager/src/usb/libusb/usb_handler.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_handler.cc
* \brief UsbHandler class source file.
*
@@ -39,7 +39,9 @@
#include "transport_manager/usb/common.h"
#include "transport_manager/transport_adapter/transport_adapter_impl.h"
+#include "utils/macro.h"
#include "utils/logger.h"
+#include "utils/threads/thread.h"
namespace transport_manager {
namespace transport_adapter {
@@ -75,14 +77,16 @@ class UsbHandler::ControlTransferSequenceState {
UsbHandler::UsbHandler()
: shutdown_requested_(false),
- thread_(),
+ thread_(NULL),
usb_device_listeners_(),
devices_(),
transfer_sequences_(),
device_handles_to_close_(),
libusb_context_(NULL),
arrived_callback_handle_(),
- left_callback_handle_() {}
+ left_callback_handle_() {
+ thread_ = threads::CreateThread("UsbHandler", new UsbHandlerDelegate(this));
+}
UsbHandler::~UsbHandler() {
shutdown_requested_ = true;
@@ -91,12 +95,15 @@ UsbHandler::~UsbHandler() {
arrived_callback_handle_);
libusb_hotplug_deregister_callback(libusb_context_, left_callback_handle_);
}
- pthread_join(thread_, 0);
+ thread_->stop();
LOG4CXX_INFO(logger_, "UsbHandler thread finished");
if (libusb_context_) {
libusb_exit(libusb_context_);
libusb_context_ = 0;
}
+ thread_->join();
+ delete thread_->delegate();
+ threads::DeleteThread(thread_);
}
void UsbHandler::DeviceArrived(libusb_device* device_libusb) {
@@ -209,11 +216,6 @@ void UsbHandler::CloseDeviceHandle(libusb_device_handle* device_handle) {
device_handles_to_close_.push_back(device_handle);
}
-void* UsbHandlerThread(void* data) {
- static_cast<UsbHandler*>(data)->Thread();
- return 0;
-}
-
int ArrivedCallback(libusb_context* context, libusb_device* device,
libusb_hotplug_event event, void* data) {
LOG4CXX_TRACE(logger_, "enter. libusb device arrived (bus number "
@@ -286,19 +288,12 @@ TransportAdapter::Error UsbHandler::Init() {
return TransportAdapter::FAIL;
}
- const int thread_start_error =
- pthread_create(&thread_, 0, &UsbHandlerThread, this);
- if (0 != thread_start_error) {
- LOG4CXX_ERROR(logger_, "USB device scanner thread start failed, error code "
- << thread_start_error);
+ if (!thread_->start()) {
+ LOG4CXX_ERROR(logger_, "USB device scanner thread start failed, error code");
LOG4CXX_TRACE(logger_,
- "exit with TransportAdapter::FAIL. Condition: 0 !== thread_start_error");
+ "exit with TransportAdapter::FAIL.");
return TransportAdapter::FAIL;
}
- LOG4CXX_INFO(logger_, "UsbHandler thread started");
- pthread_setname_np(thread_, "UsbHandler" );
- LOG4CXX_TRACE(logger_,
- "exit with TransportAdapter::OK. Condition: 0 == thread_start_error");
return TransportAdapter::OK;
}
@@ -357,13 +352,13 @@ void UsbHandler::SubmitControlTransfer(
assert(transfer->Type() == UsbControlTransfer::VENDOR);
const libusb_request_type request_type = LIBUSB_REQUEST_TYPE_VENDOR;
- libusb_endpoint_direction endpoint_direction;
+ libusb_endpoint_direction endpoint_direction = LIBUSB_ENDPOINT_IN;
if (transfer->Direction() == UsbControlTransfer::IN) {
endpoint_direction = LIBUSB_ENDPOINT_IN;
} else if (transfer->Direction() == UsbControlTransfer::OUT) {
endpoint_direction = LIBUSB_ENDPOINT_OUT;
} else {
- assert(0);
+ NOTREACHED();
}
const uint8_t request = transfer->Request();
const uint16_t value = transfer->Value();
@@ -470,5 +465,16 @@ void UsbHandler::ControlTransferSequenceState::Finish() {
finished_ = true;
}
-} // namespace
-} // namespace
+UsbHandler::UsbHandlerDelegate::UsbHandlerDelegate(
+ UsbHandler* handler)
+ : handler_(handler) {
+}
+
+void UsbHandler::UsbHandlerDelegate::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(handler_);
+ handler_->Thread();
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/src/usb/qnx/platform_usb_device.cc b/src/components/transport_manager/src/usb/qnx/platform_usb_device.cc
index 0f35a16ae7..132fe52cae 100644
--- a/src/components/transport_manager/src/usb/qnx/platform_usb_device.cc
+++ b/src/components/transport_manager/src/usb/qnx/platform_usb_device.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file platform_usb_device.cc
* \brief QNX PlatformUsbDevice class source file.
*
diff --git a/src/components/transport_manager/src/usb/qnx/usb_connection.cc b/src/components/transport_manager/src/usb/qnx/usb_connection.cc
index db3cac014d..a3844b2e04 100644
--- a/src/components/transport_manager/src/usb/qnx/usb_connection.cc
+++ b/src/components/transport_manager/src/usb/qnx/usb_connection.cc
@@ -50,7 +50,7 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
UsbConnection::UsbConnection(const DeviceUID& device_uid,
const ApplicationHandle& app_handle,
TransportAdapterController* controller,
- const UsbHandlerSptr& libusb_handler,
+ const UsbHandlerSptr libusb_handler,
PlatformUsbDevice* device)
: device_uid_(device_uid),
app_handle_(app_handle),
@@ -60,6 +60,7 @@ UsbConnection::UsbConnection(const DeviceUID& device_uid,
in_pipe_(NULL),
out_pipe_(NULL),
in_buffer_(NULL),
+ out_buffer_(NULL),
in_urb_(NULL),
out_urb_(NULL),
out_messages_(),
@@ -69,7 +70,6 @@ UsbConnection::UsbConnection(const DeviceUID& device_uid,
disconnecting_(false),
pending_in_transfer_(false),
pending_out_transfer_(false) {
- pthread_mutex_init(&out_messages_mutex_, 0);
}
UsbConnection::~UsbConnection() {
@@ -89,8 +89,6 @@ UsbConnection::~UsbConnection() {
LOG4CXX_ERROR(logger_, "Failed to close pipe: " << close_pipe_rc);
}
}
-
- pthread_mutex_destroy(&out_messages_mutex_);
}
void InTransferCallback(usbd_urb* urb, usbd_pipe*, void* data) {
@@ -212,7 +210,7 @@ void UsbConnection::OnOutTransfer(usbd_urb* urb) {
}
}
- pthread_mutex_lock(&out_messages_mutex_);
+ sync_primitives::AutoLock locker(out_messages_mutex_);
if (error) {
LOG4CXX_ERROR(logger_, "USB out transfer failed");
@@ -234,14 +232,13 @@ void UsbConnection::OnOutTransfer(usbd_urb* urb) {
} else {
pending_out_transfer_ = false;
}
- pthread_mutex_unlock(&out_messages_mutex_);
}
TransportAdapter::Error UsbConnection::SendData(::protocol_handler::RawMessagePtr message) {
if (disconnecting_) {
return TransportAdapter::BAD_STATE;
}
- pthread_mutex_lock(&out_messages_mutex_);
+ sync_primitives::AutoLock locker(out_messages_mutex_);
if (current_out_message_.valid()) {
out_messages_.push_back(message);
} else {
@@ -251,13 +248,12 @@ TransportAdapter::Error UsbConnection::SendData(::protocol_handler::RawMessagePt
DataSendError());
}
}
- pthread_mutex_unlock(&out_messages_mutex_);
return TransportAdapter::OK;
}
void UsbConnection::Finalise() {
LOG4CXX_INFO(logger_, "Finalising");
- pthread_mutex_lock(&out_messages_mutex_);
+ sync_primitives::AutoLock locker(out_messages_mutex_);
disconnecting_ = true;
usbd_abort_pipe(in_pipe_);
usbd_abort_pipe(out_pipe_);
@@ -265,7 +261,6 @@ void UsbConnection::Finalise() {
it != out_messages_.end(); it = out_messages_.erase(it)) {
controller_->DataSendFailed(device_uid_, app_handle_, *it, DataSendError());
}
- pthread_mutex_unlock(&out_messages_mutex_);
while (pending_in_transfer_ || pending_out_transfer_) sched_yield();
}
diff --git a/src/components/transport_manager/src/usb/qnx/usb_handler.cc b/src/components/transport_manager/src/usb/qnx/usb_handler.cc
index 7ab36169b1..d78b6c8184 100644
--- a/src/components/transport_manager/src/usb/qnx/usb_handler.cc
+++ b/src/components/transport_manager/src/usb/qnx/usb_handler.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_handler.cc
* \brief UsbHandler class source file.
*
diff --git a/src/components/transport_manager/src/usb/usb_aoa_adapter.cc b/src/components/transport_manager/src/usb/usb_aoa_adapter.cc
index 464b9ea35e..b3ebb104dc 100644
--- a/src/components/transport_manager/src/usb/usb_aoa_adapter.cc
+++ b/src/components/transport_manager/src/usb/usb_aoa_adapter.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file usb_aoa_adapter.cpp
* \brief UsbAoaAdapter class source file.
*
diff --git a/src/components/transport_manager/src/usb/usb_connection_factory.cc b/src/components/transport_manager/src/usb/usb_connection_factory.cc
index d57391ebcc..4562473536 100644
--- a/src/components/transport_manager/src/usb/usb_connection_factory.cc
+++ b/src/components/transport_manager/src/usb/usb_connection_factory.cc
@@ -54,7 +54,7 @@ TransportAdapter::Error UsbConnectionFactory::Init() {
return TransportAdapter::OK;
}
-void UsbConnectionFactory::SetUsbHandler(const UsbHandlerSptr& usb_handler) {
+void UsbConnectionFactory::SetUsbHandler(const UsbHandlerSptr usb_handler) {
usb_handler_ = usb_handler;
}
diff --git a/src/components/transport_manager/src/usb/usb_device_scanner.cc b/src/components/transport_manager/src/usb/usb_device_scanner.cc
index bf9535941c..bddc20dd3c 100644
--- a/src/components/transport_manager/src/usb/usb_device_scanner.cc
+++ b/src/components/transport_manager/src/usb/usb_device_scanner.cc
@@ -47,7 +47,8 @@ CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
class AoaInitSequence : public UsbControlTransferSequence {
public:
AoaInitSequence();
- virtual ~AoaInitSequence() {}
+ virtual ~AoaInitSequence() {
+ }
private:
class AoaGetProtocolRequest;
@@ -56,7 +57,7 @@ class AoaInitSequence : public UsbControlTransferSequence {
};
void UsbDeviceScanner::OnDeviceArrived(PlatformUsbDevice* device) {
- LOG4CXX_TRACE(logger_, "enter. PlatformUsbDevice* " << device);
+ LOG4CXX_AUTO_TRACE(logger_);
if (IsAppleDevice(device)) {
SupportedDeviceFound(device);
} else {
@@ -66,13 +67,13 @@ void UsbDeviceScanner::OnDeviceArrived(PlatformUsbDevice* device) {
TurnIntoAccessoryMode(device);
}
}
- LOG4CXX_TRACE(logger_, "exit");
}
void UsbDeviceScanner::OnDeviceLeft(PlatformUsbDevice* device) {
- LOG4CXX_TRACE(logger_, "enter. PlatformUsbDevice " << device);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "PlatformUsbDevice " << device);
bool list_changed = false;
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
for (Devices::iterator it = devices_.begin(); it != devices_.end(); ++it) {
if (device == *it) {
devices_.erase(it);
@@ -80,24 +81,22 @@ void UsbDeviceScanner::OnDeviceLeft(PlatformUsbDevice* device) {
break;
}
}
- pthread_mutex_unlock(&devices_mutex_);
+ devices_mutex_.Release();
if (list_changed) {
UpdateList();
}
- LOG4CXX_TRACE(logger_, "exit");
}
UsbDeviceScanner::UsbDeviceScanner(TransportAdapterController* controller)
- : controller_(controller) {
- pthread_mutex_init(&devices_mutex_, 0);
+ : controller_(controller) {
}
UsbDeviceScanner::~UsbDeviceScanner() {
- pthread_mutex_destroy(&devices_mutex_);
}
class AoaInitSequence::AoaGetProtocolRequest : public UsbControlInTransfer {
- virtual ~AoaGetProtocolRequest() {}
+ virtual ~AoaGetProtocolRequest() {
+ }
virtual RequestType Type() const {
return VENDOR;
}
@@ -115,7 +114,7 @@ class AoaInitSequence::AoaGetProtocolRequest : public UsbControlInTransfer {
}
virtual bool OnCompleted(unsigned char* data) const {
const int protocol_version = data[1] << 8 | data[0];
- LOG4CXX_INFO(logger_, "AOA protocol version " << protocol_version);
+ LOG4CXX_DEBUG(logger_, "AOA protocol version " << protocol_version);
if (protocol_version == 0) {
// AOA protocol not supported
return false;
@@ -127,10 +126,14 @@ class AoaInitSequence::AoaGetProtocolRequest : public UsbControlInTransfer {
class AoaInitSequence::AoaSendIdString : public UsbControlOutTransfer {
public:
AoaSendIdString(uint16_t index, const char* string, uint16_t length)
- : index_(index), string_(string), length_(length) {}
+ : index_(index),
+ string_(string),
+ length_(length) {
+ }
private:
- virtual ~AoaSendIdString() {}
+ virtual ~AoaSendIdString() {
+ }
virtual RequestType Type() const {
return VENDOR;
}
@@ -155,7 +158,8 @@ class AoaInitSequence::AoaSendIdString : public UsbControlOutTransfer {
};
class AoaInitSequence::AoaTurnIntoAccessoryMode : public UsbControlOutTransfer {
- virtual ~AoaTurnIntoAccessoryMode() {}
+ virtual ~AoaTurnIntoAccessoryMode() {
+ }
virtual RequestType Type() const {
return VENDOR;
}
@@ -183,7 +187,8 @@ static char version[] = "1.0";
static char uri[] = "http://www.ford.com";
static char serial_num[] = "N000000";
-AoaInitSequence::AoaInitSequence() : UsbControlTransferSequence() {
+AoaInitSequence::AoaInitSequence()
+ : UsbControlTransferSequence() {
AddTransfer(new AoaGetProtocolRequest);
AddTransfer(new AoaSendIdString(0, manufacturer, sizeof(manufacturer)));
AddTransfer(new AoaSendIdString(1, model_name, sizeof(model_name)));
@@ -195,25 +200,26 @@ AoaInitSequence::AoaInitSequence() : UsbControlTransferSequence() {
}
void UsbDeviceScanner::TurnIntoAccessoryMode(PlatformUsbDevice* device) {
- LOG4CXX_TRACE(logger_, "enter. PlatformUsbDevice: " << device);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "PlatformUsbDevice: " << device);
GetUsbHandler()->StartControlTransferSequence(new AoaInitSequence, device);
- LOG4CXX_TRACE(logger_, "exit");
}
void UsbDeviceScanner::SupportedDeviceFound(PlatformUsbDevice* device) {
- LOG4CXX_TRACE(logger_, "enter PlatformUsbDevice: " << device);
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_TRACE(logger_, "PlatformUsbDevice: " << device);
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
devices_.push_back(device);
- pthread_mutex_unlock(&devices_mutex_);
- LOG4CXX_INFO(logger_, "USB device (bus number "
- << static_cast<int>(device->bus_number())
- << ", address "
- << static_cast<int>(device->address())
- << ") identified as: " << device->GetManufacturer()
- << ", " << device->GetProductName());
+ devices_mutex_.Release();
+ LOG4CXX_DEBUG(
+ logger_,
+ "USB device (bus number " << static_cast<int>(device->bus_number())
+ << ", address " << static_cast<int>(device->address())
+ << ") identified as: " << device->GetManufacturer()
+ << ", " << device->GetProductName()
+ << ", serial: " << device->GetSerialNumber());
UpdateList();
- LOG4CXX_TRACE(logger_, "exit");
}
TransportAdapter::Error UsbDeviceScanner::Init() {
@@ -225,30 +231,28 @@ TransportAdapter::Error UsbDeviceScanner::Scan() {
}
void UsbDeviceScanner::UpdateList() {
- LOG4CXX_TRACE(logger_, "enter");
+ LOG4CXX_AUTO_TRACE(logger_);
DeviceVector device_vector;
- pthread_mutex_lock(&devices_mutex_);
+ devices_mutex_.Acquire();
for (Devices::const_iterator it = devices_.begin(); it != devices_.end();
- ++it) {
- const std::string device_name =
- (*it)->GetManufacturer() + " " + (*it)->GetProductName();
+ ++it) {
+ const std::string device_name = (*it)->GetManufacturer() + " "
+ + (*it)->GetProductName();
std::ostringstream oss;
oss << (*it)->GetManufacturer() << ":" << (*it)->GetProductName() << ":"
- << (*it)->GetSerialNumber() << ":"
- << static_cast<int>((*it)->bus_number()) << ":"
- << static_cast<int>((*it)->address());
+ << (*it)->GetSerialNumber();
const DeviceUID device_uid = oss.str();
DeviceSptr device(new UsbDevice(*it, device_name, device_uid));
device_vector.push_back(device);
}
- pthread_mutex_unlock(&devices_mutex_);
+ devices_mutex_.Release();
- LOG4CXX_INFO(logger_, "USB search done " << device_vector.size());
+ LOG4CXX_DEBUG(logger_, "USB search done " << device_vector.size());
controller_->SearchDeviceDone(device_vector);
- LOG4CXX_TRACE(logger_, "exit");
}
-void UsbDeviceScanner::Terminate() {}
+void UsbDeviceScanner::Terminate() {
+}
bool UsbDeviceScanner::IsInitialised() const {
return true;
diff --git a/src/components/transport_manager/test/CMakeLists.txt b/src/components/transport_manager/test/CMakeLists.txt
new file mode 100644
index 0000000000..630b85b8a6
--- /dev/null
+++ b/src/components/transport_manager/test/CMakeLists.txt
@@ -0,0 +1,85 @@
+# Copyright (c) 2014, Ford Motor Company
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided with the
+# distribution.
+#
+# Neither the name of the Ford Motor Company nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+if(BUILD_TESTS)
+
+include_directories(
+ ${LOG4CXX_INCLUDE_DIRECTORY}
+ ${GMOCK_INCLUDE_DIRECTORY}
+ ${COMPONENTS_DIR}/smart_objects/include
+ ${COMPONENTS_DIR}/transport_manager/include
+ ${COMPONENTS_DIR}/utils/include
+ ${COMPONENTS_DIR}/include
+ ${COMPONENTS_DIR}/connection_handler/include
+ ${JSONCPP_INCLUDE_DIRECTORY}
+ ${CMAKE_BINARY_DIR}
+)
+
+set(LIBRARIES
+ gmock
+ ConfigProfile
+ transport_manager
+ ApplicationManagerTest
+ Utils
+ ConfigProfile
+ Resumption
+ jsoncpp
+)
+
+if (BUILD_USB_SUPPORT)
+ list(APPEND LIBRARIES Libusb-1.0.16)
+endif()
+
+if (BUILD_BT_SUPPORT)
+ list(APPEND LIBRARIES bluetooth)
+endif()
+
+if (BUILD_AVAHI_SUPPORT)
+ list(APPEND LIBRARIES avahi-client avahi-common)
+endif()
+
+
+set(SOURCES
+ ${COMPONENTS_DIR}/transport_manager/test/main.cc
+ ${COMPONENTS_DIR}/transport_manager/test/mock_application.cc
+ ${COMPONENTS_DIR}/transport_manager/test/transport_manager_test.cc
+ ${COMPONENTS_DIR}/transport_manager/test/mock_connection_factory.cc
+ ${COMPONENTS_DIR}/transport_manager/test/mock_connection.cc
+ ${COMPONENTS_DIR}/transport_manager/test/mock_device.cc
+ ${COMPONENTS_DIR}/transport_manager/test/mock_device_scanner.cc
+ ${COMPONENTS_DIR}/transport_manager/test/raw_message_matcher.cc
+ ${COMPONENTS_DIR}/transport_manager/test/dnssd_service_browser_test.cc
+ ${COMPONENTS_DIR}/transport_manager/test/tcp_transport_adapter_test.cc
+ ${COMPONENTS_DIR}/transport_manager/test/mock_transport_adapter.cc
+)
+
+create_test("transport_manager_test" "${SOURCES}" "${LIBRARIES}")
+
+endif()
diff --git a/src/components/transport_manager/test/dnssd_service_browser_test.cc b/src/components/transport_manager/test/dnssd_service_browser_test.cc
new file mode 100644
index 0000000000..b496be58e2
--- /dev/null
+++ b/src/components/transport_manager/test/dnssd_service_browser_test.cc
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gmock/gmock.h"
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
+
+#include "transport_manager/transport_adapter/transport_adapter_controller.h"
+#include "transport_manager/tcp/dnssd_service_browser.h"
+#include "transport_manager/tcp/tcp_device.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+class MockTransportAdapterController: public TransportAdapterController {
+public:
+ MOCK_METHOD1(AddDevice,DeviceSptr(DeviceSptr device));
+ MOCK_METHOD1(SearchDeviceDone, void(const DeviceVector& devices));
+ MOCK_METHOD1(SearchDeviceFailed, void(const SearchDeviceError& error));
+ MOCK_CONST_METHOD1(FindDevice, DeviceSptr(const DeviceUID& device_handle));
+ MOCK_METHOD3(ConnectionCreated, void(ConnectionSPtr connection, const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD2(ConnectDone, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD3(ConnectFailed, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle, const ConnectError& error));
+ MOCK_METHOD2(ConnectionFinished, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD3(ConnectionAborted,void(const DeviceUID& device_handle, const ApplicationHandle& app_handle, const CommunicationError& error));
+ MOCK_METHOD2(DisconnectDone, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD3(DataReceiveDone, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle, const ::protocol_handler::RawMessagePtr message));
+ MOCK_METHOD3(DataReceiveFailed, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle, const DataReceiveError& error));
+ MOCK_METHOD3(DataSendDone, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle, const ::protocol_handler::RawMessagePtr message));
+ MOCK_METHOD4(DataSendFailed, void(const DeviceUID& device_handle, const ApplicationHandle& app_handle, const ::protocol_handler::RawMessagePtr message, const DataSendError& error));
+ MOCK_METHOD0(FindNewApplicationsRequest, void());
+ MOCK_METHOD1(ApplicationListUpdated, void(const DeviceUID& device_handle));
+ MOCK_METHOD2(DeviceDisconnected, void (const DeviceUID& device_handle,const DisconnectDeviceError& error));
+};
+
+in_addr_t GetIfaceAddress() {
+ in_addr_t result = 0;
+ ifaddrs* if_addrs = NULL;
+// void * tmpAddrPtr = NULL;
+
+ getifaddrs(&if_addrs);
+ for (ifaddrs* ifa = if_addrs; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr->sa_family == AF_INET) {
+ result = ((struct sockaddr_in *) ifa->ifa_addr)->sin_addr.s_addr;
+ if (result != htonl(INADDR_LOOPBACK)) {
+ break;
+ }
+ }
+ }
+ if (if_addrs)
+ freeifaddrs(if_addrs);
+ return result;
+}
+static in_addr_t iface_address = GetIfaceAddress();
+
+MATCHER_P(HasService, service_port, ""){
+for(DeviceVector::const_iterator it = arg.begin(); it != arg.end(); ++it) {
+ TcpDevice* tcp_device = dynamic_cast<TcpDevice*>(it->get());
+ if(tcp_device && tcp_device->in_addr() == iface_address) {
+ ApplicationList app_list = tcp_device->GetApplicationList();
+ for(ApplicationList::const_iterator it = app_list.begin(); it != app_list.end(); ++it) {
+ if(tcp_device->GetApplicationPort(*it) == service_port) {
+ return true;
+ }
+ }
+ }
+}
+return false;
+}
+
+// TODO{ALeshin} APPLINK-11090 - Infinite loop
+TEST(DnssdServiceBrowser, DISABLED_Basic) {
+ MockTransportAdapterController controller;
+
+ DnssdServiceBrowser dnssd_service_browser(&controller);
+ DeviceScanner& device_scanner = dnssd_service_browser;
+
+ const TransportAdapter::Error error = device_scanner.Init();
+ ASSERT_EQ(TransportAdapter::OK, error);
+
+ while (!device_scanner.IsInitialised()) {
+ sleep(0);
+ }
+ ASSERT_TRUE(device_scanner.IsInitialised());
+
+ EXPECT_EQ(TransportAdapter::NOT_SUPPORTED, device_scanner.Scan()); //method Scan now returns only NOT_SUPPORTED value
+
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/test/include/mock_application.h b/src/components/transport_manager/test/include/mock_application.h
new file mode 100644
index 0000000000..7ec71ebb1e
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_application.h
@@ -0,0 +1,80 @@
+/*
+ * mock_application.h
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MOCK_APPLICATION_H_
+#define MOCK_APPLICATION_H_
+
+#include <pthread.h>
+
+#include <sstream>
+#include <string>
+
+#include <transport_manager/common.h>
+#include <transport_manager/transport_manager.h>
+#include <transport_manager/transport_adapter/transport_adapter_impl.h>
+#include <transport_manager/transport_manager_impl.h>
+#include "mock_device_scanner.h"
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockDevice;
+using ::transport_manager::ApplicationHandle;
+
+class MockApplication {
+ public:
+ const MockDevice *device;
+ ApplicationHandle handle;
+ pthread_t workerThread;
+ pthread_cond_t ready_cond;
+ pthread_mutex_t ready_mutex;
+ int sockfd;
+ bool active;
+ private:
+ std::string socket_name_;
+ public:
+ MockApplication(const MockDevice* device, ApplicationHandle id);
+ void Start();
+ void Stop();
+ const std::string &socket_name() const {
+ return socket_name_;
+ }
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* MOCK_APPLICATION_H_ */
diff --git a/src/components/transport_manager/test/include/mock_connection.h b/src/components/transport_manager/test/include/mock_connection.h
new file mode 100644
index 0000000000..8f67107065
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_connection.h
@@ -0,0 +1,69 @@
+/*
+ * \file mock_connection.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKCONNECTION_H_
+#define APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKCONNECTION_H_
+
+#include "transport_manager/common.h"
+#include "transport_manager/error.h"
+#include "transport_manager/transport_adapter/transport_adapter_impl.h"
+#include "transport_manager/transport_adapter/threaded_socket_connection.h"
+
+using ::transport_manager::ApplicationHandle;
+using ::transport_manager::DeviceHandle;
+using ::transport_manager::transport_adapter::Connection;
+using ::transport_manager::transport_adapter::TransportAdapterController;
+using ::transport_manager::ConnectError;
+using ::transport_manager::transport_adapter::ThreadedSocketConnection;
+using ::transport_manager::transport_adapter::TransportAdapter;
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockTransportAdapter;
+
+class MockConnection : public ThreadedSocketConnection{
+ public:
+ MockConnection(const ::transport_manager::DeviceUID& device_handle,
+ const ApplicationHandle& app_handle,
+ TransportAdapterController* adapter);
+ bool Establish(ConnectError **error);
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKCONNECTION_H_ */
diff --git a/src/components/transport_manager/test/include/mock_connection_factory.h b/src/components/transport_manager/test/include/mock_connection_factory.h
new file mode 100644
index 0000000000..afead19cb6
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_connection_factory.h
@@ -0,0 +1,69 @@
+/*
+ * \file mock_connection_factory.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKCONNECTIONFACTORY_H_
+#define APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKCONNECTIONFACTORY_H_
+
+#include "transport_manager/transport_adapter/server_connection_factory.h"
+
+using ::transport_manager::ApplicationHandle;
+using ::transport_manager::DeviceHandle;
+using ::transport_manager::transport_adapter::TransportAdapter;
+using ::transport_manager::transport_adapter::ServerConnectionFactory;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockTransportAdapter;
+
+class MockConnectionFactory : public ServerConnectionFactory {
+ public:
+ MockConnectionFactory(MockTransportAdapter *adapter);
+ TransportAdapter::Error Init() { return TransportAdapter::OK; }
+ TransportAdapter::Error CreateConnection(const ::transport_manager::DeviceUID& device_handle,
+ const ApplicationHandle& app_handle);
+ void Terminate() {}
+ bool IsInitialised() const { return true; }
+
+ private:
+ MockTransportAdapter *controller_;
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKCONNECTIONFACTORY_H_ */
diff --git a/src/components/transport_manager/test/include/mock_device.h b/src/components/transport_manager/test/include/mock_device.h
new file mode 100644
index 0000000000..1225f851d7
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_device.h
@@ -0,0 +1,82 @@
+/*
+ * \file mock_device.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICE_H_
+#define APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICE_H_
+
+#include "transport_manager/common.h"
+#include "transport_manager/transport_adapter/transport_adapter_impl.h"
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include <transport_manager/transport_adapter/transport_adapter_impl.h>
+#include <transport_manager/transport_manager_impl.h>
+#include "mock_device_scanner.h"
+#include "mock_application.h"
+
+using ::transport_manager::ApplicationList;
+using ::transport_manager::transport_adapter::Device;
+using ::transport_manager::transport_adapter::TransportAdapterController;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockDevice : public ::transport_manager::transport_adapter::Device {
+
+ pthread_mutex_t device_started_mutex;
+ std::vector<MockApplication> applications_;
+ int applications_cnt_;
+ TransportAdapterController *controller_;
+ public:
+ MockDevice(const std::string& name, const std::string& id,
+ TransportAdapterController * controller)
+ : Device(name, id),
+ applications_cnt_(0),
+ controller_(controller) {
+ }
+ const ApplicationHandle addApplication();
+ void Start();
+ void Stop();
+ bool IsSameAs(const Device* other) const;
+ ApplicationList GetApplicationList() const;
+ bool operator == (const MockDevice &other);
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICE_H_ */
diff --git a/src/components/transport_manager/test/include/mock_device_scanner.h b/src/components/transport_manager/test/include/mock_device_scanner.h
new file mode 100644
index 0000000000..6ebae39a7c
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_device_scanner.h
@@ -0,0 +1,76 @@
+/*
+ * \file mock_device_scanner.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICESCANNER_H_
+#define APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICESCANNER_H_
+
+#include "transport_manager/transport_adapter/device_scanner.h"
+
+using ::transport_manager::transport_adapter::TransportAdapter;
+using ::transport_manager::transport_adapter::DeviceScanner;
+using ::transport_manager::transport_adapter::DeviceVector;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockTransportAdapter;
+
+class MockDeviceScanner : public DeviceScanner {
+ public:
+ MockDeviceScanner(MockTransportAdapter *adapter);
+ void reset();
+ void AddDevice(const std::string& name, const std::string& unique_id, bool start = true);
+ void RemoveDevice(const std::string& name);
+ void fail_further_search() { is_search_failed_ = true; }
+
+ protected:
+ TransportAdapter::Error Init();
+ TransportAdapter::Error Scan();
+ void Terminate();
+ bool IsInitialised() const;
+
+ private:
+ MockTransportAdapter *controller_;
+ DeviceVector devices_;
+ bool is_initialized_;
+ bool is_search_failed_;
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICESCANNER_H_ */
diff --git a/src/components/transport_manager/test/include/mock_transport_adapter.h b/src/components/transport_manager/test/include/mock_transport_adapter.h
new file mode 100644
index 0000000000..fef37f9b83
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_transport_adapter.h
@@ -0,0 +1,62 @@
+/*
+ * \file mock_transport_adapter.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICEADAPTER_H_
+#define APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICEADAPTER_H_
+
+#include "transport_manager/transport_adapter/transport_adapter_impl.h"
+
+using ::transport_manager::transport_adapter::TransportAdapterImpl;
+using ::transport_manager::transport_adapter::DeviceType;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockDeviceScanner;
+
+class MockTransportAdapter : public TransportAdapterImpl {
+ public:
+ MockTransportAdapter();
+ MockDeviceScanner* get_device_scanner() const;
+ DeviceType GetDeviceType() const { return "mock-adapter"; }
+ void reset();
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* APPLINK_TEST_COMPONENTS_TRANSPORTMANAGER_INCLUDE_MOCKDEVICEADAPTER_H_ */
diff --git a/src/components/transport_manager/test/include/mock_transport_adapter_listener.h b/src/components/transport_manager/test/include/mock_transport_adapter_listener.h
new file mode 100644
index 0000000000..e45564d275
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_transport_adapter_listener.h
@@ -0,0 +1,93 @@
+/*
+ * \file mock_transport_adapter_listener.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MOCK_transport_adapter_LISTENER_H_
+#define MOCK_transport_adapter_LISTENER_H_
+
+#include <gmock/gmock.h>
+
+#include "transport_manager/transport_adapter/transport_adapter_listener.h"
+
+using namespace transport_manager;
+using transport_manager::transport_adapter::TransportAdapter;
+using transport_manager::transport_adapter::TransportAdapterListener;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+using namespace ::protocol_handler;
+
+class MockTransportAdapterListener : public TransportAdapterListener {
+ public:
+ MOCK_METHOD1(OnSearchDeviceDone,
+ void(const TransportAdapter* transport_adapter));
+ MOCK_METHOD2(OnSearchDeviceFailed,
+ void(const TransportAdapter* transport_adapter, const SearchDeviceError& error));
+ MOCK_METHOD1(OnFindNewApplicationsRequest,
+ void(const TransportAdapter* adapter));
+ MOCK_METHOD1(OnDeviceListUpdated,
+ void(const TransportAdapter* transport_adapter));
+ MOCK_METHOD3(OnConnectDone,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD4(OnConnectFailed,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const ConnectError& error));
+ MOCK_METHOD4(OnUnexpectedDisconnect,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const CommunicationError& error));
+ MOCK_METHOD3(OnDisconnectDone,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD4(OnDisconnectFailed,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const DisconnectError& error));
+ MOCK_METHOD2(OnDisconnectDeviceDone,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle));
+ MOCK_METHOD3(OnDisconnectDeviceFailed,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const DisconnectDeviceError& error));
+ MOCK_METHOD4(OnDataSendDone,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const RawMessagePtr data_container));
+ MOCK_METHOD5(OnDataSendFailed,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const RawMessagePtr data_container, const DataSendError& error));
+ MOCK_METHOD4(OnDataReceiveDone,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const RawMessagePtr data_container));
+ MOCK_METHOD4(OnDataReceiveFailed,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle, const DataReceiveError& error));
+ MOCK_METHOD3(OnCommunicationError,
+ void(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle));
+ MOCK_METHOD3(OnConnectRequested, void(const TransportAdapter*, const DeviceUID&, const ApplicationHandle&));
+};
+
+}
+}
+}
+
+#endif /* MOCK_transport_adapter_LISTENER_H_ */
diff --git a/src/components/transport_manager/test/include/mock_transport_manager_listener.h b/src/components/transport_manager/test/include/mock_transport_manager_listener.h
new file mode 100644
index 0000000000..9518e1a92a
--- /dev/null
+++ b/src/components/transport_manager/test/include/mock_transport_manager_listener.h
@@ -0,0 +1,103 @@
+/*
+ * \file mock_transport_adapter_listener.h
+ * \brief
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MOCK_TRANSPORT_MANAGER_LISTENER_H
+#define MOCK_TRANSPORT_MANAGER_LISTENER_H
+
+#include <gmock/gmock.h>
+
+#include "transport_manager/common.h"
+#include "transport_manager/info.h"
+#include "transport_manager/transport_adapter/transport_adapter.h"
+#include "transport_manager/transport_manager_listener.h"
+
+using ::transport_manager::ApplicationList;
+using ::transport_manager::ApplicationHandle;
+using ::transport_manager::transport_adapter::TransportAdapter;
+using ::transport_manager::SearchDeviceError;
+using ::transport_manager::ConnectionUID;
+using ::transport_manager::ConnectError;
+using ::transport_manager::DisconnectError;
+using ::transport_manager::DisconnectDeviceError;
+using ::transport_manager::DataSendError;
+using ::transport_manager::DataReceiveError;
+using ::transport_manager::CommunicationError;
+using ::transport_manager::DeviceInfo;
+using ::transport_manager::DeviceHandle;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+class MockTransportManagerListener :
+ public ::transport_manager::TransportManagerListener {
+ public:
+ MOCK_METHOD1(OnDeviceListUpdated, void(const std::vector<DeviceInfo>&));
+ MOCK_METHOD0(OnFindNewApplicationsRequest, void());
+ MOCK_METHOD1(OnDeviceFound, void(const DeviceInfo &device_info));
+ MOCK_METHOD1(OnDeviceAdded, void(const DeviceInfo &device_info));
+ MOCK_METHOD1(OnDeviceRemoved, void(const DeviceInfo &device_info));
+ MOCK_METHOD0(OnNoDeviceFound, void());
+ MOCK_METHOD0(OnScanDevicesFinished, void());
+ MOCK_METHOD1(OnScanDevicesFailed, void(const SearchDeviceError& error));
+
+ MOCK_METHOD2(OnConnectionEstablished, void(const DeviceInfo& device_info,
+ const ConnectionUID &connection_id));
+ MOCK_METHOD2(OnConnectionFailed, void(const DeviceInfo& device_info,
+ const ConnectError& error));
+
+ MOCK_METHOD1(OnConnectionClosed, void(ConnectionUID connection_id));
+ MOCK_METHOD2(OnConnectionClosedFailure, void (ConnectionUID connection_id,
+ const DisconnectError& error));
+ MOCK_METHOD2(OnUnexpectedDisconnect, void (ConnectionUID connection_id,
+ const CommunicationError& error));
+ MOCK_METHOD2(OnDeviceConnectionLost, void (const DeviceHandle& device,
+ const DisconnectDeviceError& error));
+ MOCK_METHOD2(OnDisconnectFailed, void (const DeviceHandle& device,
+ const DisconnectDeviceError& error));
+
+ MOCK_METHOD1(OnTMMessageReceived, void(const RawMessagePtr data_container));
+ MOCK_METHOD2(OnTMMessageReceiveFailed, void(ConnectionUID connection_id,
+ const DataReceiveError& error));
+ MOCK_METHOD1(OnTMMessageSend, void(const RawMessagePtr message));
+ MOCK_METHOD2(OnTMMessageSendFailed, void(const DataSendError& error,
+ const RawMessagePtr message));
+};
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* MOCK_TRANSPORT_MANAGER_LISTENER_H */
diff --git a/src/components/transport_manager/test/include/raw_message_matcher.h b/src/components/transport_manager/test/include/raw_message_matcher.h
new file mode 100644
index 0000000000..89f1cdd182
--- /dev/null
+++ b/src/components/transport_manager/test/include/raw_message_matcher.h
@@ -0,0 +1,75 @@
+/*
+ * \file raw_message_matcher.h
+ * \brief matcher RawMessagePtr
+ *
+ * Copyright (c) 2013, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef APPLINK_TEST_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_RAW_MESSAGE_MATCHER_H_
+#define APPLINK_TEST_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_RAW_MESSAGE_MATCHER_H_
+
+#include <gmock/gmock.h>
+
+#include "transport_manager/common.h"
+#include "protocol/common.h"
+
+using ::testing::Matcher;
+using ::testing::MatcherInterface;
+using ::testing::MatchResultListener;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+using namespace ::protocol_handler;
+
+class RawMessageMatcher : public MatcherInterface<RawMessagePtr> {
+ public:
+ explicit RawMessageMatcher(RawMessagePtr ptr);
+
+ virtual bool MatchAndExplain(const RawMessagePtr ptr,
+ MatchResultListener* listener) const;
+ virtual void DescribeTo(::std::ostream* os) const;
+ virtual void DescribeNegationTo(::std::ostream* os) const;
+
+ private:
+ const RawMessagePtr ptr_;
+};
+
+inline const Matcher<RawMessagePtr> RawMessageEq(RawMessagePtr msg) {
+ return MakeMatcher(new RawMessageMatcher(msg));
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+#endif /* APPLINK_TEST_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_RAW_MESSAGE_MATCHER_H_ */
diff --git a/src/components/transport_manager/test/include/transport_manager_mock.h b/src/components/transport_manager/test/include/transport_manager_mock.h
new file mode 100644
index 0000000000..6593f992de
--- /dev/null
+++ b/src/components/transport_manager/test/include/transport_manager_mock.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_MOCK_H_
+#define TEST_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_MOCK_H_
+
+#include <gmock/gmock.h>
+#include <string>
+#include "transport_manager/transport_manager.h"
+#include "transport_manager/transport_adapter/transport_adapter_event.h"
+
+namespace test {
+namespace components {
+namespace transport_manager_test {
+
+using ::transport_manager::DeviceHandle;
+using ::transport_manager::ConnectionUID;
+using ::transport_manager::transport_adapter::TransportAdapter;
+using ::transport_manager::TransportAdapterEvent;
+using ::transport_manager::TransportManagerListener;
+/*
+ * MOCK implementation of ::transport_manager::TransportManager interface
+ */
+class TransportManagerMock: public ::transport_manager::TransportManager {
+ public:
+ MOCK_METHOD0(Init,
+ int());
+ MOCK_METHOD0(Reinit,
+ int());
+ MOCK_METHOD0(SearchDevices,
+ int());
+ MOCK_METHOD1(ConnectDevice,
+ int(const DeviceHandle &));
+ MOCK_METHOD1(DisconnectDevice,
+ int(const DeviceHandle &));
+ MOCK_METHOD1(Disconnect,
+ int(const ConnectionUID &));
+ MOCK_METHOD1(DisconnectForce,
+ int(const ConnectionUID &));
+ MOCK_METHOD1(SendMessageToDevice,
+ int(const ::protocol_handler::RawMessagePtr));
+ MOCK_METHOD1(ReceiveEventFromDevice,
+ int(const TransportAdapterEvent&));
+ MOCK_METHOD1(AddTransportAdapter,
+ int(TransportAdapter *));
+ MOCK_METHOD1(AddEventListener,
+ int(TransportManagerListener *));
+ MOCK_METHOD0(Stop,
+ int());
+ MOCK_METHOD1(RemoveDevice,
+ int(const DeviceHandle &));
+ MOCK_CONST_METHOD1(Visibility,
+ int(const bool &));
+};
+} // namespace transport_manager_test
+} // namespace components
+} // namespace test
+#endif // TEST_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_MOCK_H_
diff --git a/src/components/transport_manager/test/main.cc b/src/components/transport_manager/test/main.cc
new file mode 100644
index 0000000000..bc4c36c55a
--- /dev/null
+++ b/src/components/transport_manager/test/main.cc
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "gmock/gmock.h"
+
+int main(int argc, char** argv) {
+ testing::InitGoogleMock(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/components/transport_manager/test/mock_application.cc b/src/components/transport_manager/test/mock_application.cc
new file mode 100644
index 0000000000..72f99cb744
--- /dev/null
+++ b/src/components/transport_manager/test/mock_application.cc
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pthread.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include "include/mock_application.h"
+#include "include/mock_device.h"
+
+namespace {
+
+struct workerData {
+ int sockfd;
+};
+
+void *applicationWorker(void *p) {
+ workerData *data = static_cast<workerData*>(p);
+ char *buf = new char[2 * 1024 * 1024];
+ ssize_t len;
+
+ while (true) {
+ len = recv(data->sockfd, buf, 2 * 1024 * 1024, 0);
+ if (len == 0)
+ break;
+ send(data->sockfd, buf, len, 0);
+ }
+ delete[] buf;
+ delete data;
+ return NULL;
+}
+
+void * applicationListener(void *p) {
+ using test::components::transport_manager::MockApplication;
+ MockApplication *app = static_cast<MockApplication*>(p);
+
+ unlink(app->socket_name().c_str());
+
+ app->sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (app->sockfd == -1) {
+ // TODO: indicate error
+ return NULL;
+ }
+ sockaddr_un my_addr;
+ memset(&my_addr, 0, sizeof(my_addr));
+ strcpy(my_addr.sun_path, app->socket_name().c_str());
+ my_addr.sun_family = AF_UNIX;
+ int res = bind(app->sockfd, reinterpret_cast<sockaddr*>(&my_addr),
+ sizeof(my_addr));
+ if (res == -1) {
+ return NULL;
+ }
+
+ res = listen(app->sockfd, 5);
+ if (res == -1) {
+ return NULL;
+ }
+
+ pthread_mutex_lock(&app->ready_mutex);
+ app->active = true;
+ pthread_cond_signal(&app->ready_cond);
+ pthread_mutex_unlock(&app->ready_mutex);
+
+ while (app->active) {
+ socklen_t addr_size;
+ sockaddr peer_addr;
+
+ int peer_socket = accept(app->sockfd, &peer_addr, &addr_size);
+ if (peer_socket != -1) {
+ pthread_t t;
+ workerData* data = new workerData();
+ data->sockfd = peer_socket;
+ pthread_create(&t, NULL, &applicationWorker, data);
+ }
+ }
+
+ unlink(app->socket_name().c_str());
+
+ return NULL;
+}
+}
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+MockApplication::MockApplication(const MockDevice *device, ApplicationHandle id)
+ : device(device),
+ handle(id),
+ workerThread(0),
+ sockfd(-1),
+ active(false) {
+ std::ostringstream oss;
+ oss << "mockDevice" << device->unique_device_id() << "-" << id;
+ socket_name_ = oss.str();
+}
+
+void MockApplication::Start() {
+
+ pthread_cond_init(&ready_cond, NULL);
+ pthread_mutex_init(&ready_mutex, NULL);
+
+ pthread_mutex_lock(&ready_mutex);
+ pthread_create(&workerThread, NULL, &applicationListener, this);
+ pthread_cond_wait(&ready_cond, &ready_mutex);
+ pthread_mutex_unlock(&ready_mutex);
+}
+
+void MockApplication::Stop() {
+ active = false;
+ shutdown(sockfd, SHUT_RDWR);
+ close(sockfd);
+ pthread_join(workerThread, NULL);
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
diff --git a/src/components/transport_manager/test/mock_connection.cc b/src/components/transport_manager/test/mock_connection.cc
new file mode 100644
index 0000000000..8f385764a0
--- /dev/null
+++ b/src/components/transport_manager/test/mock_connection.cc
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <cstring>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sstream>
+#include "transport_manager/common.h"
+#include "include/mock_connection.h"
+
+#include <algorithm>
+
+#include "include/mock_transport_adapter.h"
+
+using ::transport_manager::transport_adapter::TransportAdapterController;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+MockConnection::MockConnection(const ::transport_manager::DeviceUID& device_handle,
+ const ApplicationHandle& app_handle,
+ TransportAdapterController* controller)
+ : ThreadedSocketConnection(device_handle, app_handle, controller) {
+}
+
+bool MockConnection::Establish(ConnectError **error) {
+ int peer_sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ sockaddr_un my_addr;
+ memset(&my_addr, 0, sizeof(my_addr));
+ std::ostringstream iss;
+ iss << "mockDevice" << device_handle() << "-" << application_handle();
+ strcpy(my_addr.sun_path, iss.str().c_str());
+ my_addr.sun_family = AF_UNIX;
+ int res = ::connect(peer_sock, reinterpret_cast<sockaddr*>(&my_addr),
+ sizeof(my_addr));
+ if (res != -1) {
+ set_socket(peer_sock);
+ return true;
+ }
+ *error = new ConnectError();
+ return false;
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
diff --git a/src/components/transport_manager/test/mock_connection_factory.cc b/src/components/transport_manager/test/mock_connection_factory.cc
new file mode 100644
index 0000000000..392ad79511
--- /dev/null
+++ b/src/components/transport_manager/test/mock_connection_factory.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "include/mock_connection.h"
+#include "include/mock_connection_factory.h"
+
+#include <algorithm>
+
+#include "include/mock_device.h"
+#include "include/mock_transport_adapter.h"
+
+using ::transport_manager::transport_adapter::DeviceSptr;
+using ::transport_manager::ConnectError;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+MockConnectionFactory::MockConnectionFactory(MockTransportAdapter *controller)
+ : controller_(controller) {}
+
+TransportAdapter::Error MockConnectionFactory::CreateConnection(
+ const ::transport_manager::DeviceUID& device_handle,
+ const ApplicationHandle& app_handle) {
+
+ MockConnection *conn = new MockConnection(device_handle, app_handle, controller_);
+ conn->Start();
+ return TransportAdapter::OK;
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
diff --git a/src/components/transport_manager/test/mock_device.cc b/src/components/transport_manager/test/mock_device.cc
new file mode 100644
index 0000000000..8e346e9d54
--- /dev/null
+++ b/src/components/transport_manager/test/mock_device.cc
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "include/mock_device.h"
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+const ApplicationHandle MockDevice::addApplication() {
+ MockApplication app(this, applications_cnt_++);
+ app.device = this;
+ app.active = false;
+ applications_.push_back(app);
+ return app.handle;
+}
+
+void MockDevice::Start() {
+ for (std::vector<MockApplication>::iterator it = applications_.begin();
+ it != applications_.end();
+ ++it) {
+ it->Start();
+ }
+}
+
+void MockDevice::Stop() {
+ for (std::vector<MockApplication>::iterator it = applications_.begin();
+ it != applications_.end();
+ ++it) {
+ it->Stop();
+ }
+}
+
+bool MockDevice::IsSameAs(const Device* other) const {
+ return unique_device_id() == other->unique_device_id();
+}
+
+static ApplicationHandle get_handle(const MockApplication& app) {
+ return app.handle;
+}
+
+ApplicationList MockDevice::GetApplicationList() const {
+ ApplicationList rc(applications_.size());
+ std::transform(
+ applications_.begin(), applications_.end(), rc.begin(),
+ &get_handle);
+ return rc;
+}
+
+bool MockDevice::operator ==(const MockDevice& other) {
+ return IsSameAs(&other);
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
diff --git a/src/components/transport_manager/test/mock_device_scanner.cc b/src/components/transport_manager/test/mock_device_scanner.cc
new file mode 100644
index 0000000000..a243162668
--- /dev/null
+++ b/src/components/transport_manager/test/mock_device_scanner.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "include/mock_device_scanner.h"
+#include "include/mock_transport_adapter.h"
+#include "include/mock_device.h"
+
+using ::transport_manager::SearchDeviceError;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+MockDeviceScanner::MockDeviceScanner(MockTransportAdapter *controller)
+ : controller_(controller),
+ is_initialized_(false),
+ is_search_failed_(false) {
+}
+
+TransportAdapter::Error MockDeviceScanner::Init() {
+ is_initialized_ = true;
+ return TransportAdapter::OK;
+}
+
+TransportAdapter::Error MockDeviceScanner::Scan() {
+ if (is_search_failed_) {
+ controller_->SearchDeviceFailed(SearchDeviceError());
+ } else {
+ controller_->SearchDeviceDone(devices_);
+ }
+ return TransportAdapter::OK;
+}
+
+void MockDeviceScanner::Terminate() {
+}
+
+void MockDeviceScanner::reset() {
+ is_search_failed_ = false;
+ for (DeviceVector::iterator it = devices_.begin();
+ it != devices_.end();
+ ++it) {
+ static_cast<MockDevice*>(it->get())->Stop();
+ }
+ devices_.clear();
+}
+
+bool MockDeviceScanner::IsInitialised() const {
+ return is_initialized_;
+}
+
+void MockDeviceScanner::AddDevice(const std::string& name,
+ const std::string& unique_id, bool start) {
+ MockDevice* dev = new MockDevice(name, unique_id, controller_);
+ dev->addApplication();
+ if (start) {
+ dev->Start();
+ }
+ devices_.push_back(dev);
+}
+
+void MockDeviceScanner::RemoveDevice(const std::string& name) {
+ for (DeviceVector::iterator t = devices_.begin(); t != devices_.end(); ++t) {
+ if ((*t)->name() == name) {
+ devices_.erase(t);
+ break;
+ }
+ }
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+// vim: set ts=2 sw=2 et:
diff --git a/src/components/transport_manager/test/mock_transport_adapter.cc b/src/components/transport_manager/test/mock_transport_adapter.cc
new file mode 100644
index 0000000000..8612ca363b
--- /dev/null
+++ b/src/components/transport_manager/test/mock_transport_adapter.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "include/mock_connection.h"
+#include "include/mock_device.h"
+#include "include/mock_transport_adapter.h"
+#include "include/mock_device_scanner.h"
+#include "include/mock_connection_factory.h"
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+MockTransportAdapter::MockTransportAdapter()
+ : TransportAdapterImpl(new MockDeviceScanner(this),
+ new MockConnectionFactory(this), NULL) {}
+
+void MockTransportAdapter::reset() {
+ get_device_scanner()->reset();
+}
+
+MockDeviceScanner* MockTransportAdapter::get_device_scanner() const {
+ return static_cast<MockDeviceScanner*>(device_scanner_);
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
diff --git a/src/components/transport_manager/test/raw_message_matcher.cc b/src/components/transport_manager/test/raw_message_matcher.cc
new file mode 100644
index 0000000000..289009d0c1
--- /dev/null
+++ b/src/components/transport_manager/test/raw_message_matcher.cc
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "include/raw_message_matcher.h"
+//#include "../../include/protocol/raw_message.h"
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+RawMessageMatcher::RawMessageMatcher(RawMessagePtr ptr)
+ : ptr_(ptr) {}
+
+bool RawMessageMatcher::MatchAndExplain(const RawMessagePtr msg,
+ MatchResultListener* listener) const {
+ if (msg->data_size() != ptr_->data_size()) {
+ return ::std::equal(msg->data(), msg->data() + msg->data_size(), ptr_->data());
+ } else
+ return false;
+}
+
+void RawMessageMatcher::DescribeTo(::std::ostream* os) const {
+ *os << "data_ is " ;
+ ::std::ostream_iterator<unsigned char> out(*os);
+ ::std::copy(ptr_->data(), ptr_->data() + ptr_->data_size(), out);
+}
+
+void RawMessageMatcher::DescribeNegationTo(::std::ostream* os) const {
+ *os << "data_ is not " ;
+ ::std::ostream_iterator<unsigned char> out(*os);
+ ::std::copy(ptr_->data(), ptr_->data() + ptr_->data_size(), out);
+}
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
diff --git a/src/components/transport_manager/test/tcp_transport_adapter_test.cc b/src/components/transport_manager/test/tcp_transport_adapter_test.cc
new file mode 100644
index 0000000000..13bf838ec0
--- /dev/null
+++ b/src/components/transport_manager/test/tcp_transport_adapter_test.cc
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "transport_manager/tcp/tcp_transport_adapter.h"
+#include "transport_manager/transport_adapter/transport_adapter_listener.h"
+#include "include/mock_transport_adapter_listener.h"
+#include "protocol/raw_message.h"
+#include "utils/logger.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+using namespace ::protocol_handler;
+
+TEST(TcpAdapterBasicTest, GetDeviceType_Return_sdltcp) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_EQ("sdl-tcp", transport_adapter->GetDeviceType());
+
+ delete transport_adapter;
+}
+
+TEST(TcpAdapterBasicTest, isServerOriginatedConnectSupported_Return_True) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_TRUE(transport_adapter->IsServerOriginatedConnectSupported());
+
+ delete transport_adapter;
+}
+
+TEST(TcpAdapterBasicTest, isClientOriginatedConnectSupported_Return_True) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_TRUE(transport_adapter->IsClientOriginatedConnectSupported());
+
+ delete transport_adapter;
+}
+
+TEST(TcpAdapterBasicTest, isSearchDevicesSupported_Return_True) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_TRUE(transport_adapter->IsSearchDevicesSupported());
+
+ delete transport_adapter;
+}
+
+TEST(TcpAdapterBasicTest, NotInitialised_Return_BAD_STATE) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_EQ(TransportAdapter::BAD_STATE, transport_adapter->SearchDevices());
+
+ delete transport_adapter;
+}
+
+//TODO(KKolodiy)APPLINK-11045
+TEST(TcpAdapterBasicTest, DISABLED_NotInitialised_Return_OK_InConnect) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_EQ(TransportAdapter::OK,
+ transport_adapter->Connect(DeviceUID("xxx"), 2));
+ delete transport_adapter;
+}
+
+TEST(TcpAdapterBasicTest, NotInitialised_Return_BAD_STATE_inDisconnect) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_EQ(TransportAdapter::BAD_STATE,
+ transport_adapter->Disconnect(DeviceUID("xxx"), 2));
+ delete transport_adapter;
+}
+
+TEST(TcpAdapterBasicTest, NotInitialised_Return_BAD_STATE_in_DisconnectDevice) {
+
+ //arrange
+ TransportAdapter* transport_adapter = new TcpTransportAdapter(12345);
+
+ //assert
+ EXPECT_EQ(TransportAdapter::BAD_STATE,
+ transport_adapter->DisconnectDevice(DeviceUID("xxx")));
+ delete transport_adapter;
+}
+
+class ClientTcpSocket {
+ public:
+ bool Connect(uint16_t server_port) {
+
+ socket_ = socket(AF_INET, SOCK_STREAM, 0);
+ std::cout << "socket is " << socket_ << "\n\n";
+ if (socket_ < 0)
+ return false;
+
+ struct sockaddr_in addr;
+ memset((char*) &addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr.sin_port = htons(server_port);
+
+ if (::connect(socket_, (struct sockaddr*) &addr, sizeof(addr)) < 0)
+ return false;
+ else
+ return true;
+ }
+
+ bool Send(const std::string& str) {
+ size_t size = str.size();
+ ssize_t written = write(socket_, str.c_str(), size);
+ if (written != -1) {
+ size_t count = static_cast<size_t>(written);
+ return count == size;
+ } else {
+ return false;
+ }
+ }
+
+ std::string receive(size_t size) {
+ char* buf = new char[size];
+ ssize_t read = recv(socket_, buf, size, MSG_WAITALL);
+ if (read != -1) {
+ return std::string(buf, buf + read);
+ } else {
+ return std::string();
+ }
+ }
+
+ void Disconnect() {
+ close(socket_);
+ }
+
+ private:
+ uint16_t port_;
+ int socket_;
+};
+
+using ::testing::_;
+using ::testing::Invoke;
+
+void Disconnect(const TransportAdapter* transport_adapter,
+ const DeviceUID device_handle,
+ const ApplicationHandle app_handle) {
+ EXPECT_EQ(
+ TransportAdapter::OK,
+ const_cast<TransportAdapter*>(transport_adapter)->Disconnect(
+ device_handle, app_handle));
+
+ std::cout << "adapter is disconnected" << "\n";
+}
+
+class TcpAdapterTest : public ::testing::Test {
+ public:
+ TcpAdapterTest()
+ : port_(ChoosePort()),
+ transport_adapter_(new TcpTransportAdapter(port_)),
+ suspended_(false),
+ finished_(false) {
+ pthread_mutex_init(&suspend_mutex_, 0);
+ pthread_cond_init(&suspend_cond_, 0);
+ }
+
+ uint16_t ChoosePort() {
+ return getpid() % 1000 + 3000;
+ }
+
+ virtual void SetUp() {
+ const TransportAdapter::Error error = transport_adapter_->Init();
+ ASSERT_EQ(TransportAdapter::OK, error);
+ transport_adapter_->AddListener(&mock_dal_);
+ time_t end_time = time(NULL) + 5;
+ while (!transport_adapter_->IsInitialised() && time(NULL) < end_time)
+ sleep(0);
+ ASSERT_TRUE(transport_adapter_->IsInitialised());
+ }
+
+ virtual void TearDown() {
+ transport_adapter_->StopClientListening();
+ }
+
+ virtual ~TcpAdapterTest() {
+ pthread_mutex_lock(&suspend_mutex_);
+ if (!finished_)
+ suspended_ = true;
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ timespec abs_time;
+ abs_time.tv_sec = now.tv_sec + 1;
+ abs_time.tv_nsec = now.tv_usec * 1000;
+ while (suspended_) {
+ if (ETIMEDOUT
+ == pthread_cond_timedwait(&suspend_cond_, &suspend_mutex_,
+ &abs_time)) {
+ break;
+ }
+ }
+ pthread_mutex_unlock(&suspend_mutex_);
+ delete transport_adapter_;
+
+ pthread_mutex_destroy(&suspend_mutex_);
+ pthread_cond_destroy(&suspend_cond_);
+ }
+
+ void wakeUp() {
+ pthread_mutex_lock(&suspend_mutex_);
+ finished_ = true;
+ suspended_ = false;
+ pthread_cond_signal(&suspend_cond_);
+ pthread_mutex_unlock(&suspend_mutex_);
+ }
+
+ uint16_t port() const {
+ return port_;
+ }
+
+ const uint16_t port_;
+ TransportAdapter* transport_adapter_;
+ ::test::components::transport_manager::MockTransportAdapterListener mock_dal_;
+ ClientTcpSocket client_;
+
+ pthread_cond_t suspend_cond_;
+ pthread_mutex_t suspend_mutex_;
+ bool suspended_;
+ bool finished_;
+
+};
+
+class TcpAdapterTestWithListenerAutoStart : public TcpAdapterTest {
+ virtual void SetUp() {
+ TcpAdapterTest::SetUp();
+ transport_adapter_->StartClientListening();
+ }
+
+};
+
+MATCHER_P(ContainsMessage, str, ""){ return strlen(str) == arg->data_size() && 0 == memcmp(str, arg->data(), arg->data_size());}
+
+// TODO{ALeshin} APPLINK-11090 - transport_adapter_->IsInitialised() doesn't return true as expected
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_Connect_Return_True) {
+ {
+ ::testing::InSequence seq;
+ EXPECT_CALL(mock_dal_, OnDeviceListUpdated(_));
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _)).WillOnce(
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+}
+
+// TODO{ALeshin} APPLINK-11090 - transport_adapter_->IsInitialised() doesn't return true as expected
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_SecondConnect_Return_True) {
+ {
+ ::testing::InSequence seq;
+ EXPECT_CALL(mock_dal_, OnDeviceListUpdated(_));
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _)).WillOnce(
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+}
+
+// TODO{ALeshin} APPLINK-11090 - transport_adapter_->IsInitialised() doesn't return true as expected
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_Receive_Return_True) {
+ {
+ ::testing::InSequence seq;
+
+ EXPECT_CALL(mock_dal_, OnDeviceListUpdated(_));
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _));
+
+ EXPECT_CALL(
+ mock_dal_,
+ OnDataReceiveDone(transport_adapter_, _, _, ContainsMessage("abcd"))).
+ WillOnce(InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+ EXPECT_TRUE(client_.Send("abcd"));
+}
+
+struct SendHelper {
+ explicit SendHelper(TransportAdapter::Error expected_error)
+ : expected_error_(expected_error),
+ message_(
+ new RawMessage(
+ 1,
+ 1,
+ const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>("efgh")),
+ 4)) {
+ }
+ void sendMessage(const TransportAdapter* transport_adapter,
+ const DeviceUID device_handle,
+ const ApplicationHandle app_handle) {
+ EXPECT_EQ(
+ expected_error_,
+ const_cast<TransportAdapter*>(transport_adapter)->SendData(
+ device_handle, app_handle, message_));
+ }
+ TransportAdapter::Error expected_error_;
+ RawMessagePtr message_;
+};
+
+// TODO{ALeshin} APPLINK-11090 - transport_adapter_->IsInitialised() doesn't return true as expected
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_Send_Message) {
+ SendHelper helper(TransportAdapter::OK);
+ {
+ ::testing::InSequence seq;
+
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _)).WillOnce(
+ Invoke(&helper, &SendHelper::sendMessage));
+ EXPECT_CALL(mock_dal_,
+ OnDataSendDone(transport_adapter_, _, _, helper.message_)).WillOnce(
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+
+ EXPECT_TRUE(client_.Connect(port()));
+ EXPECT_EQ("efgh", client_.receive(4));
+}
+
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_DisconnectFromClient) {
+ {
+ ::testing::InSequence seq;
+
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _));
+ EXPECT_CALL(mock_dal_, OnUnexpectedDisconnect(transport_adapter_, _, _, _));
+ EXPECT_CALL(mock_dal_, OnDisconnectDone(transport_adapter_, _, _)).WillOnce(
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+ client_.Disconnect();
+}
+
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_DisconnectFromServer) {
+ {
+ ::testing::InSequence seq;
+
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _)).WillOnce(
+ Invoke(Disconnect));
+ EXPECT_CALL(mock_dal_, OnDisconnectDone(transport_adapter_, _, _)).WillOnce(
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+
+}
+
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_SendToDisconnected) {
+ SendHelper* helper = new SendHelper(TransportAdapter::BAD_PARAM);
+ {
+ ::testing::InSequence seq;
+
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _)).WillOnce(
+ Invoke(Disconnect));
+ EXPECT_CALL(mock_dal_, OnDisconnectDone(transport_adapter_, _, _)).WillOnce(
+ ::testing::DoAll(Invoke(helper, &SendHelper::sendMessage),
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp)));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+}
+
+TEST_F(TcpAdapterTestWithListenerAutoStart, DISABLED_SendFailed) {
+// static unsigned char zzz[2000000]; //message will send without fail because socket buffer can contain it
+ //this test works correctly starting with number 2539009
+ static unsigned char zzz[2600000];
+ SendHelper* helper = new SendHelper(TransportAdapter::OK);
+ helper->message_ = new RawMessage(1, 1, zzz, sizeof(zzz));
+ {
+ ::testing::InSequence seq;
+ EXPECT_CALL(mock_dal_, OnConnectDone(transport_adapter_, _, _)).WillOnce(
+ Invoke(helper, &SendHelper::sendMessage));
+ EXPECT_CALL(
+ mock_dal_,
+ OnDataSendFailed(transport_adapter_, _, _, helper->message_, _));
+ EXPECT_CALL(mock_dal_, OnDisconnectDone(transport_adapter_, _, _)).WillOnce(
+ InvokeWithoutArgs(this, &TcpAdapterTest::wakeUp));
+ }
+ EXPECT_TRUE(client_.Connect(port()));
+ client_.receive(2);
+ client_.Disconnect();
+}
+
+// TODO{ALeshin} APPLINK-11090 - transport_adapter_->IsInitialised() doesn't return true as expected
+TEST_F(TcpAdapterTest, DISABLED_StartStop) {
+
+ //assert
+ EXPECT_EQ(TransportAdapter::BAD_STATE,
+ transport_adapter_->StopClientListening());
+ EXPECT_TRUE(client_.Connect(port()));
+ EXPECT_EQ(TransportAdapter::OK, transport_adapter_->StartClientListening());
+ EXPECT_TRUE(client_.Connect(port()));
+
+ //act
+ client_.Disconnect();
+
+ //assert
+ EXPECT_EQ(TransportAdapter::BAD_STATE,
+ transport_adapter_->StartClientListening());
+ EXPECT_TRUE(client_.Connect(port()));
+
+ //act
+ client_.Disconnect();
+
+ //assert
+ EXPECT_EQ(TransportAdapter::OK, transport_adapter_->StopClientListening());
+ EXPECT_TRUE(client_.Connect(port()));
+
+ //act
+ wakeUp();
+}
+
+} // namespace
+} // namespace
+
diff --git a/src/components/transport_manager/test/transport_manager_instance_test.cc b/src/components/transport_manager/test/transport_manager_instance_test.cc
new file mode 100644
index 0000000000..b5a251ba5e
--- /dev/null
+++ b/src/components/transport_manager/test/transport_manager_instance_test.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ Tests transport manager functionality with single device adapter that behaves correctly and single client
+ Following sequence is tested:
+ - TM created and runned
+ - TM client registered as listener
+ - TM client requests device scaning
+ - single device was returned to TM client with onDeviceListUpdated callback
+ - TM client calls "connect" on found device
+ - device adapter sends onApplicationConnected
+ - TM client receives onApplicationConnected
+ - device adapter sends three data parts that represents single frame
+ - TM client receives single frame with onFrameReceived callback
+ - TM client calls sendFrame with some frame data and user data
+ - TM client receives onFrameSendCompleted
+ - TM client calls DisconnectDevice
+ - TM client receives onApplicationDisconnected
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#include "../../include/transport_manager/transport_manager.h"
+#include "../include/transport_manager/transport_adapter/transport_adapter.h"
+#include "../include/transport_manager/common.h"
+#include "../include/transport_manager/transport_manager_impl.h"
+#include "../include/transport_manager/transport_manager_default.h"
+#include "../../connection_handler/include/connection_handler/connection_handler.h"
+
+
+namespace test{
+namespace test_transport_manager_instance {
+TEST(test_transport_manager_instance, test_transport_manager_instance)
+{
+ transport_manager::TransportManager *Instance = transport_manager::TransportManagerDefault::instance();
+ ASSERT_EQ(Instance, transport_manager::TransportManagerDefault::instance());
+}
+
+}}
diff --git a/src/components/transport_manager/test/transport_manager_test.cc b/src/components/transport_manager/test/transport_manager_test.cc
new file mode 100644
index 0000000000..551931788c
--- /dev/null
+++ b/src/components/transport_manager/test/transport_manager_test.cc
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2015, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <pthread.h>
+
+#include "protocol/common.h"
+#include "transport_manager/info.h"
+#include "transport_manager/common.h"
+#include "transport_manager/transport_manager_impl.h"
+
+#include "include/raw_message_matcher.h"
+#include "include/mock_transport_adapter.h"
+#include "include/mock_device.h"
+#include "include/mock_transport_manager_listener.h"
+#include "transport_manager/transport_manager_listener_empty.h"
+
+//for instance test
+#include "transport_manager/transport_manager.h"
+#include "transport_manager/transport_adapter/transport_adapter.h"
+#include "transport_manager/transport_manager_default.h"
+#include "connection_handler/connection_handler.h"
+
+using ::testing::_;
+using ::testing::AtLeast;
+
+using ::transport_manager::ApplicationHandle;
+using ::transport_manager::DeviceHandle;
+using ::transport_manager::TransportManager;
+using ::transport_manager::TransportManagerImpl;
+using ::transport_manager::DeviceUID;
+using ::transport_manager::DeviceInfo;
+
+namespace test {
+namespace components {
+namespace transport_manager {
+
+ACTION_P(SignalTest, test) {
+ if (test->thread_id != pthread_self()) {
+ pthread_mutex_lock(&test->test_mutex);
+ pthread_cond_signal(&test->test_cond);
+ pthread_mutex_unlock(&test->test_mutex);
+ } else {
+ test->one_thread = true;
+ }
+}
+
+class TransportManagerTest : public ::testing::Test {
+ public:
+ volatile bool one_thread;
+ pthread_t thread_id;
+ static pthread_mutex_t test_mutex;
+ static pthread_cond_t test_cond;
+ int number;
+
+ protected:
+ static TransportManagerImpl *tm;
+ static MockTransportAdapter *mock_adapter;
+ static MockTransportManagerListener *tm_listener;
+
+ static void SetUpTestCase() {
+ pthread_mutex_init(&test_mutex, NULL);
+ pthread_cond_init(&test_cond, NULL);
+ mock_adapter = new MockTransportAdapter();
+ mock_adapter->Init();
+ //TransportManagerAttr cfg{0};
+ tm = new TransportManagerImpl();
+
+ tm_listener = new MockTransportManagerListener();
+ tm->AddEventListener(tm_listener);
+ tm->AddTransportAdapter(mock_adapter);
+ tm->Init();
+ }
+
+ static void TearDownTestCase() {
+ tm->Stop();
+ delete tm_listener;
+ pthread_cond_destroy(&test_cond);
+ pthread_mutex_destroy(&test_mutex);
+ }
+
+ virtual void SetUp() {
+ one_thread = false;
+ thread_id = pthread_self();
+ mock_adapter->reset();
+ pthread_mutex_lock(&test_mutex);
+ }
+
+ virtual void TearDown() { pthread_mutex_unlock(&test_mutex); }
+
+ bool waitCond(int seconds) {
+ if (one_thread) return true;
+ timespec elapsed;
+ clock_gettime(CLOCK_REALTIME, &elapsed);
+ elapsed.tv_sec += seconds;
+ return pthread_cond_timedwait(&test_cond, &test_mutex, &elapsed) !=
+ ETIMEDOUT;
+ }
+};
+
+TransportManagerImpl *TransportManagerTest::tm;
+
+class MyTransportListener
+ : public ::transport_manager::TransportManagerListenerEmpty {
+ public:
+ explicit MyTransportListener(TransportManagerTest *test)
+ : TransportManagerListenerEmpty(),
+ connection(0),
+ device_handle(0),
+ test(test) {}
+ ConnectionUID connection;
+ DeviceHandle device_handle;
+ void OnConnectionEstablished(const DeviceInfo &device,
+ const ConnectionUID &connection_id) {
+ connection = connection_id;
+
+ pthread_mutex_lock(&test->test_mutex);
+ pthread_cond_signal(&test->test_cond);
+ pthread_mutex_unlock(&test->test_mutex);
+ }
+
+ void OnDeviceFound(const DeviceInfo &device_info) {
+ device_handle = device_info.device_handle();
+ }
+
+ void OnScanDevicesFinished() {
+ pthread_mutex_lock(&test->test_mutex);
+ pthread_cond_signal(&test->test_cond);
+ pthread_mutex_unlock(&test->test_mutex);
+ }
+
+ void OnTMMessageReceived(const RawMessagePtr message) {
+ static int count = 0;
+ if (++count == 100) {
+ pthread_mutex_lock(&test->test_mutex);
+ pthread_cond_signal(&test->test_cond);
+ pthread_mutex_unlock(&test->test_mutex);
+ }
+ }
+
+ void OnTMMessageSend(const RawMessagePtr message) {
+ }
+
+ private:
+ TransportManagerTest *test;
+};
+
+pthread_mutex_t TransportManagerTest::test_mutex;
+pthread_cond_t TransportManagerTest::test_cond;
+
+MockTransportAdapter *TransportManagerTest::mock_adapter = NULL;
+MockTransportManagerListener *TransportManagerTest::tm_listener = NULL;
+
+
+
+TEST_F(TransportManagerTest, ScanDeviceFailed) {
+
+ //assert
+ EXPECT_CALL(*tm_listener, OnDeviceFound(_)).Times(0);
+ EXPECT_CALL(*tm_listener, OnScanDevicesFailed(_)).WillOnce(
+ SignalTest(this));
+
+ //act
+ mock_adapter->get_device_scanner()->fail_further_search();
+ tm->SearchDevices();
+
+ //assert
+ EXPECT_TRUE(waitCond(1));
+
+ //act
+ mock_adapter->get_device_scanner()->reset();
+}
+
+TEST_F(TransportManagerTest, ScanDeviceNoFound) {
+
+ //assert
+ EXPECT_CALL(*tm_listener, OnScanDevicesFailed(_)).Times(0);
+ EXPECT_CALL(*tm_listener, OnDeviceFound(_)).Times(0);
+ EXPECT_CALL(*tm_listener, OnScanDevicesFinished()).WillOnce(SignalTest(this));
+
+ EXPECT_CALL(*tm_listener, OnDeviceListUpdated(_));
+
+ //act
+ tm->SearchDevices();
+
+ //assert
+ EXPECT_TRUE(waitCond(1));
+
+ //act
+ mock_adapter->get_device_scanner()->reset();
+}
+
+TEST_F(TransportManagerTest, ScanDeviceDone) {
+
+ //assert
+ EXPECT_CALL(*tm_listener, OnScanDevicesFailed(_)).Times(0);
+ EXPECT_CALL(*tm_listener, OnDeviceFound(_));
+ EXPECT_CALL(*tm_listener, OnScanDevicesFinished()).WillOnce(SignalTest(this));
+
+ //added to fixed warnings
+ EXPECT_CALL(*tm_listener, OnDeviceAdded(_)).Times(3);
+ EXPECT_CALL(*tm_listener, OnDeviceListUpdated(_));
+ EXPECT_CALL(*tm_listener, OnDeviceRemoved(_)).Times(3);
+
+ //act
+ mock_adapter->get_device_scanner()->AddDevice("TestDevice", "MA:CA:DR:ES:S");
+ tm->SearchDevices();
+
+ //assert
+ EXPECT_TRUE(waitCond(1));
+
+ //act
+ mock_adapter->get_device_scanner()->reset();
+}
+
+TEST_F(TransportManagerTest, ScanManyDeviceDone) {
+
+
+ //assert
+ EXPECT_CALL(*tm_listener, OnScanDevicesFailed(_)).Times(0);
+ EXPECT_CALL(*tm_listener, OnDeviceFound(_)).Times(2);
+ EXPECT_CALL(*tm_listener, OnScanDevicesFinished()).WillOnce(SignalTest(this));
+
+ //assert
+ EXPECT_CALL(*tm_listener, OnDeviceListUpdated(_));
+ //act
+ mock_adapter->get_device_scanner()->AddDevice("TestDevice1",
+ "MA:CA:DR:ES:S1");
+ mock_adapter->get_device_scanner()->AddDevice("TestDevice2",
+ "MA:CA:DR:ES:S2");
+ tm->SearchDevices();
+
+ //assert
+ EXPECT_TRUE(waitCond(1));
+
+ //act
+ mock_adapter->get_device_scanner()->reset();
+}
+
+
+TEST_F(TransportManagerTest, ConnectAddDeviceCannotFailConnection) {
+
+ //arrange
+ const DeviceInfo kInfo(1, "MA:CA:DR:ES:S", "TestDeviceName", "BTMAC");
+ const ConnectionUID kConnection = 1;
+
+ //assert
+ EXPECT_CALL(*tm_listener, OnDeviceFound(_));
+ EXPECT_CALL(*tm_listener, OnScanDevicesFinished());
+
+ EXPECT_CALL(*tm_listener, OnDeviceAdded(_));
+ EXPECT_CALL(*tm_listener, OnDeviceListUpdated(_));
+
+ //act
+ MyTransportListener *myListener = new MyTransportListener(this);
+ mock_adapter->get_device_scanner()->AddDevice(kInfo.name(),
+ kInfo.mac_address());
+ tm->AddEventListener(myListener);
+ tm->SearchDevices();
+
+ //assert
+ EXPECT_TRUE(waitCond(10));
+
+ EXPECT_CALL(*tm_listener, OnConnectionFailed(_, _)).Times(0);
+ EXPECT_CALL(*tm_listener, OnConnectionEstablished(kInfo, kConnection));
+
+ //act
+ tm->ConnectDevice(kInfo.device_handle());
+
+ //assert
+ EXPECT_TRUE(waitCond(10));
+
+ //act
+ mock_adapter->get_device_scanner()->reset();
+}
+
+
+//TODO{ALeshin}: APPLINK-10846
+//TEST_F(TransportManagerTest, ConnectDeviceSendReciveMessage) {
+
+// //arrange
+// const ConnectionUID kConnection = 1;
+// const int kTimes = 99; // Times of send message //if kTimes>99 OnTMMessageSend will fail
+// const unsigned int kVersionProtocol = 1;
+
+
+// //assert
+// EXPECT_CALL(*tm_listener, OnTMMessageSendFailed(_, _)).Times(0);
+// EXPECT_CALL(*tm_listener, OnTMMessageReceiveFailed(_, _)).Times(0);
+// EXPECT_CALL(*tm_listener, OnConnectionClosed(kConnection)).Times(0);
+
+// EXPECT_CALL(*tm_listener, OnTMMessageSend(_)).Times(kTimes);
+// EXPECT_CALL(*tm_listener, OnTMMessageReceived(_)).Times(kTimes);
+
+// //act
+// const unsigned int kSize = 12;
+// unsigned char data[kSize] = {0x20, 0x07, 0x01, 0x00, 0x00, 0x00,
+// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+// for (int i = 0; i < kTimes; ++i) {
+// const RawMessagePtr kMessage =
+// new RawMessage(kConnection, kVersionProtocol, data, kSize);
+// tm->SendMessageToDevice(kMessage);
+// usleep(1000);
+// }
+
+// //assert
+// EXPECT_TRUE(waitCond(10));
+
+// //act
+// mock_adapter->get_device_scanner()->reset();
+//}
+
+//TODO{ALeshin}: APPLINK-10846
+//TEST_F(TransportManagerTest, ConnectAddDeviceCannotFailClose) {
+
+// //arrange
+// const DeviceInfo kInfo(1, "MA:CA:DR:ES:S", "TestDeviceName", "BTMAC");
+// const ConnectionUID kConnection = 1;
+
+// //assert
+// EXPECT_CALL(*tm_listener, OnDeviceFound(_));
+// EXPECT_CALL(*tm_listener, OnScanDevicesFinished());
+// EXPECT_CALL(*tm_listener, OnDeviceListUpdated(_));
+
+
+// //act
+// MyTransportListener *myListener = new MyTransportListener(this);
+// mock_adapter->get_device_scanner()->AddDevice(kInfo.name(),
+// kInfo.mac_address());
+// tm->AddEventListener(myListener);
+// tm->SearchDevices();
+
+// //assert
+// EXPECT_TRUE(waitCond(10));
+
+// EXPECT_CALL(*tm_listener, OnConnectionClosedFailure(_, _)).Times(0);
+// EXPECT_CALL(*tm_listener, OnDisconnectFailed(kInfo.device_handle(), _))
+// .Times(0);
+// EXPECT_CALL(*tm_listener, OnConnectionClosed(kConnection)).WillOnce(SignalTest(this));
+
+// //act
+// tm->DisconnectDevice(kInfo.device_handle());
+
+// //assert
+// EXPECT_TRUE(waitCond(10));
+
+// //act
+// tm->Stop();
+// delete myListener;
+// mock_adapter->get_device_scanner()->reset();
+//}
+
+
+} // namespace transport_manager
+} // namespace components
+} // namespace test
+
+
+namespace test{
+namespace test_transport_manager_instance {
+TEST(testTransportManager, CreateOnlyInstance)
+{
+ transport_manager::TransportManager *Instance = transport_manager::TransportManagerDefault::instance();
+ ASSERT_EQ(Instance, transport_manager::TransportManagerDefault::instance());
+ delete Instance;
+}
+}}