save work

This commit is contained in:
nanosonde 2019-11-20 11:38:06 +01:00
parent f1085a39cc
commit 7c34f15e67
2 changed files with 88 additions and 50 deletions

View File

@ -6,9 +6,19 @@
#include <stdio.h>
#include <string.h>
#define MIN(a, b) ((a < b) ? (a) : (b))
#define MAX_EP_SIZE 64
#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_RX_HID_REPORT
@ -34,14 +44,8 @@ void UsbTunnelInterface::loop()
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);
sendKnxHidReport(buffer, length);
delete buffer;
}
if (!isRxQueueEmpty())
@ -56,37 +60,29 @@ void UsbTunnelInterface::loop()
/* USB TX */
bool UsbTunnelInterface::sendCemiFrame(CemiFrame& frame)
void UsbTunnelInterface::sendCemiFrame(CemiFrame& frame)
{
addFrameTxQueue(frame);
return true;
sendKnxTunnelHidReport(frame.data(), frame.dataLength());
}
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_frame->data = new uint8_t[tx_frame->length];
tx_frame->next = nullptr;
tx_buffer->length = length;
tx_buffer->data = new uint8_t[tx_buffer->length];
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)
{
_tx_queue.front = _tx_queue.back = tx_frame;
_tx_queue.front = _tx_queue.back = tx_buffer;
}
else
{
_tx_queue.back->next = tx_frame;
_tx_queue.back = tx_frame;
_tx_queue.back->next = tx_buffer;
_tx_queue.back = tx_buffer;
}
}
@ -105,30 +101,78 @@ void UsbTunnelInterface::loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBuf
{
return;
}
_queue_buffer_t* tx_frame = _tx_queue.front;
*sendBuffer = tx_frame->data;
*sendBufferLength = tx_frame->length;
_tx_queue.front = tx_frame->next;
_queue_buffer_t* tx_buffer = _tx_queue.front;
*sendBuffer = tx_buffer->data;
*sendBufferLength = tx_buffer->length;
_tx_queue.front = tx_buffer->next;
if (_tx_queue.front == nullptr)
{
_tx_queue.back = nullptr;
}
delete tx_frame;
delete tx_buffer;
}
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)
buffer[1] = 0x13; // PacketInfo must be 0x13 (SeqNo: 1, Type: 3)
if (length > maxData)
{
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[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
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
memcpy(&buffer[11], data, length + HID_HEADER_SIZE + 8);
@ -150,7 +194,7 @@ void UsbTunnelInterface::sendKnxTunnelHidReport(uint8_t* data, uint16_t length)
Serial1.println("");
#endif
sendKnxHidReport(buffer, MAX_EP_SIZE);
addBufferTxQueue(buffer, (buffer[2] + HID_HEADER_SIZE));
}
/* USB RX */
@ -180,12 +224,6 @@ void UsbTunnelInterface::addBufferRxQueue(const uint8_t* data, uint16_t 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)
{
_rx_queue.front =_rx_queue.back = rx_buffer;
@ -377,7 +415,7 @@ void UsbTunnelInterface::handleBusAccessServerProtocol(const uint8_t* requestDat
}
Serial1.println("");
#endif
sendKnxHidReport(data, MAX_EP_SIZE);
addBufferTxQueue(data, packetLength + respDataSize);
}
}

View File

@ -15,7 +15,7 @@ class UsbTunnelInterface
void loop();
// from cEMI server
bool sendCemiFrame(CemiFrame& frame);
void sendCemiFrame(CemiFrame& frame);
static const uint8_t* getKnxHidReportDescriptor();
static uint16_t getHidReportDescriptorLength();
@ -44,7 +44,7 @@ class UsbTunnelInterface
// USB TX queue
_queue_t _tx_queue;
void addFrameTxQueue(CemiFrame& frame);
void addBufferTxQueue(uint8_t* data, uint16_t length);
bool isTxQueueEmpty();
void loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength);