Open Lighting Architecture: include/ola/rdm/ResponderSettings.h Source File

| Open Lighting Architecture 0.10.9

Loading...
Searching...
No Matches
ResponderSettings.h
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library 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 GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * ResponderSettings.h
17 * Copyright (C) 2013 Simon Newton
18 */
19
20#ifndef INCLUDE_OLA_RDM_RESPONDERSETTINGS_H_
21#define INCLUDE_OLA_RDM_RESPONDERSETTINGS_H_
22
23#include <ola/base/Macro.h>
24#include <ola/rdm/RDMCommand.h>
25#include <ola/rdm/ResponderHelper.h>
26#include <stdint.h>
27#include <string>
28#include <vector>
29
30namespace ola {
31namespace rdm {
32
36 class SettingInterface {
37 public:
38 virtual ~SettingInterface() {}
39
44 virtual std::string Description() const = 0;
45
49 virtual unsigned int DescriptionResponseSize() const = 0;
50
56 virtual unsigned int GenerateDescriptionResponse(uint8_t index,
57 uint8_t *data) const = 0;
58};
59
63 class BasicSetting : SettingInterface {
64 public:
65 typedef const char* ArgType;
66
71 explicit BasicSetting(const ArgType description);
72
77 std::string Description() const { return m_description; }
78
79 unsigned int DescriptionResponseSize() const {
80 return sizeof(description_s);
81 }
82
83 unsigned int GenerateDescriptionResponse(uint8_t index,
84 uint8_t *data) const;
85
86 private:
87 PACK(
88 struct description_s {
89 uint8_t setting;
90 char description[MAX_RDM_STRING_LENGTH];
91 });
92
93 std::string m_description;
94};
95
96
101 class FrequencyModulationSetting : SettingInterface {
102 public:
106 struct FrequencyModulationArg {
107 uint32_t frequency;
108 const char *description;
109 };
110
111 typedef FrequencyModulationArg ArgType;
112
117 explicit FrequencyModulationSetting(const ArgType &arg);
118
123 std::string Description() const { return m_description; }
124
128 uint32_t Frequency() const { return m_frequency; }
129
130 unsigned int DescriptionResponseSize() const {
131 return sizeof(description_s);
132 }
133
134 unsigned int GenerateDescriptionResponse(uint8_t index,
135 uint8_t *data) const;
136
137 private:
138 PACK(
139 struct description_s {
140 uint8_t setting;
141 uint32_t frequency;
142 char description[MAX_RDM_STRING_LENGTH];
143 });
144
145 uint32_t m_frequency;
146 std::string m_description;
147};
148
149
158template <class SettingType>
159 class SettingCollection {
160 public:
166 SettingCollection(const typename SettingType::ArgType args[],
167 unsigned int arg_count,
168 bool zero_offset = false)
169 : m_zero_offset(zero_offset) {
170 for (unsigned int i = 0; i < arg_count; i++) {
171 m_settings.push_back(SettingType(args[i]));
172 }
173 }
174
175 uint8_t Count() const { return m_settings.size(); }
176
177 const SettingType *Lookup(uint8_t index) const {
178 if (index > m_settings.size()) {
179 return NULL;
180 }
181 return &m_settings[index];
182 }
183
184 unsigned int Offset() const {
185 return m_zero_offset ? 0 : 1;
186 }
187
188 protected:
189 SettingCollection() {}
190
191 private:
192 std::vector<SettingType> m_settings;
193 const bool m_zero_offset;
194};
195
196
200template <class SettingType>
201 class SettingManager {
202 public:
203 explicit SettingManager(const SettingCollection<SettingType> *settings)
204 : m_settings(settings),
205 m_current_setting(settings->Offset()) {
206 }
207
208 virtual ~SettingManager() {}
209
210 RDMResponse *Get(const RDMRequest *request) const;
211 RDMResponse *Set(const RDMRequest *request);
212 RDMResponse *GetDescription(const RDMRequest *request) const;
213
214 uint8_t Count() const {
215 return m_settings->Count();
216 }
217
218 uint8_t CurrentSetting() const {
219 return m_current_setting + m_settings->Offset();
220 }
221
222 bool ChangeSetting(uint8_t state);
223
224 private:
225 const SettingCollection<SettingType> *m_settings;
226 uint8_t m_current_setting;
227};
228
229typedef SettingCollection<BasicSetting> BasicSettingCollection;
230typedef SettingManager<BasicSetting> BasicSettingManager;
231
232template <class SettingType>
233 RDMResponse *SettingManager<SettingType>::Get(const RDMRequest *request) const {
234 uint16_t data = ((m_current_setting + m_settings->Offset()) << 8 |
235 m_settings->Count());
236 if (m_settings->Offset() == 0) {
237 // don't count the 0-state
238 data--;
239 }
240 return ResponderHelper::GetUInt16Value(request, data);
241}
242
243template <class SettingType>
244 RDMResponse *SettingManager<SettingType>::Set(const RDMRequest *request) {
245 uint8_t arg;
246 if (!ResponderHelper::ExtractUInt8(request, &arg)) {
247 return NackWithReason(request, NR_FORMAT_ERROR);
248 }
249
250 unsigned int offset = m_settings->Offset();
251 if (arg < offset || arg >= m_settings->Count() + offset) {
252 return NackWithReason(request, NR_DATA_OUT_OF_RANGE);
253 } else {
254 m_current_setting = arg - offset;
255 return ResponderHelper::EmptySetResponse(request);
256 }
257}
258
259template <class SettingType>
260 RDMResponse *SettingManager<SettingType>::GetDescription(
261 const RDMRequest *request) const {
262 uint8_t arg;
263 if (!ResponderHelper::ExtractUInt8(request, &arg)) {
264 return NackWithReason(request, NR_FORMAT_ERROR);
265 }
266
267 unsigned int offset = m_settings->Offset();
268 // never reply for the first setting - see LOCK_STATE
269 if (arg == 0 || arg >= m_settings->Count() + offset) {
270 return NackWithReason(request, NR_DATA_OUT_OF_RANGE);
271 } else {
272 const SettingType *setting = m_settings->Lookup(arg - offset);
273 uint8_t output[
274 setting->DescriptionResponseSize()]; // NOLINT(runtime/arrays)
275 unsigned int size = setting->GenerateDescriptionResponse(arg, output);
276 return GetResponseFromData(request, output, size, RDM_ACK);
277 }
278}
279
280template <class SettingType>
281bool SettingManager<SettingType>::ChangeSetting(uint8_t new_setting) {
282 uint8_t offset = m_settings->Offset();
283
284 if (new_setting < offset || new_setting >= m_settings->Count() + offset)
285 return false;
286
287 m_current_setting = new_setting - offset;
288 return true;
289}
290} // namespace rdm
291} // namespace ola
292#endif // INCLUDE_OLA_RDM_RESPONDERSETTINGS_H_
Macro.h
Helper macros.
PACK
#define PACK(__Declaration__)
Pack structures.
Definition Macro.h:171
RDMCommand.h
Classes that represent RDM commands.
ResponderHelper.h
Helper methods for building RDM responders.
RDMResponse
An RDM Command that represents responses (GET, SET or DISCOVER).
Definition RDMCommand.h:457
ola::rdm::BasicSetting::GenerateDescriptionResponse
unsigned int GenerateDescriptionResponse(uint8_t index, uint8_t *data) const
Populate the _DESCRIPTION parameter data.
Definition ResponderSettings.cpp:39
ola::rdm::BasicSetting::BasicSetting
BasicSetting(const ArgType description)
Construct a new BasicSetting.
Definition ResponderSettings.cpp:35
ola::rdm::BasicSetting::Description
std::string Description() const
The text description of this setting.
Definition ResponderSettings.h:77
ola::rdm::BasicSetting::DescriptionResponseSize
unsigned int DescriptionResponseSize() const
Return the size of the _DESCRIPTION parameter data.
Definition ResponderSettings.h:79
ola::rdm::FrequencyModulationSetting::FrequencyModulationSetting
FrequencyModulationSetting(const ArgType &arg)
Construct a new FrequencyModulationSetting.
Definition ResponderSettings.cpp:50
ola::rdm::FrequencyModulationSetting::Description
std::string Description() const
The text description of this setting.
Definition ResponderSettings.h:123
ola::rdm::FrequencyModulationSetting::DescriptionResponseSize
unsigned int DescriptionResponseSize() const
Return the size of the _DESCRIPTION parameter data.
Definition ResponderSettings.h:130
ola::rdm::FrequencyModulationSetting::Frequency
uint32_t Frequency() const
returns the frequency for this setting.
Definition ResponderSettings.h:128
ola::rdm::FrequencyModulationSetting::GenerateDescriptionResponse
unsigned int GenerateDescriptionResponse(uint8_t index, uint8_t *data) const
Populate the _DESCRIPTION parameter data.
Definition ResponderSettings.cpp:55
ola::rdm::RDMRequest
RDM Commands that represent requests (GET, SET or DISCOVER).
Definition RDMCommand.h:234
ola::rdm::RDMResponse
An RDM Command that represents responses (GET, SET or DISCOVER).
Definition RDMCommand.h:457
ola::rdm::SettingCollection
Holds the list of settings for a class of responder. A single instance is shared between all responde...
Definition ResponderSettings.h:159
ola::rdm::SettingCollection::SettingCollection
SettingCollection(const typename SettingType::ArgType args[], unsigned int arg_count, bool zero_offset=false)
Definition ResponderSettings.h:166
ola::rdm::SettingInterface
The base class all Settings inherit from.
Definition ResponderSettings.h:36
ola::rdm::SettingInterface::DescriptionResponseSize
virtual unsigned int DescriptionResponseSize() const =0
Return the size of the _DESCRIPTION parameter data.
ola::rdm::SettingInterface::Description
virtual std::string Description() const =0
The text description of this setting.
ola::rdm::SettingInterface::GenerateDescriptionResponse
virtual unsigned int GenerateDescriptionResponse(uint8_t index, uint8_t *data) const =0
Populate the _DESCRIPTION parameter data.
ola::rdm::SettingManager
Definition ResponderSettings.h:201
ola::rdm::GetResponseFromData
RDMResponse * GetResponseFromData(const RDMRequest *request, const uint8_t *data, unsigned int length, rdm_response_type type, uint8_t outstanding_messages)
Generate an ACK Response with some data.
Definition RDMCommand.cpp:584
ola::rdm::NackWithReason
RDMResponse * NackWithReason(const RDMRequest *request, rdm_nack_reason reason_enum, uint8_t outstanding_messages)
Generate a NACK response with a reason code.
Definition RDMCommand.cpp:572
ola::rdm
PLASA E1.20 Remote Device Management.
Definition AckTimerResponder.cpp:38
ola
The namespace containing all OLA symbols.
Definition Credentials.cpp:44
ola::rdm::FrequencyModulationSetting::FrequencyModulationArg
The constructor argument for the FrequencyModulationSetting.
Definition ResponderSettings.h:106
ola::rdm::FrequencyModulationSetting::FrequencyModulationArg::description
const char * description
Definition ResponderSettings.h:108
ola::rdm::FrequencyModulationSetting::FrequencyModulationArg::frequency
uint32_t frequency
Definition ResponderSettings.h:107