mirror of
https://github.com/thelsing/knx.git
synced 2025-08-17 13:47:28 +02:00
save work.
This commit is contained in:
parent
96884f768e
commit
27433fe5e1
@ -19,13 +19,19 @@ add_executable(knx-linux
|
||||
../../src/knx/bau.h
|
||||
../../src/knx/bau07B0.cpp
|
||||
../../src/knx/bau07B0.h
|
||||
../../src/knx/bau27B0.cpp
|
||||
../../src/knx/bau091A.cpp
|
||||
../../src/knx/bau091A.h
|
||||
../../src/knx/bau27B0.cpp
|
||||
../../src/knx/bau27B0.h
|
||||
../../src/knx/bau57B0.cpp
|
||||
../../src/knx/bau57B0.h
|
||||
../../src/knx/bau_systemB.cpp
|
||||
../../src/knx/bau_systemB.h
|
||||
../../src/knx/bits.cpp
|
||||
../../src/knx/bau_systemB_device.cpp
|
||||
../../src/knx/bau_systemB_device.h
|
||||
../../src/knx/bau_systemB_coupler.cpp
|
||||
../../src/knx/bau_systemB_coupler.h
|
||||
../../src/knx/bits.cpp
|
||||
../../src/knx/bits.h
|
||||
../../src/knx/callback_property.h
|
||||
../../src/knx/cemi_frame.cpp
|
||||
@ -40,9 +46,9 @@ add_executable(knx-linux
|
||||
../../src/knx/data_property.cpp
|
||||
../../src/knx/data_property.h
|
||||
../../src/knx/device_object.cpp
|
||||
../../src/knx/device_object.h
|
||||
../../src/knx/dpt.cpp
|
||||
../../src/knx/dpt.h
|
||||
../../src/knx/device_object.h
|
||||
../../src/knx/dpt.cpp
|
||||
../../src/knx/dpt.h
|
||||
../../src/knx/dptconvert.cpp
|
||||
../../src/knx/dptconvert.h
|
||||
../../src/knx/function_property.h
|
||||
|
@ -1,10 +1,7 @@
|
||||
#include "knx_facade.h"
|
||||
|
||||
#include "knx/bau57B0.h"
|
||||
#include "knx/bau27B0.h"
|
||||
#include "knx/bau07B0.h"
|
||||
#include "knx/bau091A.h"
|
||||
|
||||
#include "knx/group_object_table_object.h"
|
||||
#include "knx/bits.h"
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
@ -34,59 +31,17 @@ bool isSendHidReportPossible()
|
||||
return false;
|
||||
}
|
||||
#if MEDIUM_TYPE == 5
|
||||
KnxFacade<LinuxPlatform, Bau57B0> knx;
|
||||
KnxFacade<LinuxPlatform, Bau091A> knx;
|
||||
#elif MEDIUM_TYPE == 2
|
||||
KnxFacade<LinuxPlatform, Bau27B0> knx;
|
||||
KnxFacade<LinuxPlatform, Bau2920> knx;
|
||||
#else
|
||||
#error Only MEDIUM_TYPE IP and RF supported
|
||||
#endif
|
||||
|
||||
long lastsend = 0;
|
||||
|
||||
#define CURR knx.getGroupObject(1)
|
||||
#define MAX knx.getGroupObject(2)
|
||||
#define MIN knx.getGroupObject(3)
|
||||
#define RESET knx.getGroupObject(4)
|
||||
|
||||
void measureTemp()
|
||||
{
|
||||
long now = millis();
|
||||
if ((now - lastsend) < 10000)
|
||||
return;
|
||||
|
||||
lastsend = now;
|
||||
int r = rand();
|
||||
double currentValue = (r * 1.0) / (RAND_MAX * 1.0);
|
||||
currentValue *= 100;
|
||||
currentValue -= 50;
|
||||
// currentValue *= (670433.28 + 273);
|
||||
// currentValue -= 273;
|
||||
println(currentValue);
|
||||
CURR.value(currentValue);
|
||||
|
||||
double max = MAX.value();
|
||||
if (currentValue > max)
|
||||
MAX.value(currentValue);
|
||||
|
||||
if (currentValue < (double)MIN.value())
|
||||
MIN.value(currentValue);
|
||||
}
|
||||
|
||||
void resetCallback(GroupObject& go)
|
||||
{
|
||||
if (go.value())
|
||||
{
|
||||
MAX.valueNoSend(-273.0);
|
||||
MIN.valueNoSend(670433.28);
|
||||
}
|
||||
}
|
||||
|
||||
void appLoop()
|
||||
{
|
||||
if (!knx.configured())
|
||||
return;
|
||||
|
||||
measureTemp();
|
||||
}
|
||||
|
||||
void setup()
|
||||
@ -99,18 +54,7 @@ void setup()
|
||||
|
||||
if (knx.configured())
|
||||
{
|
||||
CURR.dataPointType(Dpt(9, 1));
|
||||
MIN.dataPointType(Dpt(9, 1));
|
||||
MIN.value(670433.28);
|
||||
MAX.dataPointType(Dpt(9, 1));
|
||||
MAX.valueNoSend(-273.0);
|
||||
RESET.dataPointType(Dpt(1, 15));
|
||||
RESET.callback(resetCallback);
|
||||
printf("Timeout: %d\n", knx.paramWord(0));
|
||||
printf("Zykl. senden: %d\n", knx.paramByte(2));
|
||||
printf("Min/Max senden: %d\n", knx.paramByte(3));
|
||||
printf("Aenderung senden: %d\n", knx.paramByte(4));
|
||||
printf("Abgleich %d\n", knx.paramByte(5));
|
||||
printf("configured %d\n", knx.paramByte(5));
|
||||
}
|
||||
else
|
||||
println("not configured");
|
||||
|
@ -10,8 +10,7 @@
|
||||
|
||||
const SecurityControl ApplicationLayer::noSecurity {.toolAccess=false, .dataSecurity=DataSecurity::none};
|
||||
|
||||
ApplicationLayer::ApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau):
|
||||
_assocTable(assocTable), _bau(bau)
|
||||
ApplicationLayer::ApplicationLayer(BusAccessUnit& bau) : _bau(bau)
|
||||
{
|
||||
}
|
||||
|
||||
@ -20,6 +19,11 @@ void ApplicationLayer::transportLayer(TransportLayer& layer)
|
||||
_transportLayer = &layer;
|
||||
}
|
||||
|
||||
void ApplicationLayer::associationTableObject(AssociationTableObject& assocTable)
|
||||
{
|
||||
_assocTable = &assocTable;
|
||||
}
|
||||
|
||||
#pragma region TL Callbacks
|
||||
|
||||
void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu)
|
||||
@ -29,6 +33,9 @@ void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priori
|
||||
|
||||
void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl)
|
||||
{
|
||||
if (_assocTable == nullptr)
|
||||
return;
|
||||
|
||||
uint8_t len = apdu.length();
|
||||
uint8_t dataArray[len];
|
||||
uint8_t* data = dataArray;
|
||||
@ -45,8 +52,8 @@ void ApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priori
|
||||
}
|
||||
|
||||
uint16_t startIdx = 0;
|
||||
int32_t asap = _assocTable.nextAsap(tsap, startIdx);
|
||||
for (; asap != -1; asap = _assocTable.nextAsap(tsap, startIdx))
|
||||
int32_t asap = _assocTable->nextAsap(tsap, startIdx);
|
||||
for (; asap != -1; asap = _assocTable->nextAsap(tsap, startIdx))
|
||||
{
|
||||
switch (apdu.type())
|
||||
{
|
||||
@ -365,12 +372,15 @@ void ApplicationLayer::dataConnectedConfirm(uint16_t tsap, const SecurityControl
|
||||
#pragma endregion
|
||||
void ApplicationLayer::groupValueReadRequest(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl& secCtrl)
|
||||
{
|
||||
if (_assocTable == nullptr)
|
||||
return;
|
||||
|
||||
_savedAsapReadRequest = asap;
|
||||
CemiFrame frame(1);
|
||||
APDU& apdu = frame.apdu();
|
||||
apdu.type(GroupValueRead);
|
||||
|
||||
int32_t value = _assocTable.translateAsap(asap);
|
||||
int32_t value = _assocTable->translateAsap(asap);
|
||||
if (value < 0)
|
||||
return; // there is no tsap in association table for this asap
|
||||
|
||||
@ -928,6 +938,9 @@ void ApplicationLayer::propertyExtDataSend(ApduType type, AckType ack, Priority
|
||||
void ApplicationLayer::groupValueSend(ApduType type, AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t& dataLength)
|
||||
{
|
||||
if (_assocTable == nullptr)
|
||||
return;
|
||||
|
||||
CemiFrame frame(dataLength + 1);
|
||||
APDU& apdu = frame.apdu();
|
||||
apdu.type(type);
|
||||
@ -943,7 +956,7 @@ void ApplicationLayer::groupValueSend(ApduType type, AckType ack, uint16_t asap,
|
||||
memcpy(apdudata + 1, data, dataLength);
|
||||
}
|
||||
// no need to check if there is a tsap. This is a response, so the read got trough
|
||||
uint16_t tsap = (uint16_t)_assocTable.translateAsap(asap);
|
||||
uint16_t tsap = (uint16_t)_assocTable->translateAsap(asap);
|
||||
dataGroupRequest(ack, hopType, priority, tsap, apdu, secCtrl);
|
||||
dataGroupIndication(hopType, priority, tsap, apdu, secCtrl);
|
||||
}
|
||||
|
@ -22,12 +22,14 @@ class ApplicationLayer
|
||||
* @param assocTable The AssociationTable is used to translate between asap (i.e. group objects) and group addresses.
|
||||
* @param bau methods are called here depending of the content of the APDU
|
||||
*/
|
||||
ApplicationLayer(AssociationTableObject& assocTable, BusAccessUnit& bau);
|
||||
ApplicationLayer(BusAccessUnit& bau);
|
||||
/**
|
||||
* Assigns the TransportLayer to which encoded APDU are submitted to.
|
||||
*/
|
||||
void transportLayer(TransportLayer& layer);
|
||||
|
||||
void associationTableObject(AssociationTableObject& assocTable);
|
||||
|
||||
// from transport layer
|
||||
// Note: without data secure feature, the application layer is just used with SecurtyControl.dataSecurity = none
|
||||
// hooks that can be implemented by derived class (e.g. SecureApplicationLayer)
|
||||
@ -204,7 +206,7 @@ class ApplicationLayer
|
||||
uint16_t _savedAsapReadRequest;
|
||||
uint16_t _savedAsapWriteRequest;
|
||||
uint16_t _savedAsapResponse;
|
||||
AssociationTableObject& _assocTable;
|
||||
AssociationTableObject* _assocTable = nullptr;
|
||||
BusAccessUnit& _bau;
|
||||
|
||||
int32_t _connectedTsap = -1;
|
||||
|
@ -8,12 +8,14 @@
|
||||
using namespace std;
|
||||
|
||||
Bau07B0::Bau07B0(Platform& platform)
|
||||
: BauSystemB(platform),
|
||||
_dlLayer(_deviceObj, _addrTable, _netLayer, _platform)
|
||||
: BauSystemBDevice(platform),
|
||||
_dlLayer(_deviceObj, _netLayer, _platform)
|
||||
#ifdef USE_CEMI_SERVER
|
||||
, _cemiServer(*this)
|
||||
#endif
|
||||
{
|
||||
_dlLayer.groupAddressTable(_addrTable);
|
||||
|
||||
_netLayer.dataLinkLayer(_dlLayer);
|
||||
#ifdef USE_CEMI_SERVER
|
||||
_cemiServer.dataLinkLayer(_dlLayer);
|
||||
|
@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#include "bau_systemB.h"
|
||||
#include "bau_systemB_device.h"
|
||||
#include "tpuart_data_link_layer.h"
|
||||
#include "cemi_server.h"
|
||||
#include "cemi_server_object.h"
|
||||
|
||||
#ifdef USE_TP
|
||||
|
||||
class Bau07B0 : public BauSystemB
|
||||
class Bau07B0 : public BauSystemBDevice
|
||||
{
|
||||
public:
|
||||
Bau07B0(Platform& platform);
|
||||
@ -26,4 +26,4 @@ class Bau07B0 : public BauSystemB
|
||||
CemiServerObject _cemiServerObject;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
121
src/knx/bau091A.cpp
Normal file
121
src/knx/bau091A.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include "config.h"
|
||||
#include "bau091A.h"
|
||||
#include "bits.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef USE_IP
|
||||
|
||||
using namespace std;
|
||||
|
||||
Bau091A::Bau091A(Platform& platform)
|
||||
: BauSystemBCoupler(platform),
|
||||
_ipParameters(_deviceObj, platform),
|
||||
_dlLayerPrimary(_deviceObj, _ipParameters, _netLayer, _platform),
|
||||
_dlLayerSecondary(_deviceObj, _netLayer, platform)
|
||||
#ifdef USE_CEMI_SERVER
|
||||
,
|
||||
_cemiServer(*this)
|
||||
#endif
|
||||
{
|
||||
_netLayer.dataLinkLayer(_dlLayerSecondary);
|
||||
#ifdef USE_CEMI_SERVER
|
||||
_cemiServer.dataLinkLayer(_dlLayer);
|
||||
_dlLayer.cemiServer(_cemiServer);
|
||||
_memory.addSaveRestore(&_cemiServerObject);
|
||||
#endif
|
||||
_memory.addSaveRestore(&_ipParameters);
|
||||
|
||||
// Set Mask Version in Device Object depending on the BAU
|
||||
_deviceObj.maskVersion(0x091A);
|
||||
|
||||
// Set which interface objects are available in the device object
|
||||
// This differs from BAU to BAU with different medium types.
|
||||
// See PID_IO_LIST
|
||||
Property* prop = _deviceObj.property(PID_IO_LIST);
|
||||
prop->write(1, (uint16_t) OT_DEVICE);
|
||||
prop->write(2, (uint16_t) OT_ADDR_TABLE);
|
||||
prop->write(3, (uint16_t) OT_ASSOC_TABLE);
|
||||
prop->write(4, (uint16_t) OT_GRP_OBJ_TABLE);
|
||||
prop->write(5, (uint16_t) OT_APPLICATION_PROG);
|
||||
prop->write(6, (uint16_t) OT_IP_PARAMETER);
|
||||
#if defined(USE_DATASECURE) && defined(USE_CEMI_SERVER)
|
||||
prop->write(7, (uint16_t) OT_SECURITY);
|
||||
prop->write(8, (uint16_t) OT_CEMI_SERVER);
|
||||
#elif defined(USE_DATASECURE)
|
||||
prop->write(7, (uint16_t) OT_SECURITY);
|
||||
#elif defined(USE_CEMI_SERVER)
|
||||
prop->write(7, (uint16_t) OT_CEMI_SERVER);
|
||||
#endif
|
||||
}
|
||||
|
||||
InterfaceObject* Bau091A::getInterfaceObject(uint8_t idx)
|
||||
{
|
||||
switch (idx)
|
||||
{
|
||||
case 0:
|
||||
return &_deviceObj;
|
||||
case 4:
|
||||
return &_appProgram;
|
||||
case 5: // would be app_program 2
|
||||
return nullptr;
|
||||
case 6:
|
||||
return &_ipParameters;
|
||||
#if defined(USE_DATASECURE) && defined(USE_CEMI_SERVER)
|
||||
case 7:
|
||||
return &_secIfObj;
|
||||
case 8:
|
||||
return &_cemiServerObject;
|
||||
#elif defined(USE_CEMI_SERVER)
|
||||
case 7:
|
||||
return &_cemiServerObject;
|
||||
#elif defined(USE_DATASECURE)
|
||||
case 7:
|
||||
return &_secIfObj;
|
||||
#endif
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
InterfaceObject* Bau091A::getInterfaceObject(ObjectType objectType, uint8_t objectInstance)
|
||||
{
|
||||
// We do not use it right now.
|
||||
// Required for coupler mode as there are multiple router objects for example
|
||||
(void) objectInstance;
|
||||
|
||||
switch (objectType)
|
||||
{
|
||||
case OT_DEVICE:
|
||||
return &_deviceObj;
|
||||
case OT_APPLICATION_PROG:
|
||||
return &_appProgram;
|
||||
case OT_IP_PARAMETER:
|
||||
return &_ipParameters;
|
||||
#ifdef USE_DATASECURE
|
||||
case OT_SECURITY:
|
||||
return &_secIfObj;
|
||||
#endif
|
||||
#ifdef USE_CEMI_SERVER
|
||||
case OT_CEMI_SERVER:
|
||||
return &_cemiServerObject;
|
||||
#endif
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Bau091A::doMasterReset(EraseCode eraseCode, uint8_t channel)
|
||||
{
|
||||
// Common SystemB objects
|
||||
BauSystemB::doMasterReset(eraseCode, channel);
|
||||
|
||||
_ipParameters.masterReset(eraseCode, channel);
|
||||
}
|
||||
|
||||
DataLinkLayer& Bau091A::dataLinkLayer()
|
||||
{
|
||||
return _dlLayerSecondary;
|
||||
}
|
||||
|
||||
#endif
|
31
src/knx/bau091A.h
Normal file
31
src/knx/bau091A.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_IP
|
||||
#include "bau_systemB_coupler.h"
|
||||
#include "ip_parameter_object.h"
|
||||
#include "ip_data_link_layer.h"
|
||||
#include "tpuart_data_link_layer.h"
|
||||
#include "cemi_server_object.h"
|
||||
|
||||
class Bau091A : public BauSystemBCoupler
|
||||
{
|
||||
public:
|
||||
Bau091A(Platform& platform);
|
||||
|
||||
protected:
|
||||
InterfaceObject* getInterfaceObject(uint8_t idx);
|
||||
InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance);
|
||||
DataLinkLayer& dataLinkLayer();
|
||||
|
||||
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel) override;
|
||||
private:
|
||||
IpParameterObject _ipParameters;
|
||||
IpDataLinkLayer _dlLayerPrimary;
|
||||
TpUartDataLinkLayer _dlLayerSecondary;
|
||||
#ifdef USE_CEMI_SERVER
|
||||
CemiServer _cemiServer;
|
||||
CemiServerObject _cemiServerObject;
|
||||
#endif
|
||||
};
|
||||
#endif
|
@ -7,8 +7,8 @@
|
||||
using namespace std;
|
||||
|
||||
Bau27B0::Bau27B0(Platform& platform)
|
||||
: BauSystemB(platform),
|
||||
_dlLayer(_deviceObj, _rfMediumObj, _addrTable, _netLayer, _platform)
|
||||
: BauSystemBDevice(platform),
|
||||
_dlLayer(_deviceObj, _rfMediumObj, _netLayer, _platform)
|
||||
#ifdef USE_CEMI_SERVER
|
||||
, _cemiServer(*this)
|
||||
#endif
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_RF
|
||||
#include "bau_systemB.h"
|
||||
#include "bau_systemB_device.h"
|
||||
#include "rf_medium_object.h"
|
||||
#include "rf_physical_layer.h"
|
||||
#include "rf_data_link_layer.h"
|
||||
#include "cemi_server.h"
|
||||
#include "cemi_server_object.h"
|
||||
|
||||
class Bau27B0 : public BauSystemB
|
||||
class Bau27B0 : public BauSystemBDevice
|
||||
{
|
||||
public:
|
||||
Bau27B0(Platform& platform);
|
||||
|
@ -9,9 +9,9 @@
|
||||
using namespace std;
|
||||
|
||||
Bau57B0::Bau57B0(Platform& platform)
|
||||
: BauSystemB(platform),
|
||||
: BauSystemBDevice(platform),
|
||||
_ipParameters(_deviceObj, platform),
|
||||
_dlLayer(_deviceObj, _addrTable, _ipParameters, _netLayer, _platform)
|
||||
_dlLayer(_deviceObj, _ipParameters, _netLayer, _platform)
|
||||
#ifdef USE_CEMI_SERVER
|
||||
,
|
||||
_cemiServer(*this)
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_IP
|
||||
#include "bau_systemB.h"
|
||||
#include "bau_systemB_device.h"
|
||||
#include "ip_parameter_object.h"
|
||||
#include "ip_data_link_layer.h"
|
||||
#include "cemi_server_object.h"
|
||||
|
||||
class Bau57B0 : public BauSystemB
|
||||
class Bau57B0 : public BauSystemBDevice
|
||||
{
|
||||
public:
|
||||
Bau57B0(Platform& platform);
|
||||
|
@ -14,41 +14,17 @@ enum NmReadSerialNumberType
|
||||
static constexpr auto kFunctionPropertyResultBufferMaxSize = 64;
|
||||
static constexpr auto kRestartProcessTime = 3;
|
||||
|
||||
BauSystemB::BauSystemB(Platform& platform): _memory(platform, _deviceObj), _addrTable(_memory),
|
||||
_assocTable(_memory), _groupObjTable(_memory), _appProgram(_memory),
|
||||
_platform(platform),
|
||||
#ifdef USE_DATASECURE
|
||||
_appLayer(_deviceObj, _secIfObj, _assocTable, _addrTable, *this),
|
||||
#else
|
||||
_appLayer(_assocTable, *this),
|
||||
#endif
|
||||
_transLayer(_appLayer, _addrTable), _netLayer(_transLayer)
|
||||
BauSystemB::BauSystemB(Platform& platform): _memory(platform, _deviceObj),
|
||||
_appProgram(_memory),
|
||||
_platform(platform)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
_secIfObj.secureApplicationLayer(_appLayer);
|
||||
#endif
|
||||
_appLayer.transportLayer(_transLayer);
|
||||
_transLayer.networkLayer(_netLayer);
|
||||
_memory.addSaveRestore(&_deviceObj);
|
||||
_memory.addSaveRestore(&_appProgram);
|
||||
_memory.addSaveRestore(&_addrTable);
|
||||
_memory.addSaveRestore(&_assocTable);
|
||||
_memory.addSaveRestore(&_groupObjTable);
|
||||
#ifdef USE_DATASECURE
|
||||
_memory.addSaveRestore(&_secIfObj);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void BauSystemB::loop()
|
||||
{
|
||||
dataLinkLayer().loop();
|
||||
_transLayer.loop();
|
||||
sendNextGroupTelegram();
|
||||
nextRestartState();
|
||||
#ifdef USE_DATASECURE
|
||||
_appLayer.loop();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool BauSystemB::enabled()
|
||||
@ -61,74 +37,6 @@ void BauSystemB::enabled(bool value)
|
||||
dataLinkLayer().enabled(value);
|
||||
}
|
||||
|
||||
void BauSystemB::sendNextGroupTelegram()
|
||||
{
|
||||
if(!configured())
|
||||
return;
|
||||
|
||||
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())
|
||||
continue;
|
||||
|
||||
SecurityControl goSecurity;
|
||||
goSecurity.toolAccess = false; // Secured group communication never uses the toolkey. ETS knows all keys, also the group keys.
|
||||
|
||||
#ifdef USE_DATASECURE
|
||||
// Get security flags from Security Interface Object for this group object
|
||||
goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap);
|
||||
#else
|
||||
goSecurity.dataSecurity = DataSecurity::none;
|
||||
#endif
|
||||
|
||||
if (flag == WriteRequest && go.transmitEnable())
|
||||
{
|
||||
uint8_t* data = go.valueRef();
|
||||
_appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity, data,
|
||||
go.sizeInTelegram());
|
||||
}
|
||||
else if (flag == ReadRequest)
|
||||
{
|
||||
_appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity);
|
||||
}
|
||||
|
||||
go.commFlag(Transmitting);
|
||||
|
||||
startIdx = asap + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
startIdx = 1;
|
||||
}
|
||||
|
||||
void BauSystemB::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(Updated);
|
||||
GroupObjectUpdatedHandler handler = go.callback();
|
||||
if (handler)
|
||||
handler(go);
|
||||
}
|
||||
|
||||
void BauSystemB::readMemory()
|
||||
{
|
||||
_memory.readMemory();
|
||||
@ -139,21 +47,16 @@ void BauSystemB::writeMemory()
|
||||
_memory.writeMemory();
|
||||
}
|
||||
|
||||
DeviceObject& BauSystemB::deviceObject()
|
||||
{
|
||||
return _deviceObj;
|
||||
}
|
||||
|
||||
GroupObjectTableObject& BauSystemB::groupObjectTable()
|
||||
{
|
||||
return _groupObjTable;
|
||||
}
|
||||
|
||||
ApplicationProgramObject& BauSystemB::parameters()
|
||||
{
|
||||
return _appProgram;
|
||||
}
|
||||
|
||||
DeviceObject& BauSystemB::deviceObject()
|
||||
{
|
||||
return _deviceObj;
|
||||
}
|
||||
|
||||
bool BauSystemB::configured()
|
||||
{
|
||||
// _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
|
||||
@ -161,10 +64,7 @@ bool BauSystemB::configured()
|
||||
if (!_configured)
|
||||
return false;
|
||||
|
||||
_configured = _groupObjTable.loadState() == LS_LOADED
|
||||
&& _addrTable.loadState() == LS_LOADED
|
||||
&& _assocTable.loadState() == LS_LOADED
|
||||
&& _appProgram.loadState() == LS_LOADED;
|
||||
_configured = _appProgram.loadState() == LS_LOADED;
|
||||
|
||||
return _configured;
|
||||
}
|
||||
@ -233,7 +133,7 @@ void BauSystemB::deviceDescriptorReadIndication(Priority priority, HopCountType
|
||||
|
||||
uint8_t data[2];
|
||||
pushWord(_deviceObj.maskVersion(), data);
|
||||
_appLayer.deviceDescriptorReadResponse(AckRequested, priority, hopType, asap, secCtrl, descriptorType, data);
|
||||
applicationLayer().deviceDescriptorReadResponse(AckRequested, priority, hopType, asap, secCtrl, descriptorType, data);
|
||||
}
|
||||
|
||||
void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number,
|
||||
@ -248,7 +148,7 @@ void BauSystemB::memoryWriteIndication(Priority priority, HopCountType hopType,
|
||||
void BauSystemB::memoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number,
|
||||
uint16_t memoryAddress)
|
||||
{
|
||||
_appLayer.memoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress,
|
||||
applicationLayer().memoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress,
|
||||
_memory.toAbsolute(memoryAddress));
|
||||
}
|
||||
|
||||
@ -256,27 +156,17 @@ void BauSystemB::memoryExtWriteIndication(Priority priority, HopCountType hopTyp
|
||||
{
|
||||
_memory.writeMemory(memoryAddress, number, data);
|
||||
|
||||
_appLayer.memoryExtWriteResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress));
|
||||
applicationLayer().memoryExtWriteResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress));
|
||||
}
|
||||
|
||||
void BauSystemB::memoryExtReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint32_t memoryAddress)
|
||||
{
|
||||
_appLayer.memoryExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress));
|
||||
applicationLayer().memoryExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, ReturnCodes::Success, number, memoryAddress, _memory.toAbsolute(memoryAddress));
|
||||
}
|
||||
|
||||
void BauSystemB::doMasterReset(EraseCode eraseCode, uint8_t channel)
|
||||
{
|
||||
_addrTable.masterReset(eraseCode, channel);
|
||||
_assocTable.masterReset(eraseCode, channel);
|
||||
_groupObjTable.masterReset(eraseCode, channel);
|
||||
_appProgram.masterReset(eraseCode, channel);
|
||||
#ifdef USE_DATASECURE
|
||||
// If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
|
||||
// and disable security mode.
|
||||
// FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
|
||||
// Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
|
||||
_secIfObj.masterReset(eraseCode, channel);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, RestartType restartType, EraseCode eraseCode, uint8_t channel)
|
||||
@ -290,7 +180,7 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp
|
||||
uint8_t errorCode = checkmasterResetValidity(eraseCode, channel);
|
||||
// We send the restart response now before actually applying the reset values
|
||||
// Processing time is kRestartProcessTime (example 3 seconds) that we require for the applying the master reset with restart
|
||||
_appLayer.restartResponse(AckRequested, priority, hopType, secCtrl, errorCode, (errorCode == 0) ? kRestartProcessTime : 0);
|
||||
applicationLayer().restartResponse(AckRequested, priority, hopType, secCtrl, errorCode, (errorCode == 0) ? kRestartProcessTime : 0);
|
||||
doMasterReset(eraseCode, channel);
|
||||
}
|
||||
else
|
||||
@ -307,12 +197,12 @@ void BauSystemB::restartRequestIndication(Priority priority, HopCountType hopTyp
|
||||
|
||||
void BauSystemB::authorizeIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint32_t key)
|
||||
{
|
||||
_appLayer.authorizeResponse(AckRequested, priority, hopType, asap, secCtrl, 0);
|
||||
applicationLayer().authorizeResponse(AckRequested, priority, hopType, asap, secCtrl, 0);
|
||||
}
|
||||
|
||||
void BauSystemB::userMemoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number, uint32_t memoryAddress)
|
||||
{
|
||||
_appLayer.userMemoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress,
|
||||
applicationLayer().userMemoryReadResponse(AckRequested, priority, hopType, asap, secCtrl, number, memoryAddress,
|
||||
_memory.toAbsolute(memoryAddress));
|
||||
}
|
||||
|
||||
@ -336,7 +226,7 @@ void BauSystemB::propertyDescriptionReadIndication(Priority priority, HopCountTy
|
||||
if (obj)
|
||||
obj->readPropertyDescription(pid, propertyIndex, writeEnable, type, numberOfElements, access);
|
||||
|
||||
_appLayer.propertyDescriptionReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, pid, propertyIndex,
|
||||
applicationLayer().propertyDescriptionReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, pid, propertyIndex,
|
||||
writeEnable, type, numberOfElements, access);
|
||||
}
|
||||
|
||||
@ -362,7 +252,7 @@ void BauSystemB::propertyValueExtWriteIndication(Priority priority, HopCountType
|
||||
|
||||
if (confirmed)
|
||||
{
|
||||
_appLayer.propertyValueExtWriteConResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, numberOfElements, startIndex, returnCode);
|
||||
applicationLayer().propertyValueExtWriteConResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, numberOfElements, startIndex, returnCode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,7 +280,7 @@ void BauSystemB::propertyValueReadIndication(Priority priority, HopCountType hop
|
||||
if (elementCount == 0)
|
||||
size = 0;
|
||||
|
||||
_appLayer.propertyValueReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, elementCount,
|
||||
applicationLayer().propertyValueReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, elementCount,
|
||||
startIndex, data, size);
|
||||
}
|
||||
|
||||
@ -418,7 +308,7 @@ void BauSystemB::propertyValueExtReadIndication(Priority priority, HopCountType
|
||||
if (elementCount == 0)
|
||||
size = 0;
|
||||
|
||||
_appLayer.propertyValueExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, elementCount,
|
||||
applicationLayer().propertyValueExtReadResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, elementCount,
|
||||
startIndex, data, size);
|
||||
}
|
||||
|
||||
@ -441,7 +331,7 @@ void BauSystemB::functionPropertyCommandIndication(Priority priority, HopCountTy
|
||||
}
|
||||
}
|
||||
|
||||
_appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength);
|
||||
applicationLayer().functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength);
|
||||
}
|
||||
|
||||
void BauSystemB::functionPropertyStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t objectIndex,
|
||||
@ -463,7 +353,7 @@ void BauSystemB::functionPropertyStateIndication(Priority priority, HopCountType
|
||||
}
|
||||
}
|
||||
|
||||
_appLayer.functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength);
|
||||
applicationLayer().functionPropertyStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectIndex, propertyId, resultData, resultLength);
|
||||
}
|
||||
|
||||
void BauSystemB::functionPropertyExtCommandIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance,
|
||||
@ -519,7 +409,7 @@ void BauSystemB::functionPropertyExtCommandIndication(Priority priority, HopCoun
|
||||
resultData[0] = ReturnCodes::GenericError;
|
||||
}
|
||||
|
||||
_appLayer.functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength);
|
||||
applicationLayer().functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength);
|
||||
}
|
||||
|
||||
void BauSystemB::functionPropertyExtStateIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, ObjectType objectType, uint8_t objectInstance,
|
||||
@ -566,13 +456,13 @@ void BauSystemB::functionPropertyExtStateIndication(Priority priority, HopCountT
|
||||
resultData[0] = ReturnCodes::GenericError;
|
||||
}
|
||||
|
||||
_appLayer.functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength);
|
||||
applicationLayer().functionPropertyExtStateResponse(AckRequested, priority, hopType, asap, secCtrl, objectType, objectInstance, propertyId, resultData, resultLength);
|
||||
}
|
||||
|
||||
void BauSystemB::individualAddressReadIndication(HopCountType hopType, const SecurityControl &secCtrl)
|
||||
{
|
||||
if (_deviceObj.progMode())
|
||||
_appLayer.individualAddressReadResponse(AckRequested, hopType, secCtrl);
|
||||
applicationLayer().individualAddressReadResponse(AckRequested, hopType, secCtrl);
|
||||
}
|
||||
|
||||
void BauSystemB::individualAddressWriteIndication(HopCountType hopType, const SecurityControl &secCtrl, uint16_t newaddress)
|
||||
@ -598,85 +488,10 @@ void BauSystemB::individualAddressSerialNumberReadIndication(Priority priority,
|
||||
if (!memcmp(knxSerialNumber, _deviceObj.propertyData(PID_SERIAL_NUMBER), 6))
|
||||
{
|
||||
uint8_t emptyDomainAddress[6] = {0x00};
|
||||
_appLayer.IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, emptyDomainAddress, knxSerialNumber);
|
||||
applicationLayer().IndividualAddressSerialNumberReadResponse(priority, hopType, secCtrl, emptyDomainAddress, knxSerialNumber);
|
||||
}
|
||||
}
|
||||
|
||||
void BauSystemB::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength, bool status)
|
||||
{
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
if (status)
|
||||
go.commFlag(Ok);
|
||||
else
|
||||
go.commFlag(Error);
|
||||
}
|
||||
|
||||
void BauSystemB::groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status)
|
||||
{
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
if (status)
|
||||
go.commFlag(Ok);
|
||||
else
|
||||
go.commFlag(Error);
|
||||
}
|
||||
|
||||
void BauSystemB::groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
DataSecurity requiredGoSecurity;
|
||||
|
||||
// Get security flags from Security Interface Object for this group object
|
||||
requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap);
|
||||
|
||||
if (secCtrl.dataSecurity != requiredGoSecurity)
|
||||
{
|
||||
println("GroupValueRead: access denied due to wrong security flags");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
|
||||
if (!go.communicationEnable() || !go.readEnable())
|
||||
return;
|
||||
|
||||
uint8_t* data = go.valueRef();
|
||||
_appLayer.groupValueReadResponse(AckRequested, asap, priority, hopType, secCtrl, data, go.sizeInTelegram());
|
||||
}
|
||||
|
||||
void BauSystemB::groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* data,
|
||||
uint8_t dataLength)
|
||||
{
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
|
||||
if (!go.communicationEnable() || !go.responseUpdateEnable())
|
||||
return;
|
||||
|
||||
updateGroupObject(go, data, dataLength);
|
||||
}
|
||||
|
||||
void BauSystemB::groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
DataSecurity requiredGoSecurity;
|
||||
|
||||
// Get security flags from Security Interface Object for this group object
|
||||
requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap);
|
||||
|
||||
if (secCtrl.dataSecurity != requiredGoSecurity)
|
||||
{
|
||||
println("GroupValueWrite: access denied due to wrong security flags");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
|
||||
if (!go.communicationEnable() || !go.writeEnable())
|
||||
return;
|
||||
|
||||
updateGroupObject(go, data, dataLength);
|
||||
}
|
||||
|
||||
void BauSystemB::addSaveRestore(SaveRestore* obj)
|
||||
{
|
||||
_memory.addSaveRestore(obj);
|
||||
@ -684,12 +499,12 @@ void BauSystemB::addSaveRestore(SaveRestore* obj)
|
||||
|
||||
bool BauSystemB::restartRequest(uint16_t asap, const SecurityControl secCtrl)
|
||||
{
|
||||
if (_appLayer.isConnected())
|
||||
if (applicationLayer().isConnected())
|
||||
return false;
|
||||
_restartState = Connecting; // order important, has to be set BEFORE connectRequest
|
||||
_restartSecurity = secCtrl;
|
||||
_appLayer.connectRequest(asap, SystemPriority);
|
||||
_appLayer.deviceDescriptorReadRequest(AckRequested, SystemPriority, NetworkLayerParameter, asap, secCtrl, 0);
|
||||
applicationLayer().connectRequest(asap, SystemPriority);
|
||||
applicationLayer().deviceDescriptorReadRequest(AckRequested, SystemPriority, NetworkLayerParameter, asap, secCtrl, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -721,7 +536,7 @@ void BauSystemB::nextRestartState()
|
||||
/* connection confirmed, we send restartRequest, but we wait a moment (sending ACK etc)... */
|
||||
if (millis() - _restartDelay > 30)
|
||||
{
|
||||
_appLayer.restartRequest(AckRequested, SystemPriority, NetworkLayerParameter, _restartSecurity);
|
||||
applicationLayer().restartRequest(AckRequested, SystemPriority, NetworkLayerParameter, _restartSecurity);
|
||||
_restartState = Restarted;
|
||||
_restartDelay = millis();
|
||||
}
|
||||
@ -730,7 +545,7 @@ void BauSystemB::nextRestartState()
|
||||
/* restart is finished, we send a discommect */
|
||||
if (millis() - _restartDelay > 30)
|
||||
{
|
||||
_appLayer.disconnectRequest(SystemPriority);
|
||||
applicationLayer().disconnectRequest(SystemPriority);
|
||||
_restartState = Idle;
|
||||
}
|
||||
default:
|
||||
@ -753,7 +568,7 @@ void BauSystemB::systemNetworkParameterReadIndication(Priority priority, HopCoun
|
||||
if (_deviceObj.progMode() && (objectType == OT_DEVICE) && (propertyId == PID_SERIAL_NUMBER))
|
||||
{
|
||||
// Send reply. testResult data is KNX serial number
|
||||
_appLayer.systemNetworkParameterReadResponse(priority, hopType, secCtrl, objectType, propertyId,
|
||||
applicationLayer().systemNetworkParameterReadResponse(priority, hopType, secCtrl, objectType, propertyId,
|
||||
testInfo, testInfoLength, (uint8_t*)_deviceObj.propertyData(PID_SERIAL_NUMBER), 6);
|
||||
}
|
||||
break;
|
||||
|
@ -2,10 +2,6 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "bau.h"
|
||||
#include "device_object.h"
|
||||
#include "address_table_object.h"
|
||||
#include "association_table_object.h"
|
||||
#include "group_object_table_object.h"
|
||||
#include "security_interface_object.h"
|
||||
#include "application_program_object.h"
|
||||
#include "application_layer.h"
|
||||
@ -21,9 +17,8 @@ class BauSystemB : protected BusAccessUnit
|
||||
public:
|
||||
BauSystemB(Platform& platform);
|
||||
virtual void loop();
|
||||
DeviceObject& deviceObject();
|
||||
GroupObjectTableObject& groupObjectTable();
|
||||
ApplicationProgramObject& parameters();
|
||||
DeviceObject& deviceObject();
|
||||
Memory& memory();
|
||||
bool configured();
|
||||
bool enabled();
|
||||
@ -43,6 +38,8 @@ class BauSystemB : protected BusAccessUnit
|
||||
|
||||
protected:
|
||||
virtual DataLinkLayer& dataLinkLayer() = 0;
|
||||
virtual ApplicationLayer& applicationLayer() = 0;
|
||||
|
||||
void memoryWriteIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number,
|
||||
uint16_t memoryAddress, uint8_t* data) override;
|
||||
void memoryReadIndication(Priority priority, HopCountType hopType, uint16_t asap, const SecurityControl &secCtrl, uint8_t number,
|
||||
@ -80,14 +77,6 @@ class BauSystemB : protected BusAccessUnit
|
||||
void individualAddressSerialNumberWriteIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t newIndividualAddress,
|
||||
uint8_t* knxSerialNumber) override;
|
||||
void individualAddressSerialNumberReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* knxSerialNumber) override;
|
||||
void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t dataLength, bool status) override;
|
||||
void groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) override;
|
||||
void groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl) override;
|
||||
void groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t dataLength) override;
|
||||
void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t dataLength) override;
|
||||
void systemNetworkParameterReadIndication(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t objectType,
|
||||
uint16_t propertyId, uint8_t* testInfo, uint16_t testinfoLength) override;
|
||||
void systemNetworkParameterReadLocalConfirm(Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint16_t objectType,
|
||||
@ -96,8 +85,6 @@ class BauSystemB : protected BusAccessUnit
|
||||
|
||||
virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0;
|
||||
virtual InterfaceObject* getInterfaceObject(ObjectType objectType, uint8_t objectInstance) = 0;
|
||||
void sendNextGroupTelegram();
|
||||
void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
|
||||
void nextRestartState();
|
||||
|
||||
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel);
|
||||
@ -110,21 +97,10 @@ class BauSystemB : protected BusAccessUnit
|
||||
Restarted
|
||||
};
|
||||
|
||||
DeviceObject _deviceObj;
|
||||
Memory _memory;
|
||||
AddressTableObject _addrTable;
|
||||
AssociationTableObject _assocTable;
|
||||
GroupObjectTableObject _groupObjTable;
|
||||
DeviceObject _deviceObj;
|
||||
ApplicationProgramObject _appProgram;
|
||||
Platform& _platform;
|
||||
#ifdef USE_DATASECURE
|
||||
SecureApplicationLayer _appLayer;
|
||||
SecurityInterfaceObject _secIfObj;
|
||||
#else
|
||||
ApplicationLayer _appLayer;
|
||||
#endif
|
||||
TransportLayer _transLayer;
|
||||
NetworkLayer _netLayer;
|
||||
bool _configured = true;
|
||||
RestartState _restartState = Idle;
|
||||
SecurityControl _restartSecurity;
|
||||
|
57
src/knx/bau_systemB_coupler.cpp
Normal file
57
src/knx/bau_systemB_coupler.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "bau_systemB_coupler.h"
|
||||
#include "bits.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
BauSystemBCoupler::BauSystemBCoupler(Platform& platform) :
|
||||
BauSystemB(platform),
|
||||
_platform(platform),
|
||||
#ifdef USE_DATASECURE
|
||||
_appLayer(_deviceObj, _secIfObj, *this),
|
||||
#else
|
||||
_appLayer(*this),
|
||||
#endif
|
||||
_transLayer(_appLayer), _netLayer(_deviceObj, _transLayer)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
_secIfObj.secureApplicationLayer(_appLayer);
|
||||
#endif
|
||||
_appLayer.transportLayer(_transLayer);
|
||||
_transLayer.networkLayer(_netLayer);
|
||||
_memory.addSaveRestore(&_deviceObj);
|
||||
_memory.addSaveRestore(&_appProgram);
|
||||
#ifdef USE_DATASECURE
|
||||
_memory.addSaveRestore(&_secIfObj);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ApplicationLayer& BauSystemBCoupler::applicationLayer()
|
||||
{
|
||||
return _appLayer;
|
||||
}
|
||||
|
||||
void BauSystemBCoupler::loop()
|
||||
{
|
||||
dataLinkLayer().loop();
|
||||
_transLayer.loop();
|
||||
#ifdef USE_DATASECURE
|
||||
_appLayer.loop();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool BauSystemBCoupler::configured()
|
||||
{
|
||||
// _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
|
||||
|
||||
if (!_configured)
|
||||
return false;
|
||||
|
||||
_configured = _appProgram.loadState() == LS_LOADED;
|
||||
|
||||
return _configured;
|
||||
}
|
||||
|
||||
void BauSystemBCoupler::doMasterReset(EraseCode eraseCode, uint8_t channel)
|
||||
{
|
||||
}
|
53
src/knx/bau_systemB_coupler.h
Normal file
53
src/knx/bau_systemB_coupler.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#include "bau_systemB.h"
|
||||
#include "device_object.h"
|
||||
#include "address_table_object.h"
|
||||
#include "association_table_object.h"
|
||||
#include "group_object_table_object.h"
|
||||
#include "security_interface_object.h"
|
||||
#include "application_program_object.h"
|
||||
#include "application_layer.h"
|
||||
#include "secure_application_layer.h"
|
||||
#include "transport_layer.h"
|
||||
#include "network_layer.h"
|
||||
#include "data_link_layer.h"
|
||||
#include "platform.h"
|
||||
#include "memory.h"
|
||||
|
||||
class BauSystemBCoupler : public BauSystemB
|
||||
{
|
||||
public:
|
||||
BauSystemBCoupler(Platform& platform);
|
||||
virtual void loop();
|
||||
bool configured();
|
||||
|
||||
protected:
|
||||
virtual DataLinkLayer& dataLinkLayer() = 0;
|
||||
virtual ApplicationLayer& applicationLayer() override;
|
||||
|
||||
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel);
|
||||
|
||||
enum RestartState
|
||||
{
|
||||
Idle,
|
||||
Connecting,
|
||||
Connected,
|
||||
Restarted
|
||||
};
|
||||
|
||||
Platform& _platform;
|
||||
#ifdef USE_DATASECURE
|
||||
SecureApplicationLayer _appLayer;
|
||||
SecurityInterfaceObject _secIfObj;
|
||||
#else
|
||||
ApplicationLayer _appLayer;
|
||||
#endif
|
||||
TransportLayer _transLayer;
|
||||
NetworkLayer _netLayer;
|
||||
bool _configured = true;
|
||||
RestartState _restartState = Idle;
|
||||
SecurityControl _restartSecurity;
|
||||
uint32_t _restartDelay = 0;
|
||||
};
|
227
src/knx/bau_systemB_device.cpp
Normal file
227
src/knx/bau_systemB_device.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
#include "bau_systemB_device.h"
|
||||
#include "bits.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
BauSystemBDevice::BauSystemBDevice(Platform& platform) :
|
||||
BauSystemB(platform),
|
||||
_addrTable(_memory),
|
||||
_assocTable(_memory), _groupObjTable(_memory),
|
||||
#ifdef USE_DATASECURE
|
||||
_appLayer(_deviceObj, _secIfObj, *this),
|
||||
#else
|
||||
_appLayer(*this),
|
||||
#endif
|
||||
_transLayer(_appLayer), _netLayer(_deviceObj, _transLayer)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
_secIfObj.secureApplicationLayer(_appLayer);
|
||||
#endif
|
||||
_appLayer.transportLayer(_transLayer);
|
||||
_appLayer.associationTableObject(_assocTable);
|
||||
_appLayer.groupAddressTable(_addrTable);
|
||||
_transLayer.networkLayer(_netLayer);
|
||||
_transLayer.groupAddressTable(_addrTable);
|
||||
|
||||
_memory.addSaveRestore(&_deviceObj);
|
||||
_memory.addSaveRestore(&_addrTable);
|
||||
_memory.addSaveRestore(&_assocTable);
|
||||
_memory.addSaveRestore(&_groupObjTable);
|
||||
#ifdef USE_DATASECURE
|
||||
_memory.addSaveRestore(&_secIfObj);
|
||||
#endif
|
||||
}
|
||||
|
||||
ApplicationLayer& BauSystemBDevice::applicationLayer()
|
||||
{
|
||||
return _appLayer;
|
||||
}
|
||||
|
||||
void BauSystemBDevice::loop()
|
||||
{
|
||||
dataLinkLayer().loop();
|
||||
_transLayer.loop();
|
||||
sendNextGroupTelegram();
|
||||
nextRestartState();
|
||||
#ifdef USE_DATASECURE
|
||||
_appLayer.loop();
|
||||
#endif
|
||||
}
|
||||
|
||||
void BauSystemBDevice::sendNextGroupTelegram()
|
||||
{
|
||||
if(!configured())
|
||||
return;
|
||||
|
||||
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())
|
||||
continue;
|
||||
|
||||
SecurityControl goSecurity;
|
||||
goSecurity.toolAccess = false; // Secured group communication never uses the toolkey. ETS knows all keys, also the group keys.
|
||||
|
||||
#ifdef USE_DATASECURE
|
||||
// Get security flags from Security Interface Object for this group object
|
||||
goSecurity.dataSecurity = _secIfObj.getGroupObjectSecurity(asap);
|
||||
#else
|
||||
goSecurity.dataSecurity = DataSecurity::none;
|
||||
#endif
|
||||
|
||||
if (flag == WriteRequest && go.transmitEnable())
|
||||
{
|
||||
uint8_t* data = go.valueRef();
|
||||
_appLayer.groupValueWriteRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity, data,
|
||||
go.sizeInTelegram());
|
||||
}
|
||||
else if (flag == ReadRequest)
|
||||
{
|
||||
_appLayer.groupValueReadRequest(AckRequested, asap, go.priority(), NetworkLayerParameter, goSecurity);
|
||||
}
|
||||
|
||||
go.commFlag(Transmitting);
|
||||
|
||||
startIdx = asap + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
startIdx = 1;
|
||||
}
|
||||
|
||||
void BauSystemBDevice::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(Updated);
|
||||
GroupObjectUpdatedHandler handler = go.callback();
|
||||
if (handler)
|
||||
handler(go);
|
||||
}
|
||||
|
||||
GroupObjectTableObject& BauSystemBDevice::groupObjectTable()
|
||||
{
|
||||
return _groupObjTable;
|
||||
}
|
||||
|
||||
bool BauSystemBDevice::configured()
|
||||
{
|
||||
// _configured is set to true initially, if the device was configured with ETS it will be set to true after restart
|
||||
|
||||
if (!_configured)
|
||||
return false;
|
||||
|
||||
_configured = _groupObjTable.loadState() == LS_LOADED
|
||||
&& _addrTable.loadState() == LS_LOADED
|
||||
&& _assocTable.loadState() == LS_LOADED
|
||||
&& _appProgram.loadState() == LS_LOADED;
|
||||
|
||||
return _configured;
|
||||
}
|
||||
|
||||
void BauSystemBDevice::doMasterReset(EraseCode eraseCode, uint8_t channel)
|
||||
{
|
||||
_addrTable.masterReset(eraseCode, channel);
|
||||
_assocTable.masterReset(eraseCode, channel);
|
||||
_groupObjTable.masterReset(eraseCode, channel);
|
||||
_appProgram.masterReset(eraseCode, channel);
|
||||
#ifdef USE_DATASECURE
|
||||
// If erase code is FactoryReset or FactoryResetWithoutIA, set FDSK as toolkey again
|
||||
// and disable security mode.
|
||||
// FIXME: the A_RestartResponse PDU has still to be sent with the current toolkey.
|
||||
// Idea: use local confirmation of sent A_RestartResponse PDU to trigger writing the FDSK afterwards
|
||||
_secIfObj.masterReset(eraseCode, channel);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BauSystemBDevice::groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength, bool status)
|
||||
{
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
if (status)
|
||||
go.commFlag(Ok);
|
||||
else
|
||||
go.commFlag(Error);
|
||||
}
|
||||
|
||||
void BauSystemBDevice::groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status)
|
||||
{
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
if (status)
|
||||
go.commFlag(Ok);
|
||||
else
|
||||
go.commFlag(Error);
|
||||
}
|
||||
|
||||
void BauSystemBDevice::groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
DataSecurity requiredGoSecurity;
|
||||
|
||||
// Get security flags from Security Interface Object for this group object
|
||||
requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap);
|
||||
|
||||
if (secCtrl.dataSecurity != requiredGoSecurity)
|
||||
{
|
||||
println("GroupValueRead: access denied due to wrong security flags");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
|
||||
if (!go.communicationEnable() || !go.readEnable())
|
||||
return;
|
||||
|
||||
uint8_t* data = go.valueRef();
|
||||
_appLayer.groupValueReadResponse(AckRequested, asap, priority, hopType, secCtrl, data, go.sizeInTelegram());
|
||||
}
|
||||
|
||||
void BauSystemBDevice::groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t* data,
|
||||
uint8_t dataLength)
|
||||
{
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
|
||||
if (!go.communicationEnable() || !go.responseUpdateEnable())
|
||||
return;
|
||||
|
||||
updateGroupObject(go, data, dataLength);
|
||||
}
|
||||
|
||||
void BauSystemBDevice::groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, uint8_t * data, uint8_t dataLength)
|
||||
{
|
||||
#ifdef USE_DATASECURE
|
||||
DataSecurity requiredGoSecurity;
|
||||
|
||||
// Get security flags from Security Interface Object for this group object
|
||||
requiredGoSecurity = _secIfObj.getGroupObjectSecurity(asap);
|
||||
|
||||
if (secCtrl.dataSecurity != requiredGoSecurity)
|
||||
{
|
||||
println("GroupValueWrite: access denied due to wrong security flags");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
GroupObject& go = _groupObjTable.get(asap);
|
||||
|
||||
if (!go.communicationEnable() || !go.writeEnable())
|
||||
return;
|
||||
|
||||
updateGroupObject(go, data, dataLength);
|
||||
}
|
56
src/knx/bau_systemB_device.h
Normal file
56
src/knx/bau_systemB_device.h
Normal file
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "config.h"
|
||||
#include "bau_systemB.h"
|
||||
#include "device_object.h"
|
||||
#include "address_table_object.h"
|
||||
#include "association_table_object.h"
|
||||
#include "group_object_table_object.h"
|
||||
#include "security_interface_object.h"
|
||||
#include "application_program_object.h"
|
||||
#include "application_layer.h"
|
||||
#include "secure_application_layer.h"
|
||||
#include "transport_layer.h"
|
||||
#include "network_layer.h"
|
||||
#include "data_link_layer.h"
|
||||
#include "platform.h"
|
||||
#include "memory.h"
|
||||
|
||||
class BauSystemBDevice : public BauSystemB
|
||||
{
|
||||
public:
|
||||
BauSystemBDevice(Platform& platform);
|
||||
virtual void loop();
|
||||
GroupObjectTableObject& groupObjectTable();
|
||||
Memory& memory();
|
||||
bool configured();
|
||||
|
||||
protected:
|
||||
virtual ApplicationLayer& applicationLayer() override;
|
||||
|
||||
void groupValueWriteLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t dataLength, bool status) override;
|
||||
void groupValueReadLocalConfirm(AckType ack, uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl, bool status) override;
|
||||
void groupValueReadIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl) override;
|
||||
void groupValueReadAppLayerConfirm(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t dataLength) override;
|
||||
void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType, const SecurityControl &secCtrl,
|
||||
uint8_t* data, uint8_t dataLength) override;
|
||||
|
||||
void sendNextGroupTelegram();
|
||||
void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
|
||||
|
||||
virtual void doMasterReset(EraseCode eraseCode, uint8_t channel);
|
||||
|
||||
AddressTableObject _addrTable;
|
||||
AssociationTableObject _assocTable;
|
||||
GroupObjectTableObject _groupObjTable;
|
||||
#ifdef USE_DATASECURE
|
||||
SecureApplicationLayer _appLayer;
|
||||
SecurityInterfaceObject _secIfObj;
|
||||
#else
|
||||
ApplicationLayer _appLayer;
|
||||
#endif
|
||||
TransportLayer _transLayer;
|
||||
NetworkLayer _netLayer;
|
||||
};
|
@ -6,9 +6,8 @@
|
||||
#include "address_table_object.h"
|
||||
#include "cemi_server.h"
|
||||
|
||||
DataLinkLayer::DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
|
||||
NetworkLayer& layer, Platform& platform) :
|
||||
_deviceObject(devObj), _groupAddressTable(addrTab), _networkLayer(layer), _platform(platform)
|
||||
DataLinkLayer::DataLinkLayer(DeviceObject& devObj, NetworkLayer& layer, Platform& platform) :
|
||||
_deviceObject(devObj), _networkLayer(layer), _platform(platform)
|
||||
{
|
||||
}
|
||||
|
||||
@ -115,18 +114,6 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addrType == InduvidualAddress && destination != _deviceObject.induvidualAddress())
|
||||
return;
|
||||
|
||||
if (addrType == GroupAddress && !_groupAddressTable.contains(destination))
|
||||
return;
|
||||
|
||||
// if (frame.npdu().octetCount() > 0)
|
||||
// {
|
||||
// _print("-> DLL ");
|
||||
// frame.apdu().printPDU();
|
||||
// }
|
||||
|
||||
_networkLayer.dataIndication(ack, addrType, destination, type, npdu, priority, source);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "device_object.h"
|
||||
#include "address_table_object.h"
|
||||
#include "knx_types.h"
|
||||
#include "network_layer.h"
|
||||
#include "cemi_server.h"
|
||||
@ -12,7 +11,7 @@
|
||||
class DataLinkLayer
|
||||
{
|
||||
public:
|
||||
DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer,
|
||||
DataLinkLayer(DeviceObject& devObj, NetworkLayer& layer,
|
||||
Platform& platform);
|
||||
|
||||
#ifdef USE_CEMI_SERVER
|
||||
@ -36,7 +35,6 @@ class DataLinkLayer
|
||||
virtual bool sendFrame(CemiFrame& frame) = 0;
|
||||
uint8_t* frameData(CemiFrame& frame);
|
||||
DeviceObject& _deviceObject;
|
||||
AddressTableObject& _groupAddressTable;
|
||||
NetworkLayer& _networkLayer;
|
||||
Platform& _platform;
|
||||
#ifdef USE_CEMI_SERVER
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "bits.h"
|
||||
#include "platform.h"
|
||||
#include "device_object.h"
|
||||
#include "address_table_object.h"
|
||||
#include "knx_ip_routing_indication.h"
|
||||
#include "knx_ip_search_request.h"
|
||||
#include "knx_ip_search_response.h"
|
||||
@ -18,8 +17,8 @@
|
||||
|
||||
#define MIN_LEN_CEMI 10
|
||||
|
||||
IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, IpParameterObject& ipParam,
|
||||
NetworkLayer& layer, Platform& platform) : DataLinkLayer(devObj, addrTab, layer, platform), _ipParameters(ipParam)
|
||||
IpDataLinkLayer::IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipParam,
|
||||
NetworkLayer& layer, Platform& platform) : DataLinkLayer(devObj, layer, platform), _ipParameters(ipParam)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ class IpDataLinkLayer : public DataLinkLayer
|
||||
using DataLinkLayer::_deviceObject;
|
||||
|
||||
public:
|
||||
IpDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, IpParameterObject& ipParam, NetworkLayer& layer,
|
||||
IpDataLinkLayer(DeviceObject& devObj, IpParameterObject& ipParam, NetworkLayer& layer,
|
||||
Platform& platform);
|
||||
|
||||
void loop();
|
||||
@ -25,4 +25,4 @@ class IpDataLinkLayer : public DataLinkLayer
|
||||
|
||||
IpParameterObject& _ipParameters;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "data_link_layer.h"
|
||||
#include "bits.h"
|
||||
|
||||
NetworkLayer::NetworkLayer(TransportLayer& layer): _transportLayer(layer)
|
||||
NetworkLayer::NetworkLayer(DeviceObject &deviceObj, TransportLayer& layer): _transportLayer(layer), _deviceObj(deviceObj)
|
||||
{
|
||||
|
||||
}
|
||||
@ -27,6 +27,21 @@ void NetworkLayer::hopCount(uint8_t value)
|
||||
void NetworkLayer::dataIndication(AckType ack, AddressType addrType, uint16_t destination, FrameFormat format, NPDU& npdu, Priority priority, uint16_t source)
|
||||
{
|
||||
HopCountType hopType = npdu.hopCount() == 7 ? UnlimitedRouting : NetworkLayerParameter;
|
||||
|
||||
// Only for devices which are not a coupler
|
||||
if (addrType == InduvidualAddress && destination != _deviceObj.induvidualAddress())
|
||||
return;
|
||||
|
||||
// TODO: remove. getTSAP() will return 0 later anyway. Get rid of dependency to GAT
|
||||
//if (addrType == GroupAddress && !_groupAddressTable.contains(destination))
|
||||
// return;
|
||||
|
||||
// if (frame.npdu().octetCount() > 0)
|
||||
// {
|
||||
// _print("-> DLL ");
|
||||
// frame.apdu().printPDU();
|
||||
// }
|
||||
|
||||
if (addrType == InduvidualAddress)
|
||||
{
|
||||
//if (npdu.octetCount() > 0)
|
||||
|
@ -5,11 +5,12 @@
|
||||
#include "npdu.h"
|
||||
#include "transport_layer.h"
|
||||
class DataLinkLayer;
|
||||
class DeviceObject;
|
||||
|
||||
class NetworkLayer
|
||||
{
|
||||
public:
|
||||
NetworkLayer(TransportLayer& layer);
|
||||
NetworkLayer(DeviceObject& deviceObj, TransportLayer& layer);
|
||||
|
||||
void dataLinkLayer(DataLinkLayer& layer);
|
||||
uint8_t hopCount() const;
|
||||
@ -38,4 +39,6 @@ class NetworkLayer
|
||||
uint8_t _hopCount = 6;
|
||||
DataLinkLayer* _dataLinkLayer = 0;
|
||||
TransportLayer& _transportLayer;
|
||||
DeviceObject& _deviceObj;
|
||||
|
||||
};
|
||||
|
@ -73,9 +73,9 @@ bool RfDataLinkLayer::sendFrame(CemiFrame& frame)
|
||||
return true;
|
||||
}
|
||||
|
||||
RfDataLinkLayer::RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, AddressTableObject& addrTab,
|
||||
RfDataLinkLayer::RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj,
|
||||
NetworkLayer& layer, Platform& platform)
|
||||
: DataLinkLayer(devObj, addrTab, layer, platform),
|
||||
: DataLinkLayer(devObj, layer, platform),
|
||||
_rfMediumObj(rfMediumObj),
|
||||
_rfPhy(*this, platform)
|
||||
{
|
||||
@ -377,4 +377,4 @@ void RfDataLinkLayer::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBuffer
|
||||
delete tx_frame;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -16,12 +16,11 @@ class RfDataLinkLayer : public DataLinkLayer
|
||||
friend class RfPhysicalLayer;
|
||||
|
||||
using DataLinkLayer::_deviceObject;
|
||||
using DataLinkLayer::_groupAddressTable;
|
||||
using DataLinkLayer::_platform;
|
||||
|
||||
public:
|
||||
RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, AddressTableObject& addrTab, NetworkLayer& layer,
|
||||
Platform& platform);
|
||||
RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, NetworkLayer& layer,
|
||||
Platform& platform);
|
||||
|
||||
void loop();
|
||||
void enabled(bool value);
|
||||
@ -60,4 +59,4 @@ class RfDataLinkLayer : public DataLinkLayer
|
||||
uint16_t calcCrcRF(uint8_t* buffer, uint32_t offset, uint32_t len);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -23,18 +23,25 @@ static constexpr uint8_t kSecureDataPdu = 0;
|
||||
static constexpr uint8_t kSecureSyncRequest = 2;
|
||||
static constexpr uint8_t kSecureSyncResponse = 3;
|
||||
|
||||
SecureApplicationLayer::SecureApplicationLayer(DeviceObject &deviceObj, SecurityInterfaceObject &secIfObj, AssociationTableObject& assocTable, AddressTableObject &addrTab, BusAccessUnit& bau):
|
||||
ApplicationLayer(assocTable, bau),
|
||||
SecureApplicationLayer::SecureApplicationLayer(DeviceObject &deviceObj, SecurityInterfaceObject &secIfObj, BusAccessUnit& bau):
|
||||
ApplicationLayer(bau),
|
||||
_secIfObj(secIfObj),
|
||||
_deviceObj(deviceObj),
|
||||
_addrTab(addrTab)
|
||||
_deviceObj(deviceObj)
|
||||
{
|
||||
}
|
||||
|
||||
void SecureApplicationLayer::groupAddressTable(AddressTableObject &addrTable)
|
||||
{
|
||||
_addrTab = &addrTable;
|
||||
}
|
||||
|
||||
/* from transport layer */
|
||||
|
||||
void SecureApplicationLayer::dataGroupIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu)
|
||||
{
|
||||
if (_addrTab == nullptr)
|
||||
return;
|
||||
|
||||
println("dataGroupIndication");
|
||||
|
||||
if (apdu.type() == SecureService)
|
||||
@ -293,12 +300,15 @@ void SecureApplicationLayer::dataConnectedConfirm(uint16_t tsap)
|
||||
|
||||
void SecureApplicationLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu, const SecurityControl& secCtrl)
|
||||
{
|
||||
if (_addrTab == nullptr)
|
||||
return;
|
||||
|
||||
println("dataGroupRequest");
|
||||
|
||||
if (secCtrl.dataSecurity != DataSecurity::none)
|
||||
{
|
||||
apdu.frame().sourceAddress(_deviceObj.induvidualAddress());
|
||||
apdu.frame().destinationAddress(_addrTab.getGroupAddress(tsap));
|
||||
apdu.frame().destinationAddress(_addrTab->getGroupAddress(tsap));
|
||||
apdu.frame().addressType(GroupAddress);
|
||||
|
||||
uint16_t secureApduLength = apdu.length() + 3 + 6 + 4; // 3(TPCI,APCI,SCF) + sizeof(seqNum) + apdu.length() + 4
|
||||
@ -507,7 +517,10 @@ void SecureApplicationLayer::blockCtr0(uint8_t* buffer, uint8_t* seqNum, uint16_
|
||||
|
||||
uint16_t SecureApplicationLayer::groupAddressIndex(uint16_t groupAddr)
|
||||
{
|
||||
return _addrTab.getTsap(groupAddr);
|
||||
// Just for safety reasons, we should never get here, because the dataGroupIndication will return already return early without doing anything
|
||||
if (_addrTab == nullptr)
|
||||
return 0;
|
||||
return _addrTab->getTsap(groupAddr);
|
||||
}
|
||||
|
||||
const uint8_t* SecureApplicationLayer::securityKey(uint16_t addr, bool isGroupAddress)
|
||||
|
@ -28,7 +28,9 @@ class SecureApplicationLayer : public ApplicationLayer
|
||||
* @param assocTable The AssociationTable is used to translate between asap (i.e. group objects) and group addresses.
|
||||
* @param bau methods are called here depending of the content of the APDU
|
||||
*/
|
||||
SecureApplicationLayer(DeviceObject& deviceObj, SecurityInterfaceObject& secIfObj, AssociationTableObject& assocTable, AddressTableObject& addrTab, BusAccessUnit& bau);
|
||||
SecureApplicationLayer(DeviceObject& deviceObj, SecurityInterfaceObject& secIfObj, BusAccessUnit& bau);
|
||||
|
||||
void groupAddressTable(AddressTableObject& addrTable);
|
||||
|
||||
void clearFailureLog();
|
||||
void getFailureCounters(uint8_t* data);
|
||||
@ -150,5 +152,5 @@ class SecureApplicationLayer : public ApplicationLayer
|
||||
|
||||
SecurityInterfaceObject& _secIfObj;
|
||||
DeviceObject& _deviceObj;
|
||||
AddressTableObject& _addrTab;
|
||||
AddressTableObject* _addrTab = nullptr;
|
||||
};
|
||||
|
@ -265,23 +265,39 @@ void TpUartDataLinkLayer::loop()
|
||||
if (!_isEcho)
|
||||
{
|
||||
uint8_t c = 0x10;
|
||||
//ceck if individual or group address
|
||||
if ((buffer[6] & 0x80) == 0)
|
||||
|
||||
// If this is not a nullptr we consider this a device to be a coupler
|
||||
// TODO: Improve for coupler mode, only ACK according to filter tables
|
||||
if (_groupAddressTable)
|
||||
{
|
||||
//check if individual or group address
|
||||
if ((buffer[6] & 0x80) == 0)
|
||||
{
|
||||
//individual
|
||||
if (_deviceObject.induvidualAddress() == getWord(buffer + 4))
|
||||
{
|
||||
c |= 0x01;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//group
|
||||
if (_groupAddressTable->contains(getWord(buffer + 4)) || getWord(buffer + 4) == 0)
|
||||
{
|
||||
c |= 0x01;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: test for only our coupler
|
||||
//individual
|
||||
if (_deviceObject.induvidualAddress() == getWord(buffer + 4))
|
||||
{
|
||||
c |= 0x01;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//group
|
||||
if (_groupAddressTable.contains(getWord(buffer + 4)) || getWord(buffer + 4) == 0)
|
||||
{
|
||||
c |= 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
_platform.writeUart(c);
|
||||
}
|
||||
}
|
||||
@ -412,12 +428,17 @@ void TpUartDataLinkLayer::stopChip()
|
||||
#endif
|
||||
}
|
||||
|
||||
TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab,
|
||||
TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj,
|
||||
NetworkLayer& layer, Platform& platform)
|
||||
: DataLinkLayer(devObj, addrTab, layer, platform)
|
||||
: DataLinkLayer(devObj, layer, platform)
|
||||
{
|
||||
}
|
||||
|
||||
void TpUartDataLinkLayer::groupAddressTable(AddressTableObject &addrTable)
|
||||
{
|
||||
_groupAddressTable = &addrTable;
|
||||
}
|
||||
|
||||
void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length)
|
||||
{
|
||||
//printHex("=>", buffer, length);
|
||||
@ -548,4 +569,4 @@ void TpUartDataLinkLayer::loadNextTxFrame()
|
||||
}
|
||||
delete tx_frame;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -11,13 +11,15 @@
|
||||
class TpUartDataLinkLayer : public DataLinkLayer
|
||||
{
|
||||
using DataLinkLayer::_deviceObject;
|
||||
using DataLinkLayer::_groupAddressTable;
|
||||
using DataLinkLayer::_platform;
|
||||
|
||||
public:
|
||||
TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer,
|
||||
TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayer& layer,
|
||||
Platform& platform);
|
||||
|
||||
;
|
||||
void groupAddressTable(AddressTableObject& addrTable);
|
||||
|
||||
void loop();
|
||||
void enabled(bool value);
|
||||
bool enabled() const;
|
||||
@ -62,5 +64,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
|
||||
void dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success);
|
||||
bool resetChip();
|
||||
void stopChip();
|
||||
|
||||
AddressTableObject* _groupAddressTable = nullptr;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "bits.h"
|
||||
#include <stdio.h>
|
||||
|
||||
TransportLayer::TransportLayer(ApplicationLayer& layer, AddressTableObject& gat): _savedFrame(0),
|
||||
_savedFrameConnecting(0), _applicationLayer(layer), _groupAddressTable(gat)
|
||||
TransportLayer::TransportLayer(ApplicationLayer& layer): _savedFrame(0),
|
||||
_savedFrameConnecting(0), _applicationLayer(layer)
|
||||
{
|
||||
_currentState = Closed;
|
||||
}
|
||||
@ -18,6 +18,11 @@ void TransportLayer::networkLayer(NetworkLayer& layer)
|
||||
_networkLayer = &layer;
|
||||
}
|
||||
|
||||
void TransportLayer::groupAddressTable(AddressTableObject &addrTable)
|
||||
{
|
||||
_groupAddressTable = &addrTable;
|
||||
}
|
||||
|
||||
void TransportLayer::dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu)
|
||||
{
|
||||
//if (tpdu.apdu().length() > 0)
|
||||
@ -361,7 +366,10 @@ void TransportLayer::dataIndividualConfirm(AckType ack, uint16_t destination, Ho
|
||||
|
||||
void TransportLayer::dataGroupIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu)
|
||||
{
|
||||
uint16_t tsap = _groupAddressTable.getTsap(destination);
|
||||
if (_groupAddressTable == nullptr)
|
||||
return;
|
||||
|
||||
uint16_t tsap = _groupAddressTable->getTsap(destination);
|
||||
if (tsap == 0)
|
||||
return;
|
||||
|
||||
@ -395,7 +403,10 @@ void TransportLayer::dataSystemBroadcastConfirm(AckType ack, HopCountType hopTyp
|
||||
|
||||
void TransportLayer::dataGroupRequest(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU& apdu)
|
||||
{
|
||||
uint16_t groupAdress = _groupAddressTable.getGroupAddress(tsap);
|
||||
if (_groupAddressTable == nullptr)
|
||||
return;
|
||||
|
||||
uint16_t groupAdress = _groupAddressTable->getGroupAddress(tsap);
|
||||
TPDU& tpdu = apdu.frame().tpdu();
|
||||
_networkLayer->dataGroupRequest(ack, groupAdress, hopType, priority, tpdu);
|
||||
}
|
||||
|
@ -16,8 +16,9 @@ enum StateType { Closed, OpenIdle, OpenWait, Connecting };
|
||||
class TransportLayer
|
||||
{
|
||||
public:
|
||||
TransportLayer(ApplicationLayer& layer, AddressTableObject& gat);
|
||||
TransportLayer(ApplicationLayer& layer);
|
||||
void networkLayer(NetworkLayer& layer);
|
||||
void groupAddressTable(AddressTableObject& addrTable);
|
||||
|
||||
#pragma region from network layer
|
||||
void dataIndividualIndication(uint16_t destination, HopCountType hopType, Priority priority, uint16_t source, TPDU& tpdu);
|
||||
@ -115,6 +116,6 @@ private:
|
||||
uint8_t _maxRepCount = 3;
|
||||
#pragma endregion
|
||||
ApplicationLayer& _applicationLayer;
|
||||
AddressTableObject& _groupAddressTable;
|
||||
AddressTableObject* _groupAddressTable;
|
||||
NetworkLayer* _networkLayer;
|
||||
};
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "linux_platform.h"
|
||||
#include "knx/bau57B0.h"
|
||||
#include "knx/bau27B0.h"
|
||||
#include "knx/bau091A.h"
|
||||
#endif
|
||||
|
||||
void buttonUp();
|
||||
|
Loading…
Reference in New Issue
Block a user