Open Lighting Architecture  Latest Git
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 
29 namespace ola {
30 namespace acn {
31 
32 typedef enum {
33  ONE_BYTES = 0x00,
34  TWO_BYTES = 0x01,
35  FOUR_BYTES = 0x02,
36  RES_BYTES = 0x03
37 } dmp_address_size;
38 
39 
40 typedef enum {
41  NON_RANGE = 0x00,
42  RANGE_SINGLE = 0x01,
43  RANGE_EQUAL = 0x02,
44  RANGE_MIXED = 0x03,
45 } dmp_address_type;
46 
47 
48 static const unsigned int MAX_TWO_BYTE = 0xffff;
49 static const unsigned int MAX_ONE_BYTE = 0xff;
50 
51 
52 /*
53  * Return the dmp_address_size that corresponds to a type
54  */
55 template <typename type>
56 dmp_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  */
73 unsigned 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  */
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  */
117 template<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 
157 
158 /*
159  * Create a new single address
160  */
161 const BaseDMPAddress *NewSingleAddress(unsigned int value);
162 
163 
164 /*
165  * These type of addresses reference multiple properties.
166  */
167 template <typename type>
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 
217 
218 
219 /*
220  * Create a new range address.
221  */
222 const BaseDMPAddress *NewRangeAddress(unsigned int value,
223  unsigned int increment,
224  unsigned int number);
225 
226 /*
227  * Decode an Address
228  */
229 const 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  */
239 template <typename type>
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_
uint16_t HostToNetwork(uint16_t value)
16-bit unsigned host to network conversion.
Definition: NetworkUtils.cpp:159
Definition: OutputStream.h:54
Definition: DMPAddress.h:240
Definition: DMPAddress.h:81
Definition: DMPAddress.h:168
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
Definition: DMPAddress.h:118