mirror of
https://github.com/thelsing/knx.git
synced 2025-09-09 17:51:55 +02:00
Working with Net'N'Node and ETS.
This commit is contained in:
parent
589aec4585
commit
322c3bbff8
@ -69,9 +69,9 @@ Control Field 1
|
||||
*/
|
||||
|
||||
CemiFrame::CemiFrame(uint8_t* data, uint16_t length)
|
||||
: _npdu(data + NPDU_LPDU_DIFF, *this),
|
||||
_tpdu(data + TPDU_LPDU_DIFF, *this),
|
||||
_apdu(data + APDU_LPDU_DIFF, *this)
|
||||
: _npdu(data + data[1] + NPDU_LPDU_DIFF, *this),
|
||||
_tpdu(data + data[1] + TPDU_LPDU_DIFF, *this),
|
||||
_apdu(data + data[1] + APDU_LPDU_DIFF, *this)
|
||||
{
|
||||
_data = data;
|
||||
_ctrl1 = data + data[1] + CEMI_HEADER_SIZE;
|
||||
|
@ -83,5 +83,5 @@ class CemiFrame
|
||||
// only for RF medium
|
||||
uint8_t* _rfSerialOrDoA = 0;
|
||||
uint8_t _rfInfo = 0;
|
||||
uint8_t _rfLfn = 0; // RF Data Link layer frame number
|
||||
uint8_t _rfLfn = 0xFF; // RF Data Link layer frame number
|
||||
};
|
@ -47,17 +47,21 @@ void CemiServer::dataConfirmationToTunnel(CemiFrame& frame)
|
||||
|
||||
void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
|
||||
{
|
||||
#if MEDIUM_TYPE == 2
|
||||
#if MEDIUM_TYPE == 2
|
||||
|
||||
uint8_t data[frame.dataLength() + 10];
|
||||
data[0] = L_data_ind; // Message Code
|
||||
data[1] = 10; // Total additional info length
|
||||
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);
|
||||
memcpy(&data[12], &((frame.data())[2]), frame.dataLength() - 2);
|
||||
#else
|
||||
uint8_t data[frame.dataLength()];
|
||||
memcpy(&data[0], frame.data(), frame.dataLength());
|
||||
#endif
|
||||
|
||||
CemiFrame tmpFrame(data, sizeof(data));
|
||||
|
||||
@ -67,21 +71,9 @@ void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
|
||||
print(tmpFrame.destinationAddress(), HEX);
|
||||
|
||||
printHex(" frame: ", tmpFrame.data(), tmpFrame.dataLength());
|
||||
tmpFrame.apdu().type();
|
||||
|
||||
_usbTunnelInterface.sendCemiFrame(tmpFrame);
|
||||
|
||||
#else
|
||||
|
||||
print("L_data_ind: src: ");
|
||||
print(frame.sourceAddress(), HEX);
|
||||
print(" dst: ");
|
||||
print(frame.destinationAddress(), HEX);
|
||||
|
||||
printHex(" frame: ", frame.data(), frame.dataLength());
|
||||
|
||||
_usbTunnelInterface.sendCemiFrame(frame);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -107,35 +99,33 @@ void CemiServer::frameReceived(CemiFrame& frame)
|
||||
frame.sourceAddress(_clientAddress);
|
||||
}
|
||||
|
||||
#if MEDIUM_TYPE == 2
|
||||
#if MEDIUM_TYPE == 2
|
||||
// Check if we have additional info for RF
|
||||
|
||||
uint8_t rfSerialOrDoA[6];
|
||||
uint8_t rfLfn;
|
||||
|
||||
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.rfInfo((frame.data())[4]);
|
||||
// Use the values provided in the RF additonal info
|
||||
memcpy(&rfSerialOrDoA, &((frame.data())[5]), 6);
|
||||
rfLfn = (frame.data())[11];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let the RF data link layer fill in its own values
|
||||
memset(&rfSerialOrDoA, 0x00, 6);
|
||||
rfLfn = 0xFF;
|
||||
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 ( (rfSerialOrDoA[0] == 0x00) && (rfSerialOrDoA[1] == 0x00) && (rfSerialOrDoA[2] == 0x00) &&
|
||||
(rfSerialOrDoA[3] == 0x00) && (rfSerialOrDoA[4] == 0x00) && (rfSerialOrDoA[5] == 0x00) )
|
||||
// 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)
|
||||
{
|
||||
frame.rfSerialOrDoA(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
frame.rfSerialOrDoA(rfSerialOrDoA);
|
||||
// Set Data Link Layer Frame Number
|
||||
frame.rfLfn(_frameNumber);
|
||||
// Link Layer frame number counts 0..7
|
||||
_frameNumber = (_frameNumber + 1) & 0x7;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -42,6 +42,7 @@ class CemiServer
|
||||
|
||||
private:
|
||||
uint16_t _clientAddress;
|
||||
uint8_t _frameNumber = 0;
|
||||
|
||||
DataLinkLayer* _dataLinkLayer;
|
||||
BauSystemB& _bau;
|
||||
|
@ -48,6 +48,7 @@ void DataLinkLayer::systemBroadcastRequest(AckType ack, FrameFormat format, Prio
|
||||
|
||||
void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success)
|
||||
{
|
||||
MessageCode backupMsgCode = frame.messageCode();
|
||||
frame.messageCode(L_data_con);
|
||||
frame.confirm(success ? ConfirmNoError : ConfirmError);
|
||||
AckType ack = frame.ack();
|
||||
@ -77,6 +78,8 @@ void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success)
|
||||
_networkLayer.broadcastConfirm(ack, type, priority, source, npdu, success);
|
||||
else
|
||||
_networkLayer.dataConfirm(ack, addrType, destination, type, priority, source, npdu, success);
|
||||
|
||||
frame.messageCode(backupMsgCode);
|
||||
}
|
||||
|
||||
void DataLinkLayer::frameRecieved(CemiFrame& frame)
|
||||
@ -172,6 +175,7 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA
|
||||
tmpFrame.rfSerialOrDoA(frame.rfSerialOrDoA());
|
||||
tmpFrame.rfInfo(frame.rfInfo());
|
||||
tmpFrame.rfLfn(frame.rfLfn());
|
||||
tmpFrame.confirm(ConfirmNoError);
|
||||
_cemiServer->dataIndicationToTunnel(tmpFrame);
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ void RfDataLinkLayer::frameBytesReceived(uint8_t* rfPacketBuf, uint16_t length)
|
||||
// then we received the domain address and not the KNX serial number
|
||||
if (systemBroadcast == Broadcast)
|
||||
{
|
||||
// Check if the received RF domain address matches the one stored in the RF medium object
|
||||
// Check if the received RF domain address matches the one stored in the RF medium object
|
||||
// If it does not match then skip the remaining processing
|
||||
if (memcmp(_rfMediumObj.rfDomainAddress(), &rfPacketBuf[4], 6))
|
||||
{
|
||||
|
@ -41,6 +41,9 @@ void RfMediumObject::writeProperty(PropertyID id, uint32_t start, uint8_t* data,
|
||||
{
|
||||
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];
|
||||
|
Loading…
Reference in New Issue
Block a user