From 7a30d482a532c69af630a9be7eabd708b97749fb Mon Sep 17 00:00:00 2001 From: Thomas Kunze Date: Tue, 20 Mar 2018 22:04:11 +0100 Subject: [PATCH] first working version --- address_table_object.cpp | 13 ++-- apdu.cpp | 2 + application_program_object.cpp | 5 +- association_table_object.cpp | 11 +-- bits.cpp | 6 +- bits.h | 124 +++------------------------------ device_object.cpp | 25 +++++-- esp_platform.cpp | 8 +-- group_object.cpp | 18 ++--- group_object_table_object.cpp | 8 +-- ip_parameter_object.cpp | 24 ++++--- network_layer.cpp | 1 + table_object.cpp | 10 +-- 13 files changed, 79 insertions(+), 176 deletions(-) diff --git a/address_table_object.cpp b/address_table_object.cpp index e1bf3d0..50b3dd5 100644 --- a/address_table_object.cpp +++ b/address_table_object.cpp @@ -28,7 +28,7 @@ uint16_t AddressTableObject::entryCount() if (loadState() != LS_LOADED) return 0; - return _groupAddresses[0]; + return ntohs(_groupAddresses[0]); } uint16_t AddressTableObject::getGa(uint16_t tsap) @@ -36,14 +36,14 @@ uint16_t AddressTableObject::getGa(uint16_t tsap) if (loadState() != LS_LOADED || tsap > entryCount() ) return 0; - return _groupAddresses[tsap]; + return ntohs(_groupAddresses[tsap]); } uint16_t AddressTableObject::getTsap(uint16_t addr) { uint16_t size = entryCount(); for (uint16_t i = 1; i <= size; i++) - if (_groupAddresses[i] == addr) + if (ntohs(_groupAddresses[i]) == addr) return i; return 1; } @@ -70,7 +70,7 @@ bool AddressTableObject::contains(uint16_t addr) { uint16_t size = entryCount(); for (uint16_t i = 1; i <= size; i++) - if (_groupAddresses[i] == addr) + if (ntohs(_groupAddresses[i]) == addr) return true; return false; @@ -82,9 +82,4 @@ void AddressTableObject::beforeStateChange(LoadState& newState) return; _groupAddresses = (uint16_t*)_data; - - uint16_t count = reverseByteOrder(_groupAddresses[0]); - // big endian -> little endian - for (size_t i = 0; i <= count; i++) - _groupAddresses[i] = reverseByteOrder(_groupAddresses[i]); } diff --git a/apdu.cpp b/apdu.cpp index 26b86bd..b65daf5 100644 --- a/apdu.cpp +++ b/apdu.cpp @@ -9,6 +9,7 @@ APDU::APDU(uint8_t* data, CemiFrame& frame): _data(data), _frame(frame) ApduType APDU::type() { uint16_t apci; + apci = getWord(_data); popWord(apci, _data); apci &= 0x3ff; if ((apci >> 6) < 11) //short apci @@ -18,6 +19,7 @@ ApduType APDU::type() void APDU::type(ApduType atype) { + // ApduType is in big endian so convert to host first, pushWord converts back pushWord((uint16_t)atype, _data); } diff --git a/application_program_object.cpp b/application_program_object.cpp index 4db44ce..1c62b24 100644 --- a/application_program_object.cpp +++ b/application_program_object.cpp @@ -43,7 +43,10 @@ uint8_t ApplicationProgramObject::propertySize(PropertyID id) { switch (id) { - case PID_PROG_VERSION: + case PID_OBJECT_TYPE: + case PID_PEI_TYPE: + return 1; + case PID_PROG_VERSION: return 5; } return TableObject::propertySize(id); diff --git a/association_table_object.cpp b/association_table_object.cpp index c7e21df..89eec6f 100644 --- a/association_table_object.cpp +++ b/association_table_object.cpp @@ -25,7 +25,7 @@ void AssociationTableObject::readProperty(PropertyID id, uint32_t start, uint32_ uint16_t AssociationTableObject::entryCount() { - return _tableData[0]; + return ntohs(_tableData[0]); } uint16_t AssociationTableObject::operator[](uint16_t idx) @@ -33,7 +33,7 @@ uint16_t AssociationTableObject::operator[](uint16_t idx) if (idx < 0 || idx >= entryCount()) return 0; - return _tableData[idx + 1]; + return ntohs(_tableData[idx + 1]); } uint8_t* AssociationTableObject::save(uint8_t* buffer) @@ -53,7 +53,7 @@ int32_t AssociationTableObject::translateAsap(uint16_t asap) uint16_t entries = entryCount(); for (uint16_t i = 0; i < entries; i++) { - uint16_t entry = operator[](i); + uint16_t entry = ntohs(operator[](i)); if (lowByte(entry) == asap) return highByte(entry); } @@ -66,9 +66,4 @@ void AssociationTableObject::beforeStateChange(LoadState& newState) return; _tableData = (uint16_t*)_data; - - uint16_t count = reverseByteOrder(_tableData[0]); - // big endian -> little endian - for (size_t i = 0; i <= count; i++) - _tableData[i] = reverseByteOrder(_tableData[i]); } \ No newline at end of file diff --git a/bits.cpp b/bits.cpp index 3941ab5..380e5f9 100644 --- a/bits.cpp +++ b/bits.cpp @@ -50,7 +50,7 @@ uint8_t* pushInt(uint32_t i, uint8_t* data) data[0] = ((i >> 24) & 0xff); data[1] = ((i >> 16) & 0xff); data[2] = ((i >> 8) & 0xff); - data[3] = (i & 0xff); + data[3] = (i & 0xff); data += 4; return data; } @@ -66,10 +66,10 @@ uint8_t* pushByteArray(const uint8_t* src, uint32_t size, uint8_t* data) uint16_t getWord(uint8_t* data) { - return (data[0] << 8) + data[1];; + return (data[0] << 8) + data[1]; } uint32_t getInt(uint8_t * data) { - return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];; + return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]; } diff --git a/bits.h b/bits.h index 73583e1..9f8019c 100644 --- a/bits.h +++ b/bits.h @@ -1,125 +1,19 @@ -/* - * bits.h - Bit and uint8_t manipulation functions. - * - * Copyright (c) 2014 Stefan Taferner - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. - */ #pragma once + #include -/** - * Compute the value of the specified bit. - * - * @param bitno - the number of the bit (0, 1, 2... 31) - */ -#define bit(bitno) (1UL << (bitno)) -/** - * Clear the bit of a number. The number can be - * any integer (uint8_t, short, uint32_t, long). - * - * @param val - the number from which to clear the bit - * @param bitno - the number of the bit (0, 1, 2... 31) - */ -#define bitClear(val, bitno) ((val) &= ~(1UL << (bitno))) - -/** - * Set the bit of a number. The number can be - * any integer (uint8_t, short, uint32_t, long). - * - * @param val - the number from which to set the bit - * @param bitno - the number of the bit (0, 1, 2... 31) - */ -#define bitSet(val, bitno) ((val) |= 1UL << (bitno)) - -/** - * Write the value of a bit of a number. - * - * @param val - the number from which to write the bit - * @param bitno - the number of the bit (0, 1, 2... 31) - * @param b - the bit value (0 or 1) - */ -#define bitWrite(val, bitno, b) ((b) ? bitSet(val, bitno) : bitClear(val, bitno)) - -/** - * Read the value of a bit of a number. The number can be - * any integer (uint8_t, short, uint32_t, long). - * - * @param val - the number from which to get the bit - * @param bitno - the number of the bit (0, 1, 2... 31) - * @return The value of the bit (0 or 1). - */ -#define bitRead(val, bitno) (((val) >> (bitno)) & 1) - -/** - * Extract the lowest (rightmost) uint8_t of a number. The number can be - * any integer (uint8_t, short, uint32_t, long). - * - * @param val - the value to extract the lowest uint8_t. - * @return The extracted uint8_t (0..255) - */ +#ifdef __linux__ +#include #define lowByte(val) ((val) & 255) - -/** - * Extract the highest (leftmost) uint8_t of a number. The number can be - * any integer (uint8_t, short, uint32_t, long). - * - * @param val - the value to extract the highest uint8_t. - * @return The extracted uint8_t (0..255) - */ #define highByte(val) (((val) >> ((sizeof(val) - 1) << 3)) & 255) - -/** - * Combine two bytes to a 16 bit uint16_t. - * - * @param high - the high uint8_t. - * @param low - the low uint8_t. - * @return The bytes combined as uint16_t. - */ -uint16_t makeWord(uint8_t high, uint8_t low); - -/** - * Reverse the uint8_t order of an integer. - * - * @param val - the value to reverse. - * @return The value with reversed uint8_t order. - */ - uint32_t reverseByteOrder(uint32_t val); - -/** - * Reverse the uint8_t order of a short integer. - * - * @param val - the value to reverse. - * @return The value with reversed uint8_t order. - */ - uint16_t reverseByteOrder(uint16_t val); +#define bitRead(val, bitno) (((val) >> (bitno)) & 1) +#else +#include +#include +#define printf Serial.printf +#endif -// -// Inline functions -// - -inline uint16_t makeWord(uint8_t high, uint8_t low) -{ - return (high << 8) | low; -} - -inline uint32_t reverseByteOrder(uint32_t val) -{ - uint32_t swapped = ((val >> 24) & 0xff) | // move uint8_t 3 to uint8_t 0 - ((val << 8) & 0xff0000) | // move uint8_t 1 to uint8_t 2 - ((val >> 8) & 0xff00) | // move uint8_t 2 to uint8_t 1 - ((val << 24) & 0xff000000); // uint8_t 0 to uint8_t 3 - return swapped;//__REV(val); -} - -inline uint16_t reverseByteOrder(uint16_t val) -{ - uint16_t swapped = (val >> 8) | (val << 8); - return swapped; -} uint8_t* popByte(uint8_t& b, uint8_t* data); uint8_t* popWord(uint16_t& w, uint8_t* data); diff --git a/device_object.cpp b/device_object.cpp index 5e6286b..3acb3bc 100644 --- a/device_object.cpp +++ b/device_object.cpp @@ -81,12 +81,25 @@ uint8_t DeviceObject::propertySize(PropertyID id) { switch (id) { - case PID_DEVICE_CONTROL: - return 1; - case PID_ROUTING_COUNT: - return 1; - case PID_PROG_MODE: - return 1; + case PID_OBJECT_TYPE: + case PID_DEVICE_CONTROL: + case PID_ROUTING_COUNT: + case PID_PROG_MODE: + case PID_MAX_APDU_LENGTH: + case PID_SUBNET_ADDR: + case PID_DEVICE_ADDR: + return 1; + case PID_MANUFACTURER_ID: + case PID_VERSION: + case PID_DEVICE_DESCRIPTOR: + return 2; + case PID_IO_LIST: + return 4; + case PID_SERIAL_NUMBER: + case PID_HARDWARE_TYPE: + return 6; + case PID_ORDER_INFO: + return 10; } return 0; } diff --git a/esp_platform.cpp b/esp_platform.cpp index 54417f3..4fc866f 100644 --- a/esp_platform.cpp +++ b/esp_platform.cpp @@ -57,9 +57,9 @@ void EspPlatform::fatalError() void EspPlatform::setupMultiCast(uint32_t addr, uint16_t port) { - _mulitcastAddr = addr; + _mulitcastAddr = htonl(addr); _mulitcastPort = port; - IPAddress mcastaddr(htonl(addr)); + IPAddress mcastaddr(_mulitcastAddr); Serial.printf("setup multicast addr: %s port: %d ip: %s\n", mcastaddr.toString().c_str(), port, WiFi.localIP().toString().c_str()); @@ -85,7 +85,7 @@ void printHex(const char* suffix, uint8_t *data, uint8_t length) bool EspPlatform::sendBytes(uint8_t * buffer, uint16_t len) { - printHex("-> ",buffer, len); + printHex("<- ",buffer, len); int result = 0; result = _udp.beginPacketMulticast(_mulitcastAddr, _mulitcastPort, WiFi.localIP()); result = _udp.write(buffer, len); @@ -106,7 +106,7 @@ int EspPlatform::readBytes(uint8_t * buffer, uint16_t maxLen) } _udp.read(buffer, len); - printHex("<- ", buffer, len); + printHex("-> ", buffer, len); return len; } diff --git a/group_object.cpp b/group_object.cpp index 4381b0c..d0e0307 100644 --- a/group_object.cpp +++ b/group_object.cpp @@ -23,7 +23,7 @@ bool GroupObject::responseUpdateEnable() if (!_table) return false; - return bitRead(_table->_tableData[_asap], 15) > 0; + return bitRead(ntohs(_table->_tableData[_asap]), 15) > 0; } bool GroupObject::transmitEnable() @@ -31,7 +31,7 @@ bool GroupObject::transmitEnable() if (!_table) return false; - return bitRead(_table->_tableData[_asap], 14) > 0; + return bitRead(ntohs(_table->_tableData[_asap]), 14) > 0 ; } bool GroupObject::valueReadOnInit() @@ -39,7 +39,7 @@ bool GroupObject::valueReadOnInit() if (!_table) return false; - return bitRead(_table->_tableData[_asap], 13) > 0; + return bitRead(ntohs(_table->_tableData[_asap]), 13) > 0; } bool GroupObject::writeEnable() @@ -47,7 +47,7 @@ bool GroupObject::writeEnable() if (!_table) return false; - return bitRead(_table->_tableData[_asap], 12) > 0; + return bitRead(ntohs(_table->_tableData[_asap]), 12) > 0 ; } bool GroupObject::readEnable() @@ -55,7 +55,7 @@ bool GroupObject::readEnable() if (!_table) return false; - return bitRead(_table->_tableData[_asap], 11) > 0; + return bitRead(ntohs(_table->_tableData[_asap]), 11) > 0; } bool GroupObject::communicationEnable() @@ -63,7 +63,7 @@ bool GroupObject::communicationEnable() if (!_table) return false; - return bitRead(_table->_tableData[_asap], 10) > 0; + return bitRead(ntohs(_table->_tableData[_asap]), 10) > 0; } @@ -72,7 +72,7 @@ Priority GroupObject::priority() if (!_table) return LowPriority; - return (Priority)((_table->_tableData[_asap] >> 6) & (3 << 2)) ; + return (Priority)((ntohs(_table->_tableData[_asap]) >> 6) & (3 << 2)) ; } uint8_t* GroupObject::valueRef() @@ -144,7 +144,7 @@ void GroupObject::commFlag(ComFlag value) int32_t GroupObject::objectReadFloat() { - uint16_t dptValue = makeWord(_data[0], _data[1]); + uint16_t dptValue = getWord(_data); return dptFromFloat(dptValue); } @@ -186,6 +186,6 @@ size_t GroupObject::valueSize() size_t GroupObject::sizeInTelegram() { - uint8_t code = lowByte(_table->_tableData[_asap]); + uint8_t code = lowByte(ntohs(_table->_tableData[_asap])); return asapValueSize(code); } diff --git a/group_object_table_object.cpp b/group_object_table_object.cpp index d9cc83c..7f3c71e 100644 --- a/group_object_table_object.cpp +++ b/group_object_table_object.cpp @@ -27,7 +27,7 @@ uint16_t GroupObjectTableObject::entryCount() if (loadState() != LS_LOADED) return 0; - return _tableData[0]; + return ntohs(_tableData[0]); } @@ -91,10 +91,6 @@ void GroupObjectTableObject::beforeStateChange(LoadState& newState) return; _tableData = (uint16_t*)_data; - uint16_t goCount = reverseByteOrder(_tableData[0]); - // big endian -> little endian - for (size_t i = 0; i <= goCount; i++) - _tableData[i] = reverseByteOrder(_tableData[i]); if (!initGroupObjects()) { @@ -108,7 +104,7 @@ bool GroupObjectTableObject::initGroupObjects() if (!_tableData) return false; - uint16_t goCount = _tableData[0]; + uint16_t goCount = ntohs(_tableData[0]); if (goCount != _groupObjectCount) return false; diff --git a/ip_parameter_object.cpp b/ip_parameter_object.cpp index d7d13e2..52a7c5d 100644 --- a/ip_parameter_object.cpp +++ b/ip_parameter_object.cpp @@ -118,24 +118,28 @@ uint8_t IpParameterObject::propertySize(PropertyID id) { switch (id) { + case PID_IP_ASSIGNMENT_METHOD: + case PID_LOAD_STATE_CONTROL: + case PID_IP_CAPABILITIES: + case PID_TTL: + case PID_KNXNETIP_DEVICE_CAPABILITIES: + case PID_FRIENDLY_NAME: + return 1; + case PID_OBJECT_TYPE: case PID_PROJECT_INSTALLATION_ID: - return 2; case PID_KNX_INDIVIDUAL_ADDRESS: return 2; - case PID_IP_ASSIGNMENT_METHOD: - return 1; + case PID_CURRENT_IP_ADDRESS: + case PID_CURRENT_SUBNET_MASK: + case PID_CURRENT_DEFAULT_GATEWAY: case PID_IP_ADDRESS: - return 4; case PID_SUBNET_MASK: - return 4; case PID_DEFAULT_GATEWAY: - return 4; + case PID_SYSTEM_SETUP_MULTICAST_ADDRESS: case PID_ROUTING_MULTICAST_ADDRESS: return 4; - case PID_TTL: - return 1; - case PID_FRIENDLY_NAME: - return 1; + case PID_MAC_ADDRESS: + return 6; } return 0; } diff --git a/network_layer.cpp b/network_layer.cpp index 83bba34..be4b09c 100644 --- a/network_layer.cpp +++ b/network_layer.cpp @@ -2,6 +2,7 @@ #include "tpdu.h" #include "cemi_frame.h" #include "data_link_layer.h" +#include "bits.h" NetworkLayer::NetworkLayer(TransportLayer& layer): _transportLayer(layer) { diff --git a/table_object.cpp b/table_object.cpp index e5ed445..57fbb3f 100644 --- a/table_object.cpp +++ b/table_object.cpp @@ -47,11 +47,11 @@ uint8_t TableObject::propertySize(PropertyID id) switch (id) { case PID_LOAD_STATE_CONTROL: - return 10; - - //case PID_MCB_TABLE: - // TODO - // break; + return 1; + case PID_TABLE_REFERENCE: + return 4; + case PID_ERROR_CODE: + return 1; } return 0; }