mirror of
https://github.com/thelsing/knx.git
synced 2025-08-13 13:46:20 +02:00
Save work
This commit is contained in:
parent
478f5c569a
commit
619c6383d2
@ -259,6 +259,17 @@ void CemiFrame::ack(AckType value)
|
||||
_ctrl1[0] |= value;
|
||||
}
|
||||
|
||||
Confirm CemiFrame::confirm() const
|
||||
{
|
||||
return (Confirm)(_ctrl1[0] & ConfirmError);
|
||||
}
|
||||
|
||||
void CemiFrame::confirm(Confirm value)
|
||||
{
|
||||
_ctrl1[0] &= ~ConfirmError;
|
||||
_ctrl1[0] |= value;
|
||||
}
|
||||
|
||||
AddressType CemiFrame::addressType() const
|
||||
{
|
||||
return (AddressType)(_ctrl1[1] & GroupAddress);
|
||||
|
@ -45,6 +45,8 @@ class CemiFrame
|
||||
void priority(Priority value);
|
||||
AckType ack() const;
|
||||
void ack(AckType value);
|
||||
Confirm confirm() const;
|
||||
void confirm(Confirm value);
|
||||
AddressType addressType() const;
|
||||
void addressType(AddressType value);
|
||||
uint8_t hopCount() const;
|
||||
|
@ -13,6 +13,9 @@ CemiServer::CemiServer(BauSystemB& bau)
|
||||
_bau.deviceObject().maskVersion(),
|
||||
_bau.deviceObject().manufacturerId())
|
||||
{
|
||||
// The cEMI server will hand out the device address + 1 to the cEMI client (e.g. ETS),
|
||||
// so that the device and the cEMI client/server connection(tunnel) can operate simultaneously.
|
||||
_clientAddress = _bau.deviceObject().induvidualAddress() + 1;
|
||||
}
|
||||
|
||||
void CemiServer::dataLinkLayer(DataLinkLayer& layer)
|
||||
@ -20,10 +23,52 @@ void CemiServer::dataLinkLayer(DataLinkLayer& layer)
|
||||
_dataLinkLayer = &layer;
|
||||
}
|
||||
|
||||
uint16_t CemiServer::clientAddress() const
|
||||
{
|
||||
return _clientAddress;
|
||||
}
|
||||
|
||||
void CemiServer::clientAddress(uint16_t value)
|
||||
{
|
||||
_clientAddress = value;
|
||||
}
|
||||
|
||||
void CemiServer::dataConfirmationToTunnel(CemiFrame& frame)
|
||||
{
|
||||
print("L_data_con: src: ");
|
||||
print(frame.sourceAddress(), HEX);
|
||||
print(" dst: ");
|
||||
print(frame.destinationAddress(), HEX);
|
||||
|
||||
printHex(" frame: ", frame.data(), frame.dataLength());
|
||||
|
||||
_usbTunnelInterface.sendCemiFrame(frame);
|
||||
}
|
||||
|
||||
void CemiServer::dataIndicationToTunnel(CemiFrame& frame)
|
||||
{
|
||||
println("L_data_ind: ");
|
||||
_usbTunnelInterface.sendCemiFrame(frame);
|
||||
static uint8_t lfn = 0;
|
||||
uint8_t data[frame.dataLength() + 10];
|
||||
data[0] = L_data_ind;
|
||||
data[1] = 10;
|
||||
data[2] = 0x02; // RF Info add. info
|
||||
data[3] = 0x08; // RF info length
|
||||
data[4] = 0x02; // RF info field (batt ok)
|
||||
pushByteArray(_bau.deviceObject().rfDomainAddress(), 6, &data[5]);
|
||||
data[11] = lfn;
|
||||
lfn = (lfn + 1) & 0x7;
|
||||
memcpy(&data[12], &frame.data()[2], frame.dataLength() - 2);
|
||||
|
||||
CemiFrame tmpFrame(data, sizeof(data));
|
||||
|
||||
print("L_data_ind: src: ");
|
||||
print(tmpFrame.sourceAddress(), HEX);
|
||||
print(" dst: ");
|
||||
print(tmpFrame.destinationAddress(), HEX);
|
||||
|
||||
printHex(" frame: ", tmpFrame.data(), tmpFrame.dataLength());
|
||||
|
||||
_usbTunnelInterface.sendCemiFrame(tmpFrame);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -42,15 +87,21 @@ void CemiServer::frameReceived(CemiFrame& frame)
|
||||
{
|
||||
case L_data_req:
|
||||
{
|
||||
println("L_data_req: ");
|
||||
// Fill in the cEMI client address if the client sets
|
||||
// source address to 0.
|
||||
if(frame.sourceAddress() == 0x0000)
|
||||
{
|
||||
frame.sourceAddress(_clientAddress);
|
||||
}
|
||||
|
||||
// Send as indication to data link layer
|
||||
frame.messageCode(L_data_ind);
|
||||
_dataLinkLayer->dataIndicationFromTunnel(frame);
|
||||
|
||||
// Send local reply to tunnel
|
||||
frame.messageCode(L_data_con);
|
||||
_usbTunnelInterface.sendCemiFrame(frame);
|
||||
print("L_data_req: src: ");
|
||||
print(frame.sourceAddress(), HEX);
|
||||
print(" dst: ");
|
||||
print(frame.destinationAddress(), HEX);
|
||||
|
||||
printHex(" frame: ", frame.data(), frame.dataLength());
|
||||
|
||||
_dataLinkLayer->dataRequestFromTunnel(frame);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -81,6 +132,24 @@ void CemiServer::frameReceived(CemiFrame& frame)
|
||||
// propertyValueRead() allocates memory for the data! Needs to be deleted again!
|
||||
_bau.propertyValueRead((ObjectType)objectType, objectInstance, propertyId, numberOfElements, startIndex, &data, dataSize);
|
||||
|
||||
// Patch result for device address in device object
|
||||
// The cEMI server will hand out the device address + 1 to the cEMI client (e.g. ETS),
|
||||
// so that the device and the cEMI client/server connection(tunnel) can operate simultaneously.
|
||||
// KNX IP Interfaces which offer multiple simultaneous tunnel connections seem to operate the same way.
|
||||
// Each tunnel has its own cEMI client address which is based on the main device address.
|
||||
if (((ObjectType) objectType == OT_DEVICE) &&
|
||||
(propertyId == PID_DEVICE_ADDR) &&
|
||||
(numberOfElements == 1))
|
||||
{
|
||||
data[0] = (uint8_t) (_clientAddress & 0xFF);
|
||||
}
|
||||
else if (((ObjectType) objectType == OT_DEVICE) &&
|
||||
(propertyId == PID_SUBNET_ADDR) &&
|
||||
(numberOfElements == 1))
|
||||
{
|
||||
data[0] = (uint8_t) ((_clientAddress >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
if (data && dataSize && numberOfElements)
|
||||
{
|
||||
printHex(" <- data: ", data, dataSize);
|
||||
@ -95,7 +164,7 @@ void CemiServer::frameReceived(CemiFrame& frame)
|
||||
responseFrame.messageCode(M_PropRead_con);
|
||||
_usbTunnelInterface.sendCemiFrame(responseFrame);
|
||||
|
||||
delete data;
|
||||
delete[] data;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -141,7 +210,31 @@ void CemiServer::frameReceived(CemiFrame& frame)
|
||||
|
||||
printHex(" -> data: ", requestData, requestDataSize);
|
||||
|
||||
_bau.propertyValueWrite((ObjectType)objectType, objectInstance, propertyId, numberOfElements, startIndex, requestData, requestDataSize);
|
||||
// Patch request for device address in device object
|
||||
if (((ObjectType) objectType == OT_DEVICE) &&
|
||||
(propertyId == PID_DEVICE_ADDR) &&
|
||||
(numberOfElements == 1))
|
||||
{
|
||||
// Temporarily store new cEMI client address in memory
|
||||
// We also be sent back if the client requests it again
|
||||
_clientAddress = (_clientAddress & 0xFF00) | requestData[0];
|
||||
print("cEMI client address: ");
|
||||
println(_clientAddress, HEX);
|
||||
}
|
||||
else if (((ObjectType) objectType == OT_DEVICE) &&
|
||||
(propertyId == PID_SUBNET_ADDR) &&
|
||||
(numberOfElements == 1))
|
||||
{
|
||||
// Temporarily store new cEMI client address in memory
|
||||
// We also be sent back if the client requests it again
|
||||
_clientAddress = (_clientAddress & 0x00FF) | (requestData[0] << 8);
|
||||
print("cEMI client address: ");
|
||||
println(_clientAddress, HEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
_bau.propertyValueWrite((ObjectType)objectType, objectInstance, propertyId, numberOfElements, startIndex, requestData, requestDataSize);
|
||||
}
|
||||
|
||||
if (numberOfElements)
|
||||
{
|
||||
@ -214,169 +307,3 @@ void CemiServer::loop()
|
||||
{
|
||||
_usbTunnelInterface.loop();
|
||||
}
|
||||
|
||||
/*
|
||||
void CemiServer::propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
|
||||
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex)
|
||||
{
|
||||
CemiFrame frame(5);
|
||||
APDU& apdu = frame.apdu();
|
||||
apdu.type(PropertyValueRead);
|
||||
uint8_t* data = apdu.data();
|
||||
data += 1;
|
||||
data = pushByte(objectIndex, data);
|
||||
data = pushByte(propertyId, data);
|
||||
pushWord(startIndex & 0xfff, data);
|
||||
*data &= ((numberOfElements & 0xf) << 4);
|
||||
|
||||
individualSend(ack, hopType, priority, asap, apdu);
|
||||
}
|
||||
|
||||
void CemiServer::propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
|
||||
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length)
|
||||
{
|
||||
propertyDataSend(PropertyValueResponse, ack, priority, hopType, asap, objectIndex, propertyId, numberOfElements,
|
||||
startIndex, data, length);
|
||||
}
|
||||
|
||||
void CemiServer::propertyValueWriteRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
|
||||
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t * data, uint8_t length)
|
||||
{
|
||||
propertyDataSend(PropertyValueWrite, ack, priority, hopType, asap, objectIndex, propertyId, numberOfElements,
|
||||
startIndex, data, length);
|
||||
}
|
||||
|
||||
void CemiServer::propertyDescriptionReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
|
||||
uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex)
|
||||
{
|
||||
CemiFrame frame(4);
|
||||
APDU& apdu = frame.apdu();
|
||||
apdu.type(PropertyDescriptionRead);
|
||||
uint8_t* data = apdu.data();
|
||||
data[1] = objectIndex;
|
||||
data[2] = propertyId;
|
||||
data[3] = propertyIndex;
|
||||
individualSend(ack, hopType, priority, asap, apdu);
|
||||
}
|
||||
|
||||
void CemiServer::propertyDescriptionReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
|
||||
uint8_t objectIndex, uint8_t propertyId, uint8_t propertyIndex, bool writeEnable, uint8_t type,
|
||||
uint16_t maxNumberOfElements, uint8_t access)
|
||||
{
|
||||
CemiFrame frame(8);
|
||||
APDU& apdu = frame.apdu();
|
||||
apdu.type(PropertyDescriptionResponse);
|
||||
uint8_t* data = apdu.data();
|
||||
data[1] = objectIndex;
|
||||
data[2] = propertyId;
|
||||
data[3] = propertyIndex;
|
||||
if (writeEnable)
|
||||
data[4] |= 0x80;
|
||||
data[4] |= (type & 0x3f);
|
||||
pushWord(maxNumberOfElements & 0xfff, data + 5);
|
||||
data[7] = access;
|
||||
individualSend(ack, hopType, priority, asap, apdu);
|
||||
}
|
||||
|
||||
|
||||
void CemiServer::propertyDataSend(ApduType type, AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
|
||||
uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex, uint8_t* data, uint8_t length)
|
||||
{
|
||||
CemiFrame frame(5 + length);
|
||||
APDU& apdu = frame.apdu();
|
||||
apdu.type(type);
|
||||
uint8_t* apduData = apdu.data();
|
||||
apduData += 1;
|
||||
apduData = pushByte(objectIndex, apduData);
|
||||
apduData = pushByte(propertyId, apduData);
|
||||
pushWord(startIndex & 0xfff, apduData);
|
||||
*apduData |= ((numberOfElements & 0xf) << 4);
|
||||
apduData += 2;
|
||||
if (length > 0)
|
||||
memcpy(apduData, data, length);
|
||||
}
|
||||
|
||||
void CemiServer::individualIndication(HopCountType hopType, Priority priority, uint16_t tsap, APDU & apdu)
|
||||
{
|
||||
uint8_t* data = apdu.data();
|
||||
switch (apdu.type())
|
||||
{
|
||||
case PropertyValueRead:
|
||||
{
|
||||
uint16_t startIndex;
|
||||
popWord(startIndex, data + 3);
|
||||
startIndex &= 0xfff;
|
||||
_bau.propertyValueReadIndication(priority, hopType, tsap, data[1], data[2], data[3] >> 4, startIndex);
|
||||
break;
|
||||
}
|
||||
case PropertyValueResponse:
|
||||
{
|
||||
uint16_t startIndex;
|
||||
popWord(startIndex, data + 3);
|
||||
startIndex &= 0xfff;
|
||||
_bau.propertyValueReadAppLayerConfirm(priority, hopType, tsap, data[1], data[2], data[3] >> 4,
|
||||
startIndex, data + 5, apdu.length() - 5);
|
||||
break;
|
||||
}
|
||||
case PropertyValueWrite:
|
||||
{
|
||||
uint16_t startIndex;
|
||||
popWord(startIndex, data + 3);
|
||||
startIndex &= 0xfff;
|
||||
_bau.propertyValueWriteIndication(priority, hopType, tsap, data[1], data[2], data[3] >> 4,
|
||||
startIndex, data + 5, apdu.length() - 5);
|
||||
break;
|
||||
}
|
||||
case PropertyDescriptionRead:
|
||||
_bau.propertyDescriptionReadIndication(priority, hopType, tsap, data[1], data[2], data[3]);
|
||||
break;
|
||||
case PropertyDescriptionResponse:
|
||||
_bau.propertyDescriptionReadAppLayerConfirm(priority, hopType, tsap, data[1], data[2], data[3],
|
||||
(data[4] & 0x80) > 0, data[4] & 0x3f, getWord(data + 5) & 0xfff, data[7]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CemiServer::individualConfirm(AckType ack, HopCountType hopType, Priority priority, uint16_t tsap, APDU & apdu, bool status)
|
||||
{
|
||||
uint8_t* data = apdu.data();
|
||||
switch (apdu.type())
|
||||
{
|
||||
case PropertyValueRead:
|
||||
{
|
||||
uint16_t startIndex;
|
||||
popWord(startIndex, data + 3);
|
||||
startIndex &= 0xfff;
|
||||
_bau.propertyValueReadLocalConfirm(ack, priority, hopType, tsap, data[1], data[2], data[3] >> 4,
|
||||
startIndex, status);
|
||||
break;
|
||||
}
|
||||
case PropertyValueResponse:
|
||||
{
|
||||
uint16_t startIndex;
|
||||
popWord(startIndex, data + 3);
|
||||
startIndex &= 0xfff;
|
||||
_bau.propertyValueReadResponseConfirm(ack, priority, hopType, tsap, data[1], data[2], data[3] >> 4,
|
||||
startIndex, data + 5, apdu.length() - 5, status);
|
||||
break;
|
||||
}
|
||||
case PropertyValueWrite:
|
||||
{
|
||||
uint16_t startIndex;
|
||||
popWord(startIndex, data + 3);
|
||||
startIndex &= 0xfff;
|
||||
_bau.propertyValueWriteLocalConfirm(ack, priority, hopType, tsap, data[1], data[2], data[3] >> 4,
|
||||
startIndex, data + 5, apdu.length() - 5, status);
|
||||
break;
|
||||
}
|
||||
case PropertyDescriptionRead:
|
||||
_bau.propertyDescriptionReadLocalConfirm(ack, priority, hopType, tsap, data[1], data[2], data[3], status);
|
||||
break;
|
||||
case PropertyDescriptionResponse:
|
||||
_bau.propertyDescriptionReadResponseConfirm(ack, priority, hopType, tsap, data[1], data[2], data[3],
|
||||
(data[4] & 0x80) > 0, data[4] & 0x3f, getWord(data + 5) & 0xfff, data[7], status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
@ -31,13 +31,19 @@ class CemiServer
|
||||
// from data link layer
|
||||
// Only L_Data service
|
||||
void dataIndicationToTunnel(CemiFrame& frame);
|
||||
void dataConfirmationToTunnel(CemiFrame& frame);
|
||||
|
||||
// From tunnel interface
|
||||
void frameReceived(CemiFrame& frame);
|
||||
|
||||
uint16_t clientAddress() const;
|
||||
void clientAddress(uint16_t value);
|
||||
|
||||
void loop();
|
||||
|
||||
private:
|
||||
uint16_t _clientAddress;
|
||||
|
||||
DataLinkLayer* _dataLinkLayer;
|
||||
BauSystemB& _bau;
|
||||
UsbDataLinkLayer _usbTunnelInterface;
|
||||
|
@ -17,21 +17,27 @@ void DataLinkLayer::cemiServer(CemiServer& cemiServer)
|
||||
_cemiServer = &cemiServer;
|
||||
}
|
||||
|
||||
void DataLinkLayer::dataIndicationFromTunnel(CemiFrame& frame)
|
||||
void DataLinkLayer::dataRequestFromTunnel(CemiFrame& frame)
|
||||
{
|
||||
uint16_t destination = frame.destinationAddress();
|
||||
uint16_t ownAddr = _deviceObject.induvidualAddress();
|
||||
AddressType addrType = frame.addressType();
|
||||
|
||||
frame.messageCode(L_data_con);
|
||||
_cemiServer->dataConfirmationToTunnel(frame);
|
||||
|
||||
frame.messageCode(L_data_ind);
|
||||
|
||||
if (addrType == InduvidualAddress)
|
||||
{
|
||||
// TODO: check if this is correct: shall we send a frame to the bus too if it was intended for us?
|
||||
if (destination == ownAddr)
|
||||
{
|
||||
// Send to local stack
|
||||
frameRecieved(frame);
|
||||
// Send back a confirmation
|
||||
//dataConReceived(frame, true);
|
||||
}
|
||||
else
|
||||
else // TODO: check if this is correct: shall we send a frame to the bus too if it was intended for us?
|
||||
{
|
||||
// Send to KNX medium
|
||||
sendFrame(frame);
|
||||
@ -63,6 +69,8 @@ void DataLinkLayer::systemBroadcastRequest(AckType ack, FrameFormat format, Prio
|
||||
|
||||
void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success)
|
||||
{
|
||||
frame.messageCode(L_data_con);
|
||||
frame.confirm(success ? ConfirmNoError : ConfirmError);
|
||||
AckType ack = frame.ack();
|
||||
AddressType addrType = frame.addressType();
|
||||
uint16_t destination = frame.destinationAddress();
|
||||
@ -72,6 +80,17 @@ void DataLinkLayer::dataConReceived(CemiFrame& frame, bool success)
|
||||
NPDU& npdu = frame.npdu();
|
||||
SystemBroadcast systemBroadcast = frame.systemBroadcast();
|
||||
|
||||
if (_cemiServer)
|
||||
{
|
||||
// Only send our own confirmation messages to the tunnel
|
||||
if (frame.sourceAddress() == _cemiServer->clientAddress())
|
||||
{
|
||||
//_cemiServer->dataConfirmationToTunnel(frame);
|
||||
// Stop processing here and do NOT send it the local network layer
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (addrType == GroupAddress && destination == 0)
|
||||
if (systemBroadcast == SysBroadcast)
|
||||
_networkLayer.systemBroadcastConfirm(ack, type, priority, source, npdu, success);
|
||||
@ -79,9 +98,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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DataLinkLayer::frameRecieved(CemiFrame& frame)
|
||||
{
|
||||
AckType ack = frame.ack();
|
||||
@ -96,8 +114,11 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame)
|
||||
|
||||
if (_cemiServer)
|
||||
{
|
||||
// if (source != _cemiServerObj.tunnelAddress)
|
||||
_cemiServer->dataIndicationToTunnel(frame);
|
||||
// Do not send our own message back to the tunnel
|
||||
if (frame.sourceAddress() != _cemiServer->clientAddress())
|
||||
{
|
||||
_cemiServer->dataIndicationToTunnel(frame);
|
||||
}
|
||||
}
|
||||
|
||||
if (source == ownAddr)
|
||||
@ -157,6 +178,12 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA
|
||||
// frame.apdu().printPDU();
|
||||
// }
|
||||
|
||||
if (_cemiServer)
|
||||
{
|
||||
CemiFrame tmpFrame(frame.data(), frame.totalLenght());
|
||||
_cemiServer->dataIndicationToTunnel(tmpFrame);
|
||||
}
|
||||
|
||||
return sendFrame(frame);
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,9 @@ class DataLinkLayer
|
||||
DataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer,
|
||||
Platform& platform);
|
||||
|
||||
// from tunnel
|
||||
void cemiServer(CemiServer& cemiServer);
|
||||
|
||||
void dataIndicationFromTunnel(CemiFrame& frame);
|
||||
void dataRequestFromTunnel(CemiFrame& frame);
|
||||
|
||||
// from network layer
|
||||
void dataRequest(AckType ack, AddressType addrType, uint16_t destinationAddr, FrameFormat format,
|
||||
|
@ -24,7 +24,10 @@ void RfDataLinkLayer::loop()
|
||||
bool RfDataLinkLayer::sendFrame(CemiFrame& frame)
|
||||
{
|
||||
if (!_enabled)
|
||||
{
|
||||
dataConReceived(frame, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Depending on this flag, use either KNX Serial Number
|
||||
// or the RF domain address that was programmed by ETS
|
||||
@ -166,7 +169,7 @@ void RfDataLinkLayer::frameBytesReceived(uint8_t* rfPacketBuf, uint16_t length)
|
||||
// Prepare CEMI by writing/overwriting certain fields in the buffer (contiguous frame without CRC checksums)
|
||||
// See 3.6.3 p.79: L_Data services for KNX RF asynchronous frames
|
||||
// For now we do not use additional info, but use normal method arguments for CEMI
|
||||
_buffer[0] = 0x29; // L_data.ind
|
||||
_buffer[0] = (uint8_t) L_data_ind; // L_data.ind
|
||||
_buffer[1] = 0; // Additional info length (spec. says that local dev management is not required to use AddInfo internally)
|
||||
_buffer[2] = 0; // CTRL1 field (will be set later, this is the field we reserved space for)
|
||||
_buffer[3] &= 0x0F; // CTRL2 field (take only RFCtrl.b3..0, b7..4 shall always be 0 for asynchronous KNX RF)
|
||||
|
@ -364,7 +364,10 @@ void TpUartDataLinkLayer::loop()
|
||||
bool TpUartDataLinkLayer::sendFrame(CemiFrame& frame)
|
||||
{
|
||||
if (!_enabled)
|
||||
{
|
||||
dataConReceived(frame, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
addFrameTxQueue(frame);
|
||||
return true;
|
||||
|
@ -207,7 +207,7 @@ static void handleBusAccessServerProtocol(const uint8_t* requestData, uint16_t p
|
||||
{
|
||||
data[2] += respDataSize; // HID Report Header: Packet Length
|
||||
data[6] += respDataSize; // USB KNX Transfer Protocol Header: Body Length
|
||||
|
||||
/*
|
||||
Serial1.print("TX HID report: len: ");
|
||||
Serial1.println((packetLength) + respDataSize, DEC);
|
||||
|
||||
@ -219,7 +219,7 @@ static void handleBusAccessServerProtocol(const uint8_t* requestData, uint16_t p
|
||||
Serial1.print(" ");
|
||||
}
|
||||
Serial1.println("");
|
||||
|
||||
*/
|
||||
usb_hid.sendReport(0, data, MAX_EP_SIZE);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user