RDMnet  0.3.0
Implementation of ANSI E1.33 (RDMnet)
View other versions:
controller.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2020 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 RDMnet. For more information, go to:
17  * https://github.com/ETCLabs/RDMnet
18  *****************************************************************************/
19 
22 
23 #ifndef RDMNET_CPP_CONTROLLER_H_
24 #define RDMNET_CPP_CONTROLLER_H_
25 
26 #include <algorithm>
27 #include <string>
28 #include <vector>
29 #include "etcpal/common.h"
30 #include "etcpal/cpp/error.h"
31 #include "etcpal/cpp/inet.h"
32 #include "etcpal/cpp/uuid.h"
33 #include "etcpal/cpp/log.h"
34 #include "rdm/cpp/uid.h"
35 #include "rdm/cpp/message.h"
36 #include "rdmnet/cpp/client.h"
37 #include "rdmnet/cpp/common.h"
38 #include "rdmnet/cpp/message.h"
39 #include "rdmnet/controller.h"
40 
41 namespace rdmnet
42 {
53 
59 {
60 public:
65 
71  {
72  public:
73  virtual ~NotifyHandler() = default;
74 
79  virtual void HandleConnectedToBroker(Handle controller_handle,
80  ScopeHandle scope_handle,
81  const ClientConnectedInfo& info) = 0;
82 
87  virtual void HandleBrokerConnectFailed(Handle controller_handle,
88  ScopeHandle scope_handle,
89  const ClientConnectFailedInfo& info) = 0;
90 
95  virtual void HandleDisconnectedFromBroker(Handle controller_handle,
96  ScopeHandle scope_handle,
97  const ClientDisconnectedInfo& info) = 0;
98 
105  virtual void HandleClientListUpdate(Handle controller_handle,
106  ScopeHandle scope_handle,
107  client_list_action_t list_action,
108  const RptClientList& list) = 0;
109 
114  virtual void HandleRdmResponse(Handle controller_handle, ScopeHandle scope_handle, const RdmResponse& resp) = 0;
115 
120  virtual void HandleRptStatus(Handle controller_handle, ScopeHandle scope_handle, const RptStatus& status) = 0;
121 
130  virtual void HandleResponderIdsReceived(Handle controller_handle,
131  ScopeHandle scope_handle,
132  const DynamicUidAssignmentList& list)
133  {
134  ETCPAL_UNUSED_ARG(controller_handle);
135  ETCPAL_UNUSED_ARG(scope_handle);
136  ETCPAL_UNUSED_ARG(list);
137  }
138  };
139 
145  {
146  public:
152  virtual RdmResponseAction HandleRdmCommand(Handle controller_handle,
153  ScopeHandle scope_handle,
154  const RdmCommand& cmd) = 0;
155 
160  virtual RdmResponseAction HandleLlrpRdmCommand(Handle controller_handle, const llrp::RdmCommand& cmd)
161  {
162  ETCPAL_UNUSED_ARG(controller_handle);
163  ETCPAL_UNUSED_ARG(cmd);
164  return rdmnet::RdmResponseAction::SendNack(kRdmNRActionNotSupported);
165  }
166  };
167 
170  struct Settings
171  {
173  rdm::Uid uid;
175 
177  bool create_llrp_target{false};
182 
184  Settings() = default;
185  Settings(const etcpal::Uuid& new_cid, const rdm::Uid& new_uid);
186  Settings(const etcpal::Uuid& new_cid, uint16_t manufacturer_id);
187 
188  bool IsValid() const;
189  };
190 
193  struct RdmData
194  {
197  uint16_t model_id{0};
200  uint32_t software_version_id{0};
203  uint16_t product_category{E120_PRODUCT_CATEGORY_CONTROL_CONTROLLER};
204 
209  bool device_label_settable{false};
210 
212  RdmData() = default;
213  RdmData(uint16_t new_model_id,
214  uint32_t new_software_version_id,
215  const char* new_manufacturer_label,
216  const char* new_device_model_description,
217  const char* new_software_version_label,
218  const char* new_device_label);
219  RdmData(uint16_t new_model_id,
220  uint32_t new_software_version_id,
221  const std::string& new_manufacturer_label,
222  const std::string& new_device_model_description,
223  const std::string& new_software_version_label,
224  const std::string& new_device_label);
225 
226  bool IsValid() const;
227  };
228 
229  Controller() = default;
230  Controller(const Controller& other) = delete;
231  Controller& operator=(const Controller& other) = delete;
232  Controller(Controller&& other) = default;
233  Controller& operator=(Controller&& other) = default;
234 
237  const Settings& settings,
238  RdmCommandHandler& rdm_handler,
239  uint8_t* rdm_response_buf = nullptr);
241 
243  const etcpal::SockAddr& static_broker_addr = etcpal::SockAddr{});
245  const etcpal::SockAddr& static_broker_addr = etcpal::SockAddr{});
246  etcpal::Expected<ScopeHandle> AddScope(const Scope& scope_config);
248  etcpal::Error RemoveScope(ScopeHandle scope_handle, rdmnet_disconnect_reason_t disconnect_reason);
250  const char* new_scope_id_str,
251  rdmnet_disconnect_reason_t disconnect_reason,
252  const etcpal::SockAddr& new_static_broker_addr = etcpal::SockAddr{});
254  const Scope& new_scope_config,
255  rdmnet_disconnect_reason_t disconnect_reason);
256  etcpal::Error ChangeSearchDomain(const char* new_search_domain, rdmnet_disconnect_reason_t disconnect_reason);
257 
259  const DestinationAddr& destination,
260  rdmnet_command_class_t command_class,
261  uint16_t param_id,
262  const uint8_t* data = nullptr,
263  uint8_t data_len = 0);
265  const DestinationAddr& destination,
266  uint16_t param_id,
267  const uint8_t* data = nullptr,
268  uint8_t data_len = 0);
270  const DestinationAddr& destination,
271  uint16_t param_id,
272  const uint8_t* data = nullptr,
273  uint8_t data_len = 0);
274 
276  etcpal::Error RequestResponderIds(ScopeHandle scope_handle, const rdm::Uid* uids, size_t num_uids);
278 
279  etcpal::Error SendRdmAck(ScopeHandle scope_handle,
280  const SavedRdmCommand& received_cmd,
281  const uint8_t* response_data = nullptr,
282  size_t response_data_len = 0);
284  const SavedRdmCommand& received_cmd,
285  rdm_nack_reason_t nack_reason);
286  etcpal::Error SendRdmNack(ScopeHandle scope_handle, const SavedRdmCommand& received_cmd, uint16_t raw_nack_reason);
288  uint16_t param_id,
289  const uint8_t* data = nullptr,
290  size_t data_len = 0);
291 
292  etcpal::Error SendLlrpAck(const llrp::SavedRdmCommand& received_cmd,
293  const uint8_t* response_data = nullptr,
294  uint8_t response_data_len = 0);
295  etcpal::Error SendLlrpNack(const llrp::SavedRdmCommand& received_cmd, rdm_nack_reason_t nack_reason);
296  etcpal::Error SendLlrpNack(const llrp::SavedRdmCommand& received_cmd, uint16_t raw_nack_reason);
297 
298  Handle handle() const;
299  const RdmData& rdm_data() const;
300  Controller::NotifyHandler* notify_handler() const;
301  Controller::RdmCommandHandler* rdm_command_handler() const;
302  etcpal::Expected<Scope> scope(ScopeHandle scope_handle) const;
303 
304  void UpdateRdmData(const RdmData& new_data);
305 
306 private:
307  Handle handle_{kInvalidHandle};
308  RdmData my_rdm_data_;
309 
310  RdmCommandHandler* rdm_cmd_handler_{nullptr};
311  NotifyHandler* notify_{nullptr};
312 };
313 
316 
317 namespace internal
318 {
319 extern "C" inline void ControllerLibCbConnected(rdmnet_controller_t controller_handle,
320  rdmnet_client_scope_t scope_handle,
321  const RdmnetClientConnectedInfo* info,
322  void* context)
323 {
324  if (info && context)
325  {
326  static_cast<Controller::NotifyHandler*>(context)->HandleConnectedToBroker(controller_handle, scope_handle, *info);
327  }
328 }
329 
330 extern "C" inline void ControllerLibCbConnectFailed(rdmnet_controller_t controller_handle,
331  rdmnet_client_scope_t scope_handle,
332  const RdmnetClientConnectFailedInfo* info,
333  void* context)
334 {
335  if (info && context)
336  {
337  static_cast<Controller::NotifyHandler*>(context)->HandleBrokerConnectFailed(controller_handle, scope_handle, *info);
338  }
339 }
340 
341 extern "C" inline void ControllerLibCbDisconnected(rdmnet_controller_t controller_handle,
342  rdmnet_client_scope_t scope_handle,
343  const RdmnetClientDisconnectedInfo* info,
344  void* context)
345 {
346  if (info && context)
347  {
348  static_cast<Controller::NotifyHandler*>(context)->HandleDisconnectedFromBroker(controller_handle, scope_handle,
349  *info);
350  }
351 }
352 
353 extern "C" inline void ControllerLibCbClientListUpdate(rdmnet_controller_t controller_handle,
354  rdmnet_client_scope_t scope_handle,
355  client_list_action_t list_action,
356  const RdmnetRptClientList* list,
357  void* context)
358 {
359  if (list && context)
360  {
361  static_cast<Controller::NotifyHandler*>(context)->HandleClientListUpdate(controller_handle, scope_handle,
362  list_action, *list);
363  }
364 }
365 
366 extern "C" inline void ControllerLibCbRdmResponseReceived(rdmnet_controller_t controller_handle,
367  rdmnet_client_scope_t scope_handle,
368  const RdmnetRdmResponse* resp,
369  void* context)
370 {
371  if (resp && context)
372  {
373  static_cast<Controller::NotifyHandler*>(context)->HandleRdmResponse(controller_handle, scope_handle, *resp);
374  }
375 }
376 
377 extern "C" inline void ControllerLibCbStatusReceived(rdmnet_controller_t controller_handle,
378  rdmnet_client_scope_t scope_handle,
379  const RdmnetRptStatus* status,
380  void* context)
381 {
382  if (status && context)
383  {
384  static_cast<Controller::NotifyHandler*>(context)->HandleRptStatus(controller_handle, scope_handle, *status);
385  }
386 }
387 
388 extern "C" inline void ControllerLibCbResponderIdsReceived(rdmnet_controller_t controller_handle,
389  rdmnet_client_scope_t scope_handle,
390  const RdmnetDynamicUidAssignmentList* list,
391  void* context)
392 {
393  if (list && context)
394  {
395  static_cast<Controller::NotifyHandler*>(context)->HandleResponderIdsReceived(controller_handle, scope_handle,
396  *list);
397  }
398 }
399 
400 extern "C" inline void ControllerLibCbRdmCommandReceived(rdmnet_controller_t controller_handle,
401  rdmnet_client_scope_t scope_handle,
402  const RdmnetRdmCommand* cmd,
403  RdmnetSyncRdmResponse* response,
404  void* context)
405 {
406  if (cmd && context)
407  {
408  *response = static_cast<Controller::RdmCommandHandler*>(context)
409  ->HandleRdmCommand(controller_handle, scope_handle, *cmd)
410  .get();
411  }
412 }
413 
414 extern "C" inline void ControllerLibCbLlrpRdmCommandReceived(rdmnet_controller_t controller_handle,
415  const LlrpRdmCommand* cmd,
416  RdmnetSyncRdmResponse* response,
417  void* context)
418 {
419  if (cmd && context)
420  {
421  *response =
422  static_cast<Controller::RdmCommandHandler*>(context)->HandleLlrpRdmCommand(controller_handle, *cmd).get();
423  }
424 }
425 
426 }; // namespace internal
427 
429 
432 inline Controller::Settings::Settings(const etcpal::Uuid& new_cid, const rdm::Uid& new_uid) : cid(new_cid), uid(new_uid)
433 {
434 }
435 
440 inline Controller::Settings::Settings(const etcpal::Uuid& new_cid, uint16_t manufacturer_id)
441  : cid(new_cid), uid(rdm::Uid::DynamicUidRequest(manufacturer_id))
442 {
443 }
444 
446 inline bool Controller::Settings::IsValid() const
447 {
448  return (!cid.IsNull() && (uid.IsStatic() || uid.IsDynamicUidRequest()));
449 }
450 
452 inline Controller::RdmData::RdmData(uint16_t new_model_id,
453  uint32_t new_software_version_id,
454  const char* new_manufacturer_label,
455  const char* new_device_model_description,
456  const char* new_software_version_label,
457  const char* new_device_label)
458  : model_id(new_model_id)
459  , software_version_id(new_software_version_id)
460  , manufacturer_label(new_manufacturer_label)
461  , device_model_description(new_device_model_description)
462  , software_version_label(new_software_version_label)
463  , device_label(new_device_label)
464 {
465 }
466 
468 inline Controller::RdmData::RdmData(uint16_t new_model_id,
469  uint32_t new_software_version_id,
470  const std::string& new_manufacturer_label,
471  const std::string& new_device_model_description,
472  const std::string& new_software_version_label,
473  const std::string& new_device_label)
474  : model_id(new_model_id)
475  , software_version_id(new_software_version_id)
476  , manufacturer_label(new_manufacturer_label)
477  , device_model_description(new_device_model_description)
478  , software_version_label(new_software_version_label)
479  , device_label(new_device_label)
480 {
481 }
482 
484 inline bool Controller::RdmData::IsValid() const
485 {
486  return ((!manufacturer_label.empty()) && (!device_model_description.empty()) && (!software_version_label.empty()) &&
487  (!device_label.empty()));
488 }
489 
502  const Settings& settings,
503  const RdmData& rdm_data)
504 {
505  if (!settings.IsValid() || !rdm_data.IsValid())
506  return kEtcPalErrInvalid;
507 
508  notify_ = &notify_handler;
509  my_rdm_data_ = rdm_data;
510 
511  // clang-format off
512  RdmnetControllerConfig config = {
513  settings.cid.get(), // CID
514  { // Callback shims
515  internal::ControllerLibCbConnected,
516  internal::ControllerLibCbConnectFailed,
517  internal::ControllerLibCbDisconnected,
518  internal::ControllerLibCbClientListUpdate,
519  internal::ControllerLibCbRdmResponseReceived,
520  internal::ControllerLibCbStatusReceived,
521  internal::ControllerLibCbResponderIdsReceived,
522  &notify_handler // Context
523  },
524  { // RDM command callback shims
525  nullptr, nullptr, nullptr, nullptr
526  },
527  { // RDM data
536  },
537  settings.uid.get(), // UID
538  settings.search_domain.c_str(), // Search domain
539  settings.create_llrp_target, // Create LLRP target
540  nullptr,
541  0
542  };
543  // clang-format on
544 
545  // LLRP network interfaces
546  if (!settings.llrp_netints.empty())
547  {
548  config.llrp_netints = settings.llrp_netints.data();
549  config.num_llrp_netints = settings.llrp_netints.size();
550  }
551 
552  return rdmnet_controller_create(&config, &handle_);
553 }
554 
570  const Settings& settings,
571  RdmCommandHandler& rdm_handler,
572  uint8_t* rdm_response_buf)
573 {
574  if (!settings.IsValid())
575  return kEtcPalErrInvalid;
576 
577  notify_ = &notify_handler;
578  rdm_cmd_handler_ = &rdm_handler;
579 
580  // clang-format off
581  RdmnetControllerConfig config = {
582  settings.cid.get(), // CID
583  { // Callback shims
584  internal::ControllerLibCbConnected,
585  internal::ControllerLibCbConnectFailed,
586  internal::ControllerLibCbDisconnected,
587  internal::ControllerLibCbClientListUpdate,
588  internal::ControllerLibCbRdmResponseReceived,
589  internal::ControllerLibCbStatusReceived,
590  internal::ControllerLibCbResponderIdsReceived,
591  &notify_handler // Context
592  },
593  { // RDM command callback shims
594  internal::ControllerLibCbRdmCommandReceived,
595  internal::ControllerLibCbLlrpRdmCommandReceived,
596  rdm_response_buf,
597  &rdm_handler // Context
598  },
600  settings.uid.get(), // UID
601  settings.search_domain.c_str(), // Search domain
602  settings.create_llrp_target, // Create LLRP target
603  nullptr,
604  0
605  };
606  // clang-format on
607 
608  // LLRP network interfaces
609  if (!settings.llrp_netints.empty())
610  {
611  config.llrp_netints = settings.llrp_netints.data();
612  config.num_llrp_netints = settings.llrp_netints.size();
613  }
614 
615  return rdmnet_controller_create(&config, &handle_);
616 }
617 
624 inline void Controller::Shutdown(rdmnet_disconnect_reason_t disconnect_reason)
625 {
626  rdmnet_controller_destroy(handle_, disconnect_reason);
627  handle_ = kInvalidHandle;
628 }
629 
641 inline etcpal::Expected<ScopeHandle> Controller::AddScope(const char* id, const etcpal::SockAddr& static_broker_addr)
642 {
643  RdmnetScopeConfig scope_config = {id, static_broker_addr.get()};
644  rdmnet_client_scope_t scope_handle;
645  auto result = rdmnet_controller_add_scope(handle_, &scope_config, &scope_handle);
646  if (result == kEtcPalErrOk)
647  return scope_handle;
648  else
649  return result;
650 }
651 
664  const etcpal::SockAddr& static_broker_addr)
665 {
666  return AddScope(id.c_str(), static_broker_addr);
667 }
668 
679 {
680  return AddScope(scope_config.id_string().c_str(), scope_config.static_broker_addr());
681 }
682 
693 {
694  return AddScope(E133_DEFAULT_SCOPE, static_broker_addr);
695 }
696 
706 {
707  return rdmnet_controller_remove_scope(handle_, scope_handle, disconnect_reason);
708 }
709 
726  const char* new_scope_id_str,
727  rdmnet_disconnect_reason_t disconnect_reason,
728  const etcpal::SockAddr& new_static_broker_addr)
729 {
730  RdmnetScopeConfig new_scope_config = {new_scope_id_str, new_static_broker_addr.get()};
731  return rdmnet_controller_change_scope(handle_, scope_handle, &new_scope_config, disconnect_reason);
732 }
733 
748  const Scope& new_scope_config,
749  rdmnet_disconnect_reason_t disconnect_reason)
750 {
751  return ChangeScope(scope_handle, new_scope_config.id_string().c_str(), disconnect_reason,
752  new_scope_config.static_broker_addr());
753 }
754 
767 inline etcpal::Error Controller::ChangeSearchDomain(const char* new_search_domain,
768  rdmnet_disconnect_reason_t disconnect_reason)
769 {
770  return rdmnet_controller_change_search_domain(handle_, new_search_domain, disconnect_reason);
771 }
772 
786  const DestinationAddr& destination,
787  rdmnet_command_class_t command_class,
788  uint16_t param_id,
789  const uint8_t* data,
790  uint8_t data_len)
791 {
792  uint32_t seq_num;
793  etcpal_error_t res = rdmnet_controller_send_rdm_command(handle_, scope_handle, &destination.get(), command_class,
794  param_id, data, data_len, &seq_num);
795  if (res == kEtcPalErrOk)
796  return seq_num;
797  else
798  return res;
799 }
800 
813  const DestinationAddr& destination,
814  uint16_t param_id,
815  const uint8_t* data,
816  uint8_t data_len)
817 {
818  uint32_t seq_num;
819  etcpal_error_t res =
820  rdmnet_controller_send_get_command(handle_, scope_handle, &destination.get(), param_id, data, data_len, &seq_num);
821  if (res == kEtcPalErrOk)
822  return seq_num;
823  else
824  return res;
825 }
826 
839  const DestinationAddr& destination,
840  uint16_t param_id,
841  const uint8_t* data,
842  uint8_t data_len)
843 {
844  uint32_t seq_num;
845  etcpal_error_t res =
846  rdmnet_controller_send_set_command(handle_, scope_handle, &destination.get(), param_id, data, data_len, &seq_num);
847  if (res == kEtcPalErrOk)
848  return seq_num;
849  else
850  return res;
851 }
852 
862 {
863  return rdmnet_controller_request_client_list(handle_, scope_handle);
864 }
865 
876 inline etcpal::Error Controller::RequestResponderIds(ScopeHandle scope_handle, const rdm::Uid* uids, size_t num_uids)
877 {
878  if (num_uids == 0)
879  return kEtcPalErrInvalid;
880 
881  std::vector<RdmUid> c_uids;
882  c_uids.reserve(num_uids);
883  std::transform(uids, uids + num_uids, std::back_inserter(c_uids), [](const rdm::Uid& uid) { return uid.get(); });
884  return rdmnet_controller_request_responder_ids(handle_, scope_handle, c_uids.data(), c_uids.size());
885 }
886 
897 {
898  return RequestResponderIds(scope_handle, uids.data(), uids.size());
899 }
900 
913  const SavedRdmCommand& received_cmd,
914  const uint8_t* response_data,
915  size_t response_data_len)
916 {
917  return rdmnet_controller_send_rdm_ack(handle_, scope_handle, &received_cmd.get(), response_data, response_data_len);
918 }
919 
931  const SavedRdmCommand& received_cmd,
932  rdm_nack_reason_t nack_reason)
933 {
934  return rdmnet_controller_send_rdm_nack(handle_, scope_handle, &received_cmd.get(), nack_reason);
935 }
936 
949  const SavedRdmCommand& received_cmd,
950  uint16_t raw_nack_reason)
951 {
952  return rdmnet_controller_send_rdm_nack(handle_, scope_handle, &received_cmd.get(),
953  static_cast<rdm_nack_reason_t>(raw_nack_reason));
954 }
955 
968  uint16_t param_id,
969  const uint8_t* data,
970  size_t data_len)
971 {
972  return rdmnet_controller_send_rdm_update(handle_, scope_handle, 0, param_id, data, data_len);
973 }
974 
986  const uint8_t* response_data,
987  uint8_t response_data_len)
988 {
989  return rdmnet_controller_send_llrp_ack(handle_, &received_cmd.get(), response_data, response_data_len);
990 }
991 
1001 inline etcpal::Error Controller::SendLlrpNack(const llrp::SavedRdmCommand& received_cmd, rdm_nack_reason_t nack_reason)
1002 {
1003  return rdmnet_controller_send_llrp_nack(handle_, &received_cmd.get(), nack_reason);
1004 }
1005 
1016 inline etcpal::Error Controller::SendLlrpNack(const llrp::SavedRdmCommand& received_cmd, uint16_t raw_nack_reason)
1017 {
1018  return rdmnet_controller_send_llrp_nack(handle_, &received_cmd.get(),
1019  static_cast<rdm_nack_reason_t>(raw_nack_reason));
1020 }
1021 
1024 {
1025  return handle_;
1026 }
1027 
1031 {
1032  return my_rdm_data_;
1033 }
1034 
1037 {
1038  return notify_;
1039 }
1040 
1044 {
1045  return rdm_cmd_handler_;
1046 }
1047 
1053 {
1054  std::string scope_id(E133_SCOPE_STRING_PADDED_LENGTH, 0);
1055  EtcPalSockAddr static_broker_addr;
1056  etcpal_error_t res = rdmnet_controller_get_scope(handle_, scope_handle, &scope_id[0], &static_broker_addr);
1057 
1058  if (res == kEtcPalErrOk)
1059  return Scope(scope_id, static_broker_addr);
1060  else
1061  return res;
1062 }
1063 
1065 inline void Controller::UpdateRdmData(const RdmData& new_data)
1066 {
1067  // TODO implement
1068  ETCPAL_UNUSED_ARG(new_data);
1069 }
1070 
1071 }; // namespace rdmnet
1072 
1073 #endif // RDMNET_CPP_CONTROLLER_H_
T back_inserter(T... args)
T c_str(T... args)
constexpr const EtcPalSockAddr & get() const noexcept
constexpr const EtcPalUuid & get() const noexcept
Information about a failed connection to a broker delivered to an RDMnet callback function.
Definition: client.h:219
Information about a successful connection to a broker delivered to an RDMnet callback function.
Definition: client.h:149
Information about a disconnect event from a broker delivered to an RDMnet callback function.
Definition: client.h:337
A base class for a class that receives notification callbacks from a controller.
Definition: controller.h:71
virtual void HandleBrokerConnectFailed(Handle controller_handle, ScopeHandle scope_handle, const ClientConnectFailedInfo &info)=0
A connection attempt failed between a controller and a broker.
virtual void HandleRdmResponse(Handle controller_handle, ScopeHandle scope_handle, const RdmResponse &resp)=0
An RDM response has been received.
virtual void HandleClientListUpdate(Handle controller_handle, ScopeHandle scope_handle, client_list_action_t list_action, const RptClientList &list)=0
A client list update has been received from a broker.
virtual void HandleRptStatus(Handle controller_handle, ScopeHandle scope_handle, const RptStatus &status)=0
An RPT status message has been received in response to a previously-sent RDM command.
virtual void HandleConnectedToBroker(Handle controller_handle, ScopeHandle scope_handle, const ClientConnectedInfo &info)=0
A controller has successfully connected to a broker.
virtual void HandleDisconnectedFromBroker(Handle controller_handle, ScopeHandle scope_handle, const ClientDisconnectedInfo &info)=0
A controller which was previously connected to a broker has disconnected.
virtual void HandleResponderIdsReceived(Handle controller_handle, ScopeHandle scope_handle, const DynamicUidAssignmentList &list)
A set of previously-requested mappings of dynamic UIDs to responder IDs has been received.
Definition: controller.h:130
A base class for a class that receives RDM commands addressed to a controller.
Definition: controller.h:145
virtual RdmResponseAction HandleRdmCommand(Handle controller_handle, ScopeHandle scope_handle, const RdmCommand &cmd)=0
An RDM command has been received addressed to a controller.
virtual RdmResponseAction HandleLlrpRdmCommand(Handle controller_handle, const llrp::RdmCommand &cmd)
An RDM command has been received over LLRP, addressed to a controller.
Definition: controller.h:160
An instance of RDMnet controller functionality.
Definition: controller.h:59
etcpal::Error SendRdmAck(ScopeHandle scope_handle, const SavedRdmCommand &received_cmd, const uint8_t *response_data=nullptr, size_t response_data_len=0)
Send an acknowledge (ACK) response to an RDM command received by a controller.
Definition: controller.h:912
void Shutdown(rdmnet_disconnect_reason_t disconnect_reason=kRdmnetDisconnectShutdown)
Shut down this controller and deallocate resources.
Definition: controller.h:624
etcpal::Expected< uint32_t > SendGetCommand(ScopeHandle scope_handle, const DestinationAddr &destination, uint16_t param_id, const uint8_t *data=nullptr, uint8_t data_len=0)
Send an RDM GET command from a controller on a scope.
Definition: controller.h:812
etcpal::Error Startup(NotifyHandler &notify_handler, const Settings &settings, const RdmData &rdm_data)
Allocate resources and start up this controller with the given configuration.
Definition: controller.h:501
etcpal::Error ChangeSearchDomain(const char *new_search_domain, rdmnet_disconnect_reason_t disconnect_reason)
Change the controller's DNS search domain.
Definition: controller.h:767
etcpal::Error SendRdmUpdate(ScopeHandle scope_handle, uint16_t param_id, const uint8_t *data=nullptr, size_t data_len=0)
Send an asynchronous RDM GET response to update the value of a local parameter.
Definition: controller.h:967
etcpal::Error SendLlrpNack(const llrp::SavedRdmCommand &received_cmd, rdm_nack_reason_t nack_reason)
Send a negative acknowledge (NACK) response to an LLRP RDM command received by a controller.
Definition: controller.h:1001
etcpal::Error RequestClientList(ScopeHandle scope_handle)
Request a client list from a broker.
Definition: controller.h:861
etcpal::Error SendRdmNack(ScopeHandle scope_handle, const SavedRdmCommand &received_cmd, rdm_nack_reason_t nack_reason)
Send a negative acknowledge (NACK) response to an RDM command received by a controller.
Definition: controller.h:930
Handle handle() const
Retrieve the handle of a controller instance.
Definition: controller.h:1023
rdmnet_controller_t Handle
A handle type used by the RDMnet library to identify controller instances.
Definition: controller.h:62
Controller & operator=(Controller &&other)=default
Move a controller instance.
etcpal::Expected< ScopeHandle > AddDefaultScope(const etcpal::SockAddr &static_broker_addr=etcpal::SockAddr{})
Shortcut to add the default RDMnet scope to a controller instance.
Definition: controller.h:692
etcpal::Expected< ScopeHandle > AddScope(const char *id, const etcpal::SockAddr &static_broker_addr=etcpal::SockAddr{})
Add a new scope to this controller instance.
Definition: controller.h:641
etcpal::Error RemoveScope(ScopeHandle scope_handle, rdmnet_disconnect_reason_t disconnect_reason)
Remove a previously-added scope from this controller instance.
Definition: controller.h:705
etcpal::Expected< uint32_t > SendSetCommand(ScopeHandle scope_handle, const DestinationAddr &destination, uint16_t param_id, const uint8_t *data=nullptr, uint8_t data_len=0)
Send an RDM SET command from a controller on a scope.
Definition: controller.h:838
const RdmData & rdm_data() const
Retrieve the RDM data that this controller was configured with on startup.
Definition: controller.h:1030
void UpdateRdmData(const RdmData &new_data)
Update the data used to identify this controller to other controllers.
Definition: controller.h:1065
Controller::NotifyHandler * notify_handler() const
Retrieve the Controller::NotifyHandler reference that this controller was configured with.
Definition: controller.h:1036
etcpal::Error SendLlrpAck(const llrp::SavedRdmCommand &received_cmd, const uint8_t *response_data=nullptr, uint8_t response_data_len=0)
Send an acknowledge (ACK) response to an LLRP RDM command received by a controller.
Definition: controller.h:985
etcpal::Error RequestResponderIds(ScopeHandle scope_handle, const rdm::Uid *uids, size_t num_uids)
Request mappings from dynamic UIDs to Responder IDs (RIDs).
Definition: controller.h:876
etcpal::Error ChangeScope(ScopeHandle scope_handle, const char *new_scope_id_str, rdmnet_disconnect_reason_t disconnect_reason, const etcpal::SockAddr &new_static_broker_addr=etcpal::SockAddr{})
Change the configuration of a scope on a controller.
Definition: controller.h:725
Controller(Controller &&other)=default
Move a controller instance.
etcpal::Expected< Scope > scope(ScopeHandle scope_handle) const
Retrieve the scope configuration associated with a given scope handle.
Definition: controller.h:1052
static constexpr Handle kInvalidHandle
An invalid Handle value.
Definition: controller.h:64
Controller::RdmCommandHandler * rdm_command_handler() const
Retrieve the Controller::RdmCommandHandler reference that this controller was configured with.
Definition: controller.h:1043
etcpal::Expected< uint32_t > SendRdmCommand(ScopeHandle scope_handle, const DestinationAddr &destination, rdmnet_command_class_t command_class, uint16_t param_id, const uint8_t *data=nullptr, uint8_t data_len=0)
Send an RDM command from a controller on a scope.
Definition: controller.h:785
A destination address for an RDM command in RDMnet's RPT protocol.
Definition: client.h:70
constexpr const RdmnetDestinationAddr & get() const noexcept
Get a const reference to the underlying C type.
Definition: client.h:130
A list of mappings from dynamic UIDs to responder IDs received from an RDMnet broker.
Definition: dynamic_uid.h:98
An RDM command received over RDMnet and delivered to an RDMnet callback function.
Definition: rdm_command.h:43
A class representing a synchronous action to take in response to a received RDM command.
Definition: common.h:106
static RdmResponseAction SendNack(rdm_nack_reason_t nack_reason)
Send an RDM NACK with a reason code.
Definition: common.h:131
An RDM response received over RDMnet and delivered to an RDMnet callback function.
Definition: rdm_response.h:47
A list of RPT client entries.
Definition: rpt_client.h:88
An RPT status message received over RDMnet and delivered to an RDMnet callback function.
Definition: rpt_status.h:42
An RDM command received over RDMnet by a local component and saved for a later response.
Definition: rdm_command.h:87
ETCPAL_CONSTEXPR_14 RdmnetSavedRdmCommand & get() noexcept
Get a mutable reference to the underlying C type.
Definition: rdm_command.h:374
An RDMnet scope configuration.
Definition: client.h:460
const etcpal::SockAddr & static_broker_addr() const noexcept
The static broker address associated with this scope.
Definition: client.h:515
const std::string & id_string() const noexcept
The ID string of this scope.
Definition: client.h:506
An RDM command received over LLRP and delivered to an RDMnet callback function.
Definition: llrp_rdm_command.h:46
An RDM command received over LLRP by a local component and saved for a later response.
Definition: llrp_rdm_command.h:91
ETCPAL_CONSTEXPR_14 LlrpSavedRdmCommand & get() noexcept
Get a mutable reference to the underlying C type.
Definition: llrp_rdm_command.h:391
Definitions for the RDMnet Controller API.
C++ wrapper for RDMnet client API definitions.
C++ wrapper for the RDMnet init/deinit functions.
RDMnet C++ message type definitions.
T data(T... args)
T empty(T... args)
etcpal_error_t
kEtcPalErrInvalid
kEtcPalErrOk
rdmnet_disconnect_reason_t
Disconnect reason defines for the BrokerDisconnectMsg.
Definition: common.h:85
rdmnet_command_class_t
An RDM command class, for RDMnet purposes.
Definition: common.h:350
client_list_action_t
How to apply the client entries to the existing client list in a client_list_update_received callback...
Definition: client.h:50
int rdmnet_client_scope_t
A handle to a scope that an RDMnet client participates in.
Definition: client.h:41
@ kRdmnetDisconnectShutdown
The remote component is shutting down.
Definition: common.h:87
etcpal_error_t rdmnet_controller_change_scope(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetScopeConfig *new_scope_config, rdmnet_disconnect_reason_t disconnect_reason)
Change the configuration of a scope on a controller.
Definition: controller.c:412
etcpal_error_t rdmnet_controller_create(const RdmnetControllerConfig *config, rdmnet_controller_t *handle)
Create a new instance of RDMnet controller functionality.
Definition: controller.c:249
etcpal_error_t rdmnet_controller_send_llrp_ack(rdmnet_controller_t controller_handle, const LlrpSavedRdmCommand *received_cmd, const uint8_t *response_data, uint8_t response_data_len)
Send an LLRP RDM ACK response from a controller.
Definition: controller.c:788
etcpal_error_t rdmnet_controller_send_rdm_ack(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetSavedRdmCommand *received_cmd, const uint8_t *response_data, size_t response_data_len)
Send an RDM ACK response from a controller on a scope.
Definition: controller.c:690
etcpal_error_t rdmnet_controller_send_rdm_update(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, uint16_t subdevice, uint16_t param_id, const uint8_t *data, size_t data_len)
Send an asynchronous RDM GET response to update the value of a local parameter.
Definition: controller.c:758
etcpal_error_t rdmnet_controller_add_scope(rdmnet_controller_t controller_handle, const RdmnetScopeConfig *scope_config, rdmnet_client_scope_t *scope_handle)
Add a new scope to a controller instance.
Definition: controller.c:321
etcpal_error_t rdmnet_controller_destroy(rdmnet_controller_t controller_handle, rdmnet_disconnect_reason_t reason)
Destroy a controller instance.
Definition: controller.c:287
etcpal_error_t rdmnet_controller_send_set_command(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetDestinationAddr *destination, uint16_t param_id, const uint8_t *data, uint8_t data_len, uint32_t *seq_num)
Send an RDM SET command from a controller on a scope.
Definition: controller.c:653
etcpal_error_t rdmnet_controller_request_client_list(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle)
Request a client list from a broker.
Definition: controller.c:503
#define RDMNET_CONTROLLER_INVALID
An invalid RDMnet controller handle value.
Definition: controller.h:56
etcpal_error_t rdmnet_controller_send_get_command(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetDestinationAddr *destination, uint16_t param_id, const uint8_t *data, uint8_t data_len, uint32_t *seq_num)
Send an RDM GET command from a controller on a scope.
Definition: controller.c:612
etcpal_error_t rdmnet_controller_request_responder_ids(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmUid *uids, size_t num_uids)
Request a set of responder IDs corresponding with dynamic responder UIDs from a broker.
Definition: controller.c:532
etcpal_error_t rdmnet_controller_change_search_domain(rdmnet_controller_t controller_handle, const char *new_search_domain, rdmnet_disconnect_reason_t disconnect_reason)
Change the controller's DNS search domain.
Definition: controller.c:475
etcpal_error_t rdmnet_controller_get_scope(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, char *scope_str_buf, EtcPalSockAddr *static_broker_addr)
Retrieve the scope configuration of a previously-added scope.
Definition: controller.c:444
etcpal_error_t rdmnet_controller_send_rdm_command(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetDestinationAddr *destination, rdmnet_command_class_t command_class, uint16_t param_id, const uint8_t *data, uint8_t data_len, uint32_t *seq_num)
Send an RDM command from a controller on a scope.
Definition: controller.c:570
etcpal_error_t rdmnet_controller_send_rdm_nack(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, const RdmnetSavedRdmCommand *received_cmd, rdm_nack_reason_t nack_reason)
Send an RDM NACK response from a controller on a scope.
Definition: controller.c:723
etcpal_error_t rdmnet_controller_remove_scope(rdmnet_controller_t controller_handle, rdmnet_client_scope_t scope_handle, rdmnet_disconnect_reason_t reason)
Remove a previously-added scope from a controller instance.
Definition: controller.c:381
etcpal_error_t rdmnet_controller_send_llrp_nack(rdmnet_controller_t controller_handle, const LlrpSavedRdmCommand *received_cmd, rdm_nack_reason_t nack_reason)
Send an LLRP RDM NACK response from a controller.
Definition: controller.c:815
#define RDMNET_CONTROLLER_RDM_DATA_DEFAULT_INIT
A default-value initializer for an RdmnetControllerRdmData struct.
Definition: controller.h:259
int rdmnet_controller_t
A handle to an RDMnet controller.
Definition: controller.h:54
rdmnet_client_scope_t ScopeHandle
A handle to a scope that an RDMnet client participates in.
Definition: client.h:447
T internal(T... args)
A namespace which contains all C++ language definitions in the RDMnet library.
Definition: broker.h:45
T reserve(T... args)
T size(T... args)
An RDM command received from a remote LLRP Manager.
Definition: message.h:439
Information provided by the library about an unsuccessful RDMnet client connection.
Definition: client.h:164
Information provided by the library about a successful RDMnet client connection.
Definition: client.h:151
Information provided by the library about an RDMnet client connection that disconnected after a succe...
Definition: client.h:196
A set of information that defines the startup parameters of an RDMnet Controller.
Definition: controller.h:266
size_t num_llrp_netints
(optional) The size of the llrp_netints array.
Definition: controller.h:315
const RdmnetMcastNetintId * llrp_netints
(optional) A set of network interfaces to use for the LLRP target associated with this controller.
Definition: controller.h:313
A list of mappings from dynamic UIDs to responder IDs received from an RDMnet broker.
Definition: message.h:245
An RDMnet RDM command received by this component.
Definition: message.h:53
An RDMnet RDM response received by a local component.
Definition: message.h:90
A structure that represents a list of RPT Client Entries.
Definition: message.h:398
An RDMnet RPT status message received by a local component.
Definition: message.h:193
A set of configuration information for a single scope in which an RDMnet client is participating.
Definition: client.h:224
This structure should not be manipulated directly - use the macros to access it:
Definition: common.h:214
A set of initial identifying RDM data to use for a controller.
Definition: controller.h:194
bool IsValid() const
Whether this data is valid (all string members are non-empty).
Definition: controller.h:484
uint16_t product_category
A number representing the product's primary function.
Definition: controller.h:203
uint16_t model_id
A number representing the product model which implements the controller.
Definition: controller.h:197
bool device_label_settable
Whether the library should allow device_label to be changed remotely.
Definition: controller.h:209
std::string device_model_description
The name of the product model which implements the controller.
Definition: controller.h:206
uint32_t software_version_id
A number representing the version of the controller software.
Definition: controller.h:200
std::string manufacturer_label
The manufacturer name of the controller.
Definition: controller.h:205
std::string device_label
A user-settable name for this controller instance.
Definition: controller.h:208
std::string software_version_label
The software version of the controller as a string.
Definition: controller.h:207
RdmData()=default
Create an empty, invalid structure by default - must be filled in before passing to Controller::Start...
A set of configuration settings that a controller needs to initialize.
Definition: controller.h:171
std::vector< RdmnetMcastNetintId > llrp_netints
(optional) A set of network interfaces to use for the LLRP target associated with this controller.
Definition: controller.h:181
bool create_llrp_target
(optional) Whether to create an LLRP target associated with this controller.
Definition: controller.h:177
etcpal::Uuid cid
The controller's Component Identifier (CID).
Definition: controller.h:172
rdm::Uid uid
The controller's RDM UID. For a dynamic UID, use rdm::Uid::DynamicUidRequest().
Definition: controller.h:173
bool IsValid() const
Determine whether a controller Settings instance contains valid data for RDMnet operation.
Definition: controller.h:446
Settings()=default
Create an empty, invalid data structure by default.
std::string search_domain
(optional) The controller's search domain for discovering brokers.
Definition: controller.h:174
T transform(T... args)