13
13
#include " libcyphal/executor.hpp"
14
14
#include " libcyphal/transport/errors.hpp"
15
15
#include " libcyphal/transport/svc_sessions.hpp"
16
- #include " libcyphal/transport/transfer_id_generators .hpp"
16
+ #include " libcyphal/transport/transfer_id_map .hpp"
17
17
#include " libcyphal/transport/types.hpp"
18
18
#include " libcyphal/types.hpp"
19
19
@@ -34,7 +34,9 @@ namespace presentation
34
34
namespace detail
35
35
{
36
36
37
- class SharedClient : public common ::cavl::Node<SharedClient>, public SharedObject
37
+ class SharedClient : public common ::cavl::Node<SharedClient>,
38
+ public SharedObject,
39
+ protected transport::detail::ITransferIdStorage
38
40
{
39
41
public:
40
42
using Node::remove;
@@ -134,17 +136,24 @@ class SharedClient : public common::cavl::Node<SharedClient>, public SharedObjec
134
136
, svc_request_tx_session_{std::move (svc_request_tx_session)}
135
137
, svc_response_rx_session_{std::move (svc_response_rx_session)}
136
138
, response_rx_params_{svc_response_rx_session_->getParams ()}
139
+ , next_transfer_id_{0 }
137
140
, nearest_deadline_{DistantFuture ()}
138
141
{
139
142
CETL_DEBUG_ASSERT (svc_request_tx_session_ != nullptr , " " );
140
143
CETL_DEBUG_ASSERT (svc_response_rx_session_ != nullptr , " " );
141
144
145
+ if (const auto * const transfer_id_map = delegate.getTransferIdMap ())
146
+ {
147
+ const SessionSpec session_spec{response_rx_params_.service_id , response_rx_params_.server_node_id };
148
+ next_transfer_id_ = transfer_id_map->getIdFor (session_spec);
149
+ }
150
+
142
151
// Override the default (2s) timeout value of the response session.
143
152
// This is done to allow multiple overlapping responses to be handled properly.
144
153
// Otherwise, the responses would be rejected (as "duplicates") if their transfer IDs are in order.
145
154
// Real duplicates (f.e. caused by redundant transports) won't cause any issues
146
155
// b/c shared RPC client expects/accepts only one response per transfer ID,
147
- // and corresponding promise callback node will be removed after the first response.
156
+ // and the corresponding promise callback node will be removed after the first response.
148
157
svc_response_rx_session_->setTransferIdTimeout ({});
149
158
150
159
svc_response_rx_session_->setOnReceiveCallback ([this ](const auto & arg) {
@@ -199,7 +208,7 @@ class SharedClient : public common::cavl::Node<SharedClient>, public SharedObjec
199
208
{
200
209
if (timeout_node.isTimeoutLinked ())
201
210
{
202
- // Remove previous timeout node (if any),
211
+ // Remove the previous timeout node (if any),
203
212
// and then reinsert the node with updated/given new deadline time.
204
213
//
205
214
timeout_nodes_by_deadline_.remove (&timeout_node);
@@ -240,9 +249,27 @@ class SharedClient : public common::cavl::Node<SharedClient>, public SharedObjec
240
249
241
250
void destroy () noexcept override
242
251
{
252
+ if (auto * const transfer_id_map = delegate_.getTransferIdMap ())
253
+ {
254
+ const SessionSpec session_spec{response_rx_params_.service_id , response_rx_params_.server_node_id };
255
+ transfer_id_map->setIdFor (session_spec, next_transfer_id_);
256
+ }
257
+
243
258
delegate_.forgetSharedClient (*this );
244
259
}
245
260
261
+ // MARK: ITransferIdStorage
262
+
263
+ transport::TransferId load () const noexcept override
264
+ {
265
+ return next_transfer_id_;
266
+ }
267
+
268
+ void save (const transport::TransferId transfer_id) noexcept override
269
+ {
270
+ next_transfer_id_ = transfer_id;
271
+ }
272
+
246
273
protected:
247
274
virtual void insertNewCallbackNode (CallbackNode& callback_node)
248
275
{
@@ -273,7 +300,8 @@ class SharedClient : public common::cavl::Node<SharedClient>, public SharedObjec
273
300
}
274
301
275
302
private:
276
- using Schedule = IExecutor::Callback::Schedule;
303
+ using Schedule = IExecutor::Callback::Schedule;
304
+ using SessionSpec = transport::ITransferIdMap::SessionSpec;
277
305
278
306
static constexpr TimePoint DistantFuture ()
279
307
{
@@ -388,6 +416,7 @@ class SharedClient : public common::cavl::Node<SharedClient>, public SharedObjec
388
416
const UniquePtr<transport::IRequestTxSession> svc_request_tx_session_;
389
417
const UniquePtr<transport::IResponseRxSession> svc_response_rx_session_;
390
418
const transport::ResponseRxParams response_rx_params_;
419
+ transport::TransferId next_transfer_id_;
391
420
common::cavl::Tree<CallbackNode> cb_nodes_by_transfer_id_;
392
421
TimePoint nearest_deadline_;
393
422
common::cavl::Tree<TimeoutNode> timeout_nodes_by_deadline_;
@@ -399,8 +428,8 @@ class SharedClient : public common::cavl::Node<SharedClient>, public SharedObjec
399
428
400
429
// / @brief Defines a shared client implementation that uses a generic transfer ID generator.
401
430
// /
402
- template <typename TransferIdGeneratorMixin >
403
- class ClientImpl final : public SharedClient, private TransferIdGeneratorMixin
431
+ template <typename TransferIdGenerator >
432
+ class ClientImpl final : public SharedClient
404
433
{
405
434
public:
406
435
ClientImpl (IPresentationDelegate& delegate,
@@ -409,7 +438,7 @@ class ClientImpl final : public SharedClient, private TransferIdGeneratorMixin
409
438
UniquePtr<transport::IResponseRxSession> svc_response_rx_session,
410
439
const transport::TransferId transfer_id_modulo)
411
440
: SharedClient{delegate, executor, std::move (svc_request_tx_session), std::move (svc_response_rx_session)}
412
- , TransferIdGeneratorMixin {transfer_id_modulo}
441
+ , transfer_id_generator_ {transfer_id_modulo, * this }
413
442
{
414
443
}
415
444
@@ -424,40 +453,41 @@ class ClientImpl final : public SharedClient, private TransferIdGeneratorMixin
424
453
private:
425
454
using Base = SharedClient;
426
455
427
- // MARK: SharedClient
428
-
429
- CETL_NODISCARD cetl::optional<transport::TransferId> nextTransferId () noexcept override
430
- {
431
- return TransferIdGeneratorMixin::nextTransferId ();
432
- }
433
-
434
456
void insertNewCallbackNode (CallbackNode& callback_node) override
435
457
{
436
458
SharedClient::insertNewCallbackNode (callback_node);
437
- TransferIdGeneratorMixin:: retainTransferId (callback_node.getTransferId ());
459
+ transfer_id_generator_. retainTransferId (callback_node.getTransferId ());
438
460
}
439
461
440
462
void removeCallbackNode (CallbackNode& callback_node) override
441
463
{
442
- TransferIdGeneratorMixin:: releaseTransferId (callback_node.getTransferId ());
464
+ transfer_id_generator_. releaseTransferId (callback_node.getTransferId ());
443
465
SharedClient::removeCallbackNode (callback_node);
444
466
}
445
467
468
+ // MARK: SharedClient
469
+
470
+ CETL_NODISCARD cetl::optional<transport::TransferId> nextTransferId () noexcept override
471
+ {
472
+ return transfer_id_generator_.nextTransferId ();
473
+ }
474
+
475
+ TransferIdGenerator transfer_id_generator_;
476
+
446
477
}; // ClientImpl<TransferIdGeneratorMixin>
447
478
448
479
// / @brief Defines a shared client specialization that uses a trivial transfer ID generator.
449
480
// /
450
481
template <>
451
- class ClientImpl <transport::detail::TrivialTransferIdGenerator> final
452
- : public SharedClient,
453
- private transport::detail::TrivialTransferIdGenerator
482
+ class ClientImpl <transport::detail::TrivialTransferIdGenerator> final : public SharedClient
454
483
{
455
484
public:
456
485
ClientImpl (IPresentationDelegate& delegate,
457
486
IExecutor& executor,
458
487
UniquePtr<transport::IRequestTxSession> svc_request_tx_session,
459
488
UniquePtr<transport::IResponseRxSession> svc_response_rx_session)
460
489
: Base{delegate, executor, std::move (svc_request_tx_session), std::move (svc_response_rx_session)}
490
+ , transfer_id_generator_{*this }
461
491
{
462
492
}
463
493
@@ -476,9 +506,11 @@ class ClientImpl<transport::detail::TrivialTransferIdGenerator> final
476
506
477
507
CETL_NODISCARD cetl::optional<transport::TransferId> nextTransferId () noexcept override
478
508
{
479
- return TrivialTransferIdGenerator:: nextTransferId ();
509
+ return transfer_id_generator_. nextTransferId ();
480
510
}
481
511
512
+ transport::detail::TrivialTransferIdGenerator transfer_id_generator_;
513
+
482
514
}; // ClientImpl<TrivialTransferIdGenerator>
483
515
484
516
} // namespace detail
0 commit comments