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
2b9057b6d2
commit
380d5e91ce
@ -19,8 +19,32 @@ void DataLinkLayer::cemiServer(CemiServer& cemiServer)
|
||||
|
||||
void DataLinkLayer::dataIndicationFromTunnel(CemiFrame& frame)
|
||||
{
|
||||
}
|
||||
uint16_t destination = frame.destinationAddress();
|
||||
uint16_t ownAddr = _deviceObject.induvidualAddress();
|
||||
AddressType addrType = frame.addressType();
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send to KNX medium
|
||||
sendFrame(frame);
|
||||
}
|
||||
}
|
||||
else // GroupAddress
|
||||
{
|
||||
// Send to local stack
|
||||
frameRecieved(frame);
|
||||
// Send to KNX medium
|
||||
sendFrame(frame);
|
||||
}
|
||||
}
|
||||
|
||||
void DataLinkLayer::dataRequest(AckType ack, AddressType addrType, uint16_t destinationAddr, FrameFormat format, Priority priority, NPDU& npdu)
|
||||
{
|
||||
@ -69,7 +93,10 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame)
|
||||
NPDU& npdu = frame.npdu();
|
||||
uint16_t ownAddr = _deviceObject.induvidualAddress();
|
||||
SystemBroadcast systemBroadcast = frame.systemBroadcast();
|
||||
|
||||
|
||||
// if (source != _cemiServerObj.tunnelAddress)
|
||||
_cemiServer->dataIndicationToTunnel(frame);
|
||||
|
||||
if (source == ownAddr)
|
||||
_deviceObject.induvidualAddressDuplication(true);
|
||||
|
||||
|
@ -48,7 +48,72 @@ static uint8_t const desc_hid_report[] =
|
||||
0xC0 // End Collection
|
||||
};
|
||||
|
||||
uint16_t parseReport(uint8_t* data, uint16_t dataLength)
|
||||
struct _rx_queue_frame_t
|
||||
{
|
||||
uint8_t* data;
|
||||
uint16_t length;
|
||||
_rx_queue_frame_t* next;
|
||||
};
|
||||
|
||||
static struct _rx_queue_t
|
||||
{
|
||||
_rx_queue_frame_t* front = NULL;
|
||||
_rx_queue_frame_t* back = NULL;
|
||||
} _rx_queue;
|
||||
|
||||
static void addFrameRxQueue(CemiFrame& frame)
|
||||
{
|
||||
_rx_queue_frame_t* rx_frame = new _rx_queue_frame_t;
|
||||
|
||||
rx_frame->length = frame.totalLenght();
|
||||
rx_frame->data = new uint8_t[rx_frame->length];
|
||||
rx_frame->next = NULL;
|
||||
|
||||
/*
|
||||
print("cEMI USB RX len: ");
|
||||
print(rx_frame->length);
|
||||
|
||||
printHex(" data:", rx_frame->data, rx_frame->length);
|
||||
*/
|
||||
if (_rx_queue.back == NULL)
|
||||
{
|
||||
_rx_queue.front = _rx_queue.back = rx_frame;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rx_queue.back->next = rx_frame;
|
||||
_rx_queue.back = rx_frame;
|
||||
}
|
||||
}
|
||||
|
||||
static bool isRxQueueEmpty()
|
||||
{
|
||||
if (_rx_queue.front == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void loadNextRxFrame(uint8_t** receiveBuffer, uint16_t* receiveBufferLength)
|
||||
{
|
||||
if (_rx_queue.front == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_rx_queue_frame_t* rx_frame = _rx_queue.front;
|
||||
*receiveBuffer = rx_frame->data;
|
||||
*receiveBufferLength = rx_frame->length;
|
||||
_rx_queue.front = rx_frame->next;
|
||||
|
||||
if (_rx_queue.front == NULL)
|
||||
{
|
||||
_rx_queue.back = NULL;
|
||||
}
|
||||
delete rx_frame;
|
||||
}
|
||||
|
||||
static uint16_t parseReport(uint8_t* data, uint16_t dataLength)
|
||||
{
|
||||
int8_t respDataSize = 0;
|
||||
bool forceSend = false;
|
||||
@ -157,6 +222,9 @@ uint16_t parseReport(uint8_t* data, uint16_t dataLength)
|
||||
data[7] == 0x01 && // KNX Tunneling (0x01)
|
||||
data[8] == 0x03 ) // EMI ID: 3 -> cEMI
|
||||
{
|
||||
CemiFrame frame(&data[11], data[6]);
|
||||
addFrameRxQueue(frame);
|
||||
|
||||
uint8_t messageCode = data[11];
|
||||
switch(messageCode)
|
||||
{
|
||||
@ -215,21 +283,48 @@ uint16_t parseReport(uint8_t* data, uint16_t dataLength)
|
||||
return respDataSize;
|
||||
}
|
||||
|
||||
void sendKnxTunnelHidReport(uint8_t* data, uint16_t length)
|
||||
{
|
||||
uint8_t buffer[length + 100];
|
||||
|
||||
buffer[0] = 0x01; // ReportID (fixed 0x01)
|
||||
buffer[1] = 0x13; // PacketInfo must be 0x13 (SeqNo: 1, Type: 3)
|
||||
buffer[3] = 0x00; // Protocol version (fixed 0x00)
|
||||
buffer[4] = 0x08; // USB KNX Transfer Protocol Header Length (fixed 0x08)
|
||||
buffer[7] = 0x01; // KNX Tunneling (0x01)
|
||||
buffer[8] = 0x03; // EMI ID: 3 -> cEMI
|
||||
buffer[9] = 0x00; // Manufacturer
|
||||
buffer[10] = 0x00; // Manufacturer
|
||||
|
||||
// Copy cEMI frame to buffer
|
||||
memcpy(&buffer[11], data, length + 100);
|
||||
|
||||
// We do not use reportId of the sendReport()-API here but instead provide it in the first byte of the buffer
|
||||
usb_hid.sendReport(0, data, length + 100);
|
||||
}
|
||||
|
||||
// Invoked when received SET_REPORT control request or
|
||||
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
||||
void set_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
|
||||
static void set_report_callback(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
|
||||
{
|
||||
// we don't use multiple report and report ID
|
||||
(void) report_id;
|
||||
(void) report_type;
|
||||
// we don't use multiple report and report ID
|
||||
(void) report_id;
|
||||
(void) report_type;
|
||||
|
||||
uint8_t tmpbuf[bufsize];
|
||||
memcpy(tmpbuf, buffer, bufsize);
|
||||
uint8_t tmpbuf[bufsize];
|
||||
memcpy(tmpbuf, buffer, bufsize);
|
||||
|
||||
if (parseReport(tmpbuf, bufsize) > 0)
|
||||
{
|
||||
usb_hid.sendReport(tmpbuf[0], &tmpbuf[1], bufsize);
|
||||
}
|
||||
if (parseReport(tmpbuf, bufsize) > 0)
|
||||
{
|
||||
sendKnxTunnelHidReport(&tmpbuf[0], bufsize);
|
||||
}
|
||||
}
|
||||
|
||||
// class UsbDataLinkLayer
|
||||
|
||||
UsbDataLinkLayer::UsbDataLinkLayer(DeviceObject& deviceObject, CemiServer& cemiServer, Platform& platform)
|
||||
: _deviceObject(deviceObject), _cemiServer(cemiServer), _platform(platform)
|
||||
{
|
||||
}
|
||||
|
||||
void UsbDataLinkLayer::loop()
|
||||
@ -241,8 +336,35 @@ void UsbDataLinkLayer::loop()
|
||||
|
||||
if (!isTxQueueEmpty())
|
||||
{
|
||||
//loadNextTxFrame();
|
||||
//sendKnxHidReport();
|
||||
uint8_t* buffer;
|
||||
uint16_t length;
|
||||
loadNextTxFrame(&buffer, &length);
|
||||
|
||||
print("cEMI USB TX len: ");
|
||||
print(length);
|
||||
|
||||
print(" data: ");
|
||||
printHex(" data: ", buffer, length);
|
||||
|
||||
sendKnxTunnelHidReport(buffer, length);
|
||||
}
|
||||
|
||||
if (!isRxQueueEmpty())
|
||||
{
|
||||
uint8_t* buffer;
|
||||
uint16_t length;
|
||||
loadNextRxFrame(&buffer, &length);
|
||||
|
||||
// Prepare the cEMI frame
|
||||
CemiFrame frame(buffer, length);
|
||||
|
||||
print("cEMI USB RX len: ");
|
||||
print(length);
|
||||
|
||||
print(" data: ");
|
||||
printHex(" data: ", buffer, length);
|
||||
|
||||
_cemiServer.frameReceived(frame);
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,33 +373,11 @@ bool UsbDataLinkLayer::sendCemiFrame(CemiFrame& frame)
|
||||
if (!_enabled)
|
||||
return false;
|
||||
|
||||
// TODO: Is queueing really required?
|
||||
// According to the spec. the upper layer may only send a new L_Data.req if it received
|
||||
// the L_Data.con for the previous L_Data.req.
|
||||
addFrameTxQueue(frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UsbDataLinkLayer::UsbDataLinkLayer(DeviceObject& deviceObject, CemiServer& cemiServer, Platform& platform)
|
||||
: _deviceObject(deviceObject), _cemiServer(cemiServer), _platform(platform)
|
||||
{
|
||||
}
|
||||
|
||||
void UsbDataLinkLayer::frameBytesReceived(uint8_t* _buffer, uint16_t length)
|
||||
{
|
||||
// Prepare the cEMI frame
|
||||
CemiFrame frame(_buffer, length);
|
||||
|
||||
print("cEMI USB RX len: ");
|
||||
print(length);
|
||||
|
||||
print(" data: ");
|
||||
printHex(" data: ", _buffer, length);
|
||||
|
||||
_cemiServer.frameReceived(frame);
|
||||
}
|
||||
|
||||
void UsbDataLinkLayer::enabled(bool value)
|
||||
{
|
||||
if (value && !_enabled)
|
||||
@ -318,11 +418,12 @@ void UsbDataLinkLayer::addFrameTxQueue(CemiFrame& frame)
|
||||
tx_frame->data = new uint8_t[tx_frame->length];
|
||||
tx_frame->next = NULL;
|
||||
|
||||
/*
|
||||
print("cEMI USB TX len: ");
|
||||
print(tx_frame->length);
|
||||
|
||||
printHex(" data:", tx_frame->data, tx_frame->length);
|
||||
|
||||
*/
|
||||
if (_tx_queue.back == NULL)
|
||||
{
|
||||
_tx_queue.front = _tx_queue.back = tx_frame;
|
||||
|
@ -21,15 +21,11 @@ class UsbDataLinkLayer
|
||||
void enabled(bool value);
|
||||
bool enabled() const;
|
||||
|
||||
// from cEMI server
|
||||
bool sendCemiFrame(CemiFrame& frame);
|
||||
|
||||
private:
|
||||
bool _enabled = false;
|
||||
uint8_t _loopState = 0;
|
||||
|
||||
uint8_t _buffer[512];
|
||||
|
||||
uint8_t _frameNumber = 0;
|
||||
|
||||
struct _tx_queue_frame_t
|
||||
{
|
||||
@ -51,5 +47,4 @@ class UsbDataLinkLayer
|
||||
void addFrameTxQueue(CemiFrame& frame);
|
||||
bool isTxQueueEmpty();
|
||||
void loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength);
|
||||
void frameBytesReceived(uint8_t* buffer, uint16_t length);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user