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) CemiFrame::CemiFrame(uint8_t* data, uint16_t length)
: _npdu(data + NPDU_LPDU_DIFF, *this), : _npdu(data + data[1] + NPDU_LPDU_DIFF, *this),
_tpdu(data + TPDU_LPDU_DIFF, *this), _tpdu(data + data[1] + TPDU_LPDU_DIFF, *this),
_apdu(data + APDU_LPDU_DIFF, *this) _apdu(data + data[1] + APDU_LPDU_DIFF, *this)
{ {
_data = data; _data = data;
_ctrl1 = data + data[1] + CEMI_HEADER_SIZE; _ctrl1 = data + data[1] + CEMI_HEADER_SIZE;

View File

@ -83,5 +83,5 @@ class CemiFrame
// only for RF medium // only for RF medium
uint8_t* _rfSerialOrDoA = 0; uint8_t* _rfSerialOrDoA = 0;
uint8_t _rfInfo = 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) void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
{ {
#if MEDIUM_TYPE == 2 #if MEDIUM_TYPE == 2
uint8_t data[frame.dataLength() + 10]; uint8_t data[frame.dataLength() + 10];
data[0] = L_data_ind; // Message Code 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[2] = 0x02; // RF add. info: type
data[3] = 0x08; // RF add. info: length data[3] = 0x08; // RF add. info: length
data[4] = frame.rfInfo(); // RF add. info: info field (batt ok, bidir) 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 pushByteArray(frame.rfSerialOrDoA(), 6, &data[5]); // RF add. info:Serial or Domain Address
data[11] = frame.rfLfn(); // RF add. info: link layer frame number 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)); CemiFrame tmpFrame(data, sizeof(data));
@ -67,21 +71,9 @@ void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
print(tmpFrame.destinationAddress(), HEX); print(tmpFrame.destinationAddress(), HEX);
printHex(" frame: ", tmpFrame.data(), tmpFrame.dataLength()); printHex(" frame: ", tmpFrame.data(), tmpFrame.dataLength());
tmpFrame.apdu().type();
_usbTunnelInterface.sendCemiFrame(tmpFrame); _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); frame.sourceAddress(_clientAddress);
} }
#if MEDIUM_TYPE == 2 #if MEDIUM_TYPE == 2
// Check if we have additional info for RF // 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 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())[2] == 0x02) && // Additional info type: RF
((frame.data())[3] == 0x08) ) // Additional info length of type RF: 8 bytes (fixed) ((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 // Use the values provided in the RF additonal info
memcpy(&rfSerialOrDoA, &((frame.data())[5]), 6); if ( ((frame.data())[5] != 0x00) || ((frame.data())[6] != 0x00) || ((frame.data())[7] != 0x00) ||
rfLfn = (frame.data())[11]; ((frame.data())[8] != 0x00) || ((frame.data())[9] != 0x00) || ((frame.data())[10] != 0x00) )
} {
else frame.rfSerialOrDoA(&((frame.data())[5]));
{ } // else leave the nullptr as it is
// Let the RF data link layer fill in its own values frame.rfLfn((frame.data())[11]);
memset(&rfSerialOrDoA, 0x00, 6);
rfLfn = 0xFF;
} }
if ( (rfSerialOrDoA[0] == 0x00) && (rfSerialOrDoA[1] == 0x00) && (rfSerialOrDoA[2] == 0x00) && // If the cEMI client does not provide a link layer frame number (LFN),
(rfSerialOrDoA[3] == 0x00) && (rfSerialOrDoA[4] == 0x00) && (rfSerialOrDoA[5] == 0x00) ) // 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); // Set Data Link Layer Frame Number
} frame.rfLfn(_frameNumber);
else // Link Layer frame number counts 0..7
{ _frameNumber = (_frameNumber + 1) & 0x7;
frame.rfSerialOrDoA(rfSerialOrDoA);
} }
#endif #endif

View File

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

View File

@ -48,6 +48,7 @@ void DataLinkLayer::systemBroadcastRequest(AckType ack, FrameFormat format, Prio
void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success) void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success)
{ {
MessageCode backupMsgCode = frame.messageCode();
frame.messageCode(L_data_con); frame.messageCode(L_data_con);
frame.confirm(success ? ConfirmNoError : ConfirmError); frame.confirm(success ? ConfirmNoError : ConfirmError);
AckType ack = frame.ack(); AckType ack = frame.ack();
@ -77,6 +78,8 @@ void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success)
_networkLayer.broadcastConfirm(ack, type, priority, source, npdu, success); _networkLayer.broadcastConfirm(ack, type, priority, source, npdu, success);
else else
_networkLayer.dataConfirm(ack, addrType, destination, type, priority, source, npdu, success); _networkLayer.dataConfirm(ack, addrType, destination, type, priority, source, npdu, success);
frame.messageCode(backupMsgCode);
} }
void DataLinkLayer::frameRecieved(CemiFrame& frame) void DataLinkLayer::frameRecieved(CemiFrame& frame)
@ -172,6 +175,7 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA
tmpFrame.rfSerialOrDoA(frame.rfSerialOrDoA()); tmpFrame.rfSerialOrDoA(frame.rfSerialOrDoA());
tmpFrame.rfInfo(frame.rfInfo()); tmpFrame.rfInfo(frame.rfInfo());
tmpFrame.rfLfn(frame.rfLfn()); tmpFrame.rfLfn(frame.rfLfn());
tmpFrame.confirm(ConfirmNoError);
_cemiServer->dataIndicationToTunnel(tmpFrame); _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 // then we received the domain address and not the KNX serial number
if (systemBroadcast == Broadcast) 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 it does not match then skip the remaining processing
if (memcmp(_rfMediumObj.rfDomainAddress(), &rfPacketBuf[4], 6)) 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) 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: case PID_RF_DOMAIN_ADDRESS:
for (uint8_t i = start; i < start + count; i++) for (uint8_t i = start; i < start + count; i++)
_rfDomainAddress[i-1] = data[i - start]; _rfDomainAddress[i-1] = data[i - start];