sACN  3.0.0
Implementation of ANSI E1.31 (Streaming ACN)
View other versions:
Loading...
Searching...
No Matches
source_detector.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright 2024 ETC Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 ******************************************************************************
16 * This file is a part of sACN. For more information, go to:
17 * https://github.com/ETCLabs/sACN
18 *****************************************************************************/
19
20#ifndef SACN_CPP_SOURCE_DETECTOR_H_
21#define SACN_CPP_SOURCE_DETECTOR_H_
22
28#include "sacn/cpp/common.h"
29
30#include <vector>
31
33#include "etcpal/cpp/inet.h"
34#include "etcpal/cpp/uuid.h"
35
42namespace sacn
43{
122{
123public:
129 {
130 public:
131 virtual ~NotifyHandler() = default;
132
148 virtual void HandleSourceUpdated(RemoteSourceHandle handle, const etcpal::Uuid& cid, const std::string& name,
149 const std::vector<uint16_t>& sourced_universes) = 0;
150
158 virtual void HandleSourceExpired(RemoteSourceHandle handle, const etcpal::Uuid& cid, const std::string& name) = 0;
159
178 };
179
184 struct Settings
185 {
186 /********* Required values **********/
187
188 /********* Optional values **********/
189
194
199
202
204 Settings() = default;
205 };
206
207 SourceDetector() = delete;
208
209 static etcpal::Error Startup(NotifyHandler& notify_handler, McastMode mcast_mode);
210 static etcpal::Error Startup(NotifyHandler& notify_handler, std::vector<SacnMcastInterface>& netints);
211 static etcpal::Error Startup(const Settings& settings, NotifyHandler& notify_handler, McastMode mcast_mode);
212 static etcpal::Error Startup(const Settings& settings, NotifyHandler& notify_handler,
214 static void Shutdown();
215 static etcpal::Error ResetNetworking(McastMode mcast_mode);
218
219private:
220 static SacnSourceDetectorConfig TranslateConfig(const Settings& settings, NotifyHandler& notify_handler);
221};
222
227namespace internal
228{
229extern "C" inline void SourceDetectorCbSourceUpdated(sacn_remote_source_t handle, const EtcPalUuid* cid,
230 const char* name, const uint16_t* sourced_universes,
231 size_t num_sourced_universes, void* context)
232{
233 if (context && cid && name)
234 {
235 std::vector<uint16_t> sourced_vec;
236 if (sourced_universes && (num_sourced_universes > 0))
237 sourced_vec.assign(sourced_universes, sourced_universes + num_sourced_universes);
238 static_cast<SourceDetector::NotifyHandler*>(context)->HandleSourceUpdated(handle, *cid, name, sourced_vec);
239 }
240}
241
242extern "C" inline void SourceDetectorCbSourceExpired(sacn_remote_source_t handle, const EtcPalUuid* cid,
243 const char* name, void* context)
244{
245 if (context && cid && name)
246 {
247 static_cast<SourceDetector::NotifyHandler*>(context)->HandleSourceExpired(handle, *cid, name);
248 }
249}
250
251extern "C" inline void SourceDetectorCbMemoryLimitExceeded(void* context)
252{
253 if (context)
254 {
255 static_cast<SourceDetector::NotifyHandler*>(context)->HandleMemoryLimitExceeded();
256 }
257}
258
259}; // namespace internal
260
284 McastMode mcast_mode = McastMode::kEnabledOnAllInterfaces)
285{
286 SacnSourceDetectorConfig config = TranslateConfig(Settings(), notify_handler);
287
288 SacnNetintConfig netint_config = SACN_NETINT_CONFIG_DEFAULT_INIT;
289 if (mcast_mode == McastMode::kDisabledOnAllInterfaces)
290 netint_config.no_netints = true;
291
292 return sacn_source_detector_create(&config, &netint_config);
293}
294
315{
316 return Startup(Settings(), notify_handler, netints);
317}
318
338inline etcpal::Error SourceDetector::Startup(const Settings& settings, NotifyHandler& notify_handler,
339 McastMode mcast_mode = McastMode::kEnabledOnAllInterfaces)
340{
341 SacnSourceDetectorConfig config = TranslateConfig(settings, notify_handler);
342
343 SacnNetintConfig netint_config = SACN_NETINT_CONFIG_DEFAULT_INIT;
344 if (mcast_mode == McastMode::kDisabledOnAllInterfaces)
345 netint_config.no_netints = true;
346
347 return sacn_source_detector_create(&config, &netint_config);
348}
349
367inline etcpal::Error SourceDetector::Startup(const Settings& settings, NotifyHandler& notify_handler,
369{
370 SacnSourceDetectorConfig config = TranslateConfig(settings, notify_handler);
371
372 if (netints.empty())
373 return sacn_source_detector_create(&config, NULL);
374
375 SacnNetintConfig netint_config = SACN_NETINT_CONFIG_DEFAULT_INIT;
376 netint_config.netints = netints.data();
377 netint_config.num_netints = netints.size();
378
379 return sacn_source_detector_create(&config, &netint_config);
380}
381
394
420inline etcpal::Error SourceDetector::ResetNetworking(McastMode mcast_mode = McastMode::kEnabledOnAllInterfaces)
421{
422 SacnNetintConfig netint_config = SACN_NETINT_CONFIG_DEFAULT_INIT;
423 if (mcast_mode == McastMode::kDisabledOnAllInterfaces)
424 netint_config.no_netints = true;
425
426 return sacn_source_detector_reset_networking(&netint_config);
427}
428
454{
455 if (sys_netints.empty())
456 {
458 }
459 else
460 {
461 SacnNetintConfig netint_config = SACN_NETINT_CONFIG_DEFAULT_INIT;
462 netint_config.netints = sys_netints.data();
463 netint_config.num_netints = sys_netints.size();
464
465 return sacn_source_detector_reset_networking(&netint_config);
466 }
467}
468
475{
476 // This uses a guessing algorithm with a while loop to avoid race conditions.
478 size_t size_guess = 4u;
479 size_t num_netints = 0u;
480
481 do
482 {
483 netints.resize(size_guess);
484 num_netints = sacn_source_detector_get_network_interfaces(netints.data(), netints.size());
485 size_guess = num_netints + 4u;
486 } while (num_netints > netints.size());
487
488 netints.resize(num_netints);
489 return netints;
490}
491
492inline SacnSourceDetectorConfig SourceDetector::TranslateConfig(const Settings& settings, NotifyHandler& notify_handler)
493{
494 // clang-format off
495 SacnSourceDetectorConfig config = {
496 {
497 internal::SourceDetectorCbSourceUpdated,
498 internal::SourceDetectorCbSourceExpired,
499 internal::SourceDetectorCbMemoryLimitExceeded,
500 &notify_handler
501 },
502 settings.source_count_max,
503 settings.universes_per_source_max,
504 settings.ip_supported
505 };
506 // clang-format on
507
508 return config;
509}
510
511}; // namespace sacn
512
513#endif // SACN_CPP_SOURCE_DETECTOR_H_
T assign(T... args)
A base class for a class that receives notification callbacks from a sACN Source Detector.
Definition source_detector.h:129
virtual void HandleSourceExpired(RemoteSourceHandle handle, const etcpal::Uuid &cid, const std::string &name)=0
Notify that a source is no longer transmitting Universe Discovery messages.
virtual void HandleMemoryLimitExceeded()
Notify that the module has run out of memory to track universes or sources.
Definition source_detector.h:177
virtual void HandleSourceUpdated(RemoteSourceHandle handle, const etcpal::Uuid &cid, const std::string &name, const std::vector< uint16_t > &sourced_universes)=0
Notify that a source is new or has changed.
An instance of sACN Source Detector functionality.
Definition source_detector.h:122
static etcpal::Error Startup(NotifyHandler &notify_handler, McastMode mcast_mode)
Start the sACN Source Detector with default settings.
Definition source_detector.h:283
static std::vector< EtcPalMcastNetintId > GetNetworkInterfaces()
Obtain the source detector's network interfaces.
Definition source_detector.h:474
static etcpal::Error ResetNetworking(McastMode mcast_mode)
Resets the underlying network sockets and packet receipt state for the sACN Source Detector.
Definition source_detector.h:420
static void Shutdown()
Destroy the sACN Source Detector.
Definition source_detector.h:390
C++ wrapper for the sACN init/deinit functions.
T data(T... args)
T empty(T... args)
sacn_ip_support_t
Definition common.h:71
uint16_t sacn_remote_source_t
Definition common.h:58
@ kSacnIpV4AndIpV6
Definition common.h:77
#define SACN_SOURCE_DETECTOR_INFINITE
Constant for "infinite" when listening for sources or universes on a source.
Definition source_detector.h:146
void sacn_source_detector_destroy()
Destroy the sACN Source Detector.
Definition source_detector.c:126
etcpal_error_t sacn_source_detector_reset_networking(const SacnNetintConfig *sys_netint_config)
Updates the source detector system network interfaces. Also resets the underlying network sockets for...
Definition source_detector.c:167
etcpal_error_t sacn_source_detector_create(const SacnSourceDetectorConfig *config, const SacnNetintConfig *netint_config)
Create the sACN Source Detector.
Definition source_detector.c:85
size_t sacn_source_detector_get_network_interfaces(EtcPalMcastNetintId *netints, size_t netints_size)
Obtain the source detector's network interfaces.
Definition source_detector.c:214
A namespace which contains all C++ language definitions in the sACN library.
Definition common.h:50
sacn_remote_source_t RemoteSourceHandle
Definition common.h:59
McastMode
Definition common.h:53
T resize(T... args)
T size(T... args)
sACN Source Detector API definitions
Definition common.h:102
bool no_netints
Definition common.h:110
size_t num_netints
Definition common.h:107
SacnMcastInterface * netints
Definition common.h:105
Definition source_detector.h:210
int source_count_max
Definition source_detector.h:219
A set of configuration settings that a source detector needs to initialize.
Definition source_detector.h:185
int universes_per_source_max
Definition source_detector.h:198
int source_count_max
Definition source_detector.h:193
sacn_ip_support_t ip_supported
Definition source_detector.h:201