Compute Graph Framework SDK Reference  5.22
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-2024 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/HashContainer.hpp>
37#include <dwshared/dwfoundation/dw/core/container/StringView.hpp>
38#include <dwshared/dwfoundation/dw/core/container/VectorFixed.hpp>
39#include <dwshared/dwfoundation/dw/core/language/cxx23.hpp>
40#include <dwshared/dwfoundation/dw/core/safety/SafeStrOps.hpp>
41#include <dwshared/dwfoundation/dw/core/safety/Safety.hpp>
42#include <dwshared/dwsockets/SocketClientServer.hpp>
43#include <dw/core/system/NvMediaExt.h>
45#include <sstream>
46#include <limits>
47
48namespace dw
49{
50namespace framework
51{
52
54
57enum class ChannelType : uint8_t
58{
61 EGLSTREAM,
62 SOCKET,
63 DDS,
64 NVSCI,
65 FSI,
66};
67
68// coverity[autosar_cpp14_a0_1_3_violation]
69inline const char* ToParam(ChannelType channelType)
70{
71 switch (channelType)
72 {
74 {
75 const char* value{"type=SHMEM_LOCAL"};
76 return value;
77 }
79 {
80 const char* value{"type=SHMEM_REMOTE"};
81 return value;
82 }
84 {
85 const char* value{"type=EGLSTREAM"};
86 return value;
87 }
89 {
90 const char* value{"type=SOCKET"};
91 return value;
92 }
94 {
95 const char* value{"type=DDS"};
96 return value;
97 }
99 {
100 const char* value{"type=NVSCI"};
101 return value;
102 }
103 case ChannelType::FSI:
104 {
105 const char* value{"type=FSI"};
106 return value;
107 }
108 // LCOV_EXCL_START all valid enumerators are covered by cases and enforced by the compiler
109 default:
110 dw::core::unreachable();
111 // LCOV_EXCL_STOP
112 }
113}
114
118enum class ChannelRole : uint8_t
119{
123};
124
125inline constexpr bool IsProducer(ChannelRole role)
126{
128}
129
130inline constexpr bool IsConsumer(ChannelRole role)
131{
133}
134
135// coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
136// coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
137static constexpr uint16_t MAX_CHANNEL_PARAM_SIZE{1024U};
138// coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
139// coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
140static constexpr uint16_t MAX_CHANNEL_ALL_PARAMS_SIZE{1024U};
141// coverity[autosar_cpp14_a0_1_1_violation]
142// coverity[autosar_cpp14_m0_1_4_violation]
143static constexpr uint16_t MAX_CHANNEL_PRODUCERS_COUNT{2048U};
144static constexpr uint16_t MAX_CHANNEL_CONSUMERS_COUNT{256U};
145// coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
146// coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
147static constexpr uint16_t MAX_CHANNEL_STREAM_NAME_SIZE{64U};
148// coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
149// coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
150static constexpr uint16_t MAX_CHANNEL_STREAM_NAMES{8U};
151
152using ChannelParamStr = dw::core::FixedString<MAX_CHANNEL_PARAM_SIZE>;
153using ChannelStreamNameStr = dw::core::FixedString<MAX_CHANNEL_STREAM_NAME_SIZE>;
154
155enum class ChannelMode
156{
157 FIFO,
158 MAILBOX,
160};
161
163{
164 uint32_t socID;
165 uint32_t vmID;
166};
167
168// NOTE(eklein): This is slightly awkward. I would much prefer to put this in
169// the ChannelNvSciStreamParams class directly, but I need access to the
170// operator overloads inside ChannelNvSciStreamParams.
171// I cannot forward declare the operators inside the class, and I cannot put the
172// operators inside the enum class (as you would ideally do). The best compromise
173// I could think of was to put this enum class here outside.
175{
176 COMPONENT_NONE = 0,
177
178 COMPONENT_CPU = 1 << 0,
179 COMPONENT_EGL = 1 << 1,
180 COMPONENT_CUDA = 1 << 2,
181 COMPONENT_PVA = 1 << 3,
182 COMPONENT_DLA = 1 << 4,
183 COMPONENT_NVMEDIA = 1 << 5,
184};
185
186// whether the channel is created statically, or dynamically at runtime
187// coverity[autosar_cpp14_a0_1_6_violation]
189{
193};
194
195// the farthest reach this channel can achieve
196// shorter reach is faster, so if topology is known upfront,
197// use the shortest matching reach for maximum performance
198// coverity[autosar_cpp14_a0_1_6_violation]
199enum class ChannelReach
200{
201 REACH_NONE = 0,
204 REACH_VM,
206};
207
210{
211 return static_cast<ChannelNvSciStreamEnabledComponents>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
212}
213
216{
217 return static_cast<ChannelNvSciStreamEnabledComponents>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
218}
219
220template <typename T>
221// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
222// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
223static inline T ParseChannelParameter(const ChannelParamStr& value);
224
225template <>
226// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
227// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
229{
230 const int32_t BASE_10{10};
231 return dw::core::safeStrtol(value.c_str(), nullptr, BASE_10);
232}
233
234template <>
235// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
236// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
238{
239 int64_t translatedSize{ParseChannelParameter<int64_t>(value)};
240 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
241 if (translatedSize < 0)
242 {
243 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: size_t is negative");
244 }
245 size_t result{static_cast<size_t>(translatedSize)};
246 return result;
247}
248
249template <>
250// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
251// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
253{
254 size_t translatedSize{ParseChannelParameter<size_t>(value)};
255 if (translatedSize > std::numeric_limits<uint32_t>::max())
256 {
257 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: value is larger than uint32_t allows");
258 }
259 uint32_t result{static_cast<uint32_t>(translatedSize)};
260 return result;
261}
262
263template <>
264// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
265// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
267{
268 size_t translatedSize{ParseChannelParameter<size_t>(value)};
269 if (translatedSize > std::numeric_limits<uint16_t>::max())
270 {
271 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: port is larger than uint16_t allows!");
272 }
273 uint16_t result{static_cast<uint16_t>(translatedSize)};
274 return result;
275}
276
277template <>
278// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
279// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
281{
282 size_t translatedSize{ParseChannelParameter<size_t>(value)};
283 if (translatedSize > std::numeric_limits<uint8_t>::max())
284 {
285 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: port is larger than uint8_t allows!");
286 }
287 uint8_t result{static_cast<uint8_t>(translatedSize)};
288 return result;
289}
290
291template <>
292// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
293// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
295{
296 // coverity[autosar_cpp14_a3_3_2_violation] RFD Pending: TID-2534
297 static const dw::core::StaticHashMap<ChannelParamStr, bool, 4> MAPPING{
298 {"true", true},
299 {"1", true},
300 {"false", false},
301 {"0", false},
302 };
303 if (!MAPPING.contains(value))
304 {
305 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: needs to be 'true' or 'false' or 1/0");
306 }
307 return MAPPING.at(value);
308}
309
310template <>
311// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
312// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
314{
315 // coverity[autosar_cpp14_a3_3_2_violation] RFD Pending: TID-2534
316 static const dw::core::StaticHashMap<ChannelParamStr, ChannelRole, 3> MAPPING{
317 // LCOV_EXCL_START no coverage data available for these lines
321 // LCOV_EXCL_STOP
322 };
323 if (!MAPPING.contains(value))
324 {
325 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: role unknown!");
326 }
327 return MAPPING.at(value);
328}
329
330template <>
331// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
332// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
334{
335 // coverity[autosar_cpp14_a3_3_2_violation] RFD Pending: TID-2534
336 static const dw::core::StaticHashMap<ChannelParamStr, ChannelType, 7> MAPPING{
337 // LCOV_EXCL_START no coverage data available for these lines
338 {"SHMEM_LOCAL", ChannelType::SHMEM_LOCAL},
339 {"SHMEM_REMOTE", ChannelType::SHMEM_REMOTE},
340 {"EGLSTREAM", ChannelType::EGLSTREAM},
341 {"SOCKET", ChannelType::SOCKET},
342 {"DDS", ChannelType::DDS},
343 {"NVSCI", ChannelType::NVSCI},
344 {"FSI", ChannelType::FSI},
345 // LCOV_EXCL_STOP
346 };
347 if (!MAPPING.contains(value))
348 {
349 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: type unknown!");
350 }
351 return MAPPING.at(value);
352}
353
354template <>
355// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
356// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
358{
359 // coverity[autosar_cpp14_a3_3_2_violation] RFD Pending: TID-2534
360 static const dw::core::StaticHashMap<ChannelParamStr, ChannelMode, 2> MAPPING{
361 // LCOV_EXCL_START no coverage data available for these lines
362 {"mailbox", ChannelMode::MAILBOX},
363 {"singleton", ChannelMode::SINGLETON},
364 // LCOV_EXCL_STOP
365 };
366 if (!MAPPING.contains(value))
367 {
368 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ParseChannelParameter: ChannelMode unknown!");
369 }
370 return MAPPING.at(value);
371}
372
373template <>
374// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
375// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
377{
378 const char* PEER_LOCATION_SEPARATOR{"."};
379 size_t pos{value.find(PEER_LOCATION_SEPARATOR)};
380 ChannelPeerLocation result{};
381 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
382 ChannelParamStr first{value.substr(0U, pos)};
383 // the parameter string length isn't close to the maximum value of size_t, hence no risk of overflow
384 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
385 ChannelParamStr second{value.substr(dw::core::safeAdd(pos, 1U).value())};
386 result.socID = ParseChannelParameter<uint32_t>(first);
387 result.vmID = ParseChannelParameter<uint32_t>(second);
388 return result;
389}
390
391template <typename T>
392// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
393// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
394void ParseChannelParameter(const ChannelParamStr& value, T& result)
395{
396 result = ParseChannelParameter<T>(value);
397}
398
399template <size_t Size>
400// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
401// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
402void ParseChannelParameter(const ChannelParamStr& value, dw::core::FixedString<Size>& result)
403{
404 result = value;
405}
406
407template <typename T, size_t N>
408// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
409// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
410void ParseChannelParameter(const ChannelParamStr& value, dw::core::VectorFixed<T, N>& result)
411{
412 const char* ELEMENT_SEPARATOR{":"};
413 size_t pos{0U};
414 size_t endpos{0U};
415 while (true)
416 {
417 endpos = value.find(ELEMENT_SEPARATOR, pos);
418 bool done{dw::core::FixedString<1>::NPOS == endpos};
419 size_t count{done ? endpos : endpos - pos};
420 T entry{};
421 ParseChannelParameter(value.substr(pos, count), entry);
422 static_cast<void>(result.push_back(entry));
423 if (done)
424 {
425 break;
426 }
427 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
428 pos = endpos + 1U;
429 }
430}
431
432template <typename T>
433// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
434// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
435static inline void ParseChannelParameters(const ChannelParamStr& key, const ChannelParamStr& value, dw::core::StringView staticKey, T& result)
436{
437 if (dw::core::StringView(key.data(), key.size()) == staticKey)
438 {
439 ParseChannelParameter(value, result);
440 }
441}
442
443template <
444 typename T, typename... Others,
445 std::enable_if_t<sizeof...(Others) != 0>* = nullptr>
446// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
447// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
448static inline void ParseChannelParameters(const ChannelParamStr& key, const ChannelParamStr& value, dw::core::StringView staticKey, T& result, Others&&... others)
449{
450 if (dw::core::StringView(key.data(), key.size()) == staticKey)
451 {
452 ParseChannelParameter(value, result);
453 return;
454 }
455 ParseChannelParameters(key, value, std::forward<Others>(others)...);
456}
457
458template <typename... Others>
459// coverity[autosar_cpp14_a2_10_4_violation] FP: nvbugs/4040101
460// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
461static inline void ParseAllChannelParameters(const ChannelParamStr& channelParams, Others&&... others)
462{
463 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
464 std::size_t key{0U};
465 const char* KEY_VALUE_SEPARATOR{"="};
466 std::size_t pos{channelParams.find(KEY_VALUE_SEPARATOR)};
467 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
468 std::size_t value{0U};
469 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2738197
470 std::size_t valueEnd{0U};
471
472 const char* PARAMETER_SEPARATOR{","};
473 ChannelParamStr keyString{};
474 ChannelParamStr valueString{};
475 while (dw::core::FixedString<1>::NPOS != pos && dw::core::FixedString<1>::NPOS != value)
476 {
477 // loop logic ensures that index 'pos' is always greater than the index 'key', hence no underflow possible
478 keyString = channelParams.substr(key, dw::core::safeSub(pos, key).value());
479 value = channelParams.find(PARAMETER_SEPARATOR, pos);
480 if (dw::core::FixedString<1>::NPOS == value)
481 {
482 // condition above ensures no overflow possible
483 // loop logic ensures that pos + 1 is never greater than the parameter length, hence no underflow possible
484 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
485 valueEnd = dw::core::safeSub(channelParams.length(), dw::core::safeAdd(pos, 1U).value()).value();
486 }
487 else
488 {
489 // loop logic ensures that index 'value' is always greater than the index 'pos', hence no underflow possible
490 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
491 valueEnd = dw::core::safeSub(dw::core::safeSub(value, pos).value(), 1U).value();
492 }
493 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
494 valueString = channelParams.substr(pos + 1U, valueEnd);
495 ParseChannelParameters(keyString, valueString, others...);
496
497 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
498 key = value + 1U;
499 pos = channelParams.find(KEY_VALUE_SEPARATOR, key);
500 }
501}
502
504{
505public:
507 const char* serverIP,
508 uint16_t port,
509 bool producerFifo = false,
510 uint16_t numBlockingConnections = 1U,
511 dw::core::FixedString<8> const sockPrefix = dw::core::FixedString<8>())
512 {
513 std::stringstream ss{};
514 static_cast<void>(ss.flags(std::ios::dec));
515 ss << "type=SOCKET";
516 if (nullptr != serverIP)
517 {
518 ss << ",ip=";
519 ss << serverIP;
520 }
521 ss << ",id=";
522 ss << port;
523 ss << ",producer-fifo=";
524 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
525 ss << (producerFifo ? 1U : 0U);
526 ss << ",num-clients=";
527 ss << numBlockingConnections;
528 ss << ",sock-prefix=";
529 ss << sockPrefix;
530 ChannelParamStr result{ss.str().c_str()};
531 return result;
532 }
533
535 explicit ChannelSocketParams(const char* params)
536 {
537 dw::core::FixedString<MAX_CHANNEL_ALL_PARAMS_SIZE> channelParams{params};
538 ParseAllChannelParameters(channelParams,
539 dw::core::StringView{"ip"}, m_serverIP,
540 dw::core::StringView{"producer-fifo"}, m_producerFifo,
541 dw::core::StringView{"id"}, m_port,
542 dw::core::StringView{"connect-timeout"}, m_connectTimeout,
543 dw::core::StringView{"sock-prefix"}, m_sockPrefix);
544 }
545
547
549
550 ChannelParamStr getServerIP() const { return m_serverIP; }
551 uint16_t getPort() const { return m_port; }
552 bool hasProducerFifo() const { return m_producerFifo; }
553 dwTime_t getConnectTimeout() const { return m_connectTimeout; }
554 dwshared::socketipc::SockPrefixStr getSockPrefix() const { return m_sockPrefix; }
555
556private:
557 ChannelParamStr m_serverIP; // needed for socket client connection
558 uint16_t m_port{0U};
559 bool m_producerFifo{false}; // Allow the socket producer to have its own fifo to queue up work
560 dwTime_t m_connectTimeout{DW_TIME_INVALID};
561 dwshared::socketipc::SockPrefixStr m_sockPrefix{};
562};
563
565
567{
568public:
570
571 explicit ChannelNvSciStreamParams(const char* params)
573 {
574 dw::core::FixedString<MAX_CHANNEL_ALL_PARAMS_SIZE> channelParams{params};
575 ParseAllChannelParameters(channelParams,
576 dw::core::StringView{"streamName"}, m_streamNames,
577 dw::core::StringView{"limits"}, m_limits,
578 dw::core::StringView{"connectPrios"}, m_connectPrios,
579 dw::core::StringView{"num-clients"}, m_localClientCount,
580 dw::core::StringView{"late-locs"}, m_lateLocs);
581 }
582
584
586
587 size_t getNumOutputs() const
588 {
589 static_assert(decltype(m_streamNames)::CAPACITY_AT_COMPILE_TIME < std::numeric_limits<size_t>::max(), "ChannelNvSciStreamParams: number of outputs over limit");
590 return m_streamNames.size();
591 }
592
593 size_t getLocalClientCount() const { return m_localClientCount; }
594
595 dw::core::span<ChannelPeerLocation const> getLateLocs() const
596 {
597 return dw::core::make_span<ChannelPeerLocation const>(m_lateLocs.data(), m_lateLocs.size());
598 }
599
600 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
601 ChannelStreamNameStr getStreamName(size_t index = 0U) const
602 {
603 if (index >= m_streamNames.size())
604 {
605 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: stream name index out of range");
606 }
607 return m_streamNames[index];
608 }
609
610 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
611 int64_t getLimiterMaxPackets(size_t index = 0U) const
612 {
613 // Note: if no limits are denoted, return -1 and make inquirers not create limiter blocks.
614 // If not, it can lead to out of range when querying
615 if (m_limits.empty())
616 {
617 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
618 return -1;
619 }
620
621 if (index >= m_limits.size())
622 {
623 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: limiter maxPackets index out of range");
624 }
625 return m_limits[index];
626 }
627
628 uint32_t getConnectPrio(size_t index = 0U) const
629 {
630 if (m_connectPrios.empty())
631 {
632 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
633 return 0U;
634 }
635
636 if (index >= m_connectPrios.size())
637 {
638 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelNvSciStreamParams: connect prio index out of range");
639 }
640 return m_connectPrios[index];
641 }
642
643protected:
644 dw::core::VectorFixed<ChannelStreamNameStr, MAX_CHANNEL_STREAM_NAMES> m_streamNames{};
645 dw::core::VectorFixed<uint32_t, MAX_CHANNEL_STREAM_NAMES> m_connectPrios{};
646 dw::core::VectorFixed<int64_t, MAX_CHANNEL_STREAM_NAMES> m_limits{};
647 dw::core::VectorFixed<ChannelPeerLocation, 32> m_lateLocs{};
649};
650
652{
653public:
654 ChannelFSIParams() = default;
655 explicit ChannelFSIParams(const char* params)
656 {
657 ChannelParamStr channelParams{params};
658 ParseAllChannelParameters(channelParams,
659 dw::core::StringView{"compat-vendor"}, m_compatVendor,
660 dw::core::StringView{"compat-app"}, m_compatApp,
661 dw::core::StringView{"num-channel"}, m_numChannel);
662 m_compat = m_compatVendor;
663 m_compat += dw::core::StringView{","};
664 m_compat += m_compatApp;
665 }
666
667 ChannelFSIParams(const ChannelFSIParams& other) = default;
668
670
671 const char* getCompat() const { return m_compat.c_str(); }
672 uint8_t getNumChannel() const { return m_numChannel; }
673
674private:
675 ChannelParamStr m_compat;
676 ChannelParamStr m_compatVendor;
677 ChannelParamStr m_compatApp;
678 uint8_t m_numChannel{0U};
679};
680
685{
686public:
687 explicit ChannelParams(const char* params)
688 {
689 m_str = params;
691 dw::core::StringView{"fifo-size"}, m_fifoSize,
692 dw::core::StringView{"id"}, m_id,
693 dw::core::StringView{"uid"}, m_uid,
694 dw::core::StringView{"connect-group-id"}, m_connectGroupID,
695 dw::core::StringView{"singleton-id"}, m_singletonId,
696 dw::core::StringView{"mode"}, m_mode,
697 dw::core::StringView{"reuse"}, m_reuseEnabled,
698 dw::core::StringView{"debug-port"}, m_debugPort,
699 dw::core::StringView{"num-clients"}, m_clientsCount,
700 dw::core::StringView{"debug-num-clients"}, m_debugClientsCount,
701 dw::core::StringView{"role"}, m_role,
702 dw::core::StringView{"type"}, m_type,
703 dw::core::StringView{"data-offset"}, m_dataOffset,
704 dw::core::StringView{"strict"}, m_strictFifo,
705 dw::core::StringView{"sync-enabled"}, m_syncEnabled,
706 dw::core::StringView{"name"}, m_name,
707 dw::core::StringView{"producer-fifo"}, m_producerFifo,
708 dw::core::StringView{"sync-object-id"}, m_syncObjectId);
709 adjustPoolCapacity();
710
711 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
712 if (0U == m_clientsCount)
713 {
714 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
715 m_clientsCount = 1U;
716 }
717
718 if (!m_singletonId.empty())
719 {
720 m_mode = ChannelMode::SINGLETON;
721 }
722
723 if (ChannelMode::MAILBOX == m_mode)
724 {
725 m_mailboxMode = true;
726 }
727 else if (ChannelMode::SINGLETON == m_mode)
728 {
729 m_singletonMode = true;
730
731 // Assign singletonId with id
732 if (!m_id.empty() && m_singletonId.empty())
733 {
734 m_singletonId = m_id;
735 }
736 }
737
738 // Why break this up like this? Code complexity.
739 // Without this, we fail the code complexity analysis.
740 ValidateMailbox();
741 ValidateSingleton();
742 setParameters(params);
743 }
744
745 ChannelParams(const ChannelParams& other) = default;
746
747 ChannelParams& operator=(const ChannelParams& other) = default;
748 ~ChannelParams() = default;
749
750 const char* getStr() const { return m_str.c_str(); }
751 ChannelParamStr getId() const { return m_id; }
752 ChannelParamStr getSingletonId() const { return m_singletonId; }
753 const ChannelParamStr& getSyncObjectId() const { return m_syncObjectId; }
754 uint16_t getDebugPort() const { return m_debugPort; }
755 bool hasProducerFifo() const { return m_producerFifo; }
756 size_t getFifoSize() const { return m_fifoSize; }
757 void setFifoSize(size_t fifoSize) { m_fifoSize = fifoSize; }
758 // Note(chale): Normally the fifo length governs whether a consumer
759 // will receive packet. The actual packet pool's size may be larger
760 // than the fifo length. non-strict mode allows consumers to receive
761 // up to the entire pool size instead of just their fifo length.
762 bool isStrictFifo() const { return m_strictFifo; }
763 void setStrictFifo(bool strictFifo)
764 {
765 m_strictFifo = strictFifo;
766 }
767 size_t getPoolCapacity() const { return m_poolCapacity; }
768 bool getMailboxMode() const { return m_mailboxMode; }
769 // Note (ajayawardane): The data-offset parameter is used to describe
770 // the consumption offset between the producer and the consumer
771 // in the sync packet use-case. For example, if a packet is produced with the
772 // sync count x, and is inteneded to be consumed when the sync count is x + 1,
773 // the data-offset would be 1. This parameter is also used to identify whether
774 // to use sync packets to transfer data, so needs to be included in both the
775 // producer and the consumer params.
776 uint32_t getDataOffset() const { return m_dataOffset; }
777 bool getSyncEnabled() const { return m_syncEnabled; }
778 void setMailboxMode(bool mailboxEnabled) { m_mailboxMode = mailboxEnabled; }
779 bool getSingletonMode() const { return m_singletonMode; }
780 bool getReuseEnabled() const { return m_reuseEnabled; }
781 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
782 bool getDebugMode() const { return m_debugPort > 0U; }
783 uint16_t getExpectedConnectionsCount() const { return m_clientsCount; }
784 uint16_t getExpectedDebugConnectionsCount() const { return m_debugClientsCount; }
785 ChannelRole getRole() const { return m_role; }
786 ChannelType getType() const { return m_type; }
787 uint32_t getUID() const { return m_uid; }
788 uint32_t getConnectGroupID() const { return m_connectGroupID; }
789
790 // coverity[autosar_cpp14_a2_10_5_violation]
791 ChannelParamStr getName() const { return m_name; }
792
794 {
795 if (ChannelType::SOCKET != m_type)
796 {
797 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getSocketParams: channel is not of type SOCKET");
798 }
799 return m_socketParams;
800 }
801
803 {
804 if (ChannelType::NVSCI != m_type && ChannelType::SHMEM_REMOTE != m_type)
805 {
806 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getNvSciStreamParams: channel is not of type NVSCI or SHMEM_REMOTE");
807 }
808 return m_nvSciStreamParams;
809 }
810
812 {
813 if (ChannelType::FSI != m_type)
814 {
815 throw ExceptionWithStatus(DW_CALL_NOT_ALLOWED, "ChannelParams: getFSIParams: channel is not of type FSI");
816 }
817 return m_fsiParams;
818 }
819
820private:
821 void ValidateMailbox()
822 {
823 if (m_singletonMode)
824 {
825 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
826 if (1U != m_fifoSize)
827 {
828 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton and mailbox modes are incompatible with a fifo setting other than 1");
829 }
830 }
831 if (!m_mailboxMode && m_reuseEnabled)
832 {
833 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: reuse=true specified when mode!=mailbox. Not valid");
834 }
835 }
836
837 void ValidateSingleton()
838 {
839 if (m_singletonMode && (ChannelType::SHMEM_LOCAL != m_type))
840 {
841 throw ExceptionWithStatus(DW_INVALID_ARGUMENT, "ChannelParams: Singleton mode is only valid for SHMEM_LOCAL channels");
842 }
843 }
844
845 void setParameters(const char* params)
846 {
847 switch (m_type)
848 {
850 break;
852 m_socketParams = ChannelSocketParams(params);
853 break;
856 m_nvSciStreamParams = ChannelNvSciStreamParams(params);
857 break;
858 case ChannelType::FSI:
859 m_fsiParams = ChannelFSIParams(params);
860 break;
862 case ChannelType::DDS:
863 default:
864 throw ExceptionWithStatus(DW_NOT_IMPLEMENTED, "ChannelParams: no parameters for channel type");
865 }
866 }
867
868 void adjustPoolCapacity()
869 {
870 // This deserves a comment. The LocalShmem pools (in the fifo-case)
871 // need the following number of slots, in the worst case:
872 // 1 for getImpl to return at any time
873 // 1 per consumer for in-flight data
874 // fifo-size to store a full fifo worth of packets
875 // So assuming max consumers, we'd need fifo-size + MAX_CHANNEL_CONSUMERS_COUNT + 1
876 // the fifo size isn't close to the maximum value of size_t, hence no risk of overflow
877 if (dw::core::safeAdd(m_fifoSize, MAX_CHANNEL_CONSUMERS_COUNT).value() >= m_poolCapacity)
878 {
879 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
880 m_poolCapacity = m_fifoSize + MAX_CHANNEL_CONSUMERS_COUNT + 1U;
881 }
882 }
883
884private:
885 ChannelParamStr m_str{};
886 ChannelParamStr m_id{};
887 ChannelParamStr m_singletonId{};
888 ChannelParamStr m_name{};
889 ChannelParamStr m_syncObjectId{};
890
891 // fifo size of the socket client that implies the maximum number of packets
892 // a client can hold simultaneously
893 size_t m_fifoSize{1U};
894 // This deserves a comment. The LocalShmem pools (in the fifo-case)
895 // need the following number of slots, in the worst case:
896 // 1 for getImpl to return at any time
897 // 1 per consumer for in-flight data
898 // fifo-size to store a full fifo worth of packets
899 // So assuming a fifo-size of 1 and max consumers, we'd need MAX_CHANNEL_CONSUMERS_COUNT + 2
900 size_t m_poolCapacity{MAX_CHANNEL_CONSUMERS_COUNT + 2U};
901 bool m_producerFifo{false};
903 uint32_t m_dataOffset{0U};
904 uint32_t m_uid{0U};
905 uint32_t m_connectGroupID{0U};
906 bool m_syncEnabled{false};
907 bool m_mailboxMode{false};
908 bool m_singletonMode{false};
909 bool m_reuseEnabled{false};
912 bool m_strictFifo{true};
913
914 uint16_t m_clientsCount{1U}; // number of clients for blocking mode for socket
915 uint16_t m_debugClientsCount{1U}; // number of debug clients for blocking mode for socket
916
917 uint16_t m_debugPort{0U};
918
919 ChannelSocketParams m_socketParams{};
920 ChannelNvSciStreamParams m_nvSciStreamParams{};
921 ChannelFSIParams m_fsiParams{};
922};
923
924} // namespace framework
925} // namespace dw
926
927#endif // DW_FRAMEWORK_CHANNEL_HPP_
ChannelFSIParams & operator=(const ChannelFSIParams &other)=default
ChannelFSIParams(const ChannelFSIParams &other)=default
uint32_t getConnectPrio(size_t index=0U) const
ChannelNvSciStreamParams & operator=(const ChannelNvSciStreamParams &other)=default
dw::core::VectorFixed< ChannelStreamNameStr, MAX_CHANNEL_STREAM_NAMES > m_streamNames
int64_t getLimiterMaxPackets(size_t index=0U) const
dw::core::VectorFixed< ChannelPeerLocation, 32 > m_lateLocs
dw::core::VectorFixed< uint32_t, MAX_CHANNEL_STREAM_NAMES > m_connectPrios
ChannelNvSciStreamParams(const ChannelNvSciStreamParams &other)=default
dw::core::span< ChannelPeerLocation const > getLateLocs() const
dw::core::VectorFixed< int64_t, MAX_CHANNEL_STREAM_NAMES > m_limits
ChannelStreamNameStr getStreamName(size_t index=0U) const
ChannelParams(const ChannelParams &other)=default
void setMailboxMode(bool mailboxEnabled)
uint16_t getExpectedConnectionsCount() const
uint16_t getExpectedDebugConnectionsCount() const
ChannelParams & operator=(const ChannelParams &other)=default
void setFifoSize(size_t fifoSize)
const ChannelSocketParams & getSocketParams() const
ChannelParamStr getName() const
const ChannelNvSciStreamParams & getNvSciStreamParams() const
const ChannelFSIParams & getFSIParams() const
ChannelParamStr getSingletonId() const
const ChannelParamStr & getSyncObjectId() const
void setStrictFifo(bool strictFifo)
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 constexpr uint16_t MAX_CHANNEL_STREAM_NAMES
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 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)
static void ParseChannelParameters(const ChannelParamStr &key, const ChannelParamStr &value, dw::core::StringView staticKey, T &result)
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
const char * ToParam(ChannelType channelType)
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:41