Skip to content

Commit 5a5212b

Browse files
committed
iox-#27 Add client and server port to Runtime
1 parent b78927d commit 5a5212b

File tree

5 files changed

+192
-0
lines changed

5 files changed

+192
-0
lines changed

iceoryx_hoofs/include/iceoryx_hoofs/error_handling/error_handling.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ namespace iox
3838
error(POSH__RUNTIME_PUBLISHER_PORT_NOT_UNIQUE) \
3939
error(POSH__RUNTIME_PUBLISHER_PORT_CREATION_UNKNOWN_ERROR) \
4040
error(POSH__RUNTIME_SUBSCRIBER_PORT_CREATION_UNKNOWN_ERROR) \
41+
error(POSH__RUNTIME_CLIENT_PORT_CREATION_UNKNOWN_ERROR) \
42+
error(POSH__RUNTIME_SERVER_PORT_CREATION_UNKNOWN_ERROR) \
4143
error(POSH__RUNTIME_ROUDI_PUBLISHER_LIST_FULL) \
4244
error(POSH__RUNTIME_ROUDI_SUBSCRIBER_LIST_FULL) \
45+
error(POSH__RUNTIME_ROUDI_OUT_OF_CLIENTS) \
46+
error(POSH__RUNTIME_ROUDI_OUT_OF_SERVERS) \
4347
error(POSH__RUNTIME_ROUDI_CONDITION_VARIABLE_LIST_FULL) \
4448
error(POSH__RUNTIME_ROUDI_EVENT_VARIABLE_LIST_FULL) \
4549
error(POSH__RUNTIME_ROUDI_REQUEST_PUBLISHER_WRONG_IPC_MESSAGE_RESPONSE) \
4650
error(POSH__RUNTIME_ROUDI_REQUEST_SUBSCRIBER_WRONG_IPC_MESSAGE_RESPONSE) \
51+
error(POSH__RUNTIME_ROUDI_REQUEST_CLIENT_WRONG_IPC_MESSAGE_RESPONSE) \
52+
error(POSH__RUNTIME_ROUDI_REQUEST_SERVER_WRONG_IPC_MESSAGE_RESPONSE) \
4753
error(POSH__RUNTIME_ROUDI_REQUEST_CONDITION_VARIABLE_WRONG_IPC_MESSAGE_RESPONSE) \
4854
error(POSH__RUNTIME_ROUDI_REQUEST_EVENT_VARIABLE_WRONG_MESSAGE_QUEUE_RESPONSE) \
4955
error(POSH__RUNTIME_ROUDI_GET_MW_INTERFACE_WRONG_IPC_MESSAGE_RESPONSE) \

iceoryx_posh/include/iceoryx_posh/internal/runtime/posh_runtime_impl.hpp

+18
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ class PoshRuntimeImpl : public PoshRuntime
5555
const popo::SubscriberOptions& subscriberOptions = popo::SubscriberOptions(),
5656
const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept override;
5757

58+
/// @copydoc PoshRuntime::getMiddlewareClient
59+
popo::ClientPortUser::MemberType_t*
60+
getMiddlewareClient(const capro::ServiceDescription& service,
61+
const popo::ClientOptions& clientOptions = {},
62+
const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept override;
63+
64+
/// @copydoc PoshRuntime::getMiddlewareServer
65+
popo::ServerPortUser::MemberType_t*
66+
getMiddlewareServer(const capro::ServiceDescription& service,
67+
const popo::ServerOptions& ServerOptions = {},
68+
const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept override;
69+
5870
/// @copydoc PoshRuntime::getMiddlewareInterface
5971
popo::InterfacePortData* getMiddlewareInterface(const capro::Interfaces interface,
6072
const NodeName_t& nodeName = {""}) noexcept override;
@@ -83,6 +95,12 @@ class PoshRuntimeImpl : public PoshRuntime
8395
cxx::expected<SubscriberPortUserType::MemberType_t*, IpcMessageErrorType>
8496
requestSubscriberFromRoudi(const IpcMessage& sendBuffer) noexcept;
8597

98+
cxx::expected<popo::ClientPortUser::MemberType_t*, IpcMessageErrorType>
99+
requestClientFromRoudi(const IpcMessage& sendBuffer) noexcept;
100+
101+
cxx::expected<popo::ServerPortUser::MemberType_t*, IpcMessageErrorType>
102+
requestServerFromRoudi(const IpcMessage& sendBuffer) noexcept;
103+
86104
cxx::expected<popo::ConditionVariableData*, IpcMessageErrorType>
87105
requestConditionVariableFromRoudi(const IpcMessage& sendBuffer) noexcept;
88106

iceoryx_posh/include/iceoryx_posh/runtime/posh_runtime.hpp

+14
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@
2121
#include "iceoryx_posh/capro/service_description.hpp"
2222
#include "iceoryx_posh/iceoryx_posh_types.hpp"
2323
#include "iceoryx_posh/internal/popo/building_blocks/condition_variable_data.hpp"
24+
#include "iceoryx_posh/internal/popo/ports/client_port_user.hpp"
2425
#include "iceoryx_posh/internal/popo/ports/interface_port.hpp"
2526
#include "iceoryx_posh/internal/popo/ports/publisher_port_user.hpp"
27+
#include "iceoryx_posh/internal/popo/ports/server_port_user.hpp"
2628
#include "iceoryx_posh/internal/popo/ports/subscriber_port_user.hpp"
2729
#include "iceoryx_posh/internal/runtime/ipc_runtime_interface.hpp"
2830
#include "iceoryx_posh/internal/runtime/node_property.hpp"
31+
#include "iceoryx_posh/popo/client_options.hpp"
32+
#include "iceoryx_posh/popo/server_options.hpp"
2933
#include "iceoryx_posh/popo/subscriber_options.hpp"
3034
#include "iceoryx_posh/runtime/port_config_info.hpp"
3135

@@ -102,6 +106,16 @@ class PoshRuntime
102106
const popo::SubscriberOptions& subscriberOptions = {},
103107
const PortConfigInfo& portConfigInfo = {}) noexcept = 0;
104108

109+
virtual popo::ClientPortUser::MemberType_t*
110+
getMiddlewareClient(const capro::ServiceDescription& service,
111+
const popo::ClientOptions& clientOptions = {},
112+
const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept = 0;
113+
114+
virtual popo::ServerPortUser::MemberType_t*
115+
getMiddlewareServer(const capro::ServiceDescription& service,
116+
const popo::ServerOptions& serverOptions = {},
117+
const PortConfigInfo& portConfigInfo = PortConfigInfo()) noexcept = 0;
118+
105119
/// @brief request the RouDi daemon to create an interface port
106120
/// @param[in] interface interface to create
107121
/// @param[in] nodeName name of the node where the interface should belong to

iceoryx_posh/source/runtime/posh_runtime_impl.cpp

+142
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,148 @@ PoshRuntimeImpl::requestSubscriberFromRoudi(const IpcMessage& sendBuffer) noexce
282282
return cxx::error<IpcMessageErrorType>(IpcMessageErrorType::REQUEST_SUBSCRIBER_WRONG_IPC_MESSAGE_RESPONSE);
283283
}
284284

285+
popo::ClientPortUser::MemberType_t* PoshRuntimeImpl::getMiddlewareClient(const capro::ServiceDescription& service,
286+
const popo::ClientOptions& clientOptions,
287+
const PortConfigInfo& portConfigInfo) noexcept
288+
{
289+
IpcMessage sendBuffer;
290+
sendBuffer << IpcMessageTypeToString(IpcMessageType::CREATE_CLIENT) << m_appName
291+
<< static_cast<cxx::Serialization>(service).toString() << clientOptions.serialize().toString()
292+
<< static_cast<cxx::Serialization>(portConfigInfo).toString();
293+
294+
auto maybeClient = requestClientFromRoudi(sendBuffer);
295+
if (maybeClient.has_error())
296+
{
297+
switch (maybeClient.get_error())
298+
{
299+
case IpcMessageErrorType::CLIENT_LIST_FULL:
300+
LogWarn() << "Could not create client as we are out of memory for clients.";
301+
errorHandler(Error::kPOSH__RUNTIME_ROUDI_OUT_OF_CLIENTS, nullptr, iox::ErrorLevel::SEVERE);
302+
break;
303+
case IpcMessageErrorType::REQUEST_CLIENT_WRONG_IPC_MESSAGE_RESPONSE:
304+
LogWarn() << "Could not create client; received wrong IPC channel response.";
305+
errorHandler(Error::kPOSH__RUNTIME_ROUDI_REQUEST_CLIENT_WRONG_IPC_MESSAGE_RESPONSE,
306+
nullptr,
307+
iox::ErrorLevel::SEVERE);
308+
break;
309+
default:
310+
LogWarn() << "Unknown error occurred while creating client";
311+
errorHandler(Error::kPOSH__RUNTIME_CLIENT_PORT_CREATION_UNKNOWN_ERROR, nullptr, iox::ErrorLevel::SEVERE);
312+
break;
313+
}
314+
return nullptr;
315+
}
316+
return maybeClient.value();
317+
}
318+
319+
cxx::expected<popo::ClientPortUser::MemberType_t*, IpcMessageErrorType>
320+
PoshRuntimeImpl::requestClientFromRoudi(const IpcMessage& sendBuffer) noexcept
321+
{
322+
IpcMessage receiveBuffer;
323+
if (sendRequestToRouDi(sendBuffer, receiveBuffer) && (3U == receiveBuffer.getNumberOfElements()))
324+
{
325+
std::string IpcMessage = receiveBuffer.getElementAtIndex(0U);
326+
327+
if (stringToIpcMessageType(IpcMessage.c_str()) == IpcMessageType::CREATE_CLIENT_ACK)
328+
{
329+
rp::BaseRelativePointer::id_t segmentId{0U};
330+
cxx::convert::fromString(receiveBuffer.getElementAtIndex(2U).c_str(), segmentId);
331+
rp::BaseRelativePointer::offset_t offset{0U};
332+
cxx::convert::fromString(receiveBuffer.getElementAtIndex(1U).c_str(), offset);
333+
auto ptr = rp::BaseRelativePointer::getPtr(segmentId, offset);
334+
return cxx::success<popo::ClientPortUser::MemberType_t*>(
335+
reinterpret_cast<popo::ClientPortUser::MemberType_t*>(ptr));
336+
}
337+
}
338+
else
339+
{
340+
if (receiveBuffer.getNumberOfElements() == 2U)
341+
{
342+
std::string IpcMessage1 = receiveBuffer.getElementAtIndex(0U);
343+
std::string IpcMessage2 = receiveBuffer.getElementAtIndex(1U);
344+
if (stringToIpcMessageType(IpcMessage1.c_str()) == IpcMessageType::ERROR)
345+
{
346+
LogError() << "Request client received no valid client port from RouDi.";
347+
return cxx::error<IpcMessageErrorType>(stringToIpcMessageErrorType(IpcMessage2.c_str()));
348+
}
349+
}
350+
}
351+
352+
LogError() << "Request client got wrong response from IPC channel :'" << receiveBuffer.getMessage() << "'";
353+
return cxx::error<IpcMessageErrorType>(IpcMessageErrorType::REQUEST_CLIENT_WRONG_IPC_MESSAGE_RESPONSE);
354+
}
355+
356+
popo::ServerPortUser::MemberType_t* PoshRuntimeImpl::getMiddlewareServer(const capro::ServiceDescription& service,
357+
const popo::ServerOptions& ServerOptions,
358+
const PortConfigInfo& portConfigInfo) noexcept
359+
{
360+
IpcMessage sendBuffer;
361+
sendBuffer << IpcMessageTypeToString(IpcMessageType::CREATE_SERVER) << m_appName
362+
<< static_cast<cxx::Serialization>(service).toString() << ServerOptions.serialize().toString()
363+
<< static_cast<cxx::Serialization>(portConfigInfo).toString();
364+
365+
auto maybeServer = requestServerFromRoudi(sendBuffer);
366+
if (maybeServer.has_error())
367+
{
368+
switch (maybeServer.get_error())
369+
{
370+
case IpcMessageErrorType::SERVER_LIST_FULL:
371+
LogWarn() << "Could not create server as we are out of memory for servers.";
372+
errorHandler(Error::kPOSH__RUNTIME_ROUDI_OUT_OF_SERVERS, nullptr, iox::ErrorLevel::SEVERE);
373+
break;
374+
case IpcMessageErrorType::REQUEST_SERVER_WRONG_IPC_MESSAGE_RESPONSE:
375+
LogWarn() << "Could not create server; received wrong IPC channel response.";
376+
errorHandler(Error::kPOSH__RUNTIME_ROUDI_REQUEST_SERVER_WRONG_IPC_MESSAGE_RESPONSE,
377+
nullptr,
378+
iox::ErrorLevel::SEVERE);
379+
break;
380+
default:
381+
LogWarn() << "Unknown error occurred while creating server";
382+
errorHandler(Error::kPOSH__RUNTIME_SERVER_PORT_CREATION_UNKNOWN_ERROR, nullptr, iox::ErrorLevel::SEVERE);
383+
break;
384+
}
385+
return nullptr;
386+
}
387+
return maybeServer.value();
388+
}
389+
390+
cxx::expected<popo::ServerPortUser::MemberType_t*, IpcMessageErrorType>
391+
PoshRuntimeImpl::requestServerFromRoudi(const IpcMessage& sendBuffer) noexcept
392+
{
393+
IpcMessage receiveBuffer;
394+
if (sendRequestToRouDi(sendBuffer, receiveBuffer) && (3U == receiveBuffer.getNumberOfElements()))
395+
{
396+
std::string IpcMessage = receiveBuffer.getElementAtIndex(0U);
397+
398+
if (stringToIpcMessageType(IpcMessage.c_str()) == IpcMessageType::CREATE_SERVER_ACK)
399+
{
400+
rp::BaseRelativePointer::id_t segmentId{0U};
401+
cxx::convert::fromString(receiveBuffer.getElementAtIndex(2U).c_str(), segmentId);
402+
rp::BaseRelativePointer::offset_t offset{0U};
403+
cxx::convert::fromString(receiveBuffer.getElementAtIndex(1U).c_str(), offset);
404+
auto ptr = rp::BaseRelativePointer::getPtr(segmentId, offset);
405+
return cxx::success<popo::ServerPortUser::MemberType_t*>(
406+
reinterpret_cast<popo::ServerPortUser::MemberType_t*>(ptr));
407+
}
408+
}
409+
else
410+
{
411+
if (receiveBuffer.getNumberOfElements() == 2U)
412+
{
413+
std::string IpcMessage1 = receiveBuffer.getElementAtIndex(0U);
414+
std::string IpcMessage2 = receiveBuffer.getElementAtIndex(1U);
415+
if (stringToIpcMessageType(IpcMessage1.c_str()) == IpcMessageType::ERROR)
416+
{
417+
LogError() << "Request server received no valid server port from RouDi.";
418+
return cxx::error<IpcMessageErrorType>(stringToIpcMessageErrorType(IpcMessage2.c_str()));
419+
}
420+
}
421+
}
422+
423+
LogError() << "Request server got wrong response from IPC channel :'" << receiveBuffer.getMessage() << "'";
424+
return cxx::error<IpcMessageErrorType>(IpcMessageErrorType::REQUEST_SERVER_WRONG_IPC_MESSAGE_RESPONSE);
425+
}
426+
285427
popo::InterfacePortData* PoshRuntimeImpl::getMiddlewareInterface(const capro::Interfaces interface,
286428
const NodeName_t& nodeName) noexcept
287429
{

iceoryx_posh/test/mocks/posh_runtime_mock.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ class PoshRuntimeMock : public iox::runtime::PoshRuntime
5757
const iox::popo::SubscriberOptions&,
5858
const iox::runtime::PortConfigInfo&),
5959
(noexcept, override));
60+
MOCK_METHOD(iox::popo::ClientPortUser::MemberType_t*,
61+
getMiddlewareClient,
62+
(const iox::capro::ServiceDescription&,
63+
const iox::popo::ClientOptions&,
64+
const iox::runtime::PortConfigInfo&),
65+
(noexcept, override));
66+
MOCK_METHOD(iox::popo::ServerPortUser::MemberType_t*,
67+
getMiddlewareServer,
68+
(const iox::capro::ServiceDescription&,
69+
const iox::popo::ServerOptions&,
70+
const iox::runtime::PortConfigInfo&),
71+
(noexcept, override));
6072
MOCK_METHOD(iox::popo::InterfacePortData*,
6173
getMiddlewareInterface,
6274
(const iox::capro::Interfaces, const iox::NodeName_t&),

0 commit comments

Comments
 (0)