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,13 @@ if(UNIX)
project(uds_unix_sockets VERSION 1.0 LANGUAGES CXX)
# Define target
add_library(uds_unix_sockets SHARED
"channel_mgnt.h"
"channel_mgnt.cpp"
"connection.h"
"connection.cpp"
add_library(uds_unix_sockets STATIC
channel_mgnt.cpp
connection.cpp
)
target_link_libraries(uds_unix_sockets rt ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
target_link_options(uds_unix_sockets PRIVATE)
target_include_directories(uds_unix_sockets PRIVATE ./include/)
set_target_properties(uds_unix_sockets PROPERTIES PREFIX "")
set_target_properties(uds_unix_sockets PROPERTIES SUFFIX ".sdv")

View File

@@ -105,7 +105,7 @@ CUnixSocketConnection::CUnixSocketConnection(int preconfiguredFd,
, m_UdsPath(udsPath)
, m_StopReceiveThread(false)
, m_StopConnectThread(false)
, m_eStatus(sdv::ipc::EConnectStatus::uninitialized)
, m_eConnectState(sdv::ipc::EConnectState::uninitialized)
, m_pReceiver(nullptr)
, m_pEvent(nullptr)
{
@@ -170,10 +170,10 @@ bool CUnixSocketConnection::SendData(sdv::sequence<sdv::pointer<uint8_t>>& seqDa
#endif
// Only send when connected and FD valid
if (m_eStatus != sdv::ipc::EConnectStatus::connected || m_Fd < 0)
if (m_eConnectState != sdv::ipc::EConnectState::connected || m_Fd < 0)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SDV_LOG_WARNING("[UDS][TX] Send requested while not connected or FD invalid (status=", static_cast<int>(m_eStatus.load()), ")");
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][TX] Send requested while not connected or FD invalid (state=", static_cast<int>(m_eConnectState.load()), ")");
return false;
}
@@ -328,7 +328,7 @@ bool CUnixSocketConnection::SendData(sdv::sequence<sdv::pointer<uint8_t>>& seqDa
return true;
}
uint64_t CUnixSocketConnection::RegisterStatusEventCallback(sdv::IInterfaceAccess* pEventCallback)
uint64_t CUnixSocketConnection::RegisterStateEventCallback(sdv::IInterfaceAccess* pEventCallback)
{
if (!pEventCallback) return 0;
@@ -351,7 +351,7 @@ uint64_t CUnixSocketConnection::RegisterStatusEventCallback(sdv::IInterfaceAcces
return cookie;
}
void CUnixSocketConnection::UnregisterStatusEventCallback(uint64_t uiCookie)
void CUnixSocketConnection::UnregisterStateEventCallback(uint64_t uiCookie)
{
if (!uiCookie) return;
@@ -386,7 +386,7 @@ bool CUnixSocketConnection::AsyncConnect(sdv::IInterfaceAccess* pReceiver)
std::lock_guard<std::mutex> lk(m_StateMtx);
m_pReceiver = sdv::TInterfaceAccessPtr(pReceiver).GetInterface<sdv::ipc::IDataReceiveCallback>();
m_pEvent = sdv::TInterfaceAccessPtr(pReceiver).GetInterface<sdv::ipc::IConnectEventCallback>();
m_eStatus = sdv::ipc::EConnectStatus::initializing;
m_eConnectState = sdv::ipc::EConnectState::initializing;
// Reset stop flags
m_StopReceiveThread.store(false);
@@ -450,22 +450,22 @@ int CUnixSocketConnection::AcceptConnection() // deprecated
bool CUnixSocketConnection::WaitForConnection(uint32_t uiWaitMs)
{
if (m_eStatus.load(std::memory_order_acquire) == sdv::ipc::EConnectStatus::connected) return true;
if (m_eConnectState.load(std::memory_order_acquire) == sdv::ipc::EConnectState::connected) return true;
std::unique_lock<std::mutex> lk(m_MtxConnect);
if (uiWaitMs == 0xFFFFFFFFu)
{
m_CvConnect.wait(lk, [this]{
return m_eStatus.load(std::memory_order_acquire) == sdv::ipc::EConnectStatus::connected;
return m_eConnectState.load(std::memory_order_acquire) == sdv::ipc::EConnectState::connected;
});
return true;
}
if (uiWaitMs == 0u)
return (m_eStatus.load(std::memory_order_acquire) == sdv::ipc::EConnectStatus::connected);
return (m_eConnectState.load(std::memory_order_acquire) == sdv::ipc::EConnectState::connected);
return m_CvConnect.wait_for(lk, std::chrono::milliseconds(uiWaitMs),
[this]{ return m_eStatus.load(std::memory_order_acquire) == sdv::ipc::EConnectStatus::connected; });
[this]{ return m_eConnectState.load(std::memory_order_acquire) == sdv::ipc::EConnectState::connected; });
}
void CUnixSocketConnection::CancelWait()
@@ -476,33 +476,33 @@ void CUnixSocketConnection::CancelWait()
void CUnixSocketConnection::Disconnect()
{
StopThreadsAndCloseSockets(/*unlinkPath*/ false);
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
}
sdv::ipc::EConnectStatus CUnixSocketConnection::GetStatus() const
sdv::ipc::EConnectState CUnixSocketConnection::GetConnectState() const
{
return m_eStatus;
return m_eConnectState;
}
void CUnixSocketConnection::DestroyObject()
{
m_StopReceiveThread.store(true);
m_eStatus = sdv::ipc::EConnectStatus::disconnected;
m_eConnectState = sdv::ipc::EConnectState::disconnected;
}
void CUnixSocketConnection::SetStatus(sdv::ipc::EConnectStatus eStatus)
void CUnixSocketConnection::SetConnectState(sdv::ipc::EConnectState eConnectState)
{
// Update internal state atomically and wake up waiters.
{
std::lock_guard<std::mutex> lk(m_MtxConnect);
m_eStatus.store(eStatus, std::memory_order_release);
m_eConnectState.store(eConnectState, std::memory_order_release);
}
m_CvConnect.notify_all();
// Notify the legacy single-listener (kept for backward compatibility).
try
{
m_pEvent->SetStatus(eStatus);
m_pEvent->SetConnectState(eConnectState);
}
catch (...) { /* swallow: user callback must not crash transport */ }
@@ -515,7 +515,7 @@ void CUnixSocketConnection::SetStatus(sdv::ipc::EConnectStatus eStatus)
if (!entry.pCallback) { needCompact = true; continue; }
try
{
entry.pCallback->SetStatus(eStatus);
entry.pCallback->SetConnectState(eConnectState);
}
catch (...) { /* swallow per-listener */ }
}
@@ -588,7 +588,7 @@ void CUnixSocketConnection::ConnectWorker()
if (!EnsureDir(dir))
{
SDV_LOG_ERROR("[UDS][Server] ensure_dir('", dir, "') failed: ", std::strerror(errno));
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
@@ -596,7 +596,7 @@ void CUnixSocketConnection::ConnectWorker()
if (m_ListenFd < 0)
{
SDV_LOG_ERROR("[UDS][Server] socket() failed: ", std::strerror(errno));
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
@@ -608,7 +608,7 @@ void CUnixSocketConnection::ConnectWorker()
{
SDV_LOG_ERROR("[UDS][Server] bind('", m_UdsPath, "') failed: ", std::strerror(errno));
::close(m_ListenFd); m_ListenFd = -1;
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
@@ -618,7 +618,7 @@ void CUnixSocketConnection::ConnectWorker()
{
SDV_LOG_ERROR("[UDS][Server] listen() failed: ", std::strerror(errno));
::close(m_ListenFd); m_ListenFd = -1;
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
@@ -670,12 +670,12 @@ void CUnixSocketConnection::ConnectWorker()
}
if (clientFd < 0)
{
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
m_Fd = clientFd;
SetStatus(sdv::ipc::EConnectStatus::connected);
SetConnectState(sdv::ipc::EConnectState::connected);
StartReceiveThread_Unsafe();
return;
}
@@ -686,7 +686,7 @@ void CUnixSocketConnection::ConnectWorker()
if (m_Fd < 0)
{
SDV_LOG_ERROR("[UDS][Client] socket() failed: ", std::strerror(errno));
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
@@ -702,7 +702,7 @@ void CUnixSocketConnection::ConnectWorker()
{
if (::connect(m_Fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) == 0)
{
SetStatus(sdv::ipc::EConnectStatus::connected);
SetConnectState(sdv::ipc::EConnectState::connected);
#if ENABLE_REPORTING >= 1
TRACE("[UDS][Client] Connected");
#endif
@@ -719,19 +719,19 @@ void CUnixSocketConnection::ConnectWorker()
}
::close(m_Fd); m_Fd = -1;
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
return;
}
}
catch (const std::exception& ex)
{
SDV_LOG_ERROR("[UDS][ConnectWorker] exception: ", ex.what());
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
}
catch (...)
{
SDV_LOG_ERROR("[UDS][ConnectWorker] unknown exception");
SetStatus(sdv::ipc::EConnectStatus::connection_error);
SetConnectState(sdv::ipc::EConnectState::connection_error);
}
}
@@ -741,7 +741,7 @@ void CUnixSocketConnection::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);
SDV_LOG_WARNING("[UDS][RX] sync_answer with invalid version");
return;
}
@@ -772,13 +772,13 @@ void CUnixSocketConnection::ReceiveMessages()
while (!m_StopReceiveThread.load())
{
if (m_eStatus == sdv::ipc::EConnectStatus::terminating) break;
if (m_eConnectState == sdv::ipc::EConnectState::terminating) break;
// Snapshot FD
const int fd = m_Fd;
if (fd < 0)
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
SDV_LOG_WARNING("[UDS][RX] FD invalidated -> disconnected");
break;
}
@@ -789,7 +789,7 @@ void CUnixSocketConnection::ReceiveMessages()
if (pr == 0)
{
if (!m_AcceptConnectionRequired && (m_eStatus == sdv::ipc::EConnectStatus::initialized))
if (!m_AcceptConnectionRequired && (m_eConnectState == sdv::ipc::EConnectState::initialized))
{
auto now = std::chrono::high_resolution_clock::now();
if (std::chrono::duration<double>(now - tpStart).count() > 0.5)
@@ -805,7 +805,7 @@ void CUnixSocketConnection::ReceiveMessages()
if (pr < 0 || (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
SDV_LOG_WARNING("[UDS][RX] poll() hangup/error -> disconnected");
break;
}
@@ -815,7 +815,7 @@ void CUnixSocketConnection::ReceiveMessages()
uint32_t packetSize = 0;
if (!ReadTransportHeader(packetSize))
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
SDV_LOG_WARNING("[UDS][RX] Invalid/missing transport header -> disconnected");
break;
}
@@ -824,7 +824,7 @@ void CUnixSocketConnection::ReceiveMessages()
std::vector<uint8_t> payload(packetSize);
if (!ReadNumberOfBytes(reinterpret_cast<char*>(payload.data()), packetSize))
{
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
SDV_LOG_WARNING("[UDS][RX] Incomplete payload read -> disconnected");
break;
}
@@ -832,12 +832,12 @@ void CUnixSocketConnection::ReceiveMessages()
CMessage msg(std::move(payload));
if (!msg.IsValid())
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][RX] Invalid SDV message (envelope)");
continue;
}
if (m_eStatus == sdv::ipc::EConnectStatus::terminating) break;
if (m_eConnectState == sdv::ipc::EConnectState::terminating) break;
#if ENABLE_REPORTING >= 1
switch (msg.GetMsgHdr().eType)
@@ -874,12 +874,12 @@ void CUnixSocketConnection::ReceiveMessages()
catch (const std::exception& ex)
{
SDV_LOG_ERROR("[UDS][RX] exception: ", ex.what());
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
}
catch (...)
{
SDV_LOG_ERROR("[UDS][RX] unknown exception");
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
}
}
@@ -888,7 +888,7 @@ void CUnixSocketConnection::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);
SDV_LOG_WARNING("[UDS][RX] sync_request with invalid version");
return;
}
@@ -907,7 +907,7 @@ void CUnixSocketConnection::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);
SDV_LOG_WARNING("[UDS][RX] connect_request with invalid version");
return;
}
@@ -927,19 +927,19 @@ void CUnixSocketConnection::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);
SDV_LOG_WARNING("[UDS][RX] connect_answer with invalid version");
return;
}
// Fully established
SetStatus(sdv::ipc::EConnectStatus::connected);
SetConnectState(sdv::ipc::EConnectState::connected);
}
void CUnixSocketConnection::ReceiveConnectTerm(const CMessage& /*message*/)
{
// Peer requested termination
SetStatus(sdv::ipc::EConnectStatus::disconnected);
SetConnectState(sdv::ipc::EConnectState::disconnected);
m_StopReceiveThread.store(true);
}
@@ -999,7 +999,7 @@ void CUnixSocketConnection::ReceiveDataMessage(const CMessage& rMessage, SDataCo
uint32_t uiOffset = ReadDataTable(rMessage, rsDataCtxt);
if (!uiOffset)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][RX] Invalid data table");
return;
}
@@ -1012,7 +1012,7 @@ void CUnixSocketConnection::ReceiveDataMessage(const CMessage& rMessage, SDataCo
if (!ReadDataChunk(rMessage, uiOffset, rsDataCtxt))
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][RX] Failed to read data chunk");
return;
}
@@ -1034,7 +1034,7 @@ void CUnixSocketConnection::ReceiveDataFragmentMessage(const CMessage& rMessage,
uiOffset = ReadDataTable(rMessage, rsDataCtxt);
if (!uiOffset)
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][RX] Invalid fragmented data table");
return;
}
@@ -1048,7 +1048,7 @@ void CUnixSocketConnection::ReceiveDataFragmentMessage(const CMessage& rMessage,
if (!ReadDataChunk(rMessage, uiOffset, rsDataCtxt))
{
SetStatus(sdv::ipc::EConnectStatus::communication_error);
SetConnectState(sdv::ipc::EConnectState::communication_error);
SDV_LOG_WARNING("[UDS][RX] Failed to read fragmented chunk");
return;
}

View File

@@ -82,24 +82,24 @@ public:
/** @brief Optionally cancel WaitForConnection (no-op in current implementation). */
void CancelWait() override;
/** @brief Disconnect and teardown threads/FDs; sets status to 'disconnected'. */
/** @brief Disconnect and teardown threads/FDs; sets state to 'disconnected'. */
void Disconnect() override;
// ---------- IConnect: event callbacks ----------
/** @brief Register a status event callback (no-op storage in UDS). */
uint64_t RegisterStatusEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback) override;
/** @brief Register a state event callback (no-op storage in UDS). */
uint64_t RegisterStateEventCallback(/*in*/ sdv::IInterfaceAccess* pEventCallback) override;
/** @brief Unregister a previously registered callback (no-op storage in UDS). */
void UnregisterStatusEventCallback(/*in*/ uint64_t uiCookie) override;
void UnregisterStateEventCallback(/*in*/ uint64_t uiCookie) override;
/** @brief Get current connection status. */
sdv::ipc::EConnectStatus GetStatus() const override;
/** @brief Get current connection state. */
sdv::ipc::EConnectState GetConnectState() const override;
/** @brief Destroy object (IObjectDestroy). */
void DestroyObject() override;
/** @brief Set status and notify listeners (callback-safe). */
void SetStatus(sdv::ipc::EConnectStatus eStatus);
/** @brief Set state and notify listeners (callback-safe). */
void SetConnectState(sdv::ipc::EConnectState eConnectState);
/** @brief @return true if this side is server (needs accept()), false otherwise. */
bool IsServer() const;
@@ -297,7 +297,7 @@ public:
* @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.
*/
@@ -352,7 +352,7 @@ public:
// ---------- Internal threading ----------
/** @brief Connect worker (server accept loop or client connect retry). */
void ConnectWorker();
/** @brief Start RX thread (precondition: status=connected, FD valid). */
/** @brief Start RX thread (precondition: state=connected, FD valid). */
void StartReceiveThread_Unsafe();
/**
* @brief Stop workers and close sockets, then optionally unlink path.
@@ -373,9 +373,9 @@ private:
std::thread m_ReceiveThread;
std::thread m_ConnectThread;
//Status & synchronization
//State & synchronization
std::condition_variable m_StateCv;
std::atomic<sdv::ipc::EConnectStatus> m_eStatus { sdv::ipc::EConnectStatus::uninitialized };
std::atomic<sdv::ipc::EConnectState> m_eConnectState { sdv::ipc::EConnectState::uninitialized };
sdv::ipc::IDataReceiveCallback* m_pReceiver { nullptr };
sdv::ipc::IConnectEventCallback* m_pEvent { nullptr };
std::mutex m_MtxConnect;