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 <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);
} }
} }

View File

@ -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);