mirror of
https://github.com/thelsing/knx.git
synced 2025-01-30 00:19:01 +01:00
refactor RfMediumObject to use properties
This commit is contained in:
parent
5855f35eef
commit
f450d87d05
@ -93,6 +93,7 @@
|
||||
<ClInclude Include="..\..\src\knx\device_object.h" />
|
||||
<ClInclude Include="..\..\src\knx\dpt.h" />
|
||||
<ClInclude Include="..\..\src\knx\dptconvert.h" />
|
||||
<ClInclude Include="..\..\src\knx\function_property.h" />
|
||||
<ClInclude Include="..\..\src\knx\group_object.h" />
|
||||
<ClInclude Include="..\..\src\knx\group_object_table_object.h" />
|
||||
<ClInclude Include="..\..\src\knx\interface_object.h" />
|
||||
|
@ -194,6 +194,9 @@
|
||||
<ClInclude Include="..\..\src\knx\knx_ip_supported_service_dib.h">
|
||||
<Filter>Header files\knx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\knx\function_property.h">
|
||||
<Filter>Header files\knx</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
|
@ -7,11 +7,11 @@ class InterfaceObject;
|
||||
template <class T> class FunctionProperty : public Property
|
||||
{
|
||||
public:
|
||||
FunctionProperty(T* io, PropertyID id, uint8_t access,
|
||||
FunctionProperty(T* io, PropertyID id,
|
||||
void (*commandCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&),
|
||||
void (*stateCallback)(T*, uint8_t*, uint8_t, uint8_t*, uint8_t&))
|
||||
: Property(id, false, PDT_FUNCTION, 1, access), _interfaceObject(io), _commandCallback(commandCallback), _stateCallback(stateCallback)
|
||||
/* max_elements is set to 1, see 3.3.7 Application Layer p.68 */
|
||||
: Property(id, false, PDT_FUNCTION, 1, ReadLv0|WriteLv0), _interfaceObject(io), _commandCallback(commandCallback), _stateCallback(stateCallback)
|
||||
/* max_elements is set to 1, read and write level any value so we use Lv0, see 3.3.7 Application Layer p.68 */
|
||||
{}
|
||||
|
||||
virtual uint8_t read(uint16_t start, uint8_t count, uint8_t* data) const override
|
||||
|
@ -10,54 +10,6 @@ InterfaceObject::~InterfaceObject()
|
||||
}
|
||||
|
||||
void InterfaceObject::readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access)
|
||||
{
|
||||
PropertyDescription* descriptions = propertyDescriptions();
|
||||
uint8_t count = propertyDescriptionCount();
|
||||
|
||||
numberOfElements = 0;
|
||||
if (descriptions == nullptr || count == 0)
|
||||
return readPropertyDescription2(propertyId, propertyIndex, writeEnable, type, numberOfElements, access);
|
||||
|
||||
PropertyDescription* desc = nullptr;
|
||||
|
||||
// from KNX spec. 03.03.07 Application Layer (page 56) - 3.4.3.3 A_PropertyDescription_Read-service
|
||||
// Summary: either propertyId OR propertyIndex, but not both at the same time
|
||||
if (propertyId != 0)
|
||||
{
|
||||
for (uint8_t i = 0; i < count; i++)
|
||||
{
|
||||
PropertyDescription d = descriptions[i];
|
||||
if (d.Id != propertyId)
|
||||
continue;
|
||||
|
||||
desc = &d;
|
||||
propertyIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If propertyId is zero, propertyIndex shall be used.
|
||||
// Response: propertyIndex of received A_PropertyDescription_Read
|
||||
if (propertyIndex < count)
|
||||
{
|
||||
desc = &descriptions[propertyIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (desc != nullptr)
|
||||
{
|
||||
propertyId = desc->Id;
|
||||
writeEnable = desc->WriteEnable;
|
||||
type = desc->Type;
|
||||
numberOfElements = desc->MaxElements;
|
||||
access = desc->Access;
|
||||
}
|
||||
else
|
||||
return readPropertyDescription2(propertyId, propertyIndex, writeEnable, type, numberOfElements, access);
|
||||
}
|
||||
|
||||
void InterfaceObject::readPropertyDescription2(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access)
|
||||
{
|
||||
uint8_t count = _propertyCount;
|
||||
|
||||
@ -161,17 +113,6 @@ void InterfaceObject::state(PropertyID id, uint8_t* data, uint8_t length, uint8_
|
||||
prop->state(data, length, resultData, resultLength);
|
||||
}
|
||||
|
||||
uint8_t InterfaceObject::propertyDescriptionCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PropertyDescription* InterfaceObject::propertyDescriptions()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void InterfaceObject::initializeProperties(size_t propertiesSize, Property** properties)
|
||||
{
|
||||
_propertyCount = propertiesSize / sizeof(Property*);
|
||||
|
@ -144,9 +144,7 @@ class InterfaceObject : public SaveRestore
|
||||
*
|
||||
* @param[out] access the ::AccessLevel necessary to read/write the property.
|
||||
*/
|
||||
// TODO: remove first version after complete property refactoring
|
||||
void readPropertyDescription(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
||||
void readPropertyDescription2(uint8_t& propertyId, uint8_t& propertyIndex, bool& writeEnable, uint8_t& type, uint16_t& numberOfElements, uint8_t& access);
|
||||
|
||||
/**
|
||||
* Gets property with PropertyID id if it exists and nullptr otherwise.
|
||||
@ -181,15 +179,6 @@ class InterfaceObject : public SaveRestore
|
||||
virtual uint16_t saveSize() override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Returns the number of properties the interface object has.
|
||||
*/
|
||||
virtual uint8_t propertyDescriptionCount();
|
||||
/**
|
||||
* Returns a pointer to the first PropertyDescription of the interface object.
|
||||
* This is used by readPropertyDescription() together with propertyCount().
|
||||
*/
|
||||
virtual PropertyDescription* propertyDescriptions();
|
||||
|
||||
/**
|
||||
* Intializes the Property-array the the supplied values.
|
||||
|
@ -1,141 +1,60 @@
|
||||
#include <cstring>
|
||||
#include "rf_medium_object.h"
|
||||
#include "bits.h"
|
||||
#include "data_property.h"
|
||||
#include "function_property.h"
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_RF
|
||||
|
||||
void RfMediumObject::readProperty(PropertyID propertyId, uint16_t start, uint8_t& count, uint8_t* data)
|
||||
RfMediumObject::RfMediumObject()
|
||||
{
|
||||
switch (propertyId)
|
||||
uint8_t rfDomainAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
|
||||
Property* properties[] =
|
||||
{
|
||||
case PID_OBJECT_TYPE:
|
||||
pushWord(OT_RF_MEDIUM, data);
|
||||
break;
|
||||
case PID_RF_MULTI_TYPE:
|
||||
data[0] = 0x00; // KNX RF ready only
|
||||
break;
|
||||
case PID_RF_DOMAIN_ADDRESS:
|
||||
pushByteArray((uint8_t*)_rfDomainAddress, 6, data);
|
||||
break;
|
||||
case PID_RF_RETRANSMITTER:
|
||||
data[0] = 0x00; // No KNX RF retransmitter
|
||||
break;
|
||||
case PID_RF_BIDIR_TIMEOUT: // PDT_FUNCTION
|
||||
data[0] = 0x00; // success
|
||||
data[1] = 0xFF; // permanent bidirectional device
|
||||
data[2] = 0xFF; // permanent bidirectional device
|
||||
break;
|
||||
case PID_RF_DIAG_SA_FILTER_TABLE: // PDT_GENERIC_03[]
|
||||
pushByteArray((uint8_t*)_rfDiagSourceAddressFilterTable, 24, data);
|
||||
break;
|
||||
case PID_RF_DIAG_BUDGET_TABLE:
|
||||
pushByteArray((uint8_t*)_rfDiagLinkBudgetTable, 24, data);
|
||||
break;
|
||||
case PID_RF_DIAG_PROBE: // PDT_FUNCTION
|
||||
// Not supported yet
|
||||
break;
|
||||
default:
|
||||
count = 0;
|
||||
}
|
||||
new DataProperty(PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0, (uint16_t)OT_RF_MEDIUM),
|
||||
new DataProperty(PID_RF_MULTI_TYPE, true, PDT_GENERIC_01, 1, ReadLv3 | WriteLv2, (uint8_t)0x00),
|
||||
new DataProperty(PID_RF_RETRANSMITTER, false, PDT_GENERIC_01, 1, ReadLv3 | WriteLv0, (uint8_t)0x00),
|
||||
new DataProperty(PID_RF_DOMAIN_ADDRESS, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv2, rfDomainAddress),
|
||||
new FunctionProperty<RfMediumObject>(this, PID_RF_BIDIR_TIMEOUT,
|
||||
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||
{
|
||||
resultData[0] = 0x00; // success
|
||||
resultData[1] = 0xFF; // permanent bidirectional device
|
||||
resultData[2] = 0xFF; // permanent bidirectional device
|
||||
resultLength = 3;
|
||||
},
|
||||
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||
{
|
||||
resultData[0] = 0x00; // success
|
||||
resultData[1] = 0xFF; // permanent bidirectional device
|
||||
resultData[2] = 0xFF; // permanent bidirectional device
|
||||
resultLength = 3;
|
||||
}),
|
||||
/* This properties are used in NMP_LinkBudget_Measure to diagnose the Link Budget of the communication.
|
||||
This in not implemented yet.
|
||||
new DataProperty(PID_RF_DIAG_SA_FILTER_TABLE, true, PDT_GENERIC_03, 8, ReadLv3 | WriteLv3),
|
||||
new DataProperty(PID_RF_DIAG_BUDGET_TABLE, false, PDT_GENERIC_03, 8, ReadLv3 | WriteLv0),
|
||||
new FunctionProperty<RfMediumObject>(this, PID_RF_DIAG_PROBE,
|
||||
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||
{
|
||||
},
|
||||
[](RfMediumObject* io, uint8_t* data, uint8_t length, uint8_t* resultData, uint8_t& resultLength)
|
||||
{
|
||||
}), */
|
||||
};
|
||||
initializeProperties(sizeof(properties), properties);
|
||||
}
|
||||
|
||||
void RfMediumObject::writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count)
|
||||
const uint8_t* RfMediumObject::rfDomainAddress()
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case PID_RF_MULTI_TYPE:
|
||||
// We only support RF ready and not RF multi, ignore write request
|
||||
break;
|
||||
case PID_RF_DOMAIN_ADDRESS:
|
||||
for (uint8_t i = start; i < start + count; i++)
|
||||
_rfDomainAddress[i-1] = data[i - start];
|
||||
break;
|
||||
case PID_RF_BIDIR_TIMEOUT: // PDT_FUNCTION
|
||||
// Not supported yet (permanent bidir device)
|
||||
break;
|
||||
case PID_RF_DIAG_SA_FILTER_TABLE:
|
||||
for (uint8_t i = start; i < start + count; i++)
|
||||
_rfDiagSourceAddressFilterTable[i-1] = data[i - start];
|
||||
break;
|
||||
case PID_RF_DIAG_BUDGET_TABLE:
|
||||
for (uint8_t i = start; i < start + count; i++)
|
||||
_rfDiagLinkBudgetTable[i-1] = data[i - start];
|
||||
break;
|
||||
case PID_RF_DIAG_PROBE:
|
||||
// Not supported yet
|
||||
break;
|
||||
default:
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RfMediumObject::propertySize(PropertyID id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case PID_RF_MULTI_TYPE:
|
||||
case PID_RF_RETRANSMITTER:
|
||||
return 1;
|
||||
case PID_OBJECT_TYPE:
|
||||
return 2;
|
||||
case PID_RF_DOMAIN_ADDRESS:
|
||||
return 6;
|
||||
case PID_RF_DIAG_SA_FILTER_TABLE:
|
||||
case PID_RF_DIAG_BUDGET_TABLE:
|
||||
return 24;
|
||||
// case PID_RF_BIDIR_TIMEOUT: ?
|
||||
// case PID_RF_DIAG_PROBE: ?
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* RfMediumObject::save(uint8_t* buffer)
|
||||
{
|
||||
buffer = pushByteArray((uint8_t*)_rfDomainAddress, 6, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const uint8_t* RfMediumObject::restore(const uint8_t* buffer)
|
||||
{
|
||||
buffer = popByteArray((uint8_t*)_rfDomainAddress, 6, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint16_t RfMediumObject::saveSize()
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
uint8_t* RfMediumObject::rfDomainAddress()
|
||||
{
|
||||
return _rfDomainAddress;
|
||||
DataProperty* prop = (DataProperty*)property(PID_RF_DOMAIN_ADDRESS);
|
||||
return prop->data();
|
||||
}
|
||||
|
||||
void RfMediumObject::rfDomainAddress(const uint8_t* value)
|
||||
{
|
||||
pushByteArray(value, 6, _rfDomainAddress);
|
||||
}
|
||||
|
||||
static PropertyDescription _propertyDescriptions[] =
|
||||
{
|
||||
{ PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0 },
|
||||
{ PID_RF_MULTI_TYPE, false, PDT_GENERIC_01, 1, ReadLv3 | WriteLv0 },
|
||||
{ PID_RF_RETRANSMITTER, false, PDT_GENERIC_01, 1, ReadLv3 | WriteLv0 },
|
||||
{ PID_RF_DOMAIN_ADDRESS, true, PDT_GENERIC_06, 1, ReadLv3 | WriteLv0 }
|
||||
};
|
||||
static uint8_t _propertyDescriptionCount = sizeof(_propertyDescriptions) / sizeof(PropertyDescription);
|
||||
|
||||
uint8_t RfMediumObject::propertyDescriptionCount()
|
||||
{
|
||||
return _propertyDescriptionCount;
|
||||
}
|
||||
|
||||
PropertyDescription* RfMediumObject::propertyDescriptions()
|
||||
{
|
||||
return _propertyDescriptions;
|
||||
Property* prop = property(PID_RF_DOMAIN_ADDRESS);
|
||||
prop->write(value);
|
||||
}
|
||||
#endif
|
@ -7,21 +7,11 @@
|
||||
class RfMediumObject: public InterfaceObject
|
||||
{
|
||||
public:
|
||||
void readProperty(PropertyID id, uint16_t start, uint8_t& count, uint8_t* data) override;
|
||||
void writeProperty(PropertyID id, uint16_t start, uint8_t* data, uint8_t& count) override;
|
||||
uint8_t propertySize(PropertyID id) override;
|
||||
uint8_t* save(uint8_t* buffer) override;
|
||||
const uint8_t* restore(const uint8_t* buffer) override;
|
||||
uint16_t saveSize() override;
|
||||
|
||||
uint8_t* rfDomainAddress();
|
||||
RfMediumObject();
|
||||
const uint8_t* rfDomainAddress();
|
||||
void rfDomainAddress(const uint8_t* value);
|
||||
|
||||
protected:
|
||||
uint8_t propertyDescriptionCount() override;
|
||||
PropertyDescription* propertyDescriptions() override;
|
||||
private:
|
||||
uint8_t _rfDomainAddress[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // see KNX RF S-Mode AN160 p.11
|
||||
uint8_t _rfDiagSourceAddressFilterTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
||||
uint8_t _rfDiagLinkBudgetTable[24] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user