mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-08-30 12:15:12 +00:00
connection between 2 systems and bug fixes (#14)
This commit is contained in:
@@ -81,19 +81,19 @@ namespace
|
||||
// Directory selection (/run/user/<uid>/sdv or /tmp/sdv)
|
||||
std::string CUnixDomainSocketsChannelMgnt::MakeUserRuntimeDir()
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "/run/user/" << ::getuid();
|
||||
const std::string path = "/run/ipc/sdv";
|
||||
|
||||
struct stat st{};
|
||||
if (::stat(oss.str().c_str(), &st) == 0)
|
||||
if (::stat(path.c_str(), &st) == 0)
|
||||
{
|
||||
std::string path = oss.str() + "/sdv";
|
||||
::mkdir(path.c_str(), 0770);
|
||||
return path;
|
||||
}
|
||||
|
||||
::mkdir("/tmp/sdv", 0770);
|
||||
return "/tmp/sdv";
|
||||
// fallback if /run/ipc/sdv is not available
|
||||
const std::string fallback = "/tmp/sdv";
|
||||
::mkdir(fallback.c_str(), 0770);
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
bool CUnixDomainSocketsChannelMgnt::OnInitialize()
|
||||
@@ -102,7 +102,11 @@ bool CUnixDomainSocketsChannelMgnt::OnInitialize()
|
||||
}
|
||||
|
||||
void CUnixDomainSocketsChannelMgnt::OnShutdown()
|
||||
{}
|
||||
|
||||
void CUnixDomainSocketsChannelMgnt::OnDestroy()
|
||||
{
|
||||
m_watchdog.Clear();
|
||||
}
|
||||
|
||||
// Endpoint creation (server)
|
||||
@@ -129,33 +133,133 @@ sdv::ipc::SChannelEndpoint CUnixDomainSocketsChannelMgnt::CreateEndpoint(const s
|
||||
|
||||
path = ClampSunPath(path);
|
||||
|
||||
// Use a shared_ptr and store it to keep the server connection alive
|
||||
auto server = std::make_shared<CUnixSocketConnection>(-1, true, path);
|
||||
m_ServerConnections.push_back(server);
|
||||
// Keep lifetime consistent with shared_mem: watchdog owns active connections.
|
||||
std::shared_ptr<CUnixSocketConnection> server = std::make_shared<CUnixSocketConnection>(-1, true, path);
|
||||
// Ignore cppcheck warning; if construction failed, an exception is expected first.
|
||||
// cppcheck-suppress knownConditionTrueFalse
|
||||
if (!server)
|
||||
return {};
|
||||
server->SetWatchDogRemoveCallback([this](const void* connection)
|
||||
{
|
||||
m_watchdog.RemoveConnection(connection);
|
||||
});
|
||||
m_watchdog.AddConnection(server);
|
||||
|
||||
sdv::ipc::SChannelEndpoint ep{};
|
||||
ep.pConnection = static_cast<IInterfaceAccess*>(server.get());
|
||||
ep.ssConnectString = server->GetConnectionString();
|
||||
|
||||
// Publish a Provider-wrapped connect string for compatibility with
|
||||
// CCommunicationControl::CreateClientConnection() flows.
|
||||
const std::string udsConnectString = server->GetConnectionString();
|
||||
ep.ssConnectString = std::string("[Provider]\n") +
|
||||
"Name = \"unix_domain_sockets\"\n" +
|
||||
"ConnectString = \"" + udsConnectString + "\"\n";
|
||||
return ep;
|
||||
}
|
||||
|
||||
// Access existing endpoint (server or client)
|
||||
sdv::IInterfaceAccess* CUnixDomainSocketsChannelMgnt::Access(const sdv::u8string& ssConnectString)
|
||||
{
|
||||
const auto kv = ParseKV(static_cast<std::string>(ssConnectString));
|
||||
const bool isServer = (kv.count("role") && kv.at("role") == "server");
|
||||
const std::string path = kv.count("path") ? kv.at("path") : (MakeUserRuntimeDir() + "/UDS_auto.sock");
|
||||
const std::string input = static_cast<std::string>(ssConnectString);
|
||||
|
||||
if (isServer)
|
||||
bool isServer = false;
|
||||
bool parsed = false;
|
||||
std::string path;
|
||||
|
||||
// Parse structured TOML forms first, but only for non-raw inputs.
|
||||
// Raw connect strings (proto=uds;...) are intentionally not TOML and
|
||||
// would produce noisy parser diagnostics like "Missing value".
|
||||
if (input.rfind("proto=uds", 0) != 0)
|
||||
{
|
||||
auto server = std::make_shared<CUnixSocketConnection>(-1, true, path);
|
||||
m_ServerConnections.push_back(server);
|
||||
return static_cast<IInterfaceAccess*>(server.get());
|
||||
sdv::toml::CTOMLParser parser(input);
|
||||
if (!parser.IsValid())
|
||||
return nullptr;
|
||||
|
||||
const std::string providerName = parser.GetDirect("Provider.Name").GetValue();
|
||||
if (!providerName.empty())
|
||||
{
|
||||
if (providerName != "unix_domain_sockets" &&
|
||||
providerName != "UnixSocketsChannelControl" &&
|
||||
providerName != "UnixDomainSocketsChannelControl")
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::string nested = parser.GetDirect("Provider.ConnectString").GetValue();
|
||||
if (!nested.empty())
|
||||
{
|
||||
const auto kv = ParseKV(nested);
|
||||
if (kv.count("path"))
|
||||
path = kv.at("path");
|
||||
}
|
||||
|
||||
// Provider descriptions are consumed as client endpoints.
|
||||
parsed = true;
|
||||
isServer = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Shared-memory style callers pass [IpcChannel] config directly to Access().
|
||||
parsed = true;
|
||||
isServer = false;
|
||||
}
|
||||
|
||||
if (path.empty())
|
||||
{
|
||||
auto pathNode = parser.GetDirect("IpcChannel.Path");
|
||||
if (pathNode.GetType() == sdv::toml::ENodeType::node_string)
|
||||
{
|
||||
path = static_cast<std::string>(pathNode.GetValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto nameNode = parser.GetDirect("IpcChannel.Name");
|
||||
if (nameNode.GetType() == sdv::toml::ENodeType::node_string)
|
||||
{
|
||||
const std::string name = static_cast<std::string>(nameNode.GetValue());
|
||||
if (!name.empty())
|
||||
path = MakeUserRuntimeDir() + "/" + name + ".sock";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Client: allocated raw pointer (expected to be managed by SDV framework)
|
||||
auto* client = new CUnixSocketConnection(-1, false, path);
|
||||
return static_cast<IInterfaceAccess*>(client);
|
||||
// Raw KV fallback (legacy/tests): proto=uds;role=...;path=...;
|
||||
if (!parsed)
|
||||
{
|
||||
// Only treat as raw format when it actually starts with proto=uds.
|
||||
if (input.rfind("proto=uds", 0) != 0)
|
||||
return nullptr;
|
||||
|
||||
const auto kv = ParseKV(input);
|
||||
parsed = true;
|
||||
isServer = (kv.count("role") && kv.at("role") == "server");
|
||||
if (kv.count("path"))
|
||||
path = kv.at("path");
|
||||
}
|
||||
|
||||
if (!parsed)
|
||||
return nullptr;
|
||||
|
||||
if (path.empty())
|
||||
path = MakeUserRuntimeDir() + "/UDS_auto.sock";
|
||||
|
||||
path = ClampSunPath(path);
|
||||
|
||||
std::shared_ptr<CUnixSocketConnection> connection =
|
||||
std::make_shared<CUnixSocketConnection>(-1, isServer, path);
|
||||
// Ignore cppcheck warning; if construction failed, an exception is expected first.
|
||||
// cppcheck-suppress knownConditionTrueFalse
|
||||
if (!connection)
|
||||
return nullptr;
|
||||
|
||||
connection->SetWatchDogRemoveCallback([this](const void* instance)
|
||||
{
|
||||
m_watchdog.RemoveConnection(instance);
|
||||
});
|
||||
|
||||
m_watchdog.AddConnection(connection);
|
||||
return static_cast<IInterfaceAccess*>(connection.get());
|
||||
}
|
||||
|
||||
#endif // defined(__unix__)
|
||||
Reference in New Issue
Block a user