save work

This commit is contained in:
Nanosonde 2020-07-17 14:44:13 +02:00
parent cd0bce0c20
commit df6551af9e
11 changed files with 100 additions and 55 deletions

View File

@ -23,7 +23,9 @@ add_executable(knx-linux
../../src/knx/bau091A.h
../../src/knx/bau27B0.cpp
../../src/knx/bau27B0.h
../../src/knx/bau57B0.cpp
../../src/knx/bau2920.cpp
../../src/knx/bau2920.h
../../src/knx/bau57B0.cpp
../../src/knx/bau57B0.h
../../src/knx/bau_systemB.cpp
../../src/knx/bau_systemB.h

View File

@ -1,6 +1,7 @@
#include "knx_facade.h"
#include "knx/bau091A.h"
#include "knx/bau2920.h"
#include "knx/bits.h"
#include <time.h>

View File

@ -18,6 +18,7 @@ Bau07B0::Bau07B0(Platform& platform)
_netLayer.getEntity(0).dataLinkLayer(_dlLayer);
#ifdef USE_CEMI_SERVER
_cemiServerObject.setMediumTypeAsSupported(DptMedium::KNX_TP1);
_cemiServer.dataLinkLayer(_dlLayer);
_dlLayer.cemiServer(_cemiServer);
_memory.addSaveRestore(&_cemiServerObject);

View File

@ -4,7 +4,7 @@
#include <string.h>
#include <stdio.h>
#ifdef USE_IP
#if defined(USE_IP) && defined (USE_TP)
using namespace std;
@ -26,8 +26,10 @@ Bau091A::Bau091A(Platform& platform)
_netLayer.getEntity(1).dataLinkLayer(_dlLayerSecondary);
#ifdef USE_CEMI_SERVER
_cemiServerObject.setMediumTypeAsSupported(DptMedium::KNX_IP);
_cemiServerObject.setMediumTypeAsSupported(DptMedium::KNX_TP1);
_cemiServer.dataLinkLayer(_dlLayerSecondary); // Secondary I/F is the important one!
_dlLayer.cemiServer(_cemiServer);
_dlLayerSecondary.cemiServer(_cemiServer);
_memory.addSaveRestore(&_cemiServerObject);
#endif

View File

@ -1,7 +1,7 @@
#pragma once
#include "config.h"
#ifdef USE_IP
#if defined(USE_IP) && defined (USE_TP)
#include "bau_systemB_coupler.h"
#include "ip_parameter_object.h"
#include "ip_data_link_layer.h"

View File

@ -16,6 +16,7 @@ Bau27B0::Bau27B0(Platform& platform)
_netLayer.getEntity(0).dataLinkLayer(_dlLayer);
_memory.addSaveRestore(&_rfMediumObj);
#ifdef USE_CEMI_SERVER
_cemiServerObject.setMediumTypeAsSupported(DptMedium::KNX_RF);
_cemiServer.dataLinkLayer(_dlLayer);
_dlLayer.cemiServer(_cemiServer);
_memory.addSaveRestore(&_cemiServerObject);

View File

@ -19,6 +19,7 @@ Bau57B0::Bau57B0(Platform& platform)
{
_netLayer.getEntity(0).dataLinkLayer(_dlLayer);
#ifdef USE_CEMI_SERVER
_cemiServerObject.setMediumTypeAsSupported(DptMedium::KNX_IP);
_cemiServer.dataLinkLayer(_dlLayer);
_dlLayer.cemiServer(_cemiServer);
_memory.addSaveRestore(&_cemiServerObject);

View File

@ -16,7 +16,9 @@ BauSystemBDevice::BauSystemBDevice(Platform& platform) :
{
_appLayer.transportLayer(_transLayer);
_appLayer.associationTableObject(_assocTable);
#ifdef USE_DATASECURE
_appLayer.groupAddressTable(_addrTable);
#endif
_transLayer.networkLayer(_netLayer);
_transLayer.groupAddressTable(_addrTable);

View File

@ -56,21 +56,24 @@ void CemiServer::dataConfirmationToTunnel(CemiFrame& frame)
void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
{
#if MEDIUM_TYPE == 2
bool isRf = _dataLinkLayer->isOpenMedium();
uint8_t data[frame.dataLength() + (isRf ? 10 : 0)];
uint8_t data[frame.dataLength() + 10];
data[0] = L_data_ind; // Message Code
data[1] = 0x0A; // Total additional info length
data[2] = 0x02; // RF add. info: type
data[3] = 0x08; // RF add. info: length
data[4] = frame.rfInfo(); // RF add. info: info field (batt ok, bidir)
pushByteArray(frame.rfSerialOrDoA(), 6, &data[5]); // RF add. info:Serial or Domain Address
data[11] = frame.rfLfn(); // RF add. info: link layer frame number
memcpy(&data[12], &((frame.data())[2]), frame.dataLength() - 2);
#else
uint8_t data[frame.dataLength()];
memcpy(&data[0], frame.data(), frame.dataLength());
#endif
if (_dataLinkLayer->isOpenMedium())
{
data[0] = L_data_ind; // Message Code
data[1] = 0x0A; // Total additional info length
data[2] = 0x02; // RF add. info: type
data[3] = 0x08; // RF add. info: length
data[4] = frame.rfInfo(); // RF add. info: info field (batt ok, bidir)
pushByteArray(frame.rfSerialOrDoA(), 6, &data[5]); // RF add. info:Serial or Domain Address
data[11] = frame.rfLfn(); // RF add. info: link layer frame number
memcpy(&data[12], &((frame.data())[2]), frame.dataLength() - 2);
}
else
{
memcpy(&data[0], frame.data(), frame.dataLength());
}
CemiFrame tmpFrame(data, sizeof(data));
@ -87,6 +90,8 @@ void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
void CemiServer::frameReceived(CemiFrame& frame)
{
bool isRf = _dataLinkLayer->isOpenMedium();
switch(frame.messageCode())
{
case L_data_req:
@ -98,35 +103,36 @@ void CemiServer::frameReceived(CemiFrame& frame)
frame.sourceAddress(_clientAddress);
}
#if MEDIUM_TYPE == 2
// Check if we have additional info for RF
if (((frame.data())[1] == 0x0A) && // Additional info total length: we only handle one additional info of type RF
((frame.data())[2] == 0x02) && // Additional info type: RF
((frame.data())[3] == 0x08) ) // Additional info length of type RF: 8 bytes (fixed)
if (isRf)
{
frame.rfInfo((frame.data())[4]);
// Use the values provided in the RF additonal info
if ( ((frame.data())[5] != 0x00) || ((frame.data())[6] != 0x00) || ((frame.data())[7] != 0x00) ||
((frame.data())[8] != 0x00) || ((frame.data())[9] != 0x00) || ((frame.data())[10] != 0x00) )
// Check if we have additional info for RF
if (((frame.data())[1] == 0x0A) && // Additional info total length: we only handle one additional info of type RF
((frame.data())[2] == 0x02) && // Additional info type: RF
((frame.data())[3] == 0x08) ) // Additional info length of type RF: 8 bytes (fixed)
{
frame.rfSerialOrDoA(&((frame.data())[5]));
} // else leave the nullptr as it is
frame.rfLfn((frame.data())[11]);
}
frame.rfInfo((frame.data())[4]);
// Use the values provided in the RF additonal info
if ( ((frame.data())[5] != 0x00) || ((frame.data())[6] != 0x00) || ((frame.data())[7] != 0x00) ||
((frame.data())[8] != 0x00) || ((frame.data())[9] != 0x00) || ((frame.data())[10] != 0x00) )
{
frame.rfSerialOrDoA(&((frame.data())[5]));
} // else leave the nullptr as it is
frame.rfLfn((frame.data())[11]);
}
// If the cEMI client does not provide a link layer frame number (LFN),
// we use our own counter.
// Note: There is another link layer frame number counter inside the RF data link layer class!
// That counter is solely for the local application!
// If we set a LFN here, the data link layer counter is NOT used!
if (frame.rfLfn() == 0xFF)
{
// Set Data Link Layer Frame Number
frame.rfLfn(_frameNumber);
// Link Layer frame number counts 0..7
_frameNumber = (_frameNumber + 1) & 0x7;
// If the cEMI client does not provide a link layer frame number (LFN),
// we use our own counter.
// Note: There is another link layer frame number counter inside the RF data link layer class!
// That counter is solely for the local application!
// If we set a LFN here, the data link layer counter is NOT used!
if (frame.rfLfn() == 0xFF)
{
// Set Data Link Layer Frame Number
frame.rfLfn(_frameNumber);
// Link Layer frame number counts 0..7
_frameNumber = (_frameNumber + 1) & 0x7;
}
}
#endif
print("L_data_req: src: ");
print(frame.sourceAddress(), HEX);

View File

@ -8,26 +8,51 @@
CemiServerObject::CemiServerObject()
{
uint16_t mediumType = 0;
#if MEDIUM_TYPE == 0
mediumType = 2; // TP1 supported
#elif MEDIUM_TYPE == 2
mediumType = 16; // RF supported
#elif MEDIUM_TYPE == 5
mediumType = 32; // IP supported
#endif
Property* properties[] =
{
new DataProperty( PID_OBJECT_TYPE, false, PDT_UNSIGNED_INT, 1, ReadLv3 | WriteLv0, (uint16_t)OT_CEMI_SERVER ),
new DataProperty( PID_MEDIUM_TYPE, false, PDT_BITSET16, 1, ReadLv3 | WriteLv0, mediumType),
new DataProperty( PID_MEDIUM_TYPE, false, PDT_BITSET16, 1, ReadLv3 | WriteLv0, (uint16_t)0),
new DataProperty( PID_COMM_MODE, false, PDT_ENUM8, 1, ReadLv3 | WriteLv0, (uint16_t)0),
new DataProperty( PID_COMM_MODES_SUPPORTED, false, PDT_BITSET16, 1, ReadLv3 | WriteLv0, (uint16_t)0x100),
new DataProperty( PID_MEDIUM_AVAILABILITY, false, PDT_BITSET16, 1, ReadLv3 | WriteLv0, mediumType),
new DataProperty( PID_MEDIUM_AVAILABILITY, false, PDT_BITSET16, 1, ReadLv3 | WriteLv0, (uint16_t)0),
// cEMI additional info types supported by this cEMI server: only 0x02 (RF Control Octet and Serial Number or DoA)
new DataProperty( PID_ADD_INFO_TYPES, false, PDT_ENUM8, 1, ReadLv3 | WriteLv0, (uint8_t)0x02)
};
initializeProperties(sizeof(properties), properties);
}
void CemiServerObject::setMediumTypeAsSupported(DptMedium dptMedium)
{
uint16_t mediaTypesSupported;
property(PID_MEDIUM_TYPE)->read(mediaTypesSupported);
switch(dptMedium)
{
case DptMedium::KNX_IP:
mediaTypesSupported |= 1 << 1;
break;
case DptMedium::KNX_RF:
mediaTypesSupported |= 1 << 4;
break;
case DptMedium::KNX_TP1:
mediaTypesSupported |= 1 << 5;
break;
case DptMedium::KNX_PL110:
mediaTypesSupported |= 1 << 2;
break;
}
property(PID_MEDIUM_TYPE)->write(mediaTypesSupported);
// We also set the medium as available too
property(PID_MEDIUM_AVAILABILITY)->write(mediaTypesSupported);
}
void CemiServerObject::clearSupportedMediaTypes()
{
property(PID_MEDIUM_TYPE)->write((uint16_t) 0);
// We also set the medium as not available too
property(PID_MEDIUM_AVAILABILITY)->write((uint16_t) 0);
}
#endif

View File

@ -9,5 +9,9 @@ class CemiServerObject: public InterfaceObject
{
public:
CemiServerObject();
void setMediumTypeAsSupported(DptMedium dptMedium);
void clearSupportedMediaTypes();
};
#endif
#endif