Open Lighting Architecture  0.10.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
RDMCommand.h
Go to the documentation of this file.
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15  *
16  * RDMCommand.h
17  * All the classes that represent RDM commands.
18  * Copyright (C) 2005 Simon Newton
19  */
20 
21 
30 #ifndef INCLUDE_OLA_RDM_RDMCOMMAND_H_
31 #define INCLUDE_OLA_RDM_RDMCOMMAND_H_
32 
33 #include <stdint.h>
34 #include <ola/base/Macro.h>
35 #include <ola/io/ByteString.h>
36 #include <ola/io/OutputStream.h>
37 #include <ola/rdm/CommandPrinter.h>
38 #include <ola/rdm/RDMEnums.h>
39 #include <ola/rdm/RDMPacket.h>
40 #include <ola/rdm/RDMResponseCodes.h>
41 #include <ola/rdm/UID.h>
42 #include <sstream>
43 #include <string>
44 
45 namespace ola {
46 namespace rdm {
47 
59 class RDMCommand {
60  public:
65  // TODO(simon): remove this in favor of the new one in RDMEnums.h
66  typedef enum {
69  GET_COMMAND = 0x20,
71  SET_COMMAND = 0x30,
73  INVALID_COMMAND = 0xff,
75 
76  virtual ~RDMCommand();
77 
89  std::string ToString() const;
90 
97  friend std::ostream& operator<<(std::ostream &out,
98  const RDMCommand &command) {
99  return out << command.ToString();
100  }
101 
110  virtual uint8_t SubStartCode() const { return SUB_START_CODE; }
111 
113  virtual uint8_t MessageLength() const;
114 
116  const UID& SourceUID() const { return m_source; }
117 
119  const UID& DestinationUID() const { return m_destination; }
120 
122  uint8_t TransactionNumber() const { return m_transaction_number; }
123 
125  uint8_t PortIdResponseType() const { return m_port_id; }
126 
128  uint8_t MessageCount() const { return m_message_count; }
129 
131  uint16_t SubDevice() const { return m_sub_device; }
132 
134  virtual RDMCommandClass CommandClass() const = 0;
135 
137  uint16_t ParamId() const { return m_param_id; }
138 
140  unsigned int ParamDataSize() const { return m_data_length; }
141 
143  const uint8_t *ParamData() const { return m_data; }
144 
154  virtual uint16_t Checksum(uint16_t checksum) const { return checksum; }
155 
163  virtual void Print(CommandPrinter *printer,
164  bool summarize,
165  bool unpack_param_data) const {
166  printer->Print(this, summarize, unpack_param_data);
167  }
168 
174  bool operator==(const RDMCommand &other) const;
175 
179  static const uint8_t START_CODE = 0xcc;
180 
187  static RDMCommand *Inflate(const uint8_t *data, unsigned int length);
188 
189  protected:
190  uint8_t m_port_id;
191  UID m_source;
192  UID m_destination;
193  uint8_t m_transaction_number;
194 
198  RDMCommand(const UID &source,
199  const UID &destination,
200  uint8_t transaction_number,
201  uint8_t port_id,
202  uint8_t message_count,
203  uint16_t sub_device,
204  uint16_t param_id,
205  const uint8_t *data,
206  unsigned int length);
207 
208  void SetParamData(const uint8_t *data, unsigned int length);
209 
210  static RDMStatusCode VerifyData(const uint8_t *data,
211  size_t length,
212  RDMCommandHeader *command_message);
213 
214  static RDMCommandClass ConvertCommandClass(uint8_t command_type);
215 
216  private:
217  uint8_t m_message_count;
218  uint16_t m_sub_device;
219  uint16_t m_param_id;
220  uint8_t *m_data;
221  unsigned int m_data_length;
222 
223  static uint16_t CalculateChecksum(const uint8_t *data,
224  unsigned int packet_length);
225 
226  DISALLOW_COPY_AND_ASSIGN(RDMCommand);
227 };
228 
229 
233 class RDMRequest: public RDMCommand {
234  public:
236  public:
242  : has_message_length(false),
243  has_checksum(false),
244  sub_start_code(SUB_START_CODE),
245  message_length(0),
246  message_count(0),
247  checksum(0) {
248  }
249 
250  void SetMessageLength(uint8_t message_length_arg) {
251  has_message_length = true;
252  message_length = message_length_arg;
253  }
254 
255  void SetChecksum(uint16_t checksum_arg) {
256  has_checksum = true;
257  checksum = checksum_arg;
258  }
259 
260  bool has_message_length;
261  bool has_checksum;
262 
263  uint8_t sub_start_code;
264  uint8_t message_length;
265  uint8_t message_count;
266  uint16_t checksum;
267  };
268 
282  RDMRequest(const UID &source,
283  const UID &destination,
284  uint8_t transaction_number,
285  uint8_t port_id,
286  uint16_t sub_device,
287  RDMCommandClass command_class,
288  uint16_t param_id,
289  const uint8_t *data,
290  unsigned int length,
291  const OverrideOptions &options = OverrideOptions());
292 
293  RDMCommandClass CommandClass() const { return m_command_class; }
294 
299  uint8_t PortId() const { return m_port_id; }
300 
305  virtual RDMRequest *Duplicate() const {
306  return new RDMRequest(
307  SourceUID(),
308  DestinationUID(),
310  PortId(),
311  SubDevice(),
312  m_command_class,
313  ParamId(),
314  ParamData(),
315  ParamDataSize(),
316  m_override_options);
317  }
318 
319  virtual void Print(CommandPrinter *printer,
320  bool summarize,
321  bool unpack_param_data) const {
322  printer->Print(this, summarize, unpack_param_data);
323  }
324 
329  bool IsDUB() const;
330 
331  uint8_t SubStartCode() const;
332  uint8_t MessageLength() const;
333  uint16_t Checksum(uint16_t checksum) const;
334 
344  void SetSourceUID(const UID &source_uid) {
345  m_source = source_uid;
346  }
347 
352  void SetTransactionNumber(uint8_t transaction_number) {
353  m_transaction_number = transaction_number;
354  }
355 
360  void SetPortId(uint8_t port_id) {
361  m_port_id = port_id;
362  }
363 
372  static RDMRequest* InflateFromData(const uint8_t *data,
373  unsigned int length);
374 
375  protected:
376  OverrideOptions m_override_options;
377 
378  private:
379  RDMCommandClass m_command_class;
380 };
381 
382 
387  public:
401  RDMGetSetRequest(const UID &source,
402  const UID &destination,
403  uint8_t transaction_number,
404  uint8_t port_id,
405  uint16_t sub_device,
406  RDMCommandClass command_class,
407  uint16_t param_id,
408  const uint8_t *data,
409  unsigned int length,
410  const OverrideOptions &options)
411  : RDMRequest(source, destination, transaction_number, port_id,
412  sub_device, command_class, param_id, data, length, options) {
413  }
414 };
415 
416 
417 template <RDMCommand::RDMCommandClass command_class>
419  public:
420  BaseRDMRequest(const UID &source,
421  const UID &destination,
422  uint8_t transaction_number,
423  uint8_t port_id,
424  uint16_t sub_device,
425  uint16_t param_id,
426  const uint8_t *data,
427  unsigned int length,
428  const OverrideOptions &options = OverrideOptions())
429  : RDMGetSetRequest(source, destination, transaction_number, port_id,
430  sub_device, command_class, param_id, data, length,
431  options) {
432  }
433 
436  SourceUID(),
437  DestinationUID(),
439  PortId(),
440  SubDevice(),
441  ParamId(),
442  ParamData(),
443  ParamDataSize(),
444  m_override_options);
445  }
446 };
447 
448 typedef BaseRDMRequest<RDMCommand::GET_COMMAND> RDMGetRequest;
449 typedef BaseRDMRequest<RDMCommand::SET_COMMAND> RDMSetRequest;
450 
451 
456 class RDMResponse: public RDMCommand {
457  public:
471  RDMResponse(const UID &source,
472  const UID &destination,
473  uint8_t transaction_number,
474  uint8_t response_type,
475  uint8_t message_count,
476  uint16_t sub_device,
477  RDMCommand::RDMCommandClass command_class,
478  uint16_t param_id,
479  const uint8_t *data,
480  unsigned int length)
481  : RDMCommand(source, destination, transaction_number, response_type,
482  message_count, sub_device, param_id, data, length),
483  m_command_class(command_class) {
484  }
485 
486  virtual void Print(CommandPrinter *printer,
487  bool summarize,
488  bool unpack_param_data) const {
489  printer->Print(this, summarize, unpack_param_data);
490  }
491 
497  return new RDMResponse(
498  SourceUID(),
499  DestinationUID(),
501  ResponseType(),
502  MessageCount(),
503  SubDevice(),
504  CommandClass(),
505  ParamId(),
506  ParamData(),
507  ParamDataSize());
508  }
509 
519  uint8_t ResponseType() const { return m_port_id; }
520 
521  RDMCommandClass CommandClass() const { return m_command_class; }
522 
534  void SetDestinationUID(const UID &destination_uid) {
535  m_destination = destination_uid;
536  }
537 
542  void SetTransactionNumber(uint8_t transaction_number) {
543  m_transaction_number = transaction_number;
544  }
545 
553  static const unsigned int MAX_OVERFLOW_SIZE = 4 << 10;
554 
563  static RDMResponse* InflateFromData(const uint8_t *data,
564  size_t length,
565  RDMStatusCode *status_code,
566  const RDMRequest *request = NULL);
567 
576  RDMStatusCode *status_code,
577  const RDMRequest *request = NULL) {
578  return InflateFromData(input.data(), input.size(), status_code, request);
579  }
580 
591  static RDMResponse* CombineResponses(const RDMResponse *response1,
592  const RDMResponse *response2);
593 
594  private:
595  RDMCommand::RDMCommandClass m_command_class;
596 };
597 
598 
603  public:
604  RDMGetSetResponse(const UID &source,
605  const UID &destination,
606  uint8_t transaction_number,
607  uint8_t response_type,
608  uint8_t message_count,
609  uint16_t sub_device,
610  RDMCommand::RDMCommandClass command_class,
611  uint16_t param_id,
612  const uint8_t *data,
613  unsigned int length)
614  : RDMResponse(source, destination, transaction_number, response_type,
615  message_count, sub_device, command_class, param_id, data,
616  length) {
617  }
618 };
619 
620 
621 template <RDMCommand::RDMCommandClass command_class>
623  public:
624  BaseRDMResponse(const UID &source,
625  const UID &destination,
626  uint8_t transaction_number,
627  uint8_t response_type,
628  uint8_t message_count,
629  uint16_t sub_device,
630  uint16_t param_id,
631  const uint8_t *data,
632  unsigned int length)
633  : RDMGetSetResponse(source, destination, transaction_number,
634  response_type, message_count, sub_device,
635  command_class, param_id, data, length) {
636  }
637 };
638 
641 
642 // Helper functions for dealing with RDMCommands
643 // These are mostly used with the RDM-TRI & dummy plugin
644 
648 RDMResponse *NackWithReason(const RDMRequest *request,
649  rdm_nack_reason reason,
650  uint8_t outstanding_messages = 0);
655  const uint8_t *data = NULL,
656  unsigned int length = 0,
657  rdm_response_type type = RDM_ACK,
658  uint8_t outstanding_messages = 0);
659 
664  uint16_t pid,
665  const uint8_t *data,
666  unsigned int length,
667  uint8_t type = RDM_ACK,
668  uint8_t outstanding_messages = 0);
669 
674  public:
675  RDMDiscoveryRequest(const UID &source,
676  const UID &destination,
677  uint8_t transaction_number,
678  uint8_t port_id,
679  uint16_t sub_device,
680  uint16_t param_id,
681  const uint8_t *data,
682  unsigned int length,
683  const OverrideOptions &options = OverrideOptions())
684  : RDMRequest(source,
685  destination,
686  transaction_number,
687  port_id,
688  sub_device,
690  param_id,
691  data,
692  length,
693  options) {
694  }
695 
696  uint8_t PortId() const { return m_port_id; }
697 
698  virtual void Print(CommandPrinter *printer,
699  bool summarize,
700  bool unpack_param_data) const {
701  printer->Print(this, summarize, unpack_param_data);
702  }
703 
704  static RDMDiscoveryRequest* InflateFromData(const uint8_t *data,
705  unsigned int length);
706 };
707 
708 
709 // Because the number of discovery requests is small (3 type) we provide a
710 // helper method for each here.
714 RDMDiscoveryRequest *NewDiscoveryUniqueBranchRequest(
715  const UID &source,
716  const UID &lower,
717  const UID &upper,
718  uint8_t transaction_number,
719  uint8_t port_id = 1);
720 
721 
725 RDMDiscoveryRequest *NewMuteRequest(const UID &source,
726  const UID &destination,
727  uint8_t transaction_number,
728  uint8_t port_id = 1);
729 
733 RDMDiscoveryRequest *NewUnMuteRequest(const UID &source,
734  const UID &destination,
735  uint8_t transaction_number,
736  uint8_t port_id = 1);
737 
738 
743  public:
744  RDMDiscoveryResponse(const UID &source,
745  const UID &destination,
746  uint8_t transaction_number,
747  uint8_t port_id,
748  uint8_t message_count,
749  uint16_t sub_device,
750  uint16_t param_id,
751  const uint8_t *data,
752  unsigned int length)
753  : RDMResponse(source,
754  destination,
755  transaction_number,
756  port_id,
757  message_count,
758  sub_device,
760  param_id,
761  data,
762  length) {
763  }
764 
765  virtual void Print(CommandPrinter *printer,
766  bool summarize,
767  bool unpack_param_data) const {
768  printer->Print(this, summarize, unpack_param_data);
769  }
770 
771  static RDMDiscoveryResponse* InflateFromData(const uint8_t *data,
772  unsigned int length);
773 };
775 } // namespace rdm
776 } // namespace ola
777 #endif // INCLUDE_OLA_RDM_RDMCOMMAND_H_
bool operator==(const RDMCommand &other) const
Test for equality.
Definition: RDMCommand.cpp:127
Structures and constants used with RDM Packets.
Definition: RDMCommand.h:418
RDMDiscoveryRequest * NewUnMuteRequest(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t port_id)
Definition: RDMCommand.cpp:734
RDMCommandClass CommandClass() const
The CommmandClass of this message.
Definition: RDMCommand.h:521
Definition: RDMPacket.h:44
RDMResponse(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t response_type, uint8_t message_count, uint16_t sub_device, RDMCommand::RDMCommandClass command_class, uint16_t param_id, const uint8_t *data, unsigned int length)
Create a new RDM Response.
Definition: RDMCommand.h:471
An RDM Command that represents responses (GET, SET or DISCOVER).
Definition: RDMCommand.h:456
RDMResponse * GetResponseFromData(const RDMRequest *request, const uint8_t *data, unsigned int length, rdm_response_type type, uint8_t outstanding_messages)
Generate an ACK Response with some data.
Definition: RDMCommand.cpp:584
void SetSourceUID(const UID &source_uid)
Set the source UID.
Definition: RDMCommand.h:344
The base class for GET/SET responses.
Definition: RDMCommand.h:602
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:765
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:698
Definition: CommandPrinter.h:31
const uint8_t * ParamData() const
Returns the Parameter Data of the RDMCommand.
Definition: RDMCommand.h:143
uint16_t Checksum(uint16_t checksum) const
Modify the calculated checksum for this command.
Definition: RDMCommand.cpp:313
RDMCommandClass
A set of values representing CommandClasses in E1.20.
Definition: RDMEnums.h:55
static const unsigned int MAX_OVERFLOW_SIZE
The maximum size of an ACK_OVERFLOW session that we'll buffer.
Definition: RDMCommand.h:553
virtual RDMRequest * Duplicate() const
Make a copy of the request.
Definition: RDMCommand.h:305
std::string ToString() const
Create a human readable string from the RDMCommand object.
Definition: RDMCommand.cpp:112
RDM Commands that represent requests (GET, SET or DISCOVER).
Definition: RDMCommand.h:233
A RDM unique identifier (UID).
RDMRequest(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t port_id, uint16_t sub_device, RDMCommandClass command_class, uint16_t param_id, const uint8_t *data, unsigned int length, const OverrideOptions &options=OverrideOptions())
Create a new request.
Definition: RDMCommand.cpp:280
An RDM response of type DISCOVER_COMMAND.
Definition: RDMCommand.h:742
Definition: RDMCommand.h:69
static RDMResponse * InflateFromData(const uint8_t *data, size_t length, RDMStatusCode *status_code, const RDMRequest *request=NULL)
Definition: RDMCommand.cpp:378
const UID & SourceUID() const
Returns the Source UID of the RDMCommand.
Definition: RDMCommand.h:116
Definition: RDMCommand.h:73
RDMResponse * NackWithReason(const RDMRequest *request, rdm_nack_reason reason_enum, uint8_t outstanding_messages)
Generate a NACK response with a reason code.
Definition: RDMCommand.cpp:572
virtual RDMCommandClass CommandClass() const =0
The CommmandClass of this message.
void SetTransactionNumber(uint8_t transaction_number)
Set the transaction number.
Definition: RDMCommand.h:352
friend std::ostream & operator<<(std::ostream &out, const RDMCommand &command)
Output an RDMCommand object to an ostream.
Definition: RDMCommand.h:97
void SetTransactionNumber(uint8_t transaction_number)
Set the transaction number.
Definition: RDMCommand.h:542
An RDM Get / Set Request.
Definition: RDMCommand.h:386
RDMGetSetRequest(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t port_id, uint16_t sub_device, RDMCommandClass command_class, uint16_t param_id, const uint8_t *data, unsigned int length, const OverrideOptions &options)
Create a new Get / Set Request.
Definition: RDMCommand.h:401
static RDMResponse * InflateFromData(const ola::io::ByteString &input, RDMStatusCode *status_code, const RDMRequest *request=NULL)
Definition: RDMCommand.h:575
An RDM request of type DISCOVER_COMMAND.
Definition: RDMCommand.h:673
RDMCommandClass
A set of values representing CommandClasses in E1.20.
Definition: RDMCommand.h:66
The base class that all RDM requests & responses inherit from.
Definition: RDMCommand.h:59
void SetDestinationUID(const UID &destination_uid)
Set the destination UID.
Definition: RDMCommand.h:534
BaseRDMRequest< command_class > * Duplicate() const
Make a copy of the request.
Definition: RDMCommand.h:434
static RDMDiscoveryRequest * InflateFromData(const uint8_t *data, unsigned int length)
Inflate a discovery request.
Definition: RDMCommand.cpp:650
RDMResponse * Duplicate() const
Make a copy of the response.
Definition: RDMCommand.h:496
RDMCommand(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t port_id, uint8_t message_count, uint16_t sub_device, uint16_t param_id, const uint8_t *data, unsigned int length)
Protected constructor for derived classes.
Definition: RDMCommand.cpp:84
void SetPortId(uint8_t port_id)
Set the Port Id.
Definition: RDMCommand.h:360
RDMResponse * GetResponseWithPid(const RDMRequest *request, uint16_t pid, const uint8_t *data, unsigned int length, uint8_t type, uint8_t outstanding_messages)
Construct an RDM response from a RDMRequest object.
Definition: RDMCommand.cpp:598
RDMDiscoveryRequest * NewDiscoveryUniqueBranchRequest(const UID &source, const UID &lower, const UID &upper, uint8_t transaction_number, uint8_t port_id)
Create a new DUB request object.
Definition: RDMCommand.cpp:692
void SetParamData(const uint8_t *data, unsigned int length)
Definition: RDMCommand.cpp:171
Definition: RDMCommand.h:622
Definition: RDMCommand.h:235
virtual uint16_t Checksum(uint16_t checksum) const
Modify the calculated checksum for this command.
Definition: RDMCommand.h:154
unsigned int ParamDataSize() const
Returns the Size of the Parameter Data of the RDMCommand.
Definition: RDMCommand.h:140
uint8_t MessageLength() const
The Message length field.
Definition: RDMCommand.cpp:305
static RDMRequest * InflateFromData(const uint8_t *data, unsigned int length)
Inflate a request from some data.
Definition: RDMCommand.cpp:318
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:163
const UID & DestinationUID() const
Returns the Destination UID of the RDMCommand.
Definition: RDMCommand.h:119
static const uint8_t START_CODE
The RDM Start Code.
Definition: RDMCommand.h:179
OverrideOptions()
Allow all fields in a RDMRequest to be specified. Using values other than the default may result in i...
Definition: RDMCommand.h:241
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:319
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:486
uint8_t PortIdResponseType() const
Returns the Port ID of the RDMCommand.
Definition: RDMCommand.h:125
virtual uint8_t MessageLength() const
The Message length field.
Definition: RDMCommand.cpp:162
Definition: RDMCommand.h:71
bool IsDUB() const
Check if this is a DUB request.
Definition: RDMCommand.cpp:296
static RDMCommand * Inflate(const uint8_t *data, unsigned int length)
Extract a RDMCommand from raw data.
Definition: RDMCommand.cpp:141
uint16_t ParamId() const
Returns the Parameter ID of the RDMCommand.
Definition: RDMCommand.h:137
Helper macros.
RDMDiscoveryRequest * NewMuteRequest(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t port_id)
Create a new Mute Request Object.
Definition: RDMCommand.cpp:716
uint16_t SubDevice() const
Returns the SubDevice of the RDMCommand.
Definition: RDMCommand.h:131
RDMCommandClass CommandClass() const
The CommmandClass of this message.
Definition: RDMCommand.h:293
Various constants used in RDM.
virtual uint8_t SubStartCode() const
The Sub-Start code for the RDMCommand.
Definition: RDMCommand.h:110
static RDMDiscoveryResponse * InflateFromData(const uint8_t *data, unsigned int length)
Definition: RDMCommand.cpp:752
Represents a RDM UID.
Definition: UID.h:57
uint8_t MessageCount() const
Returns the Message Count of the RDMCommand.
Definition: RDMCommand.h:128
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
std::basic_string< uint8_t > ByteString
A contiguous block of uint8_t data.
Definition: ByteString.h:40
uint8_t SubStartCode() const
The Sub-Start code for the RDMCommand.
Definition: RDMCommand.cpp:301
uint8_t PortId() const
The Port ID for this request.
Definition: RDMCommand.h:299
Definition: RDMCommand.h:67
uint8_t TransactionNumber() const
Returns the Transaction Number of the RDMCommand.
Definition: RDMCommand.h:122
uint8_t ResponseType() const
The Response Type.
Definition: RDMCommand.h:519
static RDMResponse * CombineResponses(const RDMResponse *response1, const RDMResponse *response2)
Combine two RDMResponses.
Definition: RDMCommand.cpp:516