Open Lighting Architecture 0.10.9
Loading...
Searching...
No Matches
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
29namespace ola {
30namespace acn {
31
32/*
33 * The Base PDU class
34 * TODO(simon): make this into a template based on vector size.
35 */
36class 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 */
102template <class C>
103class 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 */
144template <class C>
145bool 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 */
165template <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_
Definition PDU.h:103
void Write(ola::io::OutputStream *stream) const
Definition PDU.h:166
Definition PDU.h:36
virtual void Write(ola::io::OutputStream *stream) const
Definition PDU.cpp:117
static void PrependFlagsAndLength(ola::io::OutputBufferInterface *output, uint8_t flags=VFLAG_MASK|HFLAG_MASK|DFLAG_MASK)
Definition PDU.cpp:152
Definition OutputBuffer.h:36
Definition OutputStream.h:53
The namespace containing all OLA symbols.
Definition Credentials.cpp:44