mirror of
https://github.com/thelsing/knx.git
synced 2024-12-18 19:08:18 +01:00
306 lines
9.1 KiB
C++
306 lines
9.1 KiB
C++
#include "bau57B0.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
using namespace std;
|
|
|
|
Bau57B0::Bau57B0(Platform& platform): _memoryReference((uint8_t*)&_deviceObj), _memory(platform), _addrTable(_memoryReference),
|
|
_assocTable(_memoryReference), _groupObjTable(_memoryReference), _appProgram(_memoryReference),
|
|
_ipParameters(_deviceObj, platform), _platform(platform), _appLayer(_assocTable, *this),
|
|
_transLayer(_appLayer, _addrTable, _platform), _netLayer(_transLayer),
|
|
_dlLayer(_deviceObj, _addrTable, _ipParameters, _netLayer, _platform)
|
|
{
|
|
_appLayer.transportLayer(_transLayer);
|
|
_transLayer.networkLayer(_netLayer);
|
|
_netLayer.dataLinkLayer(_dlLayer);
|
|
_memory.addSaveRestore(&_deviceObj);
|
|
_memory.addSaveRestore(&_ipParameters);
|
|
_memory.addSaveRestore(&_appProgram);
|
|
_memory.addSaveRestore(&_addrTable);
|
|
_memory.addSaveRestore(&_assocTable);
|
|
_memory.addSaveRestore(&_groupObjTable);
|
|
}
|
|
|
|
void Bau57B0::loop()
|
|
{
|
|
_dlLayer.loop();
|
|
_transLayer.loop();
|
|
sendNextGroupTelegram();
|
|
}
|
|
|
|
void Bau57B0::sendNextGroupTelegram()
|
|
{
|
|
static uint16_t startIdx = 1;
|
|
|
|
GroupObjectTableObject& table = _groupObjTable;
|
|
uint16_t objCount = table.entryCount();
|
|
|
|
for (uint16_t asap = startIdx; asap < objCount; asap++)
|
|
{
|
|
GroupObject& go = table.get(asap);
|
|
|
|
ComFlag flag = go.commFlag();
|
|
if (flag != ReadRequest && flag != WriteRequest)
|
|
continue;
|
|
|
|
if(!go.communicationEnable() || ! go.transmitEnable())
|
|
continue;
|
|
|
|
if (flag == WriteRequest)
|
|
{
|
|
uint8_t* data = go.valueRef();
|
|
_appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, data,
|
|
go.sizeInTelegram());
|
|
}
|
|
else
|
|
{
|
|
_appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter);
|
|
}
|
|
|
|
go.commFlag(Transmitting);
|
|
|
|
startIdx = asap + 1;
|
|
return;
|
|
}
|
|
|
|
startIdx = 1;
|
|
}
|
|
|
|
void Bau57B0::updateGroupObject(GroupObject & go, uint8_t * data, uint8_t length)
|
|
{
|
|
uint8_t* goData = go.valueRef();
|
|
if (length != go.valueSize())
|
|
{
|
|
go.commFlag(Error);
|
|
return;
|
|
}
|
|
|
|
memcpy(goData, data, length);
|
|
|
|
go.commFlag(cfUpdate);
|
|
if (go.updateHandler)
|
|
go.updateHandler(go);
|
|
}
|
|
|
|
void Bau57B0::readMemory()
|
|
{
|
|
_memory.readMemory();
|
|
}
|
|
|
|
DeviceObject& Bau57B0::deviceObject()
|
|
{
|
|
return _deviceObj;
|
|
}
|
|
|
|
GroupObjectTableObject& Bau57B0::groupObjectTable()
|
|
{
|
|
return _groupObjTable;
|
|
}
|
|
|
|
ApplicationProgramObject& Bau57B0::parameters()
|
|
{
|
|
return _appProgram;
|
|
}
|
|
|
|
bool Bau57B0::configured()
|
|
{
|
|
return _groupObjTable.loadState() == LS_LOADED
|
|
&& _addrTable.loadState() == LS_LOADED
|
|
&& _assocTable.loadState() == LS_LOADED
|
|
&& _appProgram.loadState() == LS_LOADED;
|
|
}
|
|
|
|
bool Bau57B0::enabled()
|
|
{
|
|
return _dlLayer.enabled();
|
|
}
|
|
|
|
void Bau57B0::enabled(bool value)
|
|
{
|
|
_dlLayer.enabled(value);
|
|
}
|
|
|
|
void Bau57B0::memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number,
|
|
uint16_t memoryAddress, uint8_t * data)
|
|
{
|
|
memcpy(_memoryReference + memoryAddress, data, number);
|
|
_memory.memoryModified();
|
|
|
|
if (_deviceObj.verifyMode())
|
|
memoryReadIndication(priority, hopType, asap, number, memoryAddress);
|
|
}
|
|
|
|
void Bau57B0::memoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number,
|
|
uint16_t memoryAddress)
|
|
{
|
|
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
|
|
_memoryReference + memoryAddress);
|
|
}
|
|
|
|
void Bau57B0::deviceDescriptorReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t descriptorType)
|
|
{
|
|
if (descriptorType != 0)
|
|
descriptorType = 0x3f;
|
|
|
|
uint8_t descriptor[] = { 0x57, 0xb0 };
|
|
|
|
_appLayer.deviceDescriptorReadResponse(AckRequested, priority, hopType, asap, descriptorType, descriptor);
|
|
}
|
|
|
|
void Bau57B0::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap)
|
|
{
|
|
// for platforms that don't really restart
|
|
_deviceObj.progMode(false);
|
|
|
|
// Flush the EEPROM before resetting
|
|
_memory.writeMemory();
|
|
_platform.restart();
|
|
}
|
|
|
|
void Bau57B0::authorizeIndication(Priority priority, HopCountType hopType, uint16_t asap, uint32_t key)
|
|
{
|
|
_appLayer.authorizeResponse(AckRequested, priority, hopType, asap, 0);
|
|
}
|
|
|
|
void Bau57B0::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress)
|
|
{
|
|
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, number, memoryAddress,
|
|
_memoryReference + memoryAddress);
|
|
}
|
|
|
|
void Bau57B0::userMemoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t number, uint32_t memoryAddress, uint8_t* data)
|
|
{
|
|
memcpy(_memoryReference + memoryAddress, data, number);
|
|
_memory.memoryModified();
|
|
|
|
if (_deviceObj.verifyMode())
|
|
userMemoryReadIndication(priority, hopType, asap, number, memoryAddress);
|
|
}
|
|
|
|
void Bau57B0::propertyDescriptionReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
|
|
uint8_t propertyId, uint8_t propertyIndex)
|
|
{
|
|
uint8_t pid = propertyId;
|
|
bool writeEnable = false;
|
|
uint8_t type = 0;
|
|
uint16_t numberOfElements = 0;
|
|
uint8_t access = 0;
|
|
InterfaceObject* obj = getInterfaceObject(objectIndex);
|
|
if (obj)
|
|
obj->readPropertyDescription(pid, propertyIndex, writeEnable, type, numberOfElements, access);
|
|
|
|
_appLayer.propertyDescriptionReadResponse(AckRequested, priority, hopType, asap, objectIndex, pid, propertyIndex,
|
|
writeEnable, type, numberOfElements, access);
|
|
}
|
|
|
|
void Bau57B0::propertyValueWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
|
|
uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length)
|
|
{
|
|
InterfaceObject* obj = getInterfaceObject(objectIndex);
|
|
if(obj)
|
|
obj->writeProperty((PropertyID)propertyId, startIndex, data, numberOfElements);
|
|
propertyValueReadIndication(priority, hopType, asap, objectIndex, propertyId, numberOfElements, startIndex);
|
|
}
|
|
|
|
void Bau57B0::propertyValueReadIndication(Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
|
|
uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex)
|
|
{
|
|
uint8_t size = 0;
|
|
uint32_t elementCount = numberOfElements;
|
|
InterfaceObject* obj = getInterfaceObject(objectIndex);
|
|
if (obj)
|
|
{
|
|
uint8_t elementSize = obj->propertySize((PropertyID)propertyId);
|
|
size = elementSize * numberOfElements;
|
|
}
|
|
else
|
|
elementCount = 0;
|
|
|
|
uint8_t data[size];
|
|
if(obj)
|
|
obj->readProperty((PropertyID)propertyId, startIndex, elementCount, data);
|
|
_appLayer.propertyValueReadResponse(AckRequested, priority, hopType, asap, objectIndex, propertyId, elementCount,
|
|
startIndex, data, size);
|
|
}
|
|
|
|
void Bau57B0::individualAddressReadIndication(HopCountType hopType)
|
|
{
|
|
if (_deviceObj.progMode())
|
|
_appLayer.individualAddressReadResponse(AckRequested, hopType);
|
|
}
|
|
|
|
void Bau57B0::individualAddressWriteIndication(HopCountType hopType, uint16_t newaddress)
|
|
{
|
|
if (_deviceObj.progMode())
|
|
_deviceObj.induvidualAddress(newaddress);
|
|
}
|
|
|
|
void Bau57B0::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, uint8_t * data, uint8_t dataLength, bool status)
|
|
{
|
|
GroupObject& go = _groupObjTable.get(asap);
|
|
if (status)
|
|
go.commFlag(Ok);
|
|
else
|
|
go.commFlag(Error);
|
|
}
|
|
|
|
void Bau57B0::groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, bool status)
|
|
{
|
|
GroupObject& go = _groupObjTable.get(asap);
|
|
if (status)
|
|
go.commFlag(Ok);
|
|
else
|
|
go.commFlag(Error);
|
|
}
|
|
|
|
void Bau57B0::groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType)
|
|
{
|
|
GroupObject& go = _groupObjTable.get(asap);
|
|
uint8_t* data = go.valueRef();
|
|
_appLayer.groupValueReadResponse(AckRequested, asap, priority, hopType, data, go.sizeInTelegram());
|
|
}
|
|
|
|
void Bau57B0::groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, uint8_t* data,
|
|
uint8_t dataLength)
|
|
{
|
|
GroupObject& go = _groupObjTable.get(asap);
|
|
|
|
if (!go.communicationEnable() || !go.responseUpdateEnable())
|
|
return;
|
|
|
|
updateGroupObject(go, data, dataLength);
|
|
}
|
|
|
|
void Bau57B0::groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, uint8_t * data, uint8_t dataLength)
|
|
{
|
|
GroupObject& go = _groupObjTable.get(asap);
|
|
|
|
if (!go.communicationEnable() || !go.writeEnable())
|
|
return;
|
|
|
|
updateGroupObject(go, data, dataLength);
|
|
}
|
|
|
|
InterfaceObject* Bau57B0::getInterfaceObject(uint8_t idx)
|
|
{
|
|
switch (idx)
|
|
{
|
|
case 0:
|
|
return &_deviceObj;
|
|
case 1:
|
|
return &_addrTable;
|
|
case 2:
|
|
return &_assocTable;
|
|
case 3:
|
|
return &_groupObjTable;
|
|
case 4:
|
|
return &_appProgram;
|
|
case 5: // would be app_program 2
|
|
return nullptr;
|
|
case 6:
|
|
return &_ipParameters;
|
|
default:
|
|
return nullptr;
|
|
}
|
|
} |