mirror of
https://github.com/thelsing/knx.git
synced 2025-08-17 13:47:28 +02:00
save work
This commit is contained in:
parent
f1085a39cc
commit
7c34f15e67
@ -6,9 +6,19 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define MIN(a, b) ((a < b) ? (a) : (b))
|
||||||
|
|
||||||
#define MAX_EP_SIZE 64
|
#define MAX_EP_SIZE 64
|
||||||
#define HID_HEADER_SIZE 3
|
#define HID_HEADER_SIZE 3
|
||||||
|
|
||||||
|
// Maximum possible payload data bytes in a transfer protocol body
|
||||||
|
#define MAX_DATASIZE_START_PACKET 52
|
||||||
|
#define MAX_DATASIZE_PARTIAL_PACKET 61
|
||||||
|
|
||||||
|
#define PACKET_TYPE_START 1
|
||||||
|
#define PACKET_TYPE_END 2
|
||||||
|
#define PACKET_TYPE_PARTIAL 4
|
||||||
|
|
||||||
//#define DEBUG_TX_HID_REPORT
|
//#define DEBUG_TX_HID_REPORT
|
||||||
//#define DEBUG_RX_HID_REPORT
|
//#define DEBUG_RX_HID_REPORT
|
||||||
|
|
||||||
@ -34,14 +44,8 @@ void UsbTunnelInterface::loop()
|
|||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
loadNextTxFrame(&buffer, &length);
|
loadNextTxFrame(&buffer, &length);
|
||||||
/*
|
sendKnxHidReport(buffer, length);
|
||||||
print("cEMI USB TX len: ");
|
delete buffer;
|
||||||
print(length);
|
|
||||||
|
|
||||||
print(" data: ");
|
|
||||||
printHex(" data: ", buffer, length);
|
|
||||||
*/
|
|
||||||
sendKnxTunnelHidReport(buffer, length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRxQueueEmpty())
|
if (!isRxQueueEmpty())
|
||||||
@ -56,37 +60,29 @@ void UsbTunnelInterface::loop()
|
|||||||
|
|
||||||
/* USB TX */
|
/* USB TX */
|
||||||
|
|
||||||
bool UsbTunnelInterface::sendCemiFrame(CemiFrame& frame)
|
void UsbTunnelInterface::sendCemiFrame(CemiFrame& frame)
|
||||||
{
|
{
|
||||||
addFrameTxQueue(frame);
|
sendKnxTunnelHidReport(frame.data(), frame.dataLength());
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsbTunnelInterface::addFrameTxQueue(CemiFrame& frame)
|
void UsbTunnelInterface::addBufferTxQueue(uint8_t* data, uint16_t length)
|
||||||
{
|
{
|
||||||
_queue_buffer_t* tx_frame = new _queue_buffer_t;
|
_queue_buffer_t* tx_buffer = new _queue_buffer_t;
|
||||||
|
|
||||||
tx_frame->length = frame.dataLength();
|
tx_buffer->length = length;
|
||||||
tx_frame->data = new uint8_t[tx_frame->length];
|
tx_buffer->data = new uint8_t[tx_buffer->length];
|
||||||
tx_frame->next = nullptr;
|
tx_buffer->next = nullptr;
|
||||||
|
|
||||||
memcpy(tx_frame->data, frame.data(), tx_frame->length);
|
memcpy(tx_buffer->data, data, tx_buffer->length);
|
||||||
|
|
||||||
/*
|
|
||||||
print("cEMI USB TX len: ");
|
|
||||||
print(tx_frame->length);
|
|
||||||
|
|
||||||
printHex(" data:", tx_frame->data, tx_frame->length);
|
|
||||||
*/
|
|
||||||
if (_tx_queue.back == nullptr)
|
if (_tx_queue.back == nullptr)
|
||||||
{
|
{
|
||||||
_tx_queue.front = _tx_queue.back = tx_frame;
|
_tx_queue.front = _tx_queue.back = tx_buffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_tx_queue.back->next = tx_frame;
|
_tx_queue.back->next = tx_buffer;
|
||||||
_tx_queue.back = tx_frame;
|
_tx_queue.back = tx_buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,30 +101,78 @@ void UsbTunnelInterface::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBuf
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_queue_buffer_t* tx_frame = _tx_queue.front;
|
_queue_buffer_t* tx_buffer = _tx_queue.front;
|
||||||
*sendBuffer = tx_frame->data;
|
*sendBuffer = tx_buffer->data;
|
||||||
*sendBufferLength = tx_frame->length;
|
*sendBufferLength = tx_buffer->length;
|
||||||
_tx_queue.front = tx_frame->next;
|
_tx_queue.front = tx_buffer->next;
|
||||||
|
|
||||||
if (_tx_queue.front == nullptr)
|
if (_tx_queue.front == nullptr)
|
||||||
{
|
{
|
||||||
_tx_queue.back = nullptr;
|
_tx_queue.back = nullptr;
|
||||||
}
|
}
|
||||||
delete tx_frame;
|
delete tx_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsbTunnelInterface::sendKnxTunnelHidReport(uint8_t* data, uint16_t length)
|
void UsbTunnelInterface::sendKnxTunnelHidReport(uint8_t* data, uint16_t length)
|
||||||
{
|
{
|
||||||
uint8_t buffer[length + 11];
|
uint16_t maxData = MAX_DATASIZE_START_PACKET;
|
||||||
|
uint8_t packetType = PACKET_TYPE_START;
|
||||||
|
|
||||||
buffer[0] = 0x01; // ReportID (fixed 0x01)
|
if (length > maxData)
|
||||||
buffer[1] = 0x13; // PacketInfo must be 0x13 (SeqNo: 1, Type: 3)
|
{
|
||||||
|
packetType |= PACKET_TYPE_PARTIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t offset = 0;
|
||||||
|
uint8_t* buffer = nullptr;
|
||||||
|
|
||||||
|
for(uint8_t seqNum = 1; seqNum < 6; seqNum++)
|
||||||
|
{
|
||||||
|
uint16_t copyLen = MIN(length, maxData);
|
||||||
|
|
||||||
|
// If this is the first packet we include the transport protocol header
|
||||||
|
if (packetType & PACKET_TYPE_START)
|
||||||
|
{
|
||||||
|
buffer = new uint8_t[copyLen + 8 + HID_HEADER_SIZE]; // length of transport protocol header: 11 bytes
|
||||||
|
buffer[2] = 8 + copyLen; // KNX USB Transfer Protocol Header length
|
||||||
buffer[3] = 0x00; // Protocol version (fixed 0x00)
|
buffer[3] = 0x00; // Protocol version (fixed 0x00)
|
||||||
buffer[4] = 0x08; // USB KNX Transfer Protocol Header Length (fixed 0x08)
|
buffer[4] = 0x08; // USB KNX Transfer Protocol Header Length (fixed 0x08)
|
||||||
buffer[7] = 0x01; // KNX Tunneling (0x01)
|
buffer[7] = 0x01; // KNX Tunneling (0x01)
|
||||||
buffer[8] = 0x03; // EMI ID: 3 -> cEMI
|
buffer[8] = 0x03; // EMI ID: 3 -> cEMI
|
||||||
buffer[9] = 0x00; // Manufacturer
|
buffer[9] = 0x00; // Manufacturer
|
||||||
buffer[10] = 0x00; // Manufacturer
|
buffer[10] = 0x00; // Manufacturer
|
||||||
|
memcpy(&buffer[11], &data[offset], copyLen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer = new uint8_t[copyLen]; // length of transport protocol header: 11 bytes
|
||||||
|
buffer[2] = copyLen; // KNX USB Transfer Protocol Header length
|
||||||
|
memcpy(&buffer[0], &data[offset], copyLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += copyLen;
|
||||||
|
if (offset >= length)
|
||||||
|
{
|
||||||
|
packetType |= PACKET_TYPE_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0] = 0x01; // ReportID (fixed 0x01)
|
||||||
|
buffer[1] = ((seqNum << 4) & 0xF0) | (packetType & 0x07); // PacketInfo (SeqNo and Type)
|
||||||
|
addBufferTxQueue(buffer, (buffer[2] + HID_HEADER_SIZE));
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
if (offset >= length)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetType &= ~PACKET_TYPE_START;
|
||||||
|
maxData = MAX_DATASIZE_PARTIAL_PACKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t buffer[length + 11];
|
||||||
|
|
||||||
|
|
||||||
// Copy cEMI frame to buffer
|
// Copy cEMI frame to buffer
|
||||||
memcpy(&buffer[11], data, length + HID_HEADER_SIZE + 8);
|
memcpy(&buffer[11], data, length + HID_HEADER_SIZE + 8);
|
||||||
@ -150,7 +194,7 @@ void UsbTunnelInterface::sendKnxTunnelHidReport(uint8_t* data, uint16_t length)
|
|||||||
Serial1.println("");
|
Serial1.println("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sendKnxHidReport(buffer, MAX_EP_SIZE);
|
addBufferTxQueue(buffer, (buffer[2] + HID_HEADER_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USB RX */
|
/* USB RX */
|
||||||
@ -180,12 +224,6 @@ void UsbTunnelInterface::addBufferRxQueue(const uint8_t* data, uint16_t length)
|
|||||||
|
|
||||||
memcpy(rx_buffer->data, data, rx_buffer->length);
|
memcpy(rx_buffer->data, data, rx_buffer->length);
|
||||||
|
|
||||||
/*
|
|
||||||
print("cEMI USB RX len: ");
|
|
||||||
print(rx_buffer->length);
|
|
||||||
|
|
||||||
printHex(" data:", rx_buffer->data, rx_buffer->length);
|
|
||||||
*/
|
|
||||||
if (_rx_queue.back == nullptr)
|
if (_rx_queue.back == nullptr)
|
||||||
{
|
{
|
||||||
_rx_queue.front =_rx_queue.back = rx_buffer;
|
_rx_queue.front =_rx_queue.back = rx_buffer;
|
||||||
@ -377,7 +415,7 @@ void UsbTunnelInterface::handleBusAccessServerProtocol(const uint8_t* requestDat
|
|||||||
}
|
}
|
||||||
Serial1.println("");
|
Serial1.println("");
|
||||||
#endif
|
#endif
|
||||||
sendKnxHidReport(data, MAX_EP_SIZE);
|
addBufferTxQueue(data, packetLength + respDataSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class UsbTunnelInterface
|
|||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
// from cEMI server
|
// from cEMI server
|
||||||
bool sendCemiFrame(CemiFrame& frame);
|
void sendCemiFrame(CemiFrame& frame);
|
||||||
|
|
||||||
static const uint8_t* getKnxHidReportDescriptor();
|
static const uint8_t* getKnxHidReportDescriptor();
|
||||||
static uint16_t getHidReportDescriptorLength();
|
static uint16_t getHidReportDescriptorLength();
|
||||||
@ -44,7 +44,7 @@ class UsbTunnelInterface
|
|||||||
|
|
||||||
// USB TX queue
|
// USB TX queue
|
||||||
_queue_t _tx_queue;
|
_queue_t _tx_queue;
|
||||||
void addFrameTxQueue(CemiFrame& frame);
|
void addBufferTxQueue(uint8_t* data, uint16_t length);
|
||||||
bool isTxQueueEmpty();
|
bool isTxQueueEmpty();
|
||||||
void loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength);
|
void loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user