Compute Graph Framework SDK Reference  5.14
ChannelParameters.hpp
Go to the documentation of this file.
1
2//
3// Notice
4// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
5// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
6// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
7// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8//
9// NVIDIA CORPORATION & AFFILIATES assumes no responsibility for the consequences of use of such
10// information or for any infringement of patents or other rights of third parties that may
11// result from its use. No license is granted by implication or otherwise under any patent
12// or patent rights of NVIDIA CORPORATION & AFFILIATES. No third party distribution is allowed unless
13// expressly authorized by NVIDIA. Details are subject to change without notice.
14// This code supersedes and replaces all information previously supplied.
15// NVIDIA CORPORATION & AFFILIATES products are not authorized for use as critical
16// components in life support devices or systems without express written approval of
17// NVIDIA CORPORATION & AFFILIATES.
18//
19// SPDX-FileCopyrightText: Copyright (c) 2018-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
20// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
21//
22// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
23// property and proprietary rights in and to this material, related
24// documentation and any modifications thereto. Any use, reproduction,
25// disclosure or distribution of this material and related documentation
26// without an express license agreement from NVIDIA CORPORATION or
27// its affiliates is strictly prohibited.
28//
30
31#ifndef DW_FRAMEWORK_CHANNEL_PARAMETERS_HPP_
32#define DW_FRAMEWORK_CHANNEL_PARAMETERS_HPP_
33
34#include <dwshared/dwfoundation/dw/core/base/ExceptionWithStatus.hpp>
35#include <dwshared/dwfoundation/dw/core/container/BaseString.hpp>
36#include <dwshared/dwfoundation/dw/core/container/VectorFixed.hpp>
37#include <dwshared/dwfoundation/dw/core/language/cxx23.hpp>
38#include <dwshared/dwfoundation/dw/core/safety/Safety.hpp>
39#include <dwshared/dwsockets/SocketClientServer.hpp>
40#include <dw/core/system/NvMediaExt.h>
42#include <sstream>
43#include <limits>
44
45namespace dw
46{
47namespace framework
48{
49
51
54enum class ChannelType : uint8_t
55{
56 // coverity[autosar_cpp14_a5_1_1_violation]
57 SHMEM_LOCAL = 0,
58 SHMEM_REMOTE = 1,
59 EGLSTREAM = 2,
60 // coverity[autosar_cpp14_a5_1_1_violation]
61 SOCKET = 3,
62 DDS = 4,
63 // coverity[autosar_cpp14_a5_1_1_violation]
64 NVSCI = 5,
65 // coverity[autosar_cpp14_a5_1_1_violation]
66 FSI = 6,
67};
68
69// coverity[autosar_cpp14_a0_1_3_violation]
70static inline const char* ToParam(ChannelType channelType)
71{
72 switch (channelType)
73 {
75 // coverity[autosar_cpp14_a5_1_1_violation]
76 return "type=SHMEM_LOCAL";
78 // coverity[autosar_cpp14_a5_1_1_violation]
79 return "type=SHMEM_REMOTE";
81 // coverity[autosar_cpp14_a5_1_1_violation]
82 return "type=EGLSTREAM";
84 // coverity[autosar_cpp14_a5_1_1_violation]
85 return "type=SOCKET";
87 // coverity[autosar_cpp14_a5_1_1_violation]
88 return "type=DDS";
90 // coverity[autosar_cpp14_a5_1_1_violation]
91 return "type=NVSCI";
93 // coverity[autosar_cpp14_a5_1_1_violation]
94 return "type=FSI";
95 default:
96 dw::core::unreachable();
97 }
98}
99
103enum class ChannelRole : uint8_t
104{
108};
109
110inline constexpr bool IsProducer(ChannelRole role)
111{
113}
114
115inline constexpr bool IsConsumer(ChannelRole role)
116{
118}
119
120// coverity[autosar_cpp14_a0_1_1_violation]
121// coverity[autosar_cpp14_m0_1_4_violation]
122static constexpr uint16_t MAX_CHANNEL_PARAM_SIZE{1024U};
123// coverity[autosar_cpp14_a0_1_1_violation]
124// coverity[autosar_cpp14_m0_1_4_violation]
125static constexpr uint16_t MAX_CHANNEL_ALL_PARAMS_SIZE{1024U};
126// coverity[autosar_cpp14_a0_1_1_violation]
127// coverity[autosar_cpp14_m0_1_4_violation]
128static constexpr uint16_t MAX_CHANNEL_PRODUCERS_COUNT{2048U};
129static constexpr uint16_t MAX_CHANNEL_CONSUMERS_COUNT{256U};
130// coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
131// coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
132static constexpr uint16_t MAX_CHANNEL_STREAM_NAME_SIZE{64U};
133
134using ChannelParamStr = dw::core::FixedString<MAX_CHANNEL_PARAM_SIZE>;
135using ChannelStreamNameStr = dw::core::FixedString<MAX_CHANNEL_STREAM_NAME_SIZE>;
136
137enum class ChannelMode
138{
139 FIFO,
140 MAILBOX,
142};
143
145{
146 uint32_t socID;
147 uint32_t vmID;
148};
149
150// NOTE(eklein): This is slightly awkward. I would much prefer to put this in
151// the ChannelNvSciStreamParams class directly, but I need access to the
152// operator overloads inside ChannelNvSciStreamParams.
153// I cannot forward declare the operators inside the class, and I cannot put the
154// operators inside the enum class (as you would ideally do). The best compromise
155// I could think of was to put this enum class here outside.
157{
158 COMPONENT_NONE = 0,
159
160 COMPONENT_CPU = 1 << 0,
161 COMPONENT_EGL = 1 << 1,
162 COMPONENT_CUDA = 1 << 2,
163 COMPONENT_PVA = 1 << 3,
164 COMPONENT_DLA = 1 << 4,
165 COMPONENT_NVMEDIA = 1 << 5,
166};
167
168// whether the channel is created statically, or dynamically at runtime
169// coverity[autosar_cpp14_a0_1_6_violation]
171{
175};
176
177// the farthest reach this channel can achieve
178// shorter reach is faster, so if topology is known upfront,
179// use the shortest matching reach for maximum performance
180// coverity[autosar_cpp14_a0_1_6_violation]
181enum class ChannelReach
182{
183 REACH_NONE = 0,
186 REACH_VM,
188};
189
192{
193 return static_cast<ChannelNvSciStreamEnabledComponents>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
194}
195
198{
199 return static_cast<ChannelNvSciStreamEnabledComponents>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
200}
201
202template <typename T>
203// coverity[autosar_cpp14_a2_10_4_violation]
204// coverity[autosar_cpp14_a2_10_5_violation]
205static inline T ParseChannelParameter(const ChannelParamStr& value);
206
207template <>
208// coverity[autosar_cpp14_a2_10_4_violation]
209// coverity[autosar_cpp14_a2_10_5_violation]
211{
212 // coverity[autosar_cpp14_a5_1_1_violation]
213 return dw::core::safeStrtol(value.c_str(), nullptr, 10);
214}
215
216template <>
217// coverity[autosar_cpp14_a2_10_4_violation]
218// coverity[autosar_cpp14_a2_10_5_violation]
220{
221 int64_t translatedSize{ParseChannelParameter<int64_t>(value)};
222 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
223 if (translatedSize < 0)
224 {
225 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: size_t is negative");
226 }
227 size_t result{static_cast<size_t>(translatedSize)};
228 return result;
229}
230
231template <>
232// coverity[autosar_cpp14_a2_10_4_violation]
233// coverity[autosar_cpp14_a2_10_5_violation]
235{
236 size_t translatedSize{ParseChannelParameter<size_t>(value)};
237 if (translatedSize > std::numeric_limits<uint32_t>::max())
238 {
239 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: value is larger than uint32_t allows");
240 }
241 uint32_t result{static_cast<uint32_t>(translatedSize)};
242 return result;
243}
244
245template <>
246// coverity[autosar_cpp14_a2_10_4_violation]
247// coverity[autosar_cpp14_a2_10_5_violation]
249{
250 size_t translatedSize{ParseChannelParameter<size_t>(value)};
251 if (translatedSize > std::numeric_limits<uint16_t>::max())
252 {
253 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: port is larger than uint16_t allows!");
254 }
255 uint16_t result{static_cast<uint16_t>(translatedSize)};
256 return result;
257}
258
259template <>
260// coverity[autosar_cpp14_a2_10_4_violation]
261// coverity[autosar_cpp14_a2_10_5_violation]
263{
264 size_t translatedSize{ParseChannelParameter<size_t>(value)};
265 if (translatedSize > std::numeric_limits<uint8_t>::max())
266 {
267 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: port is larger than uint8_t allows!");
268 }
269 uint8_t result{static_cast<uint8_t>(translatedSize)};
270 return result;
271}
272
273template <>
274// coverity[autosar_cpp14_a2_10_4_violation]
275// coverity[autosar_cpp14_a2_10_5_violation]
277{
278 bool result;
279 // coverity[autosar_cpp14_a5_1_1_violation]
280 if ((value == "true") || (value == "1"))
281 {
282 result = true;
283 }
284 // coverity[autosar_cpp14_a5_1_1_violation]
285 else if ((value == "false") || (value == "0"))
286 {
287 result = false;
288 }
289 else
290 {
291 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: needs to be 'true' or 'false' or 1/0");
292 }
293 return result;
294}
295
296template <>
297// coverity[autosar_cpp14_a2_10_4_violation]
298// coverity[autosar_cpp14_a2_10_5_violation]
300{
301 // coverity[autosar_cpp14_a5_1_1_violation]
302 if (value == "producer")
303 {
305 }
306 // coverity[autosar_cpp14_a5_1_1_violation]
307 if (value == "consumer")
308 {
310 }
311 // coverity[autosar_cpp14_a5_1_1_violation]
312 if (value == "composite")
313 {
315 }
316 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: role unknown!");
317}
318
319template <>
320// coverity[autosar_cpp14_a2_10_4_violation]
321// coverity[autosar_cpp14_a2_10_5_violation]
323{
324 // coverity[autosar_cpp14_a5_1_1_violation]
325 if (value == "SHMEM_LOCAL")
326 {
328 }
329 // coverity[autosar_cpp14_a5_1_1_violation]
330 if (value == "SHMEM_REMOTE")
331 {
333 }
334 // coverity[autosar_cpp14_a5_1_1_violation]
335 if (value == "EGLSTREAM")
336 {
338 }
339 // coverity[autosar_cpp14_a5_1_1_violation]
340 if (value == "SOCKET")
341 {
342 return ChannelType::SOCKET;
343 }
344 // coverity[autosar_cpp14_a5_1_1_violation]
345 if (value == "DDS")
346 {
347 return ChannelType::DDS;
348 }
349 // coverity[autosar_cpp14_a5_1_1_violation]
350 if (value == "NVSCI")
351 {
352 return ChannelType::NVSCI;
353 }
354 // coverity[autosar_cpp14_a5_1_1_violation]
355 if (value == "FSI")
356 {
357 return ChannelType::FSI;
358 }
359 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: type unknown!");
360}
361
362template <>
363// coverity[autosar_cpp14_a2_10_4_violation]
364// coverity[autosar_cpp14_a2_10_5_violation]
366{
367 ChannelMode result;
368 // coverity[autosar_cpp14_a5_1_1_violation]
369 if (value == "mailbox")
370 {
371 result = ChannelMode::MAILBOX;
372 }
373 // coverity[autosar_cpp14_a5_1_1_violation]
374 else if (value == "singleton")
375 {
376 result = ChannelMode::SINGLETON;
377 }
378 else
379 {
380 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: ChannelMode unknown!");
381 }
382 return result;
383}
384
385template <>
386// coverity[autosar_cpp14_a2_10_4_violation]
387// coverity[autosar_cpp14_a2_10_5_violation]
389{
390 // coverity[autosar_cpp14_a5_1_1_violation]
391 size_t pos{value.find(".")};
392 ChannelPeerLocation result{};
393 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
394 ChannelParamStr first{value.substr(0U, pos)};
395 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
396 ChannelParamStr second{value.substr(dw::core::safeAdd(pos, 1U).value())};
397 result.socID = ParseChannelParameter<uint32_t>(first);
398 result.vmID = ParseChannelParameter<uint32_t>(second);
399 return result;
400}
401
402template <typename T>
403// coverity[autosar_cpp14_a2_10_4_violation]
404// coverity[autosar_cpp14_a2_10_5_violation]
405void ParseChannelParameter(const ChannelParamStr& value, T& result)
406{
407 result = ParseChannelParameter<T>(value);
408}
409
410template <size_t Size>
411// coverity[autosar_cpp14_a2_10_4_violation]
412// coverity[autosar_cpp14_a2_10_5_violation]
413void ParseChannelParameter(const ChannelParamStr& value, dw::core::FixedString<Size>& result)
414{
415 result = value;
416}
417
418template <typename T, size_t N>
419// coverity[autosar_cpp14_a2_10_4_violation]
420// coverity[autosar_cpp14_a2_10_5_violation]
421void ParseChannelParameter(const ChannelParamStr& value, dw::core::VectorFixed<T, N>& result)
422{
423 size_t pos{0U};
424 size_t endpos{0U};
425 while (true)
426 {
427 // coverity[autosar_cpp14_a5_1_1_violation]
428 endpos = value.find(":", pos);
429 bool done{endpos == dw::core::FixedString<1>::NPOS};
430 size_t count{done ? endpos : endpos - pos};
431 T entry{};
432 ParseChannelParameter(value.substr(pos, count), entry);
433 result.push_back(entry);
434 if (done)
435 {
436 break;
437 }
438 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
439 pos = endpos + 1U;
440 }
441}
442
443// coverity[autosar_cpp14_a2_10_4_violation]
444// coverity[autosar_cpp14_a2_10_5_violation]
445// coverity[autosar_cpp14_m0_1_8_violation]
447{
448 return;
449}
450
451template <typename T, typename... Others>
452// coverity[autosar_cpp14_a2_10_4_violation]
453// coverity[autosar_cpp14_a2_10_5_violation]
454static inline void ParseChannelParameters(const ChannelParamStr& key, const ChannelParamStr& value, const char* staticKey, T& result, Others&&... others)
455{
456 if (key == staticKey)
457 {
458 ParseChannelParameter(value, result);
459 return;
460 }
461 ParseChannelParameters(key, value, std::forward<Others>(others)...);
462}
463
464template <typename... Others>
465// coverity[autosar_cpp14_a2_10_4_violation]
466// coverity[autosar_cpp14_a2_10_5_violation]
467static inline void ParseAllChannelParameters(const ChannelParamStr& channelParams, Others&&... others)
468{
469 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
470 std::size_t key{0U};
471 // coverity[autosar_cpp14_a5_1_1_violation]
472 std::size_t pos{channelParams.find("=")};
473 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
474 std::size_t value{0U};
475 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
476 std::size_t valueEnd{0U};
477
478 ChannelParamStr keyString{};
479 ChannelParamStr valueString{};
480 while (pos != dw::core::FixedString<1>::NPOS && value != dw::core::FixedString<1>::NPOS)
481 {
482 keyString = channelParams.substr(key, dw::core::safeSub(pos, key).value());
483 // coverity[autosar_cpp14_a5_1_1_violation]
484 value = channelParams.find(",", pos);
485 if (value == dw::core::FixedString<1>::NPOS)
486 {
487 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
488 valueEnd = dw::core::safeSub(channelParams.length(), dw::core::safeAdd(pos, 1U).value()).value();
489 }
490 else
491 {
492 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
493 valueEnd = dw::core::safeSub(dw::core::safeSub(value, pos).value(), 1U).value();
494 }
495 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
496 valueString = channelParams.substr(pos + 1U, valueEnd);
497 ParseChannelParameters(keyString, valueString, std::forward<Others>(others)...);
498
499 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
500 key = value + 1U;
501 // coverity[autosar_cpp14_a5_1_1_violation]
502 pos = channelParams.find("=", key);
503 }
504}
505
507{
508public:
509 static inline ChannelParamStr getParamStr(const char* serverIP,
510 uint16_t port,
511 bool producerFifo = false,
512 uint16_t numBlockingConnections = 1U,
513 dw::core::FixedString<8> const sockPrefix = dw::core::FixedString<8>())
514 {
515 std::stringstream ss{};
516 ss.flags(std::ios::dec);
517 ss << "type=SOCKET";
518 if (serverIP != nullptr)
519 {
520 ss << ",ip=";
521 ss << serverIP;
522 }
523 ss << ",id=";
524 ss << port;
525 ss << ",producer-fifo=";
526 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
527 ss << (producerFifo ? 1U : 0U);
528 ss << ",num-clients=";
529 ss << numBlockingConnections;
530 ss << ",sock-prefix=";
531 ss << sockPrefix;
532 ChannelParamStr result{ss.str().c_str()};
533 return result;
534 }
535
537 explicit ChannelSocketParams(const char* params)
538 {
539 dw::core::FixedString<MAX_CHANNEL_ALL_PARAMS_SIZE> channelParams{params};
540 ParseAllChannelParameters(channelParams,
541 // coverity[autosar_cpp14_a5_1_1_violation]
542 "ip", m_serverIP,
543 // coverity[autosar_cpp14_a5_1_1_violation]
544 "producer-fifo", m_producerFifo,
545 // coverity[autosar_cpp14_a5_1_1_violation]
546 "id", m_port,
547 // coverity[autosar_cpp14_a5_1_1_violation]
548 "connect-timeout", m_connectTimeout,
549 // coverity[autosar_cpp14_a5_1_1_violation]
550 "sock-prefix", m_sockPrefix);
551 }
552
554
556
557 ChannelParamStr getServerIP() const { return m_serverIP; }
558 uint16_t getPort() const { return m_port; }
559 bool hasProducerFifo() const { return m_producerFifo; }
560 dwTime_t getConnectTimeout() const { return m_connectTimeout; }
561 dwshared::socketipc::SockPrefixStr getSockPrefix() const { return m_sockPrefix; }
562
563private:
564 ChannelParamStr m_serverIP; // needed for socket client connection
565 uint16_t m_port{0U};
566 bool m_producerFifo{false}; // Allow the socket producer to have its own fifo to queue up work
567 dwTime_t m_connectTimeout{DW_TIME_INVALID};
568 dwshared::socketipc::SockPrefixStr m_sockPrefix{};
569};
570
572
574{
575public:
577
578 explicit ChannelNvSciStreamParams(const char* params)
580 {
581 dw::core::FixedString<MAX_CHANNEL_ALL_PARAMS_SIZE> channelParams{params};
582 ParseAllChannelParameters(channelParams,
583 // coverity[autosar_cpp14_a5_1_1_violation]
584 "streamName", m_streamNames,
585 // coverity[autosar_cpp14_a5_1_1_violation]
586 "limits", m_limits,
587 // coverity[autosar_cpp14_a5_1_1_violation]
588 "num-clients", m_localClientCount,
589 // coverity[autosar_cpp14_a5_1_1_violation]
590 "late-locs", m_lateLocs);
591 }
592
594
596
597 size_t getNumOutputs() const
598 {
599 static_assert(decltype(m_streamNames)::CAPACITY_AT_COMPILE_TIME < std::numeric_limits<size_t>::max(), "ChannelNvSciStreamParams: number of outputs over limit");
600 return m_streamNames.size();
601 }
602
603 size_t getLocalClientCount() const { return m_localClientCount; }
604
605 dw::core::span<ChannelPeerLocation const> getLateLocs() const
606 {
607 return dw::core::make_span<ChannelPeerLocation const>(m_lateLocs.data(), m_lateLocs.size());
608 }
609
610 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
611 ChannelStreamNameStr getStreamName(size_t index = 0U) const
612 {
613 if (index >= m_streamNames.size())
614 {
615 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: stream name index out of range");
616 }
617 return m_streamNames[index];
618 }
619
620 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
621 int64_t getLimiterMaxPackets(size_t index = 0U) const
622 {
623 // Note: if no limits are denoted, return -1 and make inquirers not create limiter blocks.
624 // If not, it can lead to out of range when querying
625 if (m_limits.empty())
626 {
627 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
628 return -1;
629 }
630
631 if (index >= m_limits.size())
632 {
633 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: limiter maxPackets index out of range");
634 }
635 return m_limits[index];
636 }
637
638protected:
639 dw::core::VectorFixed<ChannelStreamNameStr, 8> m_streamNames{};
640 dw::core::VectorFixed<int64_t, 8> m_limits{};
641 dw::core::VectorFixed<ChannelPeerLocation, 32> m_lateLocs{};
643};
644
646{
647public:
648 ChannelFSIParams() = default;
649 explicit ChannelFSIParams(const char* params)
650 {
651 ChannelParamStr channelParams{params};
652 ParseAllChannelParameters(channelParams,
653 // coverity[autosar_cpp14_a5_1_1_violation]
654 "compat-vendor", m_compatVendor,
655 // coverity[autosar_cpp14_a5_1_1_violation]
656 "compat-app", m_compatApp,
657 // coverity[autosar_cpp14_a5_1_1_violation]
658 "num-channel", m_numChannel);
659 m_compat = m_compatVendor;
660 // coverity[autosar_cpp14_a5_1_1_violation]
661 m_compat += ",";
662 m_compat += m_compatApp;
663 }
664
665 ChannelFSIParams(const ChannelFSIParams& other) = default;
666
668
669 const char* getCompat() const { return m_compat.c_str(); }
670 uint8_t getNumChannel() const { return m_numChannel; }
671
672private:
673 ChannelParamStr m_compat;
674 ChannelParamStr m_compatVendor;
675 ChannelParamStr m_compatApp;
676 uint8_t m_numChannel{0U};
677};
678
683{
684public:
685 explicit ChannelParams(const char* params)
686 {
687 m_str = params;
689 // coverity[autosar_cpp14_a5_1_1_violation]
690 "fifo-size", m_fifoSize,
691 // coverity[autosar_cpp14_a5_1_1_violation]
692 "id", m_id,
693 // coverity[autosar_cpp14_a5_1_1_violation]
694 "uid", m_uid,
695 // coverity[autosar_cpp14_a5_1_1_violation]
696 "connect-group-id", m_connectGroupID,
697 // coverity[autosar_cpp14_a5_1_1_violation]
698 "singleton-id", m_singletonId,
699 // coverity[autosar_cpp14_a5_1_1_violation]
700 "mode", m_mode,
701 // coverity[autosar_cpp14_a5_1_1_violation]
702 "reuse", m_reuseEnabled,
703 // coverity[autosar_cpp14_a5_1_1_violation]
704 "debug-port", m_debugPort,
705 // coverity[autosar_cpp14_a5_1_1_violation]
706 "num-clients", m_clientsCount,
707 // coverity[autosar_cpp14_a5_1_1_violation]
708 "debug-num-clients", m_debugClientsCount,
709 // coverity[autosar_cpp14_a5_1_1_violation]
710 "role", m_role,
711 // coverity[autosar_cpp14_a5_1_1_violation]
712 "type", m_type,
713 // coverity[autosar_cpp14_a5_1_1_violation]
714 "data-offset", m_dataOffset,
715 // coverity[autosar_cpp14_a5_1_1_violation]
716 "strict", m_strictFifo,
717 // coverity[autosar_cpp14_a5_1_1_violation]
718 "sync-enabled", m_syncEnabled,
719 // coverity[autosar_cpp14_a5_1_1_violation]
720 "name", m_name);
721
722 adjustPoolCapacity();
723
724 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
725 if (m_clientsCount == 0U)
726 {
727 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
728 m_clientsCount = 1U;
729 }
730
731 if (!m_singletonId.empty())
732 {
733 m_mode = ChannelMode::SINGLETON;
734 }
735
736 if (m_mode == ChannelMode::MAILBOX)
737 {
738 m_mailboxMode = true;
739 }
740 else if (m_mode == ChannelMode::SINGLETON)
741 {
742 m_singletonMode = true;
743
744 // Assign singletonId with id
745 if (!m_id.empty() && m_singletonId.empty())
746 {
747 m_singletonId = m_id;
748 }
749 }
750
751 // Why break this up like this? Code complexity.
752 // Without this, we fail the code complexity analysis.
753 ValidateMailbox();
754 ValidateSingleton();
755
756 switch (m_type)
757 {
759 break;
761 m_socketParams = ChannelSocketParams(params);
762 break;
764 m_nvSciStreamParams = ChannelNvSciStreamParams(params);
765 break;
766 case ChannelType::FSI:
767 m_fsiParams = ChannelFSIParams(params);
768 break;
771 case ChannelType::DDS:
772 default:
773 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED, "ChannelParams: no parameters for channel type");
774 }
775 }
776
778 {
779 *this = other;
780 }
781
782 ChannelParams& operator=(const ChannelParams& other) = default;
783 ~ChannelParams() = default;
784
785 const char* getStr() const { return m_str.c_str(); }
786 ChannelParamStr getId() const { return m_id; }
787 ChannelParamStr getSingletonId() const { return m_singletonId; }
788 uint16_t getDebugPort() const { return m_debugPort; }
789 size_t getFifoSize() const { return m_fifoSize; }
790 // Note(chale): Normally the fifo length governs whether a consumer
791 // will receive packet. The actual packet pool's size may be larger
792 // than the fifo length. non-strict mode allows consumers to receive
793 // up to the entire pool size instead of just their fifo length.
794 bool isStrictFifo() const { return m_strictFifo; }
795 void setStrictFifo(bool strictFifo)
796 {
797 m_strictFifo = strictFifo;
798 }
799 size_t getPoolCapacity() const { return m_poolCapacity; }
800 bool getMailboxMode() const { return m_mailboxMode; }
801 // Note (ajayawardane): The data-offset parameter is used to describe
802 // the consumption offset between the producer and the consumer
803 // in the sync packet use-case. For example, if a packet is produced with the
804 // sync count x, and is inteneded to be consumed when the sync count is x + 1,
805 // the data-offset would be 1. This parameter is also used to identify whether
806 // to use sync packets to transfer data, so needs to be included in both the
807 // producer and the consumer params.
808 uint32_t getDataOffset() const { return m_dataOffset; }
809 bool getSyncEnabled() const { return m_syncEnabled; }
810 void setMailboxMode(bool mailboxEnabled) { m_mailboxMode = mailboxEnabled; }
811 bool getSingletonMode() const { return m_singletonMode; }
812 bool getReuseEnabled() const { return m_reuseEnabled; }
813 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
814 bool getDebugMode() const { return m_debugPort > 0U; }
815 uint16_t getExpectedConnectionsCount() const { return m_clientsCount; }
816 uint16_t getExpectedDebugConnectionsCount() const { return m_debugClientsCount; }
817 ChannelRole getRole() const { return m_role; }
818 ChannelType getType() const { return m_type; }
819 uint32_t getUID() const { return m_uid; }
820 uint32_t getConnectGroupID() const { return m_connectGroupID; }
821
822 // coverity[autosar_cpp14_a2_10_5_violation]
823 ChannelParamStr getName() const { return m_name; }
824
826 {
827 if (m_type != ChannelType::SOCKET)
828 {
829 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getSocketParams: channel is not of type SOCKET");
830 }
831 return m_socketParams;
832 }
833
835 {
836 if (m_type != ChannelType::NVSCI)
837 {
838 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getNvSciStreamParams: channel is not of type NVSCI");
839 }
840 return m_nvSciStreamParams;
841 }
842
844 {
845 if (m_type != ChannelType::FSI)
846 {
847 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getFSIParams: channel is not of type FSI");
848 }
849 return m_fsiParams;
850 }
851
852private:
853 void ValidateMailbox()
854 {
855 if (m_singletonMode)
856 {
857 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
858 if (m_fifoSize != 1U)
859 {
860 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton and mailbox modes are incompatible with a fifo setting other than 1");
861 }
862 }
863 if (!m_mailboxMode && m_reuseEnabled)
864 {
865 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: reuse=true specified when mode!=mailbox. Not valid");
866 }
867 if (m_mailboxMode && m_singletonMode)
868 {
869 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode is incompatible mailbox mode");
870 }
871 }
872
873 void ValidateSingleton()
874 {
875 // Assign singletonId with id in singleton mode
876 if (m_singletonMode && m_singletonId.empty())
877 {
878 m_singletonId = m_id;
879 }
880 if (!m_singletonMode && !m_singletonId.empty())
881 {
882 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode requires both the mode set AND singletonId set");
883 }
884 if (m_singletonMode && (m_type != ChannelType::SHMEM_LOCAL))
885 {
886 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode is only valid for SHMEM_LOCAL channels");
887 }
888 }
889
890 void adjustPoolCapacity()
891 {
892 // This deserves a comment. The LocalShmem pools (in the fifo-case)
893 // need the following number of slots, in the worst case:
894 // 1 for getImpl to return at any time
895 // 1 per consumer for in-flight data
896 // fifo-size to store a full fifo worth of packets
897 // So assuming max consumers, we'd need fifo-size + MAX_CHANNEL_CONSUMERS_COUNT + 1
898 if (dw::core::safeAdd(m_fifoSize, MAX_CHANNEL_CONSUMERS_COUNT).value() >= m_poolCapacity)
899 {
900 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
901 m_poolCapacity = m_fifoSize + MAX_CHANNEL_CONSUMERS_COUNT + 1U;
902 }
903 }
904
905private:
906 ChannelParamStr m_str{};
907 ChannelParamStr m_id{};
908 ChannelParamStr m_singletonId{};
909 ChannelParamStr m_name{};
910
911 // fifo size of the socket client that implies the maximum number of packets
912 // a client can hold simultaneously
913 size_t m_fifoSize{1U};
914 // This deserves a comment. The LocalShmem pools (in the fifo-case)
915 // need the following number of slots, in the worst case:
916 // 1 for getImpl to return at any time
917 // 1 per consumer for in-flight data
918 // fifo-size to store a full fifo worth of packets
919 // So assuming a fifo-size of 1 and max consumers, we'd need MAX_CHANNEL_CONSUMERS_COUNT + 2
920 size_t m_poolCapacity{MAX_CHANNEL_CONSUMERS_COUNT + 2U};
922 uint32_t m_dataOffset{0U};
923 uint32_t m_uid{0U};
924 uint32_t m_connectGroupID{0U};
925 bool m_syncEnabled{false};
926 bool m_mailboxMode{false};
927 bool m_singletonMode{false};
928 bool m_reuseEnabled{false};
931 bool m_strictFifo{true};
932
933 uint16_t m_clientsCount{1U}; // number of clients for blocking mode for socket
934 uint16_t m_debugClientsCount{1U}; // number of debug clients for blocking mode for socket
935
936 uint16_t m_debugPort{0U};
937
938 ChannelSocketParams m_socketParams{};
939 ChannelNvSciStreamParams m_nvSciStreamParams{};
940 ChannelFSIParams m_fsiParams{};
941};
942
943} // namespace framework
944} // namespace dw
945
946#endif // DW_FRAMEWORK_CHANNEL_HPP_
ChannelFSIParams & operator=(const ChannelFSIParams &other)=default
ChannelFSIParams(const ChannelFSIParams &other)=default
ChannelNvSciStreamParams & operator=(const ChannelNvSciStreamParams &other)=default
int64_t getLimiterMaxPackets(size_t index=0U) const
dw::core::VectorFixed< ChannelStreamNameStr, 8 > m_streamNames
dw::core::VectorFixed< ChannelPeerLocation, 32 > m_lateLocs
ChannelNvSciStreamParams(const ChannelNvSciStreamParams &other)=default
dw::core::span< ChannelPeerLocation const > getLateLocs() const
dw::core::VectorFixed< int64_t, 8 > m_limits
ChannelStreamNameStr getStreamName(size_t index=0U) const
void setMailboxMode(bool mailboxEnabled)
uint16_t getExpectedConnectionsCount() const
uint16_t getExpectedDebugConnectionsCount() const
ChannelParams & operator=(const ChannelParams &other)=default
const ChannelSocketParams & getSocketParams() const
ChannelParamStr getName() const
const ChannelNvSciStreamParams & getNvSciStreamParams() const
const ChannelFSIParams & getFSIParams() const
ChannelParamStr getSingletonId() const
void setStrictFifo(bool strictFifo)
ChannelParams(const ChannelParams &other)
ChannelParamStr getId() const
ChannelSocketParams & operator=(const ChannelSocketParams &other)=default
dwshared::socketipc::SockPrefixStr getSockPrefix() const
ChannelSocketParams(const ChannelSocketParams &other)=default
static ChannelParamStr getParamStr(const char *serverIP, uint16_t port, bool producerFifo=false, uint16_t numBlockingConnections=1U, dw::core::FixedString< 8 > const sockPrefix=dw::core::FixedString< 8 >())
static const char * ToParam(ChannelType channelType)
static constexpr uint16_t MAX_CHANNEL_ALL_PARAMS_SIZE
dw::core::FixedString< MAX_CHANNEL_PARAM_SIZE > ChannelParamStr
@ DW_CHANNEL_ROLE_PRODUCER
allows producer only
@ DW_CHANNEL_ROLE_CONSUMER
allows consumer only
@ DW_CHANNEL_ROLE_COMPOSITE
allows both producer and consumer
static void ParseChannelParameters(const ChannelParamStr &, const ChannelParamStr &)
static constexpr uint16_t MAX_CHANNEL_STREAM_NAME_SIZE
constexpr bool IsProducer(ChannelRole role)
static T ParseChannelParameter(const ChannelParamStr &value)
constexpr ChannelNvSciStreamEnabledComponents operator&(ChannelNvSciStreamEnabledComponents a, ChannelNvSciStreamEnabledComponents b)
constexpr ChannelNvSciStreamEnabledComponents operator|(ChannelNvSciStreamEnabledComponents a, ChannelNvSciStreamEnabledComponents b)
static void ParseAllChannelParameters(const ChannelParamStr &channelParams, Others &&... others)
static constexpr uint16_t MAX_CHANNEL_PARAM_SIZE
constexpr bool IsConsumer(ChannelRole role)
static constexpr uint16_t MAX_CHANNEL_PRODUCERS_COUNT
dw::core::FixedString< MAX_CHANNEL_STREAM_NAME_SIZE > ChannelStreamNameStr
static constexpr uint16_t MAX_CHANNEL_CONSUMERS_COUNT
@ SHMEM_LOCAL
local shared memory
@ DDS
Data Distribution Service (DDS)
@ SHMEM_REMOTE
remote shared memory
Definition: Buffer.hpp:40