knx
ETS configurable knx-stack
interface_object.cpp
Go to the documentation of this file.
1 #include <cstring>
2 
3 #include "interface_object.h"
4 #include "data_property.h"
5 
7 {
8  if (_properties != nullptr)
9  delete[] _properties;
10 }
11 
12 void InterfaceObject::readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access)
13 {
14  uint8_t count = _propertyCount;
15 
16  numberOfElements = 0;
17 
18  if (_properties == nullptr || count == 0)
19  return;
20 
21  Property* prop = nullptr;
22 
23  // from KNX spec. 03.03.07 Application Layer (page 56) - 3.4.3.3 A_PropertyDescription_Read-service
24  // Summary: either propertyId OR propertyIndex, but not both at the same time
25  if (propertyId != 0)
26  {
27  for (uint8_t i = 0; i < count; i++)
28  {
29  Property* p = _properties[i];
30 
31  if (p->Id() != propertyId)
32  continue;
33 
34  prop = p;
35  propertyIndex = i;
36  break;
37  }
38  }
39  else
40  {
41  // If propertyId is zero, propertyIndex shall be used.
42  // Response: propertyIndex of received A_PropertyDescription_Read
43  if (propertyIndex < count)
44  {
45  prop = _properties[propertyIndex];
46  }
47  }
48 
49  if (prop != nullptr)
50  {
51  propertyId = prop->Id();
52  writeEnable = prop->WriteEnable();
53  type = prop->Type();
54  numberOfElements = prop->MaxElements();
55  access = prop->Access();
56  }
57 }
58 
59 void InterfaceObject::masterReset(EraseCode eraseCode, uint8_t channel)
60 {
61  // every interface object shall implement this
62  // However, for the time being we provide an empty default implementation
63 }
64 
66 {
67  uint8_t count = 1;
68  uint16_t propval = 0;
69  readProperty(id, 0, count, (uint8_t*)&propval);
70 
71  if (count == 0)
72  {
73  length = 0;
74  return;
75  }
76 
77  length = ntohs(propval);
78 }
79 
80 void InterfaceObject::readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data)
81 {
82  Property* prop = property(id);
83 
84  if (prop == nullptr)
85  {
86  count = 0;
87  return;
88  }
89 
90  count = prop->read(start, count, data);
91 }
92 
93 void InterfaceObject::writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count)
94 {
95  Property* prop = property(id);
96 
97  if (prop == nullptr)
98  {
99  count = 0;
100  return;
101  }
102 
103  count = prop->write(start, count, data);
104 }
105 
107 {
108  Property* prop = property(id);
109 
110  if (prop == nullptr)
111  {
112  return 0;
113  }
114 
115  return prop->ElementSize();
116 }
117 
118 void InterfaceObject::command(PropertyID id, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
119 {
120  Property* prop = property(id);
121 
122  if (prop == nullptr)
123  {
124  resultLength = 0;
125  return;
126  }
127 
128  prop->command(data, length, resultData, resultLength);
129 }
130 
131 void InterfaceObject::state(PropertyID id, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
132 {
133  Property* prop = property(id);
134 
135  if (prop == nullptr)
136  {
137  resultLength = 0;
138  return;
139  }
140 
141  prop->state(data, length, resultData, resultLength);
142 }
143 
144 void InterfaceObject::initializeProperties(size_t propertiesSize, Property** properties)
145 {
146  _propertyCount = propertiesSize / sizeof(Property*);
148  memcpy(_properties, properties, propertiesSize);
149 }
150 
151 
153 {
154  for (int i = 0; i < _propertyCount; i++)
155  if (_properties[i]->Id() == id)
156  return _properties[i];
157 
158  return nullptr;
159 }
160 
161 
162 uint8_t* InterfaceObject::save(uint8_t* buffer)
163 {
164  for (int i = 0; i < _propertyCount; i++)
165  {
166  Property* prop = _properties[i];
167 
168  if (!prop->WriteEnable())
169  continue;
170 
171  buffer = prop->save(buffer);
172  }
173 
174  return buffer;
175 }
176 
177 
178 const uint8_t* InterfaceObject::restore(const uint8_t* buffer)
179 {
180  for (int i = 0; i < _propertyCount; i++)
181  {
182  Property* prop = _properties[i];
183 
184  if (!prop->WriteEnable())
185  continue;
186 
187  buffer = prop->restore(buffer);
188  }
189 
190  return buffer;
191 }
192 
193 
195 {
196  uint16_t size = 0;
197 
198  for (int i = 0; i < _propertyCount; i++)
199  {
200  Property* prop = _properties[i];
201 
202  if (!prop->WriteEnable())
203  continue;
204 
205  size += prop->saveSize();
206  }
207 
208  return size;
209 }
210 
211 
213 {
214  for (int i = 0; i < _propertyCount; i++)
215  if (_properties[i]->Id() == id)
216  return _properties[i];
217 
218  return nullptr;
219 }
220 
221 
223 {
224  DataProperty* prop = (DataProperty*)property(id);
225  return prop->data();
226 }
227 
228 const uint8_t* InterfaceObject::propertyData(PropertyID id, uint16_t elementIndex)
229 {
230  DataProperty* prop = (DataProperty*)property(id);
231  return prop->data(elementIndex);
232 }
const uint8_t * data()
uint8_t * save(uint8_t *buffer) override
This method is called when the object should save its state to the buffer.
const uint8_t * propertyData(PropertyID id)
Property ** _properties
const uint8_t * restore(const uint8_t *buffer) override
This method is called when the object should restore its state from the buffer.
void readPropertyDescription(uint8_t &propertyId, uint8_t &propertyIndex, bool &writeEnable, uint8_t &type, uint16_t &numberOfElements, uint8_t &access)
Read the Description of a property of the interface object.
virtual void masterReset(EraseCode eraseCode, uint8_t channel)
virtual void command(PropertyID id, uint8_t *data, uint8_t length, uint8_t *resultData, uint8_t &resultLength)
Call command of a function property of the interface object.
virtual ~InterfaceObject()
Destructor.
virtual void writeProperty(PropertyID id, uint16_t start, uint8_t *data, uint8_t &count)
Write property of the interface object.
virtual uint8_t propertySize(PropertyID id)
Gets the size of of property in bytes.
virtual void readProperty(PropertyID id, uint16_t start, uint8_t &count, uint8_t *data)
Read a property of the interface object.
virtual void state(PropertyID id, uint8_t *data, uint8_t length, uint8_t *resultData, uint8_t &resultLength)
Get state of a function property of the interface object.
virtual void readPropertyLength(PropertyID id, uint16_t &length)
Read length of a property of the interface object.
virtual void initializeProperties(size_t propertiesSize, Property **properties)
Intializes the Property-array the the supplied values.
uint16_t saveSize() override
Property * property(PropertyID id)
Gets property with PropertyID id if it exists and nullptr otherwise.
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t *data) const =0
uint8_t ElementSize() const
Definition: property.cpp:31
virtual void state(uint8_t *data, uint8_t length, uint8_t *resultData, uint8_t &resultLength)
Definition: property.cpp:239
uint8_t Access() const
Definition: property.cpp:26
PropertyID Id() const
Definition: property.cpp:6
virtual uint8_t write(uint16_t start, uint8_t count, const uint8_t *data)=0
uint16_t MaxElements() const
Definition: property.cpp:21
virtual void command(uint8_t *data, uint8_t length, uint8_t *resultData, uint8_t &resultLength)
Definition: property.cpp:231
bool WriteEnable() const
Definition: property.cpp:11
PropertyDataType Type() const
Definition: property.cpp:16
virtual uint8_t * save(uint8_t *buffer)
This method is called when the object should save its state to the buffer.
Definition: save_restore.h:18
virtual const uint8_t * restore(const uint8_t *buffer)
This method is called when the object should restore its state from the buffer.
Definition: save_restore.h:31
virtual uint16_t saveSize()
Definition: save_restore.h:39
EraseCode
Definition: knx_types.h:242
PropertyID
Definition: property.h:70