Working with Net'N'Node and ETS.

This commit is contained in:
nanosonde 2019-12-04 20:32:03 +01:00
parent 589aec4585
commit 322c3bbff8
7 changed files with 39 additions and 41 deletions

View File

@ -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;

View File

@ -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
};

View File

@ -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

View File

@ -42,6 +42,7 @@ class CemiServer
private:
uint16_t _clientAddress;
uint8_t _frameNumber = 0;
DataLinkLayer* _dataLinkLayer;
BauSystemB& _bau;

View File

@ -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);
}

View File

@ -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))
{

View File

@ -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];