tunnel component & update vehicle abstraction example (#8)

This commit is contained in:
tompzf
2026-04-02 17:37:00 +02:00
committed by GitHub
parent 6ed5fdb951
commit 07cf4f654b
94 changed files with 9268 additions and 830 deletions

View File

@@ -13,16 +13,22 @@ if(WIN32)
project(uds_win_sockets VERSION 1.0 LANGUAGES CXX)
# Define target
add_library(uds_win_sockets SHARED
"channel_mgnt.h"
"channel_mgnt.cpp"
"connection.h"
"connection.cpp")
add_library(uds_win_sockets STATIC
channel_mgnt.cpp
connection.cpp
)
target_link_libraries(uds_win_sockets ${CMAKE_THREAD_LIBS_INIT} Ws2_32.lib)
target_include_directories(uds_win_sockets
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
./include/
)
target_link_options(uds_win_sockets PRIVATE)
target_include_directories(uds_win_sockets PRIVATE ./include/)
target_link_libraries(uds_win_sockets
PUBLIC
${CMAKE_THREAD_LIBS_INIT}
Ws2_32.lib
)
set_target_properties(uds_win_sockets PROPERTIES PREFIX "")
set_target_properties(uds_win_sockets PROPERTIES SUFFIX ".sdv")

View File

@@ -10,6 +10,7 @@
* Contributors:
* Denisa Ros - initial API and implementation
********************************************************************************/
#ifdef _WIN32
#include "channel_mgnt.h"
#include "connection.h"
@@ -323,15 +324,12 @@ static SOCKET ConnectUnixSocket(
const auto deadline = std::chrono::steady_clock::now() +
std::chrono::milliseconds(totalTimeoutMs);
int lastError = 0;
while (true)
{
SOCKET s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s == INVALID_SOCKET)
{
lastError = WSAGetLastError();
SDV_LOG_ERROR("[AF_UNIX] socket() FAIL (client), WSA=", lastError);
SDV_LOG_ERROR("[AF_UNIX] socket() FAIL (client), WSA=", WSAGetLastError());
return INVALID_SOCKET;
}
@@ -341,7 +339,7 @@ static SOCKET ConnectUnixSocket(
return s;
}
lastError = WSAGetLastError();
int lastError = WSAGetLastError();
closesocket(s);
if (std::chrono::steady_clock::now() >= deadline)
@@ -364,7 +362,7 @@ bool CSocketsChannelMgnt::OnInitialize()
return true;
}
void CSocketsChannelMgnt::OnServerClosed(const std::string& udsPath, CConnection* ptr)
void CSocketsChannelMgnt::OnServerClosed(const std::string& udsPath, CWinsockConnection* ptr)
{
std::lock_guard<std::mutex> lock(m_udsMtx);
@@ -411,8 +409,8 @@ sdv::ipc::SChannelEndpoint CSocketsChannelMgnt::CreateEndpoint(const sdv::u8stri
return {};
}
// Server-side CConnection, it will accept() a client on first use
auto server = std::make_shared<CConnection>(listenSocket, /*acceptRequired*/ true);
// Server-side CWinsockConnection, it will accept() a client on first use
auto server = std::make_shared<CWinsockConnection>(listenSocket, /*acceptRequired*/ true);
{
std::lock_guard<std::mutex> lock(m_udsMtx);
@@ -481,5 +479,7 @@ sdv::IInterfaceAccess* CSocketsChannelMgnt::Access(const sdv::u8string& cs)
// Client-side connection object (acceptRequired=false)
// Ownership is transferred to the caller (VAPI runtime)
return new CConnection(s, /*acceptRequired*/ false);
}
return new CWinsockConnection(s, /*acceptRequired*/ false);
}
#endif

View File

@@ -10,9 +10,10 @@
* Contributors:
* Denisa Ros - initial API and implementation
********************************************************************************/
#ifdef _WIN32
#ifndef CHANNEL_MGNT_H
#define CHANNEL_MGNT_H
#ifndef WIN_SOCKETS_CHANNEL_MGNT_H
#define WIN_SOCKETS_CHANNEL_MGNT_H
#include <support/component_impl.h>
#include <interfaces/ipc.h>
@@ -150,6 +151,8 @@ public:
DECLARE_DEFAULT_OBJECT_NAME("LocalChannelControl")
DECLARE_OBJECT_SINGLETON()
virtual ~CSocketsChannelMgnt() = default;
/**
* @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize.
* @return Returns 'true' when the initialization was successful, 'false' when not.
@@ -169,7 +172,7 @@ public:
* The endpoint is implemented as a local AF_UNIX server socket
* (listen socket) on Windows. The connect string has the format:
*
* proto=uds;path=&lt;udsPath&gt;
* proto=uds;path=<udsPath>;
*
* If no configuration is provided or no path is specified, a default
* path is used (under %LOCALAPPDATA%/sdv)
@@ -193,7 +196,7 @@ public:
* Overload of sdv::ipc::IChannelAccess::Access
*
* The connect string is expected to contain:
* proto=uds;path=&lt;udsPath&gt;
* proto=uds;path=<udsPath>;
*
* For the first Access() call with a given path, the server-side
* connection object created by CreateEndpoint() can be returned.
@@ -206,18 +209,17 @@ public:
sdv::IInterfaceAccess* Access(const sdv::u8string& ssConnectString) override;
/**
* @brief Called by a CConnection instance when the server side is closed
* @brief Called by a CWinsockConnection instance when the server side is closed
*
* Used to clean up internal registries for a given UDS path
*
* @param udsPath Path to the UDS endpoint
* @param ptr Pointer to the CConnection instance that was closed
* @param ptr Pointer to the CWinsockConnection instance that was closed
*/
void OnServerClosed(const std::string& udsPath, CConnection* ptr);
void OnServerClosed(const std::string& udsPath, CWinsockConnection* ptr);
private:
/// @brief Registry of AF_UNIX server connections keyed by normalized UDS path
std::map<std::string, std::shared_ptr<CConnection>> m_udsServers;
std::map<std::string, std::shared_ptr<CWinsockConnection>> m_udsServers;
/**
* @brief Set of UDS paths that already returned their server-side
@@ -234,4 +236,5 @@ private:
// SDV object factory macro
DEFINE_SDV_OBJECT(CSocketsChannelMgnt)
#endif // ! defined CHANNEL_MGNT_H
#endif // ! defined WIN_SOCKETS_CHANNEL_MGNT_H
#endif

View File

@@ -10,7 +10,7 @@
* Contributors:
* Denisa Ros - initial API and implementation
********************************************************************************/
#ifdef _WIN32
#include "connection.h"
#include <numeric>
@@ -18,8 +18,8 @@
#include <cstring>
#include <chrono>
CConnection::CConnection(SOCKET preconfiguredSocket, bool acceptConnectionRequired)
: m_ConnectionStatus(sdv::ipc::EConnectStatus::uninitialized)
CWinsockConnection::CWinsockConnection(unsigned long long preconfiguredSocket, bool acceptConnectionRequired)
: m_ConnectionState(sdv::ipc::EConnectState::uninitialized)
, m_AcceptConnectionRequired(acceptConnectionRequired)
, m_CancelWait(false)
{
@@ -30,23 +30,34 @@ CConnection::CConnection(SOCKET preconfiguredSocket, bool acceptConnectionRequir
if (m_AcceptConnectionRequired)
{
// Server side: we own a listening socket, active socket is not yet accepted
m_ListenSocket = preconfiguredSocket;
m_ListenSocket = static_cast<SOCKET>(preconfiguredSocket);
m_ConnectionSocket = INVALID_SOCKET;
}
else
{
// Client side: we already have a connected socket
m_ListenSocket = INVALID_SOCKET;
m_ConnectionSocket = preconfiguredSocket;
m_ConnectionSocket = static_cast<SOCKET>(preconfiguredSocket);
}
}
CConnection::~CConnection()
/*CWinsockConnection::CWinsockConnection()
: m_ConnectionState(sdv::ipc::EConnectState::uninitialized)
, m_AcceptConnectionRequired(false)
, m_CancelWait(false)
{
m_ListenSocket = INVALID_SOCKET;
m_ConnectionSocket = INVALID_SOCKET;
std::fill(std::begin(m_SendBuffer), std::end(m_SendBuffer), '\0');
std::fill(std::begin(m_ReceiveBuffer), std::end(m_ReceiveBuffer), '\0');
}*/
CWinsockConnection::~CWinsockConnection()
{
try
{
StopThreadsAndCloseSockets();
m_ConnectionStatus = sdv::ipc::EConnectStatus::disconnected;
m_ConnectionState = sdv::ipc::EConnectState::disconnected;
}
catch (...)
{
@@ -54,11 +65,11 @@ CConnection::~CConnection()
}
}
void CConnection::SetStatus(sdv::ipc::EConnectStatus status)
void CWinsockConnection::SetConnectState(sdv::ipc::EConnectState state)
{
{
std::lock_guard<std::mutex> lk(m_MtxConnect);
m_ConnectionStatus.store(status, std::memory_order_release);
m_ConnectionState.store(state, std::memory_order_release);
}
// Wake up any waiter
@@ -69,7 +80,7 @@ void CConnection::SetStatus(sdv::ipc::EConnectStatus status)
{
try
{
m_pEvent->SetStatus(status);
m_pEvent->SetConnectState(state);
}
catch (...)
{
@@ -78,7 +89,7 @@ void CConnection::SetStatus(sdv::ipc::EConnectStatus status)
}
}
int32_t CConnection::Send(const char* data, int32_t dataLength)
int32_t CWinsockConnection::Send(const char* data, int32_t dataLength)
{
int32_t total = 0;
@@ -88,7 +99,7 @@ int32_t CConnection::Send(const char* data, int32_t dataLength)
if (n == SOCKET_ERROR)
{
SDV_LOG_ERROR("send failed with error: ", std::to_string(WSAGetLastError()));
m_ConnectionStatus = sdv::ipc::EConnectStatus::communication_error;
m_ConnectionState = sdv::ipc::EConnectState::communication_error;
m_ConnectionSocket = INVALID_SOCKET;
return (total > 0) ? total : SOCKET_ERROR;
}
@@ -98,7 +109,7 @@ int32_t CConnection::Send(const char* data, int32_t dataLength)
return total;
}
int CConnection::SendExact(const char* data, int len)
int CWinsockConnection::SendExact(const char* data, int len)
{
int total = 0;
@@ -115,13 +126,13 @@ int CConnection::SendExact(const char* data, int len)
return total;
}
bool CConnection::SendData(/*inout*/ sdv::sequence<sdv::pointer<uint8_t>>& seqData)
bool CWinsockConnection::SendData(/*inout*/ sdv::sequence<sdv::pointer<uint8_t>>& seqData)
{
// Must be connected and have a valid socket
if (m_ConnectionStatus != sdv::ipc::EConnectStatus::connected ||
if (m_ConnectionState != sdv::ipc::EConnectState::connected ||
m_ConnectionSocket == INVALID_SOCKET)
{
m_ConnectionStatus = sdv::ipc::EConnectStatus::communication_error;
m_ConnectionState = sdv::ipc::EConnectState::communication_error;
return false;
}
@@ -288,11 +299,11 @@ bool CConnection::SendData(/*inout*/ sdv::sequence<sdv::pointer<uint8_t>>& seqDa
return (sentOffset == required);
}
SOCKET CConnection::AcceptConnection()
SOCKET CWinsockConnection::AcceptConnection()
{
if (m_ListenSocket == INVALID_SOCKET)
{
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return INVALID_SOCKET;
}
@@ -310,7 +321,7 @@ SOCKET CConnection::AcceptConnection()
if (sr == SOCKET_ERROR)
{
SDV_LOG_ERROR("[AF_UNIX] select(listen) FAIL, WSA=", WSAGetLastError());
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return INVALID_SOCKET;
}
@@ -329,7 +340,7 @@ SOCKET CConnection::AcceptConnection()
}
SDV_LOG_ERROR("[AF_UNIX] accept FAIL, WSA=", err);
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return INVALID_SOCKET;
}
@@ -338,11 +349,11 @@ SOCKET CConnection::AcceptConnection()
}
SDV_LOG_ERROR("[AF_UNIX] accept canceled (stop flag)");
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return INVALID_SOCKET;
}
bool CConnection::AsyncConnect(sdv::IInterfaceAccess* pReceiver)
bool CWinsockConnection::AsyncConnect(sdv::IInterfaceAccess* pReceiver)
{
// Store callbacks
m_pReceiver = sdv::TInterfaceAccessPtr(pReceiver).GetInterface<sdv::ipc::IDataReceiveCallback>();
@@ -360,14 +371,14 @@ bool CConnection::AsyncConnect(sdv::IInterfaceAccess* pReceiver)
m_ConnectThread.join();
// Start the connect worker
m_ConnectThread = std::thread(&CConnection::ConnectWorker, this);
m_ConnectThread = std::thread(&CWinsockConnection::ConnectWorker, this);
return true;
}
bool CConnection::WaitForConnection(uint32_t uiWaitMs)
bool CWinsockConnection::WaitForConnection(uint32_t uiWaitMs)
{
if (m_ConnectionStatus.load(std::memory_order_acquire) ==
sdv::ipc::EConnectStatus::connected)
if (m_ConnectionState.load(std::memory_order_acquire) ==
sdv::ipc::EConnectState::connected)
{
return true;
}
@@ -380,16 +391,16 @@ bool CConnection::WaitForConnection(uint32_t uiWaitMs)
lk,
[this]
{
return m_ConnectionStatus.load(std::memory_order_acquire) ==
sdv::ipc::EConnectStatus::connected;
return m_ConnectionState.load(std::memory_order_acquire) ==
sdv::ipc::EConnectState::connected;
});
return true;
}
if (uiWaitMs == 0u) // zero wait
{
return (m_ConnectionStatus.load(std::memory_order_acquire) ==
sdv::ipc::EConnectStatus::connected);
return (m_ConnectionState.load(std::memory_order_acquire) ==
sdv::ipc::EConnectState::connected);
}
// finite wait
@@ -398,24 +409,24 @@ bool CConnection::WaitForConnection(uint32_t uiWaitMs)
std::chrono::milliseconds(uiWaitMs),
[this]
{
return m_ConnectionStatus.load(std::memory_order_acquire) ==
sdv::ipc::EConnectStatus::connected;
return m_ConnectionState.load(std::memory_order_acquire) ==
sdv::ipc::EConnectState::connected;
});
}
void CConnection::CancelWait()
void CWinsockConnection::CancelWait()
{
m_CancelWait.store(true);
}
void CConnection::Disconnect()
void CWinsockConnection::Disconnect()
{
m_CancelWait.store(true);
StopThreadsAndCloseSockets();
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
}
uint64_t CConnection::RegisterStatusEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback)
uint64_t CWinsockConnection::RegisterStateEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback)
{
// Extract IConnectEventCallback interface
m_pEvent = sdv::TInterfaceAccessPtr(pEventCallback).GetInterface<sdv::ipc::IConnectEventCallback>();
@@ -424,7 +435,7 @@ uint64_t CConnection::RegisterStatusEventCallback(/*in*/ sdv::IInterfaceAccess*
return (m_pEvent != nullptr) ? 1ULL : 0ULL;
}
void CConnection::UnregisterStatusEventCallback(/*in*/ uint64_t uiCookie)
void CWinsockConnection::UnregisterStateEventCallback(/*in*/ uint64_t uiCookie)
{
// Only one callback supported -> cookie value is 1
if (uiCookie == 1ULL)
@@ -433,21 +444,21 @@ void CConnection::UnregisterStatusEventCallback(/*in*/ uint64_t uiCookie)
}
}
sdv::ipc::EConnectStatus CConnection::GetStatus() const
sdv::ipc::EConnectState CWinsockConnection::GetConnectState() const
{
return m_ConnectionStatus;
return m_ConnectionState;
}
void CConnection::DestroyObject()
void CWinsockConnection::DestroyObject()
{
m_StopReceiveThread = true;
m_StopConnectThread = true;
StopThreadsAndCloseSockets();
m_ConnectionStatus = sdv::ipc::EConnectStatus::disconnected;
m_ConnectionState = sdv::ipc::EConnectState::disconnected;
}
void CConnection::ConnectWorker()
void CWinsockConnection::ConnectWorker()
{
try
{
@@ -456,18 +467,18 @@ void CConnection::ConnectWorker()
// SERVER SIDE
if (m_ListenSocket == INVALID_SOCKET)
{
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
SetStatus(sdv::ipc::EConnectStatus::initializing);
SetConnectState(sdv::ipc::EConnectState::initializing);
SDV_LOG_INFO("[AF_UNIX] Srv ConnectWorker start: listen=%llu",
static_cast<uint64_t>(m_ListenSocket));
SOCKET c = AcceptConnection();
SDV_LOG_INFO("[AF_UNIX] Srv AcceptConnection returned: sock=%llu status=%d",
SDV_LOG_INFO("[AF_UNIX] Srv AcceptConnection returned: sock=%llu state=%d",
static_cast<uint64_t>(c),
static_cast<int>(m_ConnectionStatus.load()));
static_cast<int>(m_ConnectionState.load()));
if (c == INVALID_SOCKET)
{
@@ -475,7 +486,7 @@ void CConnection::ConnectWorker()
{
try
{
m_pEvent->SetStatus(m_ConnectionStatus);
m_pEvent->SetConnectState(m_ConnectionState);
}
catch (...)
{
@@ -485,7 +496,7 @@ void CConnection::ConnectWorker()
}
m_ConnectionSocket = c;
SetStatus(sdv::ipc::EConnectStatus::connected);
SetConnectState(sdv::ipc::EConnectState::connected);
StartReceiveThread_Unsafe();
return;
}
@@ -494,22 +505,22 @@ void CConnection::ConnectWorker()
// CLIENT SIDE
if (m_ConnectionSocket == INVALID_SOCKET)
{
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
}
// Client side: socket is already connected
SetStatus(sdv::ipc::EConnectStatus::connected);
SetConnectState(sdv::ipc::EConnectState::connected);
StartReceiveThread_Unsafe();
}
catch (...)
{
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
}
}
void CConnection::StartReceiveThread_Unsafe()
void CWinsockConnection::StartReceiveThread_Unsafe()
{
if (m_ReceiveThread.joinable())
{
@@ -517,10 +528,10 @@ void CConnection::StartReceiveThread_Unsafe()
}
m_StopReceiveThread.store(false);
m_ReceiveThread = std::thread(&CConnection::ReceiveMessages, this);
m_ReceiveThread = std::thread(&CWinsockConnection::ReceiveMessages, this);
}
void CConnection::StopThreadsAndCloseSockets()
void CWinsockConnection::StopThreadsAndCloseSockets()
{
// Signal stop
m_StopReceiveThread.store(true);
@@ -574,7 +585,7 @@ void CConnection::StopThreadsAndCloseSockets()
static_cast<uint64_t>(s));
}
bool CConnection::ReadNumberOfBytes(char* buffer, uint32_t length)
bool CWinsockConnection::ReadNumberOfBytes(char* buffer, uint32_t length)
{
uint32_t received = 0;
@@ -607,7 +618,7 @@ bool CConnection::ReadNumberOfBytes(char* buffer, uint32_t length)
return (received == length);
}
bool CConnection::ValidateHeader(const SMsgHeader& msgHeader)
bool CWinsockConnection::ValidateHeader(const SMsgHeader& msgHeader)
{
// Kept only for compatibility with any legacy users (not used in SDV path)
if ((msgHeader.msgStart == m_MsgStart) && (msgHeader.msgEnd == m_MsgEnd))
@@ -618,7 +629,7 @@ bool CConnection::ValidateHeader(const SMsgHeader& msgHeader)
}
uint32_t CConnection::ReadDataTable(const CMessage& message, SDataContext& dataCtx)
uint32_t CWinsockConnection::ReadDataTable(const CMessage& message, SDataContext& dataCtx)
{
uint32_t offset = 0;
@@ -691,7 +702,7 @@ uint32_t CConnection::ReadDataTable(const CMessage& message, SDataContext& dataC
return offset;
}
bool CConnection::ReadDataChunk(const CMessage& message, uint32_t offset, SDataContext& dataCtx)
bool CWinsockConnection::ReadDataChunk(const CMessage& message, uint32_t offset, SDataContext& dataCtx)
{
if (offset < sizeof(SMsgHdr))
return false;
@@ -743,12 +754,12 @@ bool CConnection::ReadDataChunk(const CMessage& message, uint32_t offset, SDataC
return true;
}
void CConnection::ReceiveSyncRequest(const CMessage& message)
void CWinsockConnection::ReceiveSyncRequest(const CMessage& message)
{
const auto hdr = message.GetMsgHdr();
if (hdr.uiVersion != SDVFrameworkInterfaceVersion)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
@@ -764,12 +775,12 @@ void CConnection::ReceiveSyncRequest(const CMessage& message)
return;
}
void CConnection::ReceiveSyncAnswer(const CMessage& message)
void CWinsockConnection::ReceiveSyncAnswer(const CMessage& message)
{
const auto hdr = message.GetMsgHdr();
if (hdr.uiVersion != SDVFrameworkInterfaceVersion)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
@@ -786,12 +797,12 @@ void CConnection::ReceiveSyncAnswer(const CMessage& message)
return;
}
void CConnection::ReceiveConnectRequest(const CMessage& message)
void CWinsockConnection::ReceiveConnectRequest(const CMessage& message)
{
const auto hdr = message.GetConnectHdr();
if (hdr.uiVersion != SDVFrameworkInterfaceVersion)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
@@ -808,42 +819,42 @@ void CConnection::ReceiveConnectRequest(const CMessage& message)
return;
}
void CConnection::ReceiveConnectAnswer(const CMessage& message)
void CWinsockConnection::ReceiveConnectAnswer(const CMessage& message)
{
const auto hdr = message.GetConnectHdr();
if (hdr.uiVersion != SDVFrameworkInterfaceVersion)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
// Handshake complete (client side)
SetStatus(sdv::ipc::EConnectStatus::connected);
SetConnectState(sdv::ipc::EConnectState::connected);
}
void CConnection::ReceiveConnectTerm(const CMessage& /*message*/)
void CWinsockConnection::ReceiveConnectTerm(const CMessage& /*message*/)
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
m_StopReceiveThread.store(true);
}
void CConnection::ReceiveDataMessage(const CMessage& message, SDataContext& dataCtx)
void CWinsockConnection::ReceiveDataMessage(const CMessage& message, SDataContext& dataCtx)
{
const uint32_t payloadOffset = ReadDataTable(message, dataCtx);
if (payloadOffset == 0)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
if (!ReadDataChunk(message, payloadOffset, dataCtx))
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
}
void CConnection::ReceiveDataFragmentMessage(const CMessage& message, SDataContext& dataCtx)
void CWinsockConnection::ReceiveDataFragmentMessage(const CMessage& message, SDataContext& dataCtx)
{
uint32_t offset = static_cast<uint32_t>(sizeof(SFragmentedMsgHdr));
@@ -852,19 +863,19 @@ void CConnection::ReceiveDataFragmentMessage(const CMessage& message, SDataConte
offset = ReadDataTable(message, dataCtx);
if (offset == 0)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
}
if (!ReadDataChunk(message, offset, dataCtx))
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
return;
}
}
void CConnection::ReceiveMessages()
void CWinsockConnection::ReceiveMessages()
{
try
{
@@ -898,14 +909,14 @@ void CConnection::ReceiveMessages()
if (!ReadNumberOfBytes(reinterpret_cast<char*>(&packetSize),
sizeof(packetSize)))
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
SDV_LOG_WARNING("[UDS][RX] Incomplete payload read -> disconnected");
break;
}
if (packetSize == 0 || packetSize > kMaxUdsPacketSize)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
break;
}
@@ -914,7 +925,7 @@ void CConnection::ReceiveMessages()
if (!ReadNumberOfBytes(reinterpret_cast<char*>(payload.data()),
packetSize))
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][RX] Invalid SDV message (envelope)");
break;
}
@@ -923,7 +934,7 @@ void CConnection::ReceiveMessages()
CMessage msg(std::move(payload));
if (!msg.IsValid())
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
continue;
}
@@ -941,12 +952,13 @@ void CConnection::ReceiveMessages()
break;
}
if (m_ConnectionStatus == sdv::ipc::EConnectStatus::terminating)
if (m_ConnectionState == sdv::ipc::EConnectState::terminating)
break;
}
}
catch (...)
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
}
}
}
#endif

View File

@@ -10,9 +10,9 @@
* Contributors:
* Denisa Ros - initial API and implementation
********************************************************************************/
#ifndef CONNECTION_H
#define CONNECTION_H
#ifdef _WIN32
#ifndef WIN_SOCKETS_CONNECTION_H
#define WIN_SOCKETS_CONNECTION_H
#include <interfaces/ipc.h>
#include <support/interface_ptr.h>
@@ -35,6 +35,7 @@
# endif
#endif
/// @brief Legacy framing markers for the old message header (not used by SDV envelope)
constexpr uint32_t m_MsgStart = 0x01020304; ///< Value to mark the start of the legacy message header
constexpr uint32_t m_MsgEnd = 0x05060708; ///< Value to mark the end of the legacy message header
@@ -67,10 +68,10 @@ struct SMsgHeader
*
* Exposes:
* - sdv::ipc::IDataSend : sending SDV-framed messages
* - sdv::ipc::IConnect : async connect / wait / status / events
* - sdv::ipc::IConnect : async connect / wait / state / events
* - sdv::IObjectDestroy : explicit destruction hook for SDV runtime
*/
class CConnection
class CWinsockConnection
: public sdv::IInterfaceAccess
, public sdv::ipc::IDataSend
, public sdv::ipc::IConnect
@@ -80,19 +81,19 @@ public:
/**
* @brief default constructor used by create endpoint - allocates new buffers m_Sender and m_Receiver
*/
CConnection();
CWinsockConnection();
/**
* @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);
CWinsockConnection(unsigned long long preconfiguredSocket, bool acceptConnectionRequired);
/**
* @brief Virtual destructor needed for "delete this;"
*/
virtual ~CConnection();
virtual ~CWinsockConnection();
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::ipc::IDataSend)
@@ -122,7 +123,7 @@ public:
* @param[in] pReceiver Object that exposes IDataReceiveCallback and
* optionally IConnectEventCallback
* @return true when the connect worker was started successfully
* Use GetStatus / WaitForConnection / callbacks for status
* Use GetConnectState / WaitForConnection / callbacks for state
*/
bool AsyncConnect(/*in*/ sdv::IInterfaceAccess* pReceiver) override;
@@ -132,7 +133,7 @@ public:
* Overload of sdv::ipc::IConnect::WaitForConnection
*
* @param[in] uiWaitMs
* - 0 : do not wait, just check current status
* - 0 : do not wait, just check current state
* - 0xFFFFFFFF: wait indefinitely
* - otherwise : wait up to uiWaitMs milliseconds
* @return true if the connection is in connected state when returning
@@ -149,36 +150,36 @@ public:
/**
* @brief Disconnect from the peer and stop I/O threads
*
* This sets the status to disconnected and releases the event interface
* This sets the state to disconnected and releases the event interface
*/
void Disconnect() override;
/**
* @brief Register event callback interface for connection status updates
* @brief Register event callback interface for connection state updates
*
* Overload of sdv::ipc::IConnect::RegisterStatusEventCallback
* Overload of sdv::ipc::IConnect::RegisterStateEventCallback
*
* @param[in] pEventCallback Pointer to an object exposing
* sdv::ipc::IConnectEventCallback.
* @return A registration cookie (1 = valid, 0 = failure)
*/
uint64_t RegisterStatusEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback) override;
uint64_t RegisterStateEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback) override;
/**
* @brief Unregister the status event callback using its cookie
* @brief Unregister the state event callback using its cookie
*
* Overload of sdv::ipc::IConnect::UnregisterStatusEventCallback
* Overload of sdv::ipc::IConnect::UnregisterStateEventCallback
*
* @param[in] uiCookie Cookie returned by RegisterStatusEventCallback
* @param[in] uiCookie Cookie returned by RegisterStateEventCallback
*/
void UnregisterStatusEventCallback(/*in*/ uint64_t uiCookie) override;
void UnregisterStateEventCallback(/*in*/ uint64_t uiCookie) override;
/**
* @brief Get current status of the connection
* @brief Get current state of the connection
*
* @return Current sdv::ipc::EConnectStatus
* @return Current sdv::ipc::EConnectState
*/
sdv::ipc::EConnectStatus GetStatus() const override;
sdv::ipc::EConnectState GetConnectState() const override;
/**
* @brief Destroy the object
@@ -196,7 +197,7 @@ private:
std::thread m_ConnectThread;
std::atomic<bool> m_StopReceiveThread{false}; ///< bool variable to stop thread
std::atomic<bool> m_StopConnectThread{false};
std::atomic<sdv::ipc::EConnectStatus> m_ConnectionStatus; ///< the status of the connection
std::atomic<sdv::ipc::EConnectState> m_ConnectionState; ///< the state of the connection
sdv::ipc::IDataReceiveCallback* m_pReceiver = nullptr; ///< Receiver to pass the messages if available
sdv::ipc::IConnectEventCallback* m_pEvent = nullptr; ///< Event receiver
@@ -217,7 +218,7 @@ private:
/// @brief Server accept loop / client connect confirmation
void ConnectWorker();
/// @brief Start the RX thread (pre: status=connected, socket valid)
/// @brief Start the RX thread (pre: state=connected, socket valid)
void StartReceiveThread_Unsafe();
/// @brief Stop worker threads and close all sockets cleanly
@@ -451,7 +452,7 @@ private:
* @brief Handle an incoming connect_term message
*
* Indicates that the peer requests immediate termination of the connection
* Sets status to disconnected and stops the RX loop
* Sets state to disconnected and stops the RX loop
*
* @param message SDV envelope containing the connect_term header
*/
@@ -503,8 +504,9 @@ private:
*/
bool ReadDataChunk(const CMessage& rMessage, uint32_t uiOffset, SDataContext& rsDataCtxt);
/// @brief Centralized status update (notifies waiters and callbacks)
void SetStatus(sdv::ipc::EConnectStatus status);
/// @brief Centralized state update (notifies waiters and callbacks)
void SetConnectState(sdv::ipc::EConnectState state);
};
#endif // CONNECTION_H
#endif // WIN_SOCKETS_CONNECTION_H
#endif