Open Lighting Architecture: libs/acn/DMPAddress.h Source File

| Open Lighting Architecture 0.10.9

Loading...
Searching...
No Matches
DMPAddress.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 * DMPAddress.h
17 * Defines the DMP property address types
18 * Copyright (C) 2007 Simon Newton
19 */
20
21#ifndef LIBS_ACN_DMPADDRESS_H_
22#define LIBS_ACN_DMPADDRESS_H_
23
24#include <stdint.h>
25#include <string.h>
26#include "ola/io/OutputStream.h"
27#include "ola/network/NetworkUtils.h"
28
29namespace ola {
30namespace acn {
31
32typedef enum {
33 ONE_BYTES = 0x00,
34 TWO_BYTES = 0x01,
35 FOUR_BYTES = 0x02,
36 RES_BYTES = 0x03
37} dmp_address_size;
38
39
40typedef enum {
41 NON_RANGE = 0x00,
42 RANGE_SINGLE = 0x01,
43 RANGE_EQUAL = 0x02,
44 RANGE_MIXED = 0x03,
45} dmp_address_type;
46
47
48static const unsigned int MAX_TWO_BYTE = 0xffff;
49static const unsigned int MAX_ONE_BYTE = 0xff;
50
51
52/*
53 * Return the dmp_address_size that corresponds to a type
54 */
55template <typename type>
56dmp_address_size TypeToDMPSize() {
57 switch (sizeof(type)) {
58 case 1:
59 return ONE_BYTES;
60 case 2:
61 return TWO_BYTES;
62 case 4:
63 return FOUR_BYTES;
64 default:
65 return RES_BYTES;
66 }
67}
68
69
70/*
71 * Return the number of bytes that correspond to a DMPType
72 */
73unsigned int DMPSizeToByteSize(dmp_address_size size);
74
75
76/*
77 * The Base DMPAddress class.
78 * The addresses represented by this class may be actual or virtual & relative
79 * or absolute, ranged or non-ranged.
80 */
81 class BaseDMPAddress {
82 public:
83 BaseDMPAddress() {}
84 virtual ~BaseDMPAddress() {}
85
86 // The start address
87 virtual unsigned int Start() const = 0;
88 // The increment
89 virtual unsigned int Increment() const = 0;
90 // The number of properties referenced
91 virtual unsigned int Number() const = 0;
92
93 // Size of this address structure
94 virtual unsigned int Size() const {
95 return (IsRange() ? 3 : 1) * BaseSize();
96 }
97
98 virtual dmp_address_size AddressSize() const = 0;
99
100 // Pack this address into memory
101 virtual bool Pack(uint8_t *data, unsigned int *length) const = 0;
102
103 // Write this address to an OutputStream
104 virtual void Write(ola::io::OutputStream *stream) const = 0;
105
106 // True if this is a range address.
107 virtual bool IsRange() const = 0;
108
109 protected:
110 virtual unsigned int BaseSize() const = 0;
111};
112
113
114/*
115 * These type of addresses only reference one property.
116 */
117template<typename type>
118 class DMPAddress: public BaseDMPAddress {
119 public:
120 explicit DMPAddress(type start):
121 BaseDMPAddress(),
122 m_start(start) {}
123
124 unsigned int Start() const { return m_start; }
125 unsigned int Increment() const { return 0; }
126 unsigned int Number() const { return 1; }
127 dmp_address_size AddressSize() const { return TypeToDMPSize<type>(); }
128
129 bool Pack(uint8_t *data, unsigned int *length) const {
130 if (*length < Size()) {
131 *length = 0;
132 return false;
133 }
134 type field = ola::network::HostToNetwork(m_start);
135 memcpy(data, &field, BaseSize());
136 *length = Size();
137 return true;
138 }
139
140 void Write(ola::io::OutputStream *stream) const {
141 *stream << ola::network::HostToNetwork(m_start);
142 }
143
144 bool IsRange() const { return false; }
145
146 protected:
147 unsigned int BaseSize() const { return sizeof(type); }
148
149 private:
150 type m_start;
151};
152
153
154typedef DMPAddress<uint8_t> OneByteDMPAddress;
155typedef DMPAddress<uint16_t> TwoByteDMPAddress;
156typedef DMPAddress<uint32_t> FourByteDMPAddress;
157
158/*
159 * Create a new single address
160 */
161const BaseDMPAddress *NewSingleAddress(unsigned int value);
162
163
164/*
165 * These type of addresses reference multiple properties.
166 */
167template <typename type>
168 class RangeDMPAddress: public BaseDMPAddress {
169 public:
170 RangeDMPAddress(type start,
171 type increment,
172 type number):
173 BaseDMPAddress(),
174 m_start(start),
175 m_increment(increment),
176 m_number(number) {}
177 unsigned int Start() const { return m_start; }
178 unsigned int Increment() const { return m_increment; }
179 unsigned int Number() const { return m_number; }
180 dmp_address_size AddressSize() const { return TypeToDMPSize<type>(); }
181
182 bool Pack(uint8_t *data, unsigned int *length) const {
183 if (*length < Size()) {
184 *length = 0;
185 return false;
186 }
187 type field[3];
188 field[0] = ola::network::HostToNetwork(m_start);
189 field[1] = ola::network::HostToNetwork(m_increment);
190 field[2] = ola::network::HostToNetwork(m_number);
191 memcpy(data, &field, Size());
192 *length = Size();
193 return true;
194 }
195
196 void Write(ola::io::OutputStream *stream) const {
197 type field[3];
198 field[0] = ola::network::HostToNetwork(m_start);
199 field[1] = ola::network::HostToNetwork(m_increment);
200 field[2] = ola::network::HostToNetwork(m_number);
201 stream->Write(reinterpret_cast<uint8_t*>(&field), Size());
202 }
203
204 bool IsRange() const { return true; }
205
206 protected:
207 unsigned int BaseSize() const { return sizeof(type); }
208
209 private:
210 type m_start, m_increment, m_number;
211};
212
213
214typedef RangeDMPAddress<uint8_t> OneByteRangeDMPAddress;
215typedef RangeDMPAddress<uint16_t> TwoByteRangeDMPAddress;
216typedef RangeDMPAddress<uint32_t> FourByteRangeDMPAddress;
217
218
219/*
220 * Create a new range address.
221 */
222const BaseDMPAddress *NewRangeAddress(unsigned int value,
223 unsigned int increment,
224 unsigned int number);
225
226/*
227 * Decode an Address
228 */
229const BaseDMPAddress *DecodeAddress(dmp_address_size size,
230 dmp_address_type type,
231 const uint8_t *data,
232 unsigned int *length);
233
234
235/*
236 * A DMPAddressData object, this hold an address/data pair
237 * @param type either DMPAddress<> or RangeDMPAddress<>
238 */
239template <typename type>
240 class DMPAddressData {
241 public:
242 DMPAddressData(const type *address,
243 const uint8_t *data,
244 unsigned int length):
245 m_address(address),
246 m_data(data),
247 m_length(length) {}
248
249 const type *Address() const { return m_address; }
250 const uint8_t *Data() const { return m_data; }
251 unsigned int Size() const { return m_address->Size() + m_length; }
252
253 // Pack the data into a buffer
254 bool Pack(uint8_t *data, unsigned int *length) const {
255 if (!m_data)
256 return false;
257
258 unsigned int total = *length;
259 if (!m_address->Pack(data, length)) {
260 length = 0;
261 return false;
262 }
263 if (total - *length < m_length) {
264 length = 0;
265 return false;
266 }
267 memcpy(data + *length, m_data, m_length);
268 *length += m_length;
269 return true;
270 }
271
272 void Write(ola::io::OutputStream *stream) const {
273 if (!m_data)
274 return;
275
276 m_address->Write(stream);
277 stream->Write(m_data, m_length);
278 }
279
280 private:
281 const type *m_address;
282 const uint8_t *m_data;
283 unsigned int m_length;
284};
285} // namespace acn
286} // namespace ola
287#endif // LIBS_ACN_DMPADDRESS_H_
ola::acn::BaseDMPAddress
Definition DMPAddress.h:81
ola::acn::DMPAddress
Definition DMPAddress.h:118
ola::acn::RangeDMPAddress
Definition DMPAddress.h:168
ola::io::OutputStream
Definition OutputStream.h:53
ola::acn
ACN related code.
ola::network::HostToNetwork
uint16_t HostToNetwork(uint16_t value)
16-bit unsigned host to network conversion.
Definition NetworkUtils.cpp:159
ola
The namespace containing all OLA symbols.
Definition Credentials.cpp:44