Open Lighting Architecture  Latest Git
PDU.h
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or
5  * (at your option) any later version.
6  *
7  * This program 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
10  * GNU Library General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15  *
16  * PDU.h
17  * Interface for the PDU and PDUBlock classes
18  * Copyright (C) 2007 Simon Newton
19  */
20 
21 #ifndef LIBS_ACN_PDU_H_
22 #define LIBS_ACN_PDU_H_
23 
24 #include <stdint.h>
25 #include <ola/io/OutputStream.h>
26 #include <ola/io/OutputBuffer.h>
27 #include <vector>
28 
29 namespace ola {
30 namespace acn {
31 
32 /*
33  * The Base PDU class
34  * TODO(simon): make this into a template based on vector size.
35  */
36 class PDU {
37  public:
38  typedef enum {
39  ONE_BYTE = 1,
40  TWO_BYTES = 2,
41  FOUR_BYTES = 4,
42  } vector_size;
43 
44  explicit PDU(unsigned int vector, vector_size size = FOUR_BYTES):
45  m_vector(vector),
46  m_vector_size(size) {}
47  virtual ~PDU() {}
48 
49  // Returns the size of this PDU
50  virtual unsigned int Size() const;
51  virtual unsigned int VectorSize() const { return m_vector_size; }
52  virtual unsigned int HeaderSize() const = 0;
53  virtual unsigned int DataSize() const = 0;
54 
55  // Set the vector
56  void SetVector(unsigned int vector) { m_vector = vector; }
57 
58  /*
59  * Pack the PDU into the memory pointed to by data
60  * @return true on success, false on failure
61  */
62  virtual bool Pack(uint8_t *data, unsigned int *length) const;
63  virtual bool PackHeader(uint8_t *data, unsigned int *length) const = 0;
64  virtual bool PackData(uint8_t *data, unsigned int *length) const = 0;
65 
69  virtual void Write(ola::io::OutputStream *stream) const;
70  virtual void PackHeader(ola::io::OutputStream *stream) const = 0;
71  virtual void PackData(ola::io::OutputStream *stream) const = 0;
72 
73  static void PrependFlagsAndLength(
75  uint8_t flags = VFLAG_MASK | HFLAG_MASK | DFLAG_MASK);
76 
77  static void PrependFlagsAndLength(
79  unsigned int length,
80  uint8_t flags);
81 
82  // This indicates a vector is present
83  static const uint8_t VFLAG_MASK = 0x40;
84  // This indicates a header field is present
85  static const uint8_t HFLAG_MASK = 0x20;
86  // This indicates a data field is present
87  static const uint8_t DFLAG_MASK = 0x10;
88 
89  private:
90  unsigned int m_vector;
91  unsigned int m_vector_size;
92 
93  // The max PDU length that can be represented with the 2 byte format for
94  // the length field.
95  static const unsigned int TWOB_LENGTH_LIMIT = 0x0FFF;
96 };
97 
98 
99 /*
100  * Represents a block of pdus
101  */
102 template <class C>
103 class PDUBlock {
104  public:
105  PDUBlock(): m_size(0) {}
106  ~PDUBlock() {}
107 
108  // Add a PDU to this block
109  void AddPDU(const C *msg) {
110  m_pdus.push_back(msg);
111  m_size += msg->Size();
112  }
113  // Remove all PDUs from the block
114  void Clear() {
115  m_pdus.clear();
116  m_size = 0;
117  }
118  // The number of bytes this block would consume, this ignores optimizations
119  // like repeating headers/vectors.
120  unsigned int Size() const { return m_size; }
121  /*
122  * Pack this PDUBlock into memory pointed to by data
123  * @return true on success, false on failure
124  */
125  bool Pack(uint8_t *data, unsigned int *length) const;
126 
130  void Write(ola::io::OutputStream *stream) const;
131 
132  private:
133  std::vector<const C*> m_pdus;
134  unsigned int m_size;
135 };
136 
137 
138 /*
139  * Pack this block of PDUs into a buffer
140  * @param data a pointer to the buffer
141  * @param length size of the buffer, updated with the number of bytes used
142  * @return true on success, false on failure
143  */
144 template <class C>
145 bool PDUBlock<C>::Pack(uint8_t *data, unsigned int *length) const {
146  bool status = true;
147  unsigned int i = 0;
148  typename std::vector<const C*>::const_iterator iter;
149  for (iter = m_pdus.begin(); iter != m_pdus.end(); ++iter) {
150  // TODO(simon): optimize repeated headers & vectors here
151  unsigned int remaining = i < *length ? *length - i : 0;
152  status &= (*iter)->Pack(data + i, &remaining);
153  i+= remaining;
154  }
155  *length = i;
156  return status;
157 }
158 
159 
160 /*
161  * Write this block of PDUs to an OutputStream.
162  * @param stream the OutputStream to write to
163  * @return true on success, false on failure
164  */
165 template <class C>
167  typename std::vector<const C*>::const_iterator iter;
168  for (iter = m_pdus.begin(); iter != m_pdus.end(); ++iter) {
169  // TODO(simon): optimize repeated headers & vectors here
170  (*iter)->Write(stream);
171  }
172 }
173 } // namespace acn
174 } // namespace ola
175 #endif // LIBS_ACN_PDU_H_
virtual void Write(ola::io::OutputStream *stream) const
Definition: PDU.cpp:117
Definition: OutputBuffer.h:36
Definition: OutputStream.h:54
void Write(ola::io::OutputStream *stream) const
Definition: PDU.h:166
Definition: PDU.h:36
static void PrependFlagsAndLength(ola::io::OutputBufferInterface *output, uint8_t flags=VFLAG_MASK|HFLAG_MASK|DFLAG_MASK)
Definition: PDU.cpp:152
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
Definition: PDU.h:103