mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-15 01:38:15 +00:00
remove unused files (#7)
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
if(WIN32)
|
||||
# Define project
|
||||
project(ipc_sockets VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Define target
|
||||
add_library(ipc_sockets SHARED
|
||||
"channel_mgnt.h"
|
||||
"channel_mgnt.cpp"
|
||||
"connection.h"
|
||||
"connection.cpp")
|
||||
target_link_libraries(ipc_sockets ${CMAKE_THREAD_LIBS_INIT} Ws2_32.lib)
|
||||
target_link_options(ipc_sockets PRIVATE)
|
||||
target_include_directories(ipc_sockets PRIVATE ./include/)
|
||||
|
||||
set_target_properties(ipc_sockets PROPERTIES PREFIX "")
|
||||
set_target_properties(ipc_sockets PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(ipc_sockets CompileCoreIDL)
|
||||
|
||||
# Appending the service in the service list
|
||||
set(SDV_Service_List ${SDV_Service_List} ipc_sockets PARENT_SCOPE)
|
||||
|
||||
endif()
|
||||
@@ -1,356 +0,0 @@
|
||||
#include "channel_mgnt.h"
|
||||
#include "connection.h"
|
||||
#include "../../global/base64.h"
|
||||
#include <support/toml.h>
|
||||
#include <interfaces/process.h>
|
||||
#include <future>
|
||||
|
||||
#pragma push_macro("interface")
|
||||
#undef interface
|
||||
#pragma push_macro("GetObject")
|
||||
#undef GetObject
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <array>
|
||||
|
||||
// Resolve conflict
|
||||
#pragma pop_macro("GetObject")
|
||||
#pragma pop_macro("interface")
|
||||
#ifdef GetClassInfo
|
||||
#undef GetClassInfo
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Define for the connection string
|
||||
*/
|
||||
#define SHARED_SOCKET "SHARED_SOCKET"
|
||||
|
||||
void CSocketsChannelMgnt::Initialize(const sdv::u8string& /*ssObjectConfig*/)
|
||||
{
|
||||
if (m_eObjectStatus != sdv::EObjectStatus::initialization_pending)
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialization_failure;
|
||||
else
|
||||
m_eObjectStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
sdv::EObjectStatus CSocketsChannelMgnt::GetStatus() const
|
||||
{
|
||||
return m_eObjectStatus;
|
||||
}
|
||||
|
||||
void CSocketsChannelMgnt::SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::running || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eObjectStatus == sdv::EObjectStatus::configuring || m_eObjectStatus == sdv::EObjectStatus::initialized)
|
||||
m_eObjectStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CSocketsChannelMgnt::Shutdown()
|
||||
{
|
||||
//m_eObjectStatus = sdv::EObjectStatus::shutdown_in_progress;
|
||||
//...
|
||||
m_eObjectStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
sdv::ipc::SChannelEndpoint CSocketsChannelMgnt::CreateEndpoint(const sdv::u8string& /*ssChannelConfig*/)
|
||||
{
|
||||
StartUpWinSock();
|
||||
addrinfo hints;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
SOCKET listenSocket = CreateSocket(hints);
|
||||
|
||||
if (listenSocket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("CreateSocket failed (could not create endpoint)");
|
||||
sdv::ipc::SChannelEndpoint connectionEndpoint{};
|
||||
return connectionEndpoint;
|
||||
}
|
||||
|
||||
CConnection* pRemoteIPCConnection = new CConnection(listenSocket, true);
|
||||
|
||||
uint16_t port = GetPort(listenSocket);
|
||||
std::string ipcCompleteConfig = "localhost";
|
||||
ipcCompleteConfig.append(";");
|
||||
ipcCompleteConfig.append(std::to_string(port));
|
||||
SDV_LOG_INFO("IPC command param: '", ipcCompleteConfig, "'");
|
||||
|
||||
sdv::ipc::SChannelEndpoint connectionEndpoint{};
|
||||
connectionEndpoint.pConnection = static_cast<IInterfaceAccess*>(pRemoteIPCConnection);
|
||||
connectionEndpoint.ssConnectString = ipcCompleteConfig;
|
||||
|
||||
return connectionEndpoint;
|
||||
}
|
||||
|
||||
|
||||
sdv::IInterfaceAccess* CSocketsChannelMgnt::Access(const sdv::u8string& ssConnectString)
|
||||
{
|
||||
bool sharedSocketRequired = ssConnectString.find(SHARED_SOCKET) != std::string::npos ? true : false;
|
||||
|
||||
if (sharedSocketRequired)
|
||||
{
|
||||
std::string base64Data(ssConnectString);
|
||||
const std::string ext(SHARED_SOCKET);
|
||||
base64Data = base64Data.substr(0, base64Data.size() - ext.size());
|
||||
|
||||
WSAPROTOCOL_INFO socketInfo = DecodeBase64<WSAPROTOCOL_INFO>(base64Data);
|
||||
|
||||
SOCKET sharedSocket = WSASocket(0, 0, 0, &socketInfo, 0, 0);
|
||||
std::string success = "Socket sharing success";
|
||||
if (sharedSocket == INVALID_SOCKET)
|
||||
{
|
||||
success = "Socket sharing did not work!";
|
||||
}
|
||||
|
||||
return static_cast<IInterfaceAccess*>(new CConnection(sharedSocket, false));
|
||||
}
|
||||
|
||||
StartUpWinSock();
|
||||
addrinfo hints;
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
|
||||
std::string host{"localhost"};
|
||||
std::string param{ssConnectString};
|
||||
auto it = param.find(";");
|
||||
if (it != std::string::npos)
|
||||
{
|
||||
host = param.substr(0, it);
|
||||
param = param.substr(it + 1, param.size() - it - 1);
|
||||
}
|
||||
|
||||
SOCKET socket = CreateAndConnectToExistingSocket(hints, host.c_str(), param.c_str());
|
||||
if (socket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not create my socket and connect to the existing socket.");
|
||||
}
|
||||
|
||||
return static_cast<IInterfaceAccess*>(new CConnection(socket, false));
|
||||
}
|
||||
|
||||
uint16_t CSocketsChannelMgnt::GetPort(SOCKET socket) const
|
||||
{
|
||||
sockaddr_in sockAddr;
|
||||
sockAddr.sin_port = 0;
|
||||
int nameLength = sizeof(sockAddr);
|
||||
getsockname(socket, reinterpret_cast<sockaddr*>(&sockAddr), &nameLength);
|
||||
return ntohs(sockAddr.sin_port);
|
||||
}
|
||||
|
||||
SOCKET CSocketsChannelMgnt::CreateAndConnectToExistingSocket(const addrinfo& hints,
|
||||
const char* hostName,
|
||||
const char* portName)
|
||||
{
|
||||
SOCKET invalidSocket{INVALID_SOCKET};
|
||||
|
||||
// Resolve the server address and port
|
||||
CAddrInfo result;
|
||||
int error = getaddrinfo(hostName, portName, &hints, &result.AddressInfo);
|
||||
if (error != 0)
|
||||
{
|
||||
|
||||
SDV_LOG_ERROR("getaddrinfo failed with error: ",
|
||||
std::to_string(error),
|
||||
" host: ",
|
||||
hostName,
|
||||
" port: ",
|
||||
portName);
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
SOCKET connectSocket{INVALID_SOCKET};
|
||||
// Attempt to connect to an address until one succeeds
|
||||
for (addrinfo* ptr = result.AddressInfo; ptr != NULL; ptr = ptr->ai_next)
|
||||
{
|
||||
// Create a SOCKET for connecting to server
|
||||
connectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
|
||||
if (connectSocket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("socket failed with error: ", std::to_string(error));
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
// Connect to server.
|
||||
error = connect(connectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
|
||||
if (error == SOCKET_ERROR)
|
||||
{
|
||||
SDV_LOG_ERROR("connect failed with error: ", std::to_string(error));
|
||||
closesocket(connectSocket);
|
||||
connectSocket = INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return connectSocket;
|
||||
}
|
||||
|
||||
SOCKET CSocketsChannelMgnt::CreateSocket(const addrinfo& hints)
|
||||
{
|
||||
static constexpr const char* defaultPort_0{"0"}; // In case a defined port is required
|
||||
SOCKET invalidSocket{INVALID_SOCKET};
|
||||
CAddrInfo result;
|
||||
int error = getaddrinfo(NULL, defaultPort_0, &hints, &result.AddressInfo);
|
||||
if (error != 0)
|
||||
{
|
||||
SDV_LOG_ERROR("getaddrinfo failed with error: ", std::to_string(error));
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
SOCKET connectSocket{INVALID_SOCKET};
|
||||
connectSocket =
|
||||
socket(result.AddressInfo->ai_family, result.AddressInfo->ai_socktype, result.AddressInfo->ai_protocol);
|
||||
if (connectSocket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("error at socket(): ", std::to_string(error));
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
error = bind(connectSocket, result.AddressInfo->ai_addr, (int)result.AddressInfo->ai_addrlen);
|
||||
if (error == SOCKET_ERROR)
|
||||
{
|
||||
closesocket(connectSocket);
|
||||
SDV_LOG_ERROR("bind failed with error: ", std::to_string(error));
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
if (listen(connectSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||
{
|
||||
closesocket(connectSocket);
|
||||
SDV_LOG_ERROR("listen failed with error: ", std::to_string(WSAGetLastError()));
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
// Change the socket mode on the listening socket from blocking to
|
||||
// non-block so the application will not block waiting for requests
|
||||
u_long NonBlock = 1;
|
||||
if (ioctlsocket(connectSocket, FIONBIO, &NonBlock) == SOCKET_ERROR)
|
||||
{
|
||||
closesocket(connectSocket);
|
||||
SDV_LOG_ERROR("ioctlsocket failed with error: ", std::to_string(WSAGetLastError()));
|
||||
return invalidSocket;
|
||||
}
|
||||
|
||||
return connectSocket;
|
||||
}
|
||||
|
||||
|
||||
SOCKET CSocketsChannelMgnt::CreateAndConnectToSocket(const addrinfo& hints, const char* defaultHost, const char* defaultPort)
|
||||
{
|
||||
SOCKET ConnectSocket{ INVALID_SOCKET };
|
||||
|
||||
// Resolve the server address and port
|
||||
CAddrInfo result;
|
||||
if (getaddrinfo(defaultHost, defaultPort, &hints, &result.AddressInfo) != 0)
|
||||
{
|
||||
SDV_LOG_ERROR("getaddrinfo() failed: ", std::to_string(WSAGetLastError()));
|
||||
return ConnectSocket;
|
||||
}
|
||||
|
||||
// Attempt to connect to an address until one succeeds
|
||||
for (addrinfo* ptr = result.AddressInfo; ptr != NULL; ptr = ptr->ai_next)
|
||||
{
|
||||
// Create a SOCKET for connecting to server
|
||||
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
|
||||
if (ConnectSocket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("creating SOCKET for connecting failed: ", std::to_string(WSAGetLastError()));
|
||||
break;
|
||||
}
|
||||
|
||||
// Connect to server.
|
||||
if (connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen) == SOCKET_ERROR)
|
||||
{
|
||||
SDV_LOG_ERROR("connect to servcer failed: ", std::to_string(WSAGetLastError()));
|
||||
closesocket(ConnectSocket);
|
||||
ConnectSocket = INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (ConnectSocket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("Failed to create valid sockaet in CreateAndConnectToSocket()");
|
||||
}
|
||||
|
||||
return ConnectSocket;
|
||||
}
|
||||
|
||||
SOCKET CSocketsChannelMgnt::Listen(const addrinfo& hints, uint32_t port)
|
||||
{
|
||||
SOCKET listenSocket = INVALID_SOCKET;
|
||||
CAddrInfo result;
|
||||
int error = getaddrinfo(NULL, std::to_string(port).c_str(), &hints, &result.AddressInfo);
|
||||
if (error != 0)
|
||||
{
|
||||
SDV_LOG_ERROR("getaddrinfo() failed: ", std::to_string(WSAGetLastError()));
|
||||
return listenSocket;
|
||||
}
|
||||
|
||||
listenSocket = socket(result.AddressInfo->ai_family, result.AddressInfo->ai_socktype, result.AddressInfo->ai_protocol);
|
||||
if (listenSocket == INVALID_SOCKET)
|
||||
{
|
||||
SDV_LOG_ERROR("2creating SOCKET for connecting failed: failed: ", std::to_string(WSAGetLastError()));
|
||||
return listenSocket;
|
||||
}
|
||||
|
||||
error = bind(listenSocket, result.AddressInfo->ai_addr, (int)result.AddressInfo->ai_addrlen);
|
||||
if (error == SOCKET_ERROR)
|
||||
{
|
||||
SDV_LOG_ERROR("bind failed with error: ", std::to_string(WSAGetLastError()));
|
||||
closesocket(listenSocket);
|
||||
listenSocket = INVALID_SOCKET;
|
||||
return listenSocket;
|
||||
}
|
||||
|
||||
if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR)
|
||||
{
|
||||
SDV_LOG_ERROR("listen to SOCKET failed: ", std::to_string(WSAGetLastError()));
|
||||
closesocket(listenSocket);
|
||||
listenSocket = INVALID_SOCKET;
|
||||
return listenSocket;
|
||||
}
|
||||
|
||||
return listenSocket;
|
||||
}
|
||||
|
||||
|
||||
SocketConnection CSocketsChannelMgnt::CreateConnectedSocketPair()
|
||||
{
|
||||
SocketConnection connection;
|
||||
|
||||
uint32_t port = 0;
|
||||
SOCKET listenSocket = Listen(getHints, port);
|
||||
|
||||
uint16_t portOfListenSocket = GetPort(listenSocket);
|
||||
auto future = std::async([listenSocket]() { return accept(listenSocket, NULL, NULL); });
|
||||
|
||||
connection.From = CreateAndConnectToSocket(getHints, "localhost", std::to_string(portOfListenSocket).c_str());
|
||||
|
||||
// Future::Get has to be called after the CreateAndConnect-Function
|
||||
connection.To = future.get();
|
||||
return connection;
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
#ifndef CHANNEL_MGNT_H
|
||||
#define CHANNEL_MGNT_H
|
||||
|
||||
#include <support/component_impl.h>
|
||||
#include <interfaces/ipc.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The CAddrInfo structure is used by the getaddrinfo function to hold host address information.
|
||||
*/
|
||||
struct CAddrInfo
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CAddrInfo() = default;
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CAddrInfo(const CAddrInfo&) = delete;
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
CAddrInfo& operator=(const CAddrInfo&) = delete;
|
||||
/**
|
||||
* @brief Move constructor
|
||||
* @param[in] other Reference to the structure to move.
|
||||
*/
|
||||
CAddrInfo(CAddrInfo&& other) = delete;
|
||||
|
||||
/**
|
||||
* @brief Move operator.
|
||||
* @param[in] other Reference to the structure to move.
|
||||
* @return Returns reference to CAddrInfo structure
|
||||
*/
|
||||
CAddrInfo& operator=(CAddrInfo&& other) = delete;
|
||||
|
||||
~CAddrInfo()
|
||||
{
|
||||
freeaddrinfo(AddressInfo);
|
||||
}
|
||||
|
||||
addrinfo* AddressInfo{nullptr}; ///< The CAddrInfo structure holding host address information.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initial startup of winSock
|
||||
* @return Returns 0 in case of no error, otherwise the error code
|
||||
*/
|
||||
inline int StartUpWinSock()
|
||||
{
|
||||
static bool isInitialized = false;
|
||||
if (isInitialized)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
WSADATA wsaData;
|
||||
int error = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (error != 0)
|
||||
{
|
||||
SDV_LOG_ERROR("WSAStartup failed with error: ", std::to_string(error));
|
||||
}
|
||||
else
|
||||
{
|
||||
SDV_LOG_INFO("WSAStartup initialized");
|
||||
isInitialized = true;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Holds to sockets.
|
||||
* Used by the core process to create a connection between to shild processes
|
||||
*/
|
||||
struct SocketConnection
|
||||
{
|
||||
SOCKET From{ INVALID_SOCKET }; ///< socket from child process
|
||||
SOCKET To{ INVALID_SOCKET }; ///< socket to child process
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief IPC channel management class for the shared memory communication.
|
||||
*/
|
||||
class CSocketsChannelMgnt : public sdv::CSdvObject, public sdv::IObjectControl, public sdv::ipc::ICreateEndpoint,
|
||||
public sdv::ipc::IChannelAccess
|
||||
{
|
||||
public:
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(sdv::ipc::IChannelAccess)
|
||||
SDV_INTERFACE_ENTRY(sdv::ipc::ICreateEndpoint)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
// Object declarations
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::SystemObject)
|
||||
DECLARE_OBJECT_CLASS_NAME("DefaultSocketsChannelControl")
|
||||
DECLARE_OBJECT_CLASS_ALIAS("RemoteChannelControl")
|
||||
DECLARE_DEFAULT_OBJECT_NAME("RemoteChannelControl")
|
||||
DECLARE_OBJECT_SINGLETON()
|
||||
|
||||
/**
|
||||
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
void Initialize(const sdv::u8string& ssObjectConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
|
||||
* @return Return the current status of the object.
|
||||
*/
|
||||
sdv::EObjectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode) override;
|
||||
|
||||
/**
|
||||
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
|
||||
*/
|
||||
void Shutdown() override;
|
||||
|
||||
/**
|
||||
* @brief Create IPC connection object and return the endpoint information. Overload of
|
||||
* sdv::ipc::ICreateEndpoint::CreateEndpoint.
|
||||
* @details The endpoints are generated using either a size and a name based on the interface and port number provided through
|
||||
* the channel configuration or if no configuration is supplied a randomly generated size and name. The following configuration
|
||||
* can be supplied:
|
||||
* @code
|
||||
* [IpcChannel]
|
||||
* Interface = "127.0.0.1"
|
||||
* Port = 2000
|
||||
* @endcode
|
||||
* @param[in] ssChannelConfig Optional channel type specific endpoint configuration.
|
||||
* @return IPC connection object
|
||||
*/
|
||||
sdv::ipc::SChannelEndpoint CreateEndpoint(/*in*/ const sdv::u8string& ssChannelConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Create a connection object from the channel connection parameters string
|
||||
* @param[in] ssConnectString Reference to the string containing the channel connection parameters.
|
||||
* @return Pointer to IInterfaceAccess interface of the connection object or NULL when the object cannot be created.
|
||||
*/
|
||||
sdv::IInterfaceAccess* Access(const sdv::u8string& ssConnectString) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Creates a listen socket without setting the port and configured the socket to return directly without
|
||||
* blocking. No blocking access when data is received. Therefore any receive function must use polling
|
||||
* @return Returns the listen socket
|
||||
*/
|
||||
SOCKET CreateSocket(const addrinfo& hints);
|
||||
|
||||
/**
|
||||
* @brief get port number of a given socket
|
||||
* @param[in] socket the port number is requested
|
||||
* @return Returns the port number of the socket
|
||||
*/
|
||||
uint16_t GetPort(SOCKET socket) const;
|
||||
|
||||
SocketConnection CreateConnectedSocketPair();
|
||||
SOCKET Listen(const addrinfo& hints, uint32_t port);
|
||||
SOCKET CreateAndConnectToSocket(const addrinfo& hints, const char* defaultHost, const char* defaultPort);
|
||||
|
||||
/**
|
||||
* @brief Creates an own socket and connects to an existing socket
|
||||
* @param[in] hints The CAddrInfo structure to create the socket.
|
||||
* @param[in] hostName host name.
|
||||
* @param[in] portName port name.
|
||||
* @return Returns an socket
|
||||
*/
|
||||
SOCKET CreateAndConnectToExistingSocket(const addrinfo& hints, const char* hostName, const char* portName);
|
||||
|
||||
inline static const addrinfo getHints
|
||||
{
|
||||
[]() constexpr {
|
||||
addrinfo hints{0, 0, 0, 0, 0, nullptr, nullptr, nullptr};
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_next = nullptr;
|
||||
|
||||
return hints;
|
||||
}()
|
||||
};
|
||||
|
||||
sdv::EObjectStatus m_eObjectStatus = sdv::EObjectStatus::initialization_pending; ///< Object status.
|
||||
};
|
||||
DEFINE_SDV_OBJECT(CSocketsChannelMgnt)
|
||||
|
||||
#endif // ! defined CHANNEL_MGNT_H
|
||||
@@ -1,353 +0,0 @@
|
||||
#include "connection.h"
|
||||
|
||||
CConnection::CConnection(SOCKET preconfiguredSocket, bool acceptConnectionRequired)
|
||||
{
|
||||
std::fill(std::begin(m_SendBuffer), std::end(m_SendBuffer), '\0');
|
||||
std::fill(std::begin(m_ReceiveBuffer), std::end(m_ReceiveBuffer), '\0');
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::uninitialized;
|
||||
m_ConnectionSocket = preconfiguredSocket;
|
||||
m_AcceptConnectionRequired = acceptConnectionRequired;
|
||||
}
|
||||
|
||||
int32_t CConnection::Send(const char* data, int32_t dataLength)
|
||||
{
|
||||
int32_t bytesSent = send(m_ConnectionSocket, data, dataLength, 0);
|
||||
if (bytesSent == SOCKET_ERROR)
|
||||
{
|
||||
SDV_LOG_ERROR("send failed with error: ", std::to_string(WSAGetLastError()));
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::communication_error;
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return bytesSent;
|
||||
}
|
||||
|
||||
bool CConnection::SendData(/*inout*/ sdv::sequence<sdv::pointer<uint8_t>>& seqData)
|
||||
{
|
||||
static uint32_t msgId = 0;
|
||||
msgId++;
|
||||
size_t requiredSize = 0;
|
||||
std::for_each(seqData.cbegin(),
|
||||
seqData.cend(),
|
||||
[&](const sdv::pointer<uint8_t>& rBuffer) { requiredSize += rBuffer.size(); });
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_SendMutex);
|
||||
|
||||
uint32_t packageNumber = 1;
|
||||
SMsgHeader msgHeader;
|
||||
msgHeader.msgStart = m_MsgStart;
|
||||
msgHeader.msgEnd = m_MsgEnd;
|
||||
msgHeader.msgId = msgId;
|
||||
msgHeader.msgSize = static_cast<uint32_t>(requiredSize);
|
||||
msgHeader.packetNumber = packageNumber;
|
||||
msgHeader.totalPacketCount = static_cast<uint32_t>((requiredSize + m_SendMessageSize - 1) / m_SendMessageSize);
|
||||
memcpy_s(&m_SendBuffer[0], m_SendBufferSize, &msgHeader, sizeof(msgHeader));
|
||||
uint32_t offsetBuffer = sizeof(SMsgHeader);
|
||||
|
||||
std::for_each(seqData.cbegin(),
|
||||
seqData.cend(),
|
||||
[&](const sdv::pointer<uint8_t>& rBuffer)
|
||||
{
|
||||
uint32_t offsetData = 0;
|
||||
while (rBuffer.size() > offsetData)
|
||||
{
|
||||
if (offsetBuffer == 0)
|
||||
{
|
||||
msgHeader.packetNumber = packageNumber;
|
||||
memcpy_s(&m_SendBuffer[0], m_SendBufferSize, &msgHeader, sizeof(msgHeader));
|
||||
offsetBuffer = sizeof(SMsgHeader);
|
||||
}
|
||||
|
||||
auto availableBufferSize = m_SendBufferSize - offsetBuffer;
|
||||
|
||||
if (availableBufferSize > (rBuffer.size() - offsetData))
|
||||
{
|
||||
// fragments fits in buffer, go to next fragment without sending
|
||||
memcpy_s(&m_SendBuffer[offsetBuffer],
|
||||
availableBufferSize,
|
||||
rBuffer.get() + offsetData,
|
||||
rBuffer.size() - offsetData);
|
||||
|
||||
offsetBuffer += (static_cast<uint32_t>(rBuffer.size()) - offsetData);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// fragments exceeds buffer, fill buffer, send buffer, keep fragment
|
||||
memcpy_s(&m_SendBuffer[offsetBuffer],
|
||||
availableBufferSize,
|
||||
rBuffer.get() + offsetData,
|
||||
availableBufferSize);
|
||||
|
||||
Send(m_SendBuffer, static_cast<int>(m_SendBufferSize));
|
||||
offsetData += (static_cast<uint32_t>(availableBufferSize));
|
||||
offsetBuffer = 0;
|
||||
packageNumber++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (0 != offsetBuffer)
|
||||
{
|
||||
Send(m_SendBuffer, static_cast<int>(offsetBuffer));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SOCKET CConnection::AcceptConnection()
|
||||
{
|
||||
SOCKET clientSocket{INVALID_SOCKET};
|
||||
|
||||
int32_t attempt = 0;
|
||||
while (clientSocket == INVALID_SOCKET)
|
||||
{
|
||||
clientSocket = accept(m_ConnectionSocket, NULL, NULL);
|
||||
if (clientSocket == INVALID_SOCKET)
|
||||
{
|
||||
Sleep(2);
|
||||
}
|
||||
attempt++;
|
||||
if (attempt > 2000)
|
||||
{
|
||||
SDV_LOG_ERROR("Accept socket failed, loop exeeded.");
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::connection_error;
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return clientSocket;
|
||||
}
|
||||
|
||||
bool CConnection::AsyncConnect(sdv::IInterfaceAccess* pReceiver)
|
||||
{
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::initializing;
|
||||
if (m_AcceptConnectionRequired)
|
||||
{
|
||||
m_ConnectionSocket = AcceptConnection();
|
||||
}
|
||||
|
||||
if (m_ConnectionSocket == INVALID_SOCKET)
|
||||
{
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::connection_error;
|
||||
return false;
|
||||
}
|
||||
m_pReceiver = sdv::TInterfaceAccessPtr(pReceiver).GetInterface<sdv::ipc::IDataReceiveCallback>();
|
||||
m_pEvent = sdv::TInterfaceAccessPtr(pReceiver).GetInterface<sdv::ipc::IConnectEventCallback>();
|
||||
m_ReceiveThread = std::thread(std::bind(&CConnection::ReceiveMessages, this));
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::connected;
|
||||
|
||||
// TODO: Connection negotiation didn't take place... implement this!
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConnection::WaitForConnection(/*in*/ uint32_t /*uiWaitMs*/)
|
||||
{
|
||||
if (m_ConnectionStatus == sdv::ipc::EConnectStatus::connected) return true;
|
||||
|
||||
// TODO: Implementation here!
|
||||
|
||||
// TODO: Suppress static code analysis while there is no implementation yet.
|
||||
// cppcheck-suppress identicalConditionAfterEarlyExit
|
||||
return m_ConnectionStatus == sdv::ipc::EConnectStatus::connected;
|
||||
}
|
||||
|
||||
void CConnection::CancelWait()
|
||||
{
|
||||
// TODO: Implementation here!
|
||||
}
|
||||
|
||||
void CConnection::Disconnect()
|
||||
{
|
||||
// TODO: Implementation here!
|
||||
}
|
||||
|
||||
uint64_t CConnection::RegisterStatusEventCallback(/*in*/ sdv::IInterfaceAccess* /*pEventCallback*/)
|
||||
{
|
||||
// TODO: Implementation here!
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CConnection::UnregisterStatusEventCallback(/*in*/ uint64_t /*uiCookie*/)
|
||||
{
|
||||
// TODO: Implementation here!
|
||||
}
|
||||
|
||||
sdv::ipc::EConnectStatus CConnection::GetStatus() const
|
||||
{
|
||||
return m_ConnectionStatus;
|
||||
}
|
||||
|
||||
void CConnection::DestroyObject()
|
||||
{
|
||||
m_StopReceiveThread = true;
|
||||
if (m_ReceiveThread.joinable())
|
||||
{
|
||||
m_ReceiveThread.join();
|
||||
}
|
||||
closesocket(m_ConnectionSocket);
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::disconnected;
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool CConnection::ValidateHeader(const SMsgHeader& msgHeader)
|
||||
{
|
||||
if ((msgHeader.msgStart == m_MsgStart) && (msgHeader.msgEnd == m_MsgEnd))
|
||||
{
|
||||
if (msgHeader.msgSize != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CConnection::ReadNumberOfBytes(char* buffer, uint32_t bufferLength)
|
||||
{
|
||||
uint32_t bytesReceived = 0;
|
||||
while (!m_StopReceiveThread && (bufferLength > bytesReceived))
|
||||
{
|
||||
bytesReceived += recv(m_ConnectionSocket, buffer + bytesReceived, bufferLength - bytesReceived, 0);
|
||||
if (bytesReceived == static_cast<uint32_t>(SOCKET_ERROR))
|
||||
{
|
||||
auto error = WSAGetLastError();
|
||||
if (error != WSAEWOULDBLOCK)
|
||||
{
|
||||
if(error == WSAECONNRESET)
|
||||
{
|
||||
SDV_LOG_INFO("Reset SOCKET, recv() failed with error: ", error, " ", m_StopReceiveThread);
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::disconnected;
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
else if (!m_StopReceiveThread)
|
||||
{
|
||||
SDV_LOG_ERROR("SOCKET_ERROR, recv() failed with error: ", error);
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::communication_error;
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bytesReceived = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bufferLength != bytesReceived)
|
||||
{
|
||||
if (!m_StopReceiveThread || (m_ConnectionStatus == sdv::ipc::EConnectStatus::disconnected))
|
||||
{
|
||||
SDV_LOG_INFO("The expected bytes could not be received.");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CConnection::ReadMessageHeader(uint32_t& msgSize, uint32_t& msgId, uint32_t& packageNumber, uint32_t& totalPackageCount, bool verifyHeader)
|
||||
{
|
||||
SMsgHeader msgHeader;
|
||||
|
||||
if (ReadNumberOfBytes(reinterpret_cast<char*>(&msgHeader), sizeof(SMsgHeader)))
|
||||
{
|
||||
if (ValidateHeader(msgHeader))
|
||||
{
|
||||
if (!verifyHeader)
|
||||
{
|
||||
if (msgHeader.msgSize == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
msgSize = msgHeader.msgSize;
|
||||
msgId = msgHeader.msgId;
|
||||
packageNumber = msgHeader.packetNumber;
|
||||
totalPackageCount = msgHeader.totalPacketCount;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((msgId == msgHeader.msgId) && (packageNumber == msgHeader.packetNumber))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDV_LOG_WARNING("Received wrong message, Id = ", std::to_string(msgHeader.msgId), " package = ",
|
||||
std::to_string(packageNumber), " (expected id = ", std::to_string(msgId), " package = ", std::to_string(packageNumber), ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_StopReceiveThread)
|
||||
{
|
||||
SDV_LOG_WARNING("Could not read message header");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CConnection::ReceiveMessages()
|
||||
{
|
||||
while (!m_StopReceiveThread && (m_ConnectionSocket != INVALID_SOCKET))
|
||||
{
|
||||
uint32_t messageSize{ 0 };
|
||||
uint32_t msgId{ 0 };
|
||||
uint32_t packageNumber{ 0 };
|
||||
uint32_t totalPackageCount{ 0 };
|
||||
|
||||
if (ReadMessageHeader(messageSize, msgId, packageNumber, totalPackageCount, false))
|
||||
{
|
||||
uint32_t dataOffset{ 0 };
|
||||
sdv::pointer<uint8_t> message;
|
||||
message.resize(messageSize);
|
||||
for (uint32_t package = 1; package <= totalPackageCount; package++)
|
||||
{
|
||||
uint32_t bytesToBeRead = m_SendMessageSize;
|
||||
if (package == totalPackageCount)
|
||||
{
|
||||
bytesToBeRead = messageSize - dataOffset; // last package
|
||||
}
|
||||
|
||||
if (package != 1)
|
||||
{
|
||||
if (!ReadMessageHeader(messageSize, msgId, package, totalPackageCount, true))
|
||||
{
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::communication_error;
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ReadNumberOfBytes(reinterpret_cast<char*>(message.get()) + dataOffset, bytesToBeRead))
|
||||
{
|
||||
m_ConnectionStatus = sdv::ipc::EConnectStatus::communication_error;
|
||||
m_ConnectionSocket = INVALID_SOCKET;
|
||||
break;
|
||||
}
|
||||
|
||||
dataOffset += bytesToBeRead;
|
||||
}
|
||||
|
||||
if (!m_StopReceiveThread && (m_pReceiver != nullptr) && (m_ConnectionSocket != INVALID_SOCKET)) // In case of shutdown the message maybe invalid/incomplete
|
||||
{
|
||||
//m_pReceiver->ReceiveData(message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/**
|
||||
* @file connection.h
|
||||
* @author Sudipta Babu Durjoy FRD DISS21 (mailto:sudipta.durjoy@zf.com)
|
||||
* @brief
|
||||
* @version 1.0
|
||||
* @date 2023-04-18
|
||||
*
|
||||
* @copyright Copyright ZF Friedrichshafen AG (c) 2023
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CHANNEL_H
|
||||
#define CHANNEL_H
|
||||
|
||||
#include <thread>
|
||||
#include <algorithm>
|
||||
|
||||
#include <interfaces/ipc.h>
|
||||
#include <support/interface_ptr.h>
|
||||
#include <support/local_service_access.h>
|
||||
#include <support/component_impl.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#endif
|
||||
|
||||
constexpr uint32_t m_MsgStart = 0x01020304; ///< value to mark the start of the message header
|
||||
constexpr uint32_t m_MsgEnd = 0x05060708; ///< value to mark the end of the message header
|
||||
|
||||
/**
|
||||
* @brief Message header which will be put before a message.
|
||||
* Can be used for validation and includes complete size of the message. Other values are not used yet
|
||||
*/
|
||||
struct SMsgHeader
|
||||
{
|
||||
uint32_t msgStart = 0; ///< marker for the start of the header
|
||||
uint32_t msgId = 0; ///< message Id, must match for all message packages
|
||||
uint32_t msgSize = 0; ///< size of the message without the header
|
||||
uint32_t packetNumber = 0; ///< number of the package starting with 1
|
||||
uint32_t totalPacketCount = 0; ///< total number of paackes required for the message
|
||||
uint32_t msgEnd = 0; ///< marker for the end of the header
|
||||
};
|
||||
|
||||
/**
|
||||
* Class for remote IPC connection
|
||||
* Created and managed by IPCAccess::AccessRemoveIPCConnection(best use unique_ptr to store, so memory address stays
|
||||
* valid)
|
||||
*/
|
||||
class CConnection : public sdv::IInterfaceAccess, public sdv::ipc::IDataSend, public sdv::ipc::IConnect, public sdv::IObjectDestroy
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief default constructor used by create endpoint - allocates new buffers m_Sender and m_Receiver
|
||||
*/
|
||||
CConnection();
|
||||
|
||||
/**
|
||||
* @brief access existing connection
|
||||
* @param[in] preconfiguredSocket Prepared socket for the connection.
|
||||
* @param[in] acceptConnectionRequired If true connection has to be accepted before receive thread can be started.
|
||||
*/
|
||||
CConnection(SOCKET preconfiguredSocket, bool acceptConnectionRequired);
|
||||
|
||||
/**
|
||||
* @brief Virtual destructor needed for "delete this;".
|
||||
*/
|
||||
virtual ~CConnection() = default;
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::ipc::IDataSend)
|
||||
SDV_INTERFACE_ENTRY(sdv::ipc::IConnect)
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectDestroy)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
/**
|
||||
* @brief Sends data consisting of multiple data chunks via the IPC connection.
|
||||
* Overload of sdv::ipc::IDataSend::SendData.
|
||||
* @param[inout] seqData Sequence of data buffers to be sent. The sequence might be changed to optimize the communication
|
||||
* without having to copy the data.
|
||||
* @return Return 'true' if all data could be sent; 'false' otherwise.
|
||||
*/
|
||||
virtual bool SendData(/*inout*/ sdv::sequence<sdv::pointer<uint8_t>>& seqData) override;
|
||||
|
||||
/**
|
||||
* @brief Establish a connection and start sending/receiving messages. Overload of
|
||||
* sdv::ipc::IConnect::AsyncConnect.
|
||||
* @param[in] pReceiver The message has to be forwarded.
|
||||
* @return Returns 'true' when a connection could be established. Use IConnectStatus or IConnectEventCallback to check the
|
||||
* connection state.
|
||||
*/
|
||||
virtual bool AsyncConnect(/*in*/ sdv::IInterfaceAccess* pReceiver) override;
|
||||
|
||||
/**
|
||||
* @brief Wait for a connection to take place. Overload of sdv::ipc::IConnect::WaitForConnection.
|
||||
* @param[in] uiWaitMs Wait for a connection to take place. A value of 0 doesn't wait at all, a value of 0xffffffff
|
||||
* waits for infinite time.
|
||||
* @return Returns 'true' when a connection took place.
|
||||
*/
|
||||
virtual bool WaitForConnection(/*in*/ uint32_t uiWaitMs) override;
|
||||
|
||||
/**
|
||||
* @brief Cancel a wait for connection. Overload of sdv::ipc::IConnect::CancelWait.
|
||||
*/
|
||||
virtual void CancelWait() override;
|
||||
|
||||
/**
|
||||
* @brief Disconnect from a connection. This will set the connect status to disconnected and release the interface
|
||||
* used for the status events.
|
||||
*/
|
||||
virtual void Disconnect() override;
|
||||
|
||||
/**
|
||||
* @brief Register event callback interface. Overload of sdv::ipc::IConnect::RegisterStatusEventCallback.
|
||||
* @details Register a connection status event callback interface. The exposed interface must be of type
|
||||
* IConnectEventCallback. The registration will exist until a call to the unregister function with the returned cookie
|
||||
* or until the connection is terminated.
|
||||
* @param[in] pEventCallback Pointer to the object exposing the IConnectEventCallback interface.
|
||||
* @return The cookie assigned to the registration.
|
||||
*/
|
||||
virtual uint64_t RegisterStatusEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister the status event callback with the returned cookie from the registration. Overload of
|
||||
* sdv::ipc::IConnect::UnregisterStatusEventCallback.
|
||||
* @param[in] uiCookie The cookie returned by a previous call to the registration function.
|
||||
*/
|
||||
virtual void UnregisterStatusEventCallback(/*in*/ uint64_t uiCookie) override;
|
||||
|
||||
/**
|
||||
* @brief Get status of the connection
|
||||
* @return Returns the ipc::EConnectStatus struct
|
||||
*/
|
||||
virtual sdv::ipc::EConnectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Destroy the object. Overload of IObjectDestroy::DestroyObject.
|
||||
* @attention After a call of this function, all exposed interfaces render invalid and should not be used any more.
|
||||
*/
|
||||
virtual void DestroyObject() override;
|
||||
|
||||
private:
|
||||
std::thread m_ReceiveThread; ///< Thread which receives data from the socket
|
||||
std::atomic<bool> m_StopReceiveThread = false; ///< bool variable to stop thread
|
||||
std::atomic<sdv::ipc::EConnectStatus> m_ConnectionStatus; ///< the status of the connection
|
||||
SOCKET m_ConnectionSocket; ///< The socket to send and receive data
|
||||
sdv::ipc::IDataReceiveCallback* m_pReceiver = nullptr; ///< Receiver to pass the messages if available
|
||||
sdv::ipc::IConnectEventCallback* m_pEvent = nullptr; ///< Event receiver.
|
||||
bool m_AcceptConnectionRequired; ///< if true connection has to be accepted before receive thread can be started
|
||||
mutable std::recursive_mutex m_SendMutex; ///< Synchronize all packages to be send.
|
||||
|
||||
static constexpr uint32_t m_SendMessageSize{ 1024 }; ///< size for the message to be send.
|
||||
static constexpr uint32_t m_SendBufferSize = sizeof(SMsgHeader) + m_SendMessageSize; ///< Initial size of the send buffer.
|
||||
char m_SendBuffer[m_SendBufferSize]; ///< send buffer length
|
||||
char m_ReceiveBuffer[sizeof(SMsgHeader)]; ///< receive buffer, just for reading the message header
|
||||
uint32_t m_ReceiveBufferLength = sizeof(SMsgHeader); ///< receive buffer length
|
||||
|
||||
/**
|
||||
* @brief Function to accept the connection to the client.
|
||||
* @return Returns the socket to receive data
|
||||
*/
|
||||
SOCKET AcceptConnection();
|
||||
|
||||
/**
|
||||
* @brief Send data function via socket.
|
||||
* @param[in] data to be send
|
||||
* @param[in] dataLength size of the data to be sent
|
||||
* @return Returns number of bytes which has been sent
|
||||
*/
|
||||
int32_t Send(const char* data, int32_t dataLength);
|
||||
|
||||
/**
|
||||
* @brief Function to receive data, runs in a thread
|
||||
*/
|
||||
void ReceiveMessages();
|
||||
|
||||
/**
|
||||
* @brief Validates the header of the message to determine if message is valid
|
||||
* @param[in] msgHeader filled message header structure
|
||||
* @return true if valid header was found, otherwise false
|
||||
*/
|
||||
bool ValidateHeader(const SMsgHeader& msgHeader);
|
||||
|
||||
/**
|
||||
* @brief read header and get the values from the header. In case verify == true validate the input values
|
||||
* @param[in] msgSize size of the message without headers
|
||||
* @param[in] msgId message id of the message
|
||||
* @param[in] packageNumber package number of the message
|
||||
* @param[in] totalPackageCount number of packages the message requires
|
||||
* @param[in] verifyHeader If true verify that the input of msgId and packageNumber match the header values
|
||||
* @return if verify == false, return true if a valid header can be read.
|
||||
* if verify == true input values of msdId and package number must match with the header values.
|
||||
*/
|
||||
bool ReadMessageHeader(uint32_t &msgSize, uint32_t &msgId, uint32_t &packageNumber, uint32_t &totalPackageCount, bool verifyHeader);
|
||||
|
||||
/**
|
||||
* @brief read number of bytes and write them to the given buffer
|
||||
* @param[in] buffer Buffer the data is stored
|
||||
* @param[in] length of the buffer to be filled
|
||||
* @return return true if the number of bytes can be read, otherwise false
|
||||
*/
|
||||
bool ReadNumberOfBytes(char* buffer, uint32_t length);
|
||||
};
|
||||
|
||||
#endif // !define CHANNEL_H
|
||||
Reference in New Issue
Block a user