mirror of
https://github.com/thelsing/knx.git
synced 2025-01-21 00:05:43 +01:00
convert CallbackProperty to template
This commit is contained in:
parent
71448efdad
commit
e128debabb
@ -24,7 +24,6 @@ add_executable(knx-linux
|
||||
../src/knx/bau_systemB.h
|
||||
../src/knx/bits.cpp
|
||||
../src/knx/bits.h
|
||||
../src/knx/callback_property.cpp
|
||||
../src/knx/callback_property.h
|
||||
../src/knx/cemi_frame.cpp
|
||||
../src/knx/cemi_frame.h
|
||||
|
@ -136,7 +136,6 @@
|
||||
<ClCompile Include="..\src\knx\bau57B0.cpp" />
|
||||
<ClCompile Include="..\src\knx\bau_systemB.cpp" />
|
||||
<ClCompile Include="..\src\knx\bits.cpp" />
|
||||
<ClCompile Include="..\src\knx\callback_property.cpp" />
|
||||
<ClCompile Include="..\src\knx\cemi_frame.cpp" />
|
||||
<ClCompile Include="..\src\knx\cemi_server.cpp" />
|
||||
<ClCompile Include="..\src\knx\cemi_server_object.cpp" />
|
||||
|
@ -301,8 +301,5 @@
|
||||
<ClCompile Include="..\src\knx\data_property.cpp">
|
||||
<Filter>Source files\knx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\knx\callback_property.cpp">
|
||||
<Filter>Source files\knx</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,29 +0,0 @@
|
||||
#include "callback_property.h"
|
||||
|
||||
CallbackProperty::CallbackProperty(PropertyID id, bool writeEnable, PropertyDataType type,
|
||||
uint16_t maxElements, uint8_t access,
|
||||
PropertyCallback readCallback, PropertyCallback writeCallback)
|
||||
: Property(id, writeEnable, type, maxElements, access), _readCallback(), _writeCallback()
|
||||
{}
|
||||
|
||||
CallbackProperty::CallbackProperty(PropertyID id, bool writeEnable, PropertyDataType type,
|
||||
uint16_t maxElements, uint8_t access,
|
||||
PropertyCallback readCallback)
|
||||
: Property(id, writeEnable, type, maxElements, access), _readCallback()
|
||||
{}
|
||||
|
||||
uint8_t CallbackProperty::read(uint16_t start, uint8_t count, uint8_t* data)
|
||||
{
|
||||
if (count == 0 || _readCallback == nullptr)
|
||||
return 0;
|
||||
|
||||
return _readCallback(start, count, data);
|
||||
}
|
||||
|
||||
uint8_t CallbackProperty::write(uint16_t start, uint8_t count, uint8_t* data)
|
||||
{
|
||||
if (count == 0 || start > _maxElements || !_writeEnable || start + count > _maxElements + 1
|
||||
|| _writeCallback == nullptr)
|
||||
return 0;
|
||||
return _writeCallback(start, count, data);
|
||||
}
|
@ -2,18 +2,37 @@
|
||||
|
||||
#include "property.h"
|
||||
|
||||
typedef uint8_t (*PropertyCallback)(uint16_t start, uint8_t count, uint8_t* data);
|
||||
class InterfaceObject;
|
||||
|
||||
class CallbackProperty : public Property
|
||||
template <class T> class CallbackProperty : public Property
|
||||
{
|
||||
public:
|
||||
CallbackProperty(PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements,
|
||||
uint8_t access, PropertyCallback readCallback, PropertyCallback writeCallback);
|
||||
CallbackProperty(PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements,
|
||||
uint8_t access, PropertyCallback readCallback);
|
||||
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) override;
|
||||
virtual uint8_t write(uint16_t start, uint8_t count, uint8_t* data) override;
|
||||
CallbackProperty(T* io, PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements,
|
||||
uint8_t access, uint8_t (*readCallback)(T*, uint16_t, uint8_t, uint8_t*),
|
||||
uint8_t (*writeCallback)(T*, uint16_t, uint8_t, uint8_t*))
|
||||
: Property(id, writeEnable, type, maxElements, access),
|
||||
_interfaceObject(io), _readCallback(readCallback), _writeCallback(writeCallback)
|
||||
{}
|
||||
CallbackProperty(T* io, PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements,
|
||||
uint8_t access, uint8_t (*readCallback)(T*, uint16_t, uint8_t, uint8_t*))
|
||||
: Property(id, writeEnable, type, maxElements, access), _interfaceObject(io), _readCallback(readCallback)
|
||||
{}
|
||||
|
||||
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) override
|
||||
{
|
||||
if (count == 0 || _readCallback == nullptr || start > _maxElements || start + count > _maxElements + 1)
|
||||
return 0;
|
||||
|
||||
return _readCallback(_interfaceObject, start, count, data);
|
||||
}
|
||||
virtual uint8_t write(uint16_t start, uint8_t count, uint8_t* data) override
|
||||
{
|
||||
if (count == 0 || start > _maxElements || !_writeEnable || start + count > _maxElements + 1 || _writeCallback == nullptr)
|
||||
return 0;
|
||||
return _writeCallback(_interfaceObject, start, count, data);
|
||||
}
|
||||
private:
|
||||
PropertyCallback _readCallback = nullptr;
|
||||
PropertyCallback _writeCallback = nullptr;
|
||||
T* _interfaceObject = nullptr;
|
||||
uint8_t (*_readCallback)(T*, uint16_t, uint8_t, uint8_t*) = nullptr;
|
||||
uint8_t (*_writeCallback)(T*, uint16_t, uint8_t, uint8_t*) = nullptr;
|
||||
};
|
||||
|
@ -81,3 +81,16 @@ DataProperty::~DataProperty()
|
||||
if (_data)
|
||||
delete[] _data;
|
||||
}
|
||||
|
||||
DataProperty::DataProperty(PropertyID id, bool writeEnable, PropertyDataType type,
|
||||
uint16_t maxElements, uint8_t access, uint16_t value)
|
||||
: Property(id, writeEnable, type, maxElements, access)
|
||||
{
|
||||
uint8_t elementSize = ElementSize();
|
||||
if (elementSize == 2)
|
||||
{
|
||||
uint8_t data[elementSize];
|
||||
pushWord(value, data);
|
||||
write(1, 1, data);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ class DataProperty : public Property
|
||||
{
|
||||
public:
|
||||
DataProperty(PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements, uint8_t access);
|
||||
DataProperty(PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements, uint8_t access, uint16_t value);
|
||||
virtual ~DataProperty() override;
|
||||
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) override;
|
||||
virtual uint8_t write(uint16_t start, uint8_t count, uint8_t* data) override;
|
||||
|
@ -56,21 +56,37 @@ void InterfaceObject::readPropertyDescription(uint8_t& propertyId, uint8_t& prop
|
||||
|
||||
void InterfaceObject::readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data)
|
||||
{
|
||||
// Set number of elements to zero as we are in the end of the call chain
|
||||
// Nobody processed the property before.
|
||||
count = 0;
|
||||
Property* prop = property(id);
|
||||
if (prop == nullptr)
|
||||
{
|
||||
count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
count = prop->read(start, count, data);
|
||||
}
|
||||
|
||||
void InterfaceObject::writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count)
|
||||
{
|
||||
// Set number of elements to zero as we are in the end of the call chain
|
||||
// Nobody processed the property before.
|
||||
count = 0;
|
||||
Property* prop = property(id);
|
||||
if (prop == nullptr)
|
||||
{
|
||||
count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
count = prop->write(start, count, data);
|
||||
}
|
||||
|
||||
uint8_t InterfaceObject::propertySize(PropertyID id)
|
||||
{
|
||||
return 0;
|
||||
Property* prop = property(id);
|
||||
if (prop == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return prop->ElementSize();
|
||||
}
|
||||
|
||||
uint8_t InterfaceObject::propertyDescriptionCount()
|
||||
@ -100,3 +116,47 @@ Property* InterfaceObject::property(PropertyID id)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* InterfaceObject::save(uint8_t* buffer)
|
||||
{
|
||||
for (int i = 0; i < _propertyCount; i++)
|
||||
{
|
||||
Property* prop = _properties[i];
|
||||
if (!prop->WriteEnable())
|
||||
continue;
|
||||
|
||||
buffer = prop->save(buffer);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
uint8_t* InterfaceObject::restore(uint8_t* buffer)
|
||||
{
|
||||
for (int i = 0; i < _propertyCount; i++)
|
||||
{
|
||||
Property* prop = _properties[i];
|
||||
if (!prop->WriteEnable())
|
||||
continue;
|
||||
|
||||
buffer = prop->restore(buffer);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
uint16_t InterfaceObject::saveSize()
|
||||
{
|
||||
uint16_t size = 0;
|
||||
|
||||
for (int i = 0; i < _propertyCount; i++)
|
||||
{
|
||||
Property* prop = _properties[i];
|
||||
if (!prop->WriteEnable())
|
||||
continue;
|
||||
|
||||
size += prop->saveSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
@ -131,6 +131,10 @@ class InterfaceObject : public SaveRestore
|
||||
*/
|
||||
Property* property(PropertyID id);
|
||||
|
||||
virtual uint8_t* save(uint8_t* buffer) override;
|
||||
virtual uint8_t* restore(uint8_t* buffer) override;
|
||||
virtual uint16_t saveSize() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Returns the number of properties the interface object has.
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include "device_object.h"
|
||||
#include "platform.h"
|
||||
#include "bits.h"
|
||||
#include "data_property.h"
|
||||
#include "callback_property.h"
|
||||
|
||||
//224.0.23.12
|
||||
#define DEFAULT_MULTICAST_ADDR 0xE000170C
|
||||
@ -11,27 +13,41 @@ IpParameterObject::IpParameterObject(DeviceObject& deviceObject, Platform& platf
|
||||
{
|
||||
Property* properties[] =
|
||||
{
|
||||
new DataProperty(PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0)
|
||||
new DataProperty(PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0, OT_IP_PARAMETER),
|
||||
new DataProperty(PID_PROJECT_INSTALLATION_ID, true, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv3),
|
||||
new CallbackProperty<IpParameterObject>(this, PID_KNX_INDIVIDUAL_ADDRESS, true, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv3,
|
||||
[](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t
|
||||
{
|
||||
pushWord(io->_deviceObject.induvidualAddress(), data);
|
||||
return 1;
|
||||
},
|
||||
[](IpParameterObject* io, uint16_t start, uint8_t count, uint8_t* data) -> uint8_t
|
||||
{
|
||||
io->_deviceObject.induvidualAddress(getWord(data));
|
||||
return 1;
|
||||
}),
|
||||
//55 PID_IP_ASSIGNMENT_METHOD 3 / 3
|
||||
//56 PID_IP_CAPABILITIES 3 / 1
|
||||
//57 PID_CURRENT_IP_ADDRESS 3 / x
|
||||
//58 PID_CURRENT_SUBNET_MASK 3 / x
|
||||
//59 PID_CURRENT_DEFAULT_GATEWAY 3 / x
|
||||
//60 PID_IP_ADDRESS 3 / 3
|
||||
//61 PID_SUBNET_MASK 3 / 3
|
||||
//62 PID_DEFAULT_GATEWAY 3 / 3
|
||||
//64 PID_MAC_ADDRESS 3 / x
|
||||
//65 PID_SYSTEM_SETUP_MULTICAST_ADDRESS 3 / x
|
||||
//66 PID_ROUTING_MULTICAST_ADDRESS 3 / 3
|
||||
//67 PID_TTL 3 / 3
|
||||
//68 PID_KNXNETIP_DEVICE_CAPABILITIES 3 / x
|
||||
//76 PID_FRIENDLY_NAME 3 / 3
|
||||
};
|
||||
initializeProperties(sizeof(properties), properties);
|
||||
initializeProperties(sizeof(properties), properties);
|
||||
}
|
||||
|
||||
void IpParameterObject::readProperty(PropertyID propertyId, uint16_t start, uint8_t& count, uint8_t* data)
|
||||
{
|
||||
switch (propertyId)
|
||||
{
|
||||
case PID_LOAD_STATE_CONTROL:
|
||||
data[0] = _state;
|
||||
break;
|
||||
case PID_OBJECT_TYPE:
|
||||
pushWord(OT_IP_PARAMETER, data);
|
||||
break;
|
||||
case PID_PROJECT_INSTALLATION_ID:
|
||||
pushWord(_projectInstallationId, data);
|
||||
break;
|
||||
case PID_KNX_INDIVIDUAL_ADDRESS:
|
||||
pushWord(_deviceObject.induvidualAddress(), data);
|
||||
break;
|
||||
case PID_IP_ASSIGNMENT_METHOD:
|
||||
data[0] = _ipAssignmentMethod;
|
||||
break;
|
||||
@ -80,7 +96,7 @@ void IpParameterObject::readProperty(PropertyID propertyId, uint16_t start, uint
|
||||
data[i-start] = _friendlyName[i-1];
|
||||
break;
|
||||
default:
|
||||
count = 0;
|
||||
InterfaceObject::readProperty(propertyId, start, count, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -89,15 +105,6 @@ void IpParameterObject::writeProperty(PropertyID id, uint16_t start, uint8_t* da
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case PID_LOAD_STATE_CONTROL:
|
||||
loadEvent(data);
|
||||
break;
|
||||
case PID_PROJECT_INSTALLATION_ID:
|
||||
_projectInstallationId = getWord(data);
|
||||
break;
|
||||
case PID_KNX_INDIVIDUAL_ADDRESS:
|
||||
_deviceObject.induvidualAddress(getWord(data));
|
||||
break;
|
||||
case PID_IP_ASSIGNMENT_METHOD:
|
||||
_ipAssignmentMethod = data[0];
|
||||
break;
|
||||
@ -121,7 +128,7 @@ void IpParameterObject::writeProperty(PropertyID id, uint16_t start, uint8_t* da
|
||||
_friendlyName[i-1] = data[i - start];
|
||||
break;
|
||||
default:
|
||||
count = 0;
|
||||
InterfaceObject::writeProperty(id, start, data, count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -137,8 +144,6 @@ uint8_t IpParameterObject::propertySize(PropertyID id)
|
||||
case PID_KNXNETIP_DEVICE_CAPABILITIES:
|
||||
case PID_FRIENDLY_NAME:
|
||||
return 1;
|
||||
case PID_OBJECT_TYPE:
|
||||
case PID_PROJECT_INSTALLATION_ID:
|
||||
case PID_KNX_INDIVIDUAL_ADDRESS:
|
||||
return 2;
|
||||
case PID_CURRENT_IP_ADDRESS:
|
||||
@ -153,7 +158,7 @@ uint8_t IpParameterObject::propertySize(PropertyID id)
|
||||
case PID_MAC_ADDRESS:
|
||||
return 6;
|
||||
}
|
||||
return 0;
|
||||
return InterfaceObject::propertySize(id);
|
||||
}
|
||||
|
||||
uint8_t* IpParameterObject::save(uint8_t* buffer)
|
||||
@ -194,125 +199,6 @@ uint32_t IpParameterObject::multicastAddress() const
|
||||
return _multicastAddress;
|
||||
}
|
||||
|
||||
void IpParameterObject::loadEvent(uint8_t* data)
|
||||
{
|
||||
switch (_state)
|
||||
{
|
||||
case LS_UNLOADED:
|
||||
loadEventUnloaded(data);
|
||||
break;
|
||||
case LS_LOADING:
|
||||
loadEventLoading(data);
|
||||
break;
|
||||
case LS_LOADED:
|
||||
loadEventLoaded(data);
|
||||
break;
|
||||
case LS_ERROR:
|
||||
loadEventError(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IpParameterObject::loadState(LoadState newState)
|
||||
{
|
||||
if (newState == _state)
|
||||
return;
|
||||
//beforeStateChange(newState);
|
||||
_state = newState;
|
||||
}
|
||||
|
||||
void IpParameterObject::loadEventUnloaded(uint8_t* data)
|
||||
{
|
||||
uint8_t event = data[0];
|
||||
switch (event)
|
||||
{
|
||||
case LE_NOOP:
|
||||
case LE_LOAD_COMPLETED:
|
||||
case LE_ADDITIONAL_LOAD_CONTROLS:
|
||||
case LE_UNLOAD:
|
||||
break;
|
||||
case LE_START_LOADING:
|
||||
loadState(LS_LOADING);
|
||||
break;
|
||||
default:
|
||||
loadState(LS_ERROR);
|
||||
_errorCode = E_GOT_UNDEF_LOAD_CMD;
|
||||
}
|
||||
}
|
||||
|
||||
void IpParameterObject::loadEventLoading(uint8_t* data)
|
||||
{
|
||||
uint8_t event = data[0];
|
||||
switch (event)
|
||||
{
|
||||
case LE_NOOP:
|
||||
case LE_START_LOADING:
|
||||
break;
|
||||
case LE_LOAD_COMPLETED:
|
||||
loadState(LS_LOADED);
|
||||
break;
|
||||
case LE_UNLOAD:
|
||||
loadState(LS_UNLOADED);
|
||||
break;
|
||||
case LE_ADDITIONAL_LOAD_CONTROLS:
|
||||
additionalLoadControls(data);
|
||||
break;
|
||||
default:
|
||||
loadState(LS_ERROR);
|
||||
_errorCode = E_GOT_UNDEF_LOAD_CMD;
|
||||
}
|
||||
}
|
||||
|
||||
void IpParameterObject::loadEventLoaded(uint8_t* data)
|
||||
{
|
||||
uint8_t event = data[0];
|
||||
switch (event)
|
||||
{
|
||||
case LE_NOOP:
|
||||
case LE_LOAD_COMPLETED:
|
||||
break;
|
||||
case LE_START_LOADING:
|
||||
loadState(LS_LOADING);
|
||||
break;
|
||||
case LE_UNLOAD:
|
||||
loadState(LS_UNLOADED);
|
||||
break;
|
||||
case LE_ADDITIONAL_LOAD_CONTROLS:
|
||||
loadState(LS_ERROR);
|
||||
_errorCode = E_INVALID_OPCODE;
|
||||
break;
|
||||
default:
|
||||
loadState(LS_ERROR);
|
||||
_errorCode = E_GOT_UNDEF_LOAD_CMD;
|
||||
}
|
||||
}
|
||||
|
||||
void IpParameterObject::loadEventError(uint8_t* data)
|
||||
{
|
||||
uint8_t event = data[0];
|
||||
switch (event)
|
||||
{
|
||||
case LE_NOOP:
|
||||
case LE_LOAD_COMPLETED:
|
||||
case LE_ADDITIONAL_LOAD_CONTROLS:
|
||||
case LE_START_LOADING:
|
||||
break;
|
||||
case LE_UNLOAD:
|
||||
loadState(LS_UNLOADED);
|
||||
break;
|
||||
default:
|
||||
loadState(LS_ERROR);
|
||||
_errorCode = E_GOT_UNDEF_LOAD_CMD;
|
||||
}
|
||||
}
|
||||
|
||||
void IpParameterObject::additionalLoadControls(uint8_t* data)
|
||||
{
|
||||
loadState(LS_ERROR);
|
||||
_errorCode = E_INVALID_OPCODE;
|
||||
return;
|
||||
}
|
||||
|
||||
static PropertyDescription _propertyDescriptions[] =
|
||||
{
|
||||
{ PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0 },
|
||||
@ -334,4 +220,4 @@ PropertyDescription* IpParameterObject::propertyDescriptions()
|
||||
uint16_t IpParameterObject::saveSize()
|
||||
{
|
||||
return 51;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "interface_object.h"
|
||||
#include "data_property.h"
|
||||
#include "device_object.h"
|
||||
#include "platform.h"
|
||||
|
||||
@ -40,17 +39,4 @@ class IpParameterObject : public InterfaceObject
|
||||
char _friendlyName[30] = {0};
|
||||
DeviceObject& _deviceObject;
|
||||
Platform& _platform;
|
||||
|
||||
void loadEvent(uint8_t* data);
|
||||
void loadEventUnloaded(uint8_t* data);
|
||||
void loadEventLoading(uint8_t* data);
|
||||
void loadEventLoaded(uint8_t* data);
|
||||
void loadEventError(uint8_t* data);
|
||||
void additionalLoadControls(uint8_t* data);
|
||||
void loadState(LoadState newState);
|
||||
LoadState _state = LS_UNLOADED;
|
||||
ErrorCode _errorCode = E_NO_FAULT;
|
||||
|
||||
Property** _properties = nullptr;
|
||||
uint8_t _propertyCount = 0;
|
||||
};
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "save_restore.h"
|
||||
|
||||
/** The data type of a property. */
|
||||
enum PropertyDataType
|
||||
@ -224,9 +225,7 @@ struct PropertyDescription
|
||||
uint8_t Access;
|
||||
};
|
||||
|
||||
typedef uint8_t (*PropertyCallback)(uint16_t start, uint8_t count, uint8_t* data);
|
||||
|
||||
class Property
|
||||
class Property : public SaveRestore
|
||||
{
|
||||
public:
|
||||
Property(PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements, uint8_t access);
|
||||
|
Loading…
Reference in New Issue
Block a user