From c0c6c993158459b7c7840d465bd677be288a580a Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Fri, 7 Sep 2018 23:25:16 +0200 Subject: [PATCH] first working version --- apdu.cpp | 20 +++++------ bits.cpp | 11 ++++++ bits.h | 5 +-- cemi_frame.cpp | 3 +- data_link_layer.cpp | 22 ++++++------ tpuart_data_link_layer.cpp | 71 +++++++++++++++++++++----------------- tpuart_data_link_layer.h | 1 + 7 files changed, 78 insertions(+), 55 deletions(-) diff --git a/apdu.cpp b/apdu.cpp index 8083b6b..369b158 100644 --- a/apdu.cpp +++ b/apdu.cpp @@ -40,14 +40,14 @@ uint8_t APDU::length() const void APDU::printPDU() { - //Print.print("APDU: "); - //print.print(type(), HEX, 4); - //print.print(" "); - //print.print(_data[0] & 0x3, HEX, 2); - //for (uint8_t i = 1; i < length() + 1; ++i) - //{ - // if (i) print.print(" "); - // print.print(_data[i], HEX, 2); - //} - //print.println(); + _print("APDU: "); + _print(type(), HEX); + _print(" "); + _print(_data[0] & 0x3, HEX); + for (uint8_t i = 1; i < length() + 1; ++i) + { + if (i) _print(" "); + _print(_data[i], HEX); + } + _println(); } diff --git a/bits.cpp b/bits.cpp index 671d9f5..ab131e4 100644 --- a/bits.cpp +++ b/bits.cpp @@ -7,6 +7,17 @@ uint8_t* popByte(uint8_t& b, uint8_t* data) return data; } +void printHex(const char* suffix, const uint8_t *data, size_t length) +{ + _print(suffix); + for (int i = 0; i < length; i++) { + if (data[i] < 0x10) { _print("0"); } + _print(data[i], HEX); + _print(" "); + } + _println(); +} + uint8_t* popWord(uint16_t& w, uint8_t* data) { w = getWord(data); diff --git a/bits.h b/bits.h index 1e5688a..00b659e 100644 --- a/bits.h +++ b/bits.h @@ -9,7 +9,7 @@ #define bitRead(val, bitno) (((val) >> (bitno)) & 1) #elif ARDUINO_ARCH_SAMD #include -#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) +#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) ) #define ntohs(x) htons(x) #define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ ((x)<< 8 & 0x00FF0000UL) | \ @@ -35,4 +35,5 @@ uint8_t* pushWord(uint16_t w, uint8_t* data); uint8_t* pushInt(uint32_t i, uint8_t* data); uint8_t* pushByteArray(const uint8_t* src, uint32_t size, uint8_t* data); uint16_t getWord(uint8_t* data); -uint32_t getInt(uint8_t* data); \ No newline at end of file +uint32_t getInt(uint8_t* data); +void printHex(const char* suffix, const uint8_t *data, size_t length); \ No newline at end of file diff --git a/cemi_frame.cpp b/cemi_frame.cpp index 4bac662..005cd2e 100644 --- a/cemi_frame.cpp +++ b/cemi_frame.cpp @@ -71,13 +71,14 @@ uint16_t CemiFrame::telegramLengthtTP() const void CemiFrame::fillTelegramTP(uint8_t* data) { uint16_t len = telegramLengthtTP(); + if (frameType() == StandardFrame) { uint8_t octet5 = (_ctrl1[1] & 0xF0) | (_ctrl1[6] & 0x0F); data[0] = _ctrl1[0]; //CTRL memcpy(data + 1, _ctrl1 + 2, 4); // SA, DA data[5] = octet5; // LEN; Hopcount, .. - memcpy(data + 6, _ctrl1 + 8, len - 7); // APDU + memcpy(data + 6, _ctrl1 + 7, len - 7); // APDU } else { diff --git a/data_link_layer.cpp b/data_link_layer.cpp index 27e8d33..81b4cd6 100644 --- a/data_link_layer.cpp +++ b/data_link_layer.cpp @@ -34,7 +34,7 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame) Priority priority = frame.priority(); NPDU& npdu = frame.npdu(); uint16_t ownAddr = _deviceObject.induvidualAddress(); - + if (source == ownAddr) _deviceObject.induvidualAddressDuplication(true); @@ -48,11 +48,11 @@ void DataLinkLayer::frameRecieved(CemiFrame& frame) if (addrType == GroupAddress && !_groupAddressTable.contains(destination)) return; - //if (frame.npdu().octetCount() > 0) - //{ - // print.print("<- DLL "); - // frame.apdu().printPDU(); - //} +// if (frame.npdu().octetCount() > 0) +// { +// _print("-> DLL "); +// frame.apdu().printPDU(); +// } _networkLayer.dataIndication(ack, addrType, destination, type, npdu, priority, source); } @@ -80,11 +80,11 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA return false; } - //if (frame.npdu().octetCount() > 0) - //{ - // print.print("-> DLL "); - // frame.apdu().printPDU(); - //} +// if (frame.npdu().octetCount() > 0) +// { +// _print("<- DLL "); +// frame.apdu().printPDU(); +// } return sendFrame(frame); } diff --git a/tpuart_data_link_layer.cpp b/tpuart_data_link_layer.cpp index a6c9f17..6c881e0 100644 --- a/tpuart_data_link_layer.cpp +++ b/tpuart_data_link_layer.cpp @@ -33,7 +33,7 @@ //knx transmit data commands #define U_L_DATA_START_CONT_REQ 0x80 //-0xBF -#define U_L_DATA_END_REQ 0x47 //-0x7F +#define U_L_DATA_END_REQ 0x40 //-0x7F //serices to host controller @@ -99,8 +99,6 @@ void TpUartDataLinkLayer::stopChip() #endif } -void printHex(const char* suffix, const uint8_t *data, size_t length); - TpUartDataLinkLayer::TpUartDataLinkLayer(DeviceObject& devObj, AddressTableObject& addrTab, NetworkLayer& layer, Platform& platform) : DataLinkLayer(devObj, addrTab, layer, platform) @@ -184,7 +182,10 @@ bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) return false; int len = 0; - uint8_t buffer[bufferSize]; + uint8_t cemiBuffer[bufferSize + 2]; + cemiBuffer[0] = 0x29; + cemiBuffer[1] = 0; + uint8_t* buffer = cemiBuffer + 2; buffer[0] = firstByte; uint8_t payloadLength = 0; @@ -192,11 +193,9 @@ bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) { //convert to extended frame format _platform.readBytesUart(buffer + 2, 5); + sendAck((AddressType)(buffer[6] & GroupAddress), getWord(buffer + 4)); payloadLength = buffer[6] & 0xF; _platform.readBytesUart(buffer + 7, payloadLength + 2); //+1 for TCPI +1 for CRC - printHex("->", buffer, 1); - printHex("->", buffer + 2, 5); - printHex("->", buffer + 7, payloadLength + 3); buffer[1] = buffer[6] & 0xF0; buffer[6] = payloadLength; } @@ -204,29 +203,15 @@ bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) { //extended frame _platform.readBytesUart(buffer + 1, 6); + sendAck((AddressType)(buffer[1] & GroupAddress), getWord(buffer + 4)); payloadLength = buffer[6]; _platform.readBytesUart(buffer + 7, payloadLength + 2); //+1 for TCPI +1 for CRC } len = payloadLength + 9; - - printHex("=>", buffer, len); - CemiFrame frame(buffer, len); - - if (frame.addressType() == InduvidualAddress && _deviceObject.induvidualAddress() == frame.destinationAddress() - || frame.addressType() == GroupAddress && _groupAddressTable.contains(frame.destinationAddress())) - { - //send ack. - _platform.writeUart(U_ACK_REQ + 1); - } - else - { - // send not addressed - _platform.writeUart(U_ACK_REQ); - } const uint8_t queueLength = 5; - static uint8_t buffers[queueLength][bufferSize]; + static uint8_t buffers[queueLength][bufferSize + 2]; static uint16_t bufferLengths[queueLength]; if (_sendBuffer != 0) @@ -253,7 +238,7 @@ bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) continue; bufferLengths[i] = len; - memcpy(&buffers[i][0], buffer, len); + memcpy(&buffers[i][0], cemiBuffer, len + 2); break; } } @@ -265,11 +250,11 @@ bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) if (bufferLengths[i] == 0) break; - frameBytesReceived(&buffers[i][0], bufferLengths[i]); + frameBytesReceived(&buffers[i][0], bufferLengths[i]+2); bufferLengths[i] = 0; } - frameBytesReceived(buffer, len); + frameBytesReceived(cemiBuffer, len+2); } return true; @@ -277,6 +262,7 @@ bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) { + //printHex("=>", buffer, length); CemiFrame frame(buffer, length); frameRecieved(frame); @@ -416,7 +402,8 @@ void TpUartDataLinkLayer::enabled(bool value) if (value && !_enabled) { _platform.setupUart(); - + _print("ownaddr "); + _println(_deviceObject.induvidualAddress(), HEX); resetChip(); _enabled = true; return; @@ -439,21 +426,43 @@ bool TpUartDataLinkLayer::enabled() const void TpUartDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length) { + //printHex("<=", bytes, length); uint8_t cmd[2]; + uint8_t oldIdx = 0; + for (int i = 0; i < length; i++) { uint8_t idx = length / 64; - cmd[0] = U_L_DATA_OFFSET_REQ | idx; - _platform.writeUart(cmd, 1); + if (idx != oldIdx) + { + oldIdx = idx; + cmd[0] = U_L_DATA_OFFSET_REQ | idx; + _platform.writeUart(cmd, 1); + } if (i != length - 1) cmd[0] = U_L_DATA_START_CONT_REQ | i; else - cmd[0] = U_L_DATA_END_REQ; + cmd[0] = U_L_DATA_END_REQ | i; cmd[1] = bytes[i]; _platform.writeUart(cmd, 2); } -} \ No newline at end of file +} + +void TpUartDataLinkLayer::sendAck(AddressType type, uint16_t address) +{ + if ( (type == InduvidualAddress && _deviceObject.induvidualAddress() == address) + || (type == GroupAddress && (_groupAddressTable.contains(address) || address == 0))) + { + //send ack. + _platform.writeUart(U_ACK_REQ + 1); + } + else + { + // send not addressed + _platform.writeUart(U_ACK_REQ); + } +} diff --git a/tpuart_data_link_layer.h b/tpuart_data_link_layer.h index 97e85bc..8ea40f1 100644 --- a/tpuart_data_link_layer.h +++ b/tpuart_data_link_layer.h @@ -37,4 +37,5 @@ private: void frameBytesReceived(uint8_t* buffer, uint16_t length); void resetChip(); void stopChip(); + void sendAck(AddressType type, uint16_t address); }; \ No newline at end of file