Open Lighting Architecture  Latest Git
DMPPDU.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  * DMPPDU.h
17  * Interface for the DMP PDU
18  * Copyright (C) 2007 Simon Newton
19  */
20 
21 #ifndef LIBS_ACN_DMPPDU_H_
22 #define LIBS_ACN_DMPPDU_H_
23 
24 #include <stdint.h>
25 #include <vector>
26 
27 #include "ola/acn/ACNVectors.h"
28 #include "libs/acn/DMPAddress.h"
29 #include "libs/acn/DMPHeader.h"
30 #include "libs/acn/PDU.h"
31 
32 namespace ola {
33 namespace acn {
34 
35 /*
36  * The base DMPPDU class.
37  * More specific dmp pdus like the SetPropery inherit from this.
38  */
39 class DMPPDU: public PDU {
40  public:
41  DMPPDU(unsigned int vector, const DMPHeader &dmp_header):
42  PDU(vector, ONE_BYTE),
43  m_header(dmp_header) {
44  }
45  ~DMPPDU() {}
46 
47  unsigned int HeaderSize() const { return DMPHeader::DMP_HEADER_SIZE; }
48  bool PackHeader(uint8_t *data, unsigned int *length) const;
49  void PackHeader(ola::io::OutputStream *stream) const;
50 
51  protected:
52  DMPHeader m_header;
53 };
54 
55 
56 /*
57  * A DMPGetPropertyPDU, templatized by the address type.
58  * Don't create these directly, instead use the helper function below which
59  * enforces compile time consistency.
60  */
61 template <typename Address>
62 class DMPGetProperty: public DMPPDU {
63  public:
64  DMPGetProperty(const DMPHeader &header,
65  const std::vector<Address> &addresses):
67  m_addresses(addresses) {}
68 
69  unsigned int DataSize() const {
70  return static_cast<unsigned int>(m_addresses.size() * m_header.Bytes() *
71  (m_header.Type() == NON_RANGE ? 1 : 3));
72  }
73 
74  bool PackData(uint8_t *data, unsigned int *length) const {
75  typename std::vector<Address>::const_iterator iter;
76  unsigned int offset = 0;
77  for (iter = m_addresses.begin(); iter != m_addresses.end(); ++iter) {
78  unsigned int remaining = *length - offset;
79  if (!iter->Pack(data + offset, &remaining))
80  return false;
81  offset += remaining;
82  }
83  *length = offset;
84  return true;
85  }
86 
87  void PackData(ola::io::OutputStream *stream) const {
88  typename std::vector<Address>::const_iterator iter;
89  for (iter = m_addresses.begin(); iter != m_addresses.end(); ++iter)
90  iter->Write(stream);
91  }
92 
93  private:
94  std::vector<Address> m_addresses;
95 };
96 
97 
98 /*
99  * Create a non-ranged GetProperty PDU
100  * @param type uint8_t, uint16_t or uint32_t
101  * @param is_virtual set to true if this is a virtual address
102  * @param is_relative set to true if this is a relative address
103  * @param addresses a vector of DMPAddress objects
104  */
105 template <typename type>
106 const DMPPDU *NewDMPGetProperty(
107  bool is_virtual,
108  bool is_relative,
109  const std::vector<DMPAddress<type> > &addresses) {
110  DMPHeader header(is_virtual,
111  is_relative,
112  NON_RANGE,
113  TypeToDMPSize<type>());
114  return new DMPGetProperty<DMPAddress<type> >(header, addresses);
115 }
116 
117 
118 /*
119  * Create a non-ranged DMP GetProperty PDU
120  * @param type uint8_t, uint16_t, uint32_t
121  */
122 template <typename type>
123 const DMPPDU *_CreateDMPGetProperty(bool is_virtual,
124  bool is_relative,
125  unsigned int start) {
126  DMPAddress<type> address((type) start);
127  std::vector<DMPAddress<type> > addresses;
128  addresses.push_back(address);
129  return NewDMPGetProperty<type>(is_virtual, is_relative, addresses);
130 }
131 
132 
133 /*
134  * A helper to create a new single, non-ranged GetProperty PDU.
135  * @param is_virtual set to true if this is a virtual address
136  * @param is_relative set to true if this is a relative address
137  * @param start the start offset
138  * @return A pointer to a DMPPDU.
139  */
140 const DMPPDU *NewDMPGetProperty(bool is_virtual,
141  bool is_relative,
142  unsigned int start);
143 
144 
145 /*
146  * Create a Ranged DMP GetProperty Message.
147  * @param type uint8_t, uint16_t or uint32_t
148  * @param is_virtual set to true if this is a virtual address
149  * @param is_relative set to true if this is a relative address
150  * @param addresses a vector of addresses that match the type
151  * @return A pointer to a DMPPDU.
152  */
153 template <typename type>
154 const DMPPDU *NewRangeDMPGetProperty(
155  bool is_virtual,
156  bool is_relative,
157  const std::vector<RangeDMPAddress<type> > &addresses) {
158  DMPHeader header(is_virtual,
159  is_relative,
160  RANGE_SINGLE,
161  TypeToDMPSize<type>());
162  return new DMPGetProperty<RangeDMPAddress<type> >(header, addresses);
163 }
164 
165 
166 template <typename type>
167 const DMPPDU *_CreateRangeDMPGetProperty(bool is_virtual,
168  bool is_relative,
169  unsigned int start,
170  unsigned int increment,
171  unsigned int number) {
172  std::vector<RangeDMPAddress<type> > addresses;
173  RangeDMPAddress<type> address((type) start, (type) increment, (type) number);
174  addresses.push_back(address);
175  return NewRangeDMPGetProperty<type>(is_virtual, is_relative, addresses);
176 }
177 
178 
179 /*
180  * A helper to create a new ranged address GetProperty PDU.
181  * @param is_virtual set to true if this is a virtual address
182  * @param is_relative set to true if this is a relative address
183  * @param start the start offset
184  * @param increment the increments between addresses
185  * @param number the number of addresses defined
186  * @return A pointer to a DMPGetProperty.
187  */
188 const DMPPDU *NewRangeDMPGetProperty(
189  bool is_virtual,
190  bool is_relative,
191  unsigned int start,
192  unsigned int increment,
193  unsigned int number);
194 
195 
196 /*
197  * A DMPSetPropertyPDU, templatized by the address type.
198  * Don't create these directly, instead use the helper functions below which
199  * enforce compile time consistency.
200  * @param type either DMPAddress<> or RangeDMPAddress<>
201  */
202 template <typename type>
203 class DMPSetProperty: public DMPPDU {
204  public:
205  typedef std::vector<DMPAddressData<type> > AddressDataChunks;
206 
207  DMPSetProperty(const DMPHeader &header, const AddressDataChunks &chunks):
209  m_chunks(chunks) {}
210 
211  unsigned int DataSize() const {
212  typename AddressDataChunks::const_iterator iter;
213  unsigned int length = 0;
214  for (iter = m_chunks.begin(); iter != m_chunks.end(); ++iter)
215  length += iter->Size();
216  return length;
217  }
218 
219  bool PackData(uint8_t *data, unsigned int *length) const {
220  typename AddressDataChunks::const_iterator iter;
221  unsigned int offset = 0;
222  for (iter = m_chunks.begin(); iter != m_chunks.end(); ++iter) {
223  unsigned int remaining = *length - offset;
224  if (!iter->Pack(data + offset, &remaining))
225  return false;
226  offset += remaining;
227  }
228  *length = offset;
229  return true;
230  }
231 
232  void PackData(ola::io::OutputStream *stream) const {
233  typename AddressDataChunks::const_iterator iter;
234  for (iter = m_chunks.begin(); iter != m_chunks.end(); ++iter)
235  iter->Write(stream);
236  }
237 
238  private:
239  AddressDataChunks m_chunks;
240 };
241 
242 
243 /*
244  * Create a new DMP SetProperty Message
245  */
246 template <typename type>
247 const DMPPDU *NewDMPSetProperty(
248  bool is_virtual,
249  bool is_relative,
250  const std::vector<DMPAddressData<DMPAddress<type> > > &chunks) {
251 
252  DMPHeader header(is_virtual,
253  is_relative,
254  NON_RANGE,
255  TypeToDMPSize<type>());
256  return new DMPSetProperty<DMPAddress<type> >(header, chunks);
257 }
258 
259 
260 /*
261  * Create a new DMP SetProperty PDU
262  * @param type either DMPAddress or RangeDMPAddress
263  * @param is_virtual set to true if this is a virtual address
264  * @param is_relative set to true if this is a relative address
265  * @param chunks a vector of DMPAddressData<type> objects
266  */
267 template <typename type>
268 const DMPPDU *NewRangeDMPSetProperty(
269  bool is_virtual,
270  bool is_relative,
271  const std::vector<DMPAddressData<RangeDMPAddress<type> > > &chunks,
272  bool multiple_elements = true,
273  bool equal_size_elements = true) {
274 
275  dmp_address_type address_type;
276  if (multiple_elements) {
277  if (equal_size_elements)
278  address_type = RANGE_EQUAL;
279  else
280  address_type = RANGE_MIXED;
281  } else {
282  address_type = RANGE_SINGLE;
283  }
284 
285  DMPHeader header(is_virtual,
286  is_relative,
287  address_type,
288  TypeToDMPSize<type>());
289  return new DMPSetProperty<RangeDMPAddress<type> >(header, chunks);
290 }
291 } // namespace acn
292 } // namespace ola
293 #endif // LIBS_ACN_DMPPDU_H_
ACN Vector values.
Definition: DMPPDU.h:203
Definition: DMPPDU.h:62
Definition: OutputStream.h:54
Definition: DMPAddress.h:240
Definition: DMPHeader.h:33
Definition: PDU.h:36
Definition: DMPAddress.h:168
The namespace containing all OLA symbols.
Definition: Credentials.cpp:44
Definition: DMPPDU.h:39
Definition: ACNVectors.h:56
Definition: DMPAddress.h:118
Definition: ACNVectors.h:57