Open Lighting Architecture  Latest Git
 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>
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 
180  static const uint8_t START_CODE = ola::rdm::START_CODE;
181 
188  static RDMCommand *Inflate(const uint8_t *data, unsigned int length);
189 
190  protected:
191  uint8_t m_port_id;
192  UID m_source;
193  UID m_destination;
194  uint8_t m_transaction_number;
195 
199  RDMCommand(const UID &source,
200  const UID &destination,
201  uint8_t transaction_number,
202  uint8_t port_id,
203  uint8_t message_count,
204  uint16_t sub_device,
205  uint16_t param_id,
206  const uint8_t *data,
207  unsigned int length);
208 
209  void SetParamData(const uint8_t *data, unsigned int length);
210 
211  static RDMStatusCode VerifyData(const uint8_t *data,
212  size_t length,
213  RDMCommandHeader *command_message);
214 
215  static RDMCommandClass ConvertCommandClass(uint8_t command_type);
216 
217  private:
218  uint8_t m_message_count;
219  uint16_t m_sub_device;
220  uint16_t m_param_id;
221  uint8_t *m_data;
222  unsigned int m_data_length;
223 
224  static uint16_t CalculateChecksum(const uint8_t *data,
225  unsigned int packet_length);
226 
227  DISALLOW_COPY_AND_ASSIGN(RDMCommand);
228 };
229 
230 
234 class RDMRequest: public RDMCommand {
235  public:
237  public:
243  : has_message_length(false),
244  has_checksum(false),
245  sub_start_code(SUB_START_CODE),
246  message_length(0),
247  message_count(0),
248  checksum(0) {
249  }
250 
251  void SetMessageLength(uint8_t message_length_arg) {
252  has_message_length = true;
253  message_length = message_length_arg;
254  }
255 
256  void SetChecksum(uint16_t checksum_arg) {
257  has_checksum = true;
258  checksum = checksum_arg;
259  }
260 
261  bool has_message_length;
262  bool has_checksum;
263 
264  uint8_t sub_start_code;
265  uint8_t message_length;
266  uint8_t message_count;
267  uint16_t checksum;
268  };
269 
283  RDMRequest(const UID &source,
284  const UID &destination,
285  uint8_t transaction_number,
286  uint8_t port_id,
287  uint16_t sub_device,
288  RDMCommandClass command_class,
289  uint16_t param_id,
290  const uint8_t *data,
291  unsigned int length,
292  const OverrideOptions &options = OverrideOptions());
293 
294  RDMCommandClass CommandClass() const { return m_command_class; }
295 
300  uint8_t PortId() const { return m_port_id; }
301 
306  virtual RDMRequest *Duplicate() const {
307  return new RDMRequest(
308  SourceUID(),
309  DestinationUID(),
311  PortId(),
312  SubDevice(),
313  m_command_class,
314  ParamId(),
315  ParamData(),
316  ParamDataSize(),
317  m_override_options);
318  }
319 
320  virtual void Print(CommandPrinter *printer,
321  bool summarize,
322  bool unpack_param_data) const {
323  printer->Print(this, summarize, unpack_param_data);
324  }
325 
330  bool IsDUB() const;
331 
332  uint8_t SubStartCode() const;
333  uint8_t MessageLength() const;
334  uint16_t Checksum(uint16_t checksum) const;
335 
345  void SetSourceUID(const UID &source_uid) {
346  m_source = source_uid;
347  }
348 
353  void SetTransactionNumber(uint8_t transaction_number) {
354  m_transaction_number = transaction_number;
355  }
356 
361  void SetPortId(uint8_t port_id) {
362  m_port_id = port_id;
363  }
364 
373  static RDMRequest* InflateFromData(const uint8_t *data,
374  unsigned int length);
375 
376  protected:
377  OverrideOptions m_override_options;
378 
379  private:
380  RDMCommandClass m_command_class;
381 };
382 
383 
388  public:
402  RDMGetSetRequest(const UID &source,
403  const UID &destination,
404  uint8_t transaction_number,
405  uint8_t port_id,
406  uint16_t sub_device,
407  RDMCommandClass command_class,
408  uint16_t param_id,
409  const uint8_t *data,
410  unsigned int length,
411  const OverrideOptions &options)
412  : RDMRequest(source, destination, transaction_number, port_id,
413  sub_device, command_class, param_id, data, length, options) {
414  }
415 };
416 
417 
418 template <RDMCommand::RDMCommandClass command_class>
420  public:
421  BaseRDMRequest(const UID &source,
422  const UID &destination,
423  uint8_t transaction_number,
424  uint8_t port_id,
425  uint16_t sub_device,
426  uint16_t param_id,
427  const uint8_t *data,
428  unsigned int length,
429  const OverrideOptions &options = OverrideOptions())
430  : RDMGetSetRequest(source, destination, transaction_number, port_id,
431  sub_device, command_class, param_id, data, length,
432  options) {
433  }
434 
437  SourceUID(),
438  DestinationUID(),
440  PortId(),
441  SubDevice(),
442  ParamId(),
443  ParamData(),
444  ParamDataSize(),
445  m_override_options);
446  }
447 };
448 
449 typedef BaseRDMRequest<RDMCommand::GET_COMMAND> RDMGetRequest;
450 typedef BaseRDMRequest<RDMCommand::SET_COMMAND> RDMSetRequest;
451 
452 
457 class RDMResponse: public RDMCommand {
458  public:
472  RDMResponse(const UID &source,
473  const UID &destination,
474  uint8_t transaction_number,
475  uint8_t response_type,
476  uint8_t message_count,
477  uint16_t sub_device,
478  RDMCommand::RDMCommandClass command_class,
479  uint16_t param_id,
480  const uint8_t *data,
481  unsigned int length)
482  : RDMCommand(source, destination, transaction_number, response_type,
483  message_count, sub_device, param_id, data, length),
484  m_command_class(command_class) {
485  }
486 
487  virtual void Print(CommandPrinter *printer,
488  bool summarize,
489  bool unpack_param_data) const {
490  printer->Print(this, summarize, unpack_param_data);
491  }
492 
498  return new RDMResponse(
499  SourceUID(),
500  DestinationUID(),
502  ResponseType(),
503  MessageCount(),
504  SubDevice(),
505  CommandClass(),
506  ParamId(),
507  ParamData(),
508  ParamDataSize());
509  }
510 
520  uint8_t ResponseType() const { return m_port_id; }
521 
522  RDMCommandClass CommandClass() const { return m_command_class; }
523 
535  void SetDestinationUID(const UID &destination_uid) {
536  m_destination = destination_uid;
537  }
538 
543  void SetTransactionNumber(uint8_t transaction_number) {
544  m_transaction_number = transaction_number;
545  }
546 
554  static const unsigned int MAX_OVERFLOW_SIZE = 4 << 10;
555 
564  static RDMResponse* InflateFromData(const uint8_t *data,
565  size_t length,
566  RDMStatusCode *status_code,
567  const RDMRequest *request = NULL);
568 
577  RDMStatusCode *status_code,
578  const RDMRequest *request = NULL) {
579  return InflateFromData(input.data(), input.size(), status_code, request);
580  }
581 
592  static RDMResponse* CombineResponses(const RDMResponse *response1,
593  const RDMResponse *response2);
594 
595  private:
596  RDMCommand::RDMCommandClass m_command_class;
597 };
598 
599 
604  public:
605  RDMGetSetResponse(const UID &source,
606  const UID &destination,
607  uint8_t transaction_number,
608  uint8_t response_type,
609  uint8_t message_count,
610  uint16_t sub_device,
611  RDMCommand::RDMCommandClass command_class,
612  uint16_t param_id,
613  const uint8_t *data,
614  unsigned int length)
615  : RDMResponse(source, destination, transaction_number, response_type,
616  message_count, sub_device, command_class, param_id, data,
617  length) {
618  }
619 };
620 
621 
622 template <RDMCommand::RDMCommandClass command_class>
624  public:
625  BaseRDMResponse(const UID &source,
626  const UID &destination,
627  uint8_t transaction_number,
628  uint8_t response_type,
629  uint8_t message_count,
630  uint16_t sub_device,
631  uint16_t param_id,
632  const uint8_t *data,
633  unsigned int length)
634  : RDMGetSetResponse(source, destination, transaction_number,
635  response_type, message_count, sub_device,
636  command_class, param_id, data, length) {
637  }
638 };
639 
642 
643 // Helper functions for dealing with RDMCommands
644 // These are mostly used with the RDM-TRI & dummy plugin
645 
649 RDMResponse *NackWithReason(const RDMRequest *request,
650  rdm_nack_reason reason,
651  uint8_t outstanding_messages = 0);
656  const uint8_t *data = NULL,
657  unsigned int length = 0,
658  rdm_response_type type = RDM_ACK,
659  uint8_t outstanding_messages = 0);
660 
665  uint16_t pid,
666  const uint8_t *data,
667  unsigned int length,
668  uint8_t type = RDM_ACK,
669  uint8_t outstanding_messages = 0);
670 
675  public:
676  RDMDiscoveryRequest(const UID &source,
677  const UID &destination,
678  uint8_t transaction_number,
679  uint8_t port_id,
680  uint16_t sub_device,
681  uint16_t param_id,
682  const uint8_t *data,
683  unsigned int length,
684  const OverrideOptions &options = OverrideOptions())
685  : RDMRequest(source,
686  destination,
687  transaction_number,
688  port_id,
689  sub_device,
691  param_id,
692  data,
693  length,
694  options) {
695  }
696 
697  uint8_t PortId() const { return m_port_id; }
698 
699  virtual void Print(CommandPrinter *printer,
700  bool summarize,
701  bool unpack_param_data) const {
702  printer->Print(this, summarize, unpack_param_data);
703  }
704 
705  static RDMDiscoveryRequest* InflateFromData(const uint8_t *data,
706  unsigned int length);
707 };
708 
709 
710 // Because the number of discovery requests is small (3 type) we provide a
711 // helper method for each here.
715 RDMDiscoveryRequest *NewDiscoveryUniqueBranchRequest(
716  const UID &source,
717  const UID &lower,
718  const UID &upper,
719  uint8_t transaction_number,
720  uint8_t port_id = 1);
721 
722 
726 RDMDiscoveryRequest *NewMuteRequest(const UID &source,
727  const UID &destination,
728  uint8_t transaction_number,
729  uint8_t port_id = 1);
730 
734 RDMDiscoveryRequest *NewUnMuteRequest(const UID &source,
735  const UID &destination,
736  uint8_t transaction_number,
737  uint8_t port_id = 1);
738 
739 
744  public:
745  RDMDiscoveryResponse(const UID &source,
746  const UID &destination,
747  uint8_t transaction_number,
748  uint8_t port_id,
749  uint8_t message_count,
750  uint16_t sub_device,
751  uint16_t param_id,
752  const uint8_t *data,
753  unsigned int length)
754  : RDMResponse(source,
755  destination,
756  transaction_number,
757  port_id,
758  message_count,
759  sub_device,
761  param_id,
762  data,
763  length) {
764  }
765 
766  virtual void Print(CommandPrinter *printer,
767  bool summarize,
768  bool unpack_param_data) const {
769  printer->Print(this, summarize, unpack_param_data);
770  }
771 
772  static RDMDiscoveryResponse* InflateFromData(const uint8_t *data,
773  unsigned int length);
774 };
776 } // namespace rdm
777 } // namespace ola
778 #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:419
RDMDiscoveryRequest * NewUnMuteRequest(const UID &source, const UID &destination, uint8_t transaction_number, uint8_t port_id)
Definition: RDMCommand.cpp:745
RDMCommandClass CommandClass() const
The CommmandClass of this message.
Definition: RDMCommand.h:522
RDMStatusCode
RDM Status Codes.
Definition: RDMResponseCodes.h:45
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:472
An RDM Command that represents responses (GET, SET or DISCOVER).
Definition: RDMCommand.h:457
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:595
void SetSourceUID(const UID &source_uid)
Set the source UID.
Definition: RDMCommand.h:345
rdm_response_type
RDM response types.
Definition: RDMResponseCodes.h:76
The base class for GET/SET responses.
Definition: RDMCommand.h:603
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:766
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:699
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:315
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:554
virtual RDMRequest * Duplicate() const
Make a copy of the request.
Definition: RDMCommand.h:306
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:234
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:282
An RDM response of type DISCOVER_COMMAND.
Definition: RDMCommand.h:743
Definition: RDMCommand.h:69
static RDMResponse * InflateFromData(const uint8_t *data, size_t length, RDMStatusCode *status_code, const RDMRequest *request=NULL)
Definition: RDMCommand.cpp:385
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:583
virtual RDMCommandClass CommandClass() const =0
The CommmandClass of this message.
void SetTransactionNumber(uint8_t transaction_number)
Set the transaction number.
Definition: RDMCommand.h:353
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:543
An RDM Get / Set Request.
Definition: RDMCommand.h:387
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:402
static RDMResponse * InflateFromData(const ola::io::ByteString &input, RDMStatusCode *status_code, const RDMRequest *request=NULL)
Definition: RDMCommand.h:576
An RDM request of type DISCOVER_COMMAND.
Definition: RDMCommand.h:674
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:535
BaseRDMRequest< command_class > * Duplicate() const
Make a copy of the request.
Definition: RDMCommand.h:435
static RDMDiscoveryRequest * InflateFromData(const uint8_t *data, unsigned int length)
Inflate a discovery request.
Definition: RDMCommand.cpp:661
RDMResponse * Duplicate() const
Make a copy of the response.
Definition: RDMCommand.h:497
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:361
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:609
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:703
Enums representing the states of a response. This is generated from the proto file.
void SetParamData(const uint8_t *data, unsigned int length)
Definition: RDMCommand.cpp:171
Definition: RDMCommand.h:623
Definition: RDMCommand.h:236
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:307
static RDMRequest * InflateFromData(const uint8_t *data, unsigned int length)
Inflate a request from some data.
Definition: RDMCommand.cpp:320
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:180
OverrideOptions()
Allow all fields in a RDMRequest to be specified. Using values other than the default may result in i...
Definition: RDMCommand.h:242
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:320
virtual void Print(CommandPrinter *printer, bool summarize, bool unpack_param_data) const
Output the contents of the command to a CommandPrinter.
Definition: RDMCommand.h:487
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:298
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:727
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:294
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:763
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:303
uint8_t PortId() const
The Port ID for this request.
Definition: RDMCommand.h:300
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:520
static RDMResponse * CombineResponses(const RDMResponse *response1, const RDMResponse *response2)
Combine two RDMResponses.
Definition: RDMCommand.cpp:525