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