abstract from knxd

This commit is contained in:
John
2022-09-03 11:22:59 +02:00
parent 1418396971
commit c3dc90914c
14 changed files with 407 additions and 81 deletions
+3 -4
View File
@@ -794,7 +794,6 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS
}
result_t NumberDataType::getFloatFromRawValue(unsigned int value, float* output) const {
int signedValue;
if (!hasFlag(REQ) && value == m_replacement) {
return RESULT_EMPTY;
}
@@ -814,9 +813,10 @@ result_t NumberDataType::getFloatFromRawValue(unsigned int value, float* output)
} else {
negative = false;
}
int signedValue;
if (m_bitCount == 32) {
if (hasFlag(EXP)) { // IEEE 754 binary32
float val = uintToFloat(value);
float val = uintToFloat(value, negative);
if (val != val) { // !isnan(val)
return RESULT_EMPTY;
}
@@ -830,7 +830,6 @@ result_t NumberDataType::getFloatFromRawValue(unsigned int value, float* output)
*output = static_cast<float>(val);
return RESULT_OK;
}
// less than 32 bit
if (!negative) {
if (m_divisor < 0) {
*output = static_cast<float>(value) * static_cast<float>(-m_divisor);
@@ -860,7 +859,6 @@ result_t NumberDataType::getFloatFromRawValue(unsigned int value, float* output)
result_t NumberDataType::readFromRawValue(unsigned int value,
OutputFormat outputFormat, ostream* output) const {
size_t length = (m_bitCount < 8) ? 1 : (m_bitCount/8);
int signedValue;
// initialize output
*output << setw(0) << std::resetiosflags(output->flags()) << dec << std::skipws << setprecision(6);
@@ -888,6 +886,7 @@ result_t NumberDataType::readFromRawValue(unsigned int value,
} else {
negative = false;
}
int signedValue;
if (m_bitCount == 32) {
if (hasFlag(EXP)) { // IEEE 754 binary32
float val = uintToFloat(value, negative);
+17
View File
@@ -0,0 +1,17 @@
add_definitions(-Wconversion -Wno-unused-parameter)
set(libknx_a_SOURCES
knx.h knx.cpp
)
set(libknx_a_LIBS
)
if(HAVE_KNXD)
set(libknx_a_SOURCES ${libknx_a_SOURCES} knxd.h)
set(libknx_a_LIBS ${libknx_a_LIBS} eibclient)
endif(HAVE_KNXD)
add_library(knx ${libknx_a_SOURCES})
target_link_libraries(knx ${libknx_a_LIBS})
+18
View File
@@ -0,0 +1,18 @@
AM_CXXFLAGS = -I$(top_srcdir)/src \
-isystem$(top_srcdir) \
-Wno-conversion
noinst_LIBRARIES = libknx.a
libknx_a_SOURCES = \
knx.h knx.cpp
if KNXD
libknx_a_SOURCES += knxd.h
libknx_a_LIBADD = -leibclient
else
libknx_a_SOURCES += knxnet.h
endif
distclean-local:
-rm -f Makefile.in
+37
View File
@@ -0,0 +1,37 @@
/*
* ebusd - daemon for communication with eBUS heating systems.
* Copyright (C) 2022 John Baier <ebusd@ebusd.eu>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "lib/knx/knx.h"
#ifdef HAVE_KNXD
#include "lib/knx/knxd.h"
#else
#include "lib/knx/knxnet.h"
#endif
KnxConnection* KnxConnection::create() {
#ifdef HAVE_KNXD
return new KnxdConnection();
#else
return new KnxNetConnection();
#endif
}
+123
View File
@@ -0,0 +1,123 @@
/*
* ebusd - daemon for communication with eBUS heating systems.
* Copyright (C) 2022 John Baier <ebusd@ebusd.eu>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIB_KNX_KNX_H_
#define LIB_KNX_KNX_H_
#include <cstdint>
// base KNX address type (group or individual)
typedef uint16_t knx_addr_t;
// the transfer types (lower 8 bits of transport control field with sequence=0, plus bit 8 with address type)
enum knx_transfer_t {
KNX_TRANSFER_NONE = -1, // no transfer available
KNX_TRANSFER_GROUP = 0x100, // data group or broadcast PDU
KNX_TRANSFER_TAG_GROUP = 0x104, // data tag group PDU
KNX_TRANSFER_INDIVIDUAL = 0x000, // data individual PDU
KNX_TRANSFER_CONNECTED = 0x040, // data connected PDU
KNX_TRANSFER_CONNECT = 0x080, // connect PDU
KNX_TRANSFER_DISCONNECT = 0x081, // disconnect PDU
KNX_TRANSFER_ACK = 0x0c2, // ACK PDU
KNX_TRANSFER_NAK = 0x0c3, // NAK PDU
};
/**
* An abstract KNX connection.
*/
class KnxConnection {
public:
/**
* Construct a new instance.
*/
KnxConnection() {}
/**
* Destructor.
*/
virtual ~KnxConnection() {}
/**
* Create a new KnxConnection.
* @param url the URL to connect to.
* @return the new KnxConnection, or @a nullptr on error.
*/
static KnxConnection* create();
/**
* Open a connection to the specified URL.
* @param url the URL to connect to.
* @return nullptr on success, or an error message.
*/
virtual const char* open(const char* url) = 0;
/**
* @return true if connected, false otherwise.
*/
virtual bool isConnected() const = 0;
/**
* Close the connection.
*/
virtual void close() = 0;
/**
* @return the file descriptor for polling.
*/
virtual int getPollFd() const = 0;
/**
* Get the available data (after the file descriptor was checked for availability).
* @param size the size of the data buffer.
* @param data the data buffer to copy the data to.
* @param len pointer to store the actual data length to.
* @param src optional pointer to store the source address (if any, depending on poll data type).
* @param dst optional pointer to store the destination address (if any, depending on poll data type).
* @return the polled transfer data type.
*/
virtual knx_transfer_t getPollData(int size, uint8_t* data, int* len, knx_addr_t* src, knx_addr_t* dst) = 0;
/**
* Send a group APDU.
* @param dst the destination address.
* @param len the APDU length.
* @param data the APDU data buffer.
* @return nullptr on success, or an error message.
*/
virtual const char* sendGroup(knx_addr_t dst, int len, const uint8_t* data) = 0;
/**
* @return true if connection allows programming via ETS.
*/
virtual bool isProgrammable() { return false; };
/**
* @return the individual address, or 0 if not programmed yet, or any non-zero value if not programmable.
*/
virtual knx_addr_t getAddress() { return 0xffff; };
/**
* @param address the individual address to set.
*/
virtual void setAddress(knx_addr_t address) {
// default implementation does nothing
}
};
#endif // LIB_KNX_KNX_H_
+102
View File
@@ -0,0 +1,102 @@
/*
* ebusd - daemon for communication with eBUS heating systems.
* Copyright (C) 2022 John Baier <ebusd@ebusd.eu>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIB_KNX_KNXD_H_
#define LIB_KNX_KNXD_H_
#include <eibclient.h>
#include "lib/knx/knx.h"
class KnxdConnection : public KnxConnection {
public:
/**
* Construct a new instance.
*/
KnxdConnection()
: KnxConnection(), m_con(nullptr) {}
/**
* Destructor.
*/
virtual ~KnxdConnection() {
close();
}
// @copydoc
const char* open(const char* url) override {
close();
m_con = EIBSocketURL(url);
if (!m_con) {
return "open error";
}
if (EIBOpen_GroupSocket(m_con, 0) < 0) {
EIBClose_sync(m_con);
m_con = nullptr;
return "open group error";
}
return nullptr;
}
// @copydoc
bool isConnected() const override {
return m_con != nullptr;
}
void close() override {
if (m_con) {
EIBClose_sync(m_con);
m_con = nullptr;
}
}
// @copydoc
int getPollFd() const override {
return EIB_Poll_FD(m_con);
}
// @copydoc
knx_transfer_t getPollData(int size, uint8_t* data, int* len, knx_addr_t* src, knx_addr_t* dst) override {
int ret = EIB_Poll_Complete(m_con);
if (ret == -1) {
// read failed
return KNX_TRANSFER_NONE;
}
ret = EIBGetGroup_Src(m_con, size, data, src, dst);
if (ret < 2) {
return KNX_TRANSFER_NONE;
}
if (len) {
*len = ret;
}
return KNX_TRANSFER_GROUP;
}
// @copydoc
const char* sendGroup(knx_addr_t dst, int len, const uint8_t* data) override {
if (EIBSendGroup(m_con, dst, len, data) < 0) {
return "send error";
}
return nullptr;
}
private:
/** the knx structure if connected, or nullptr. */
EIBConnection* m_con;
};
#endif // LIB_KNX_KNXD_H_