From 7907533bac5bdd0d2b87868b47766c0355481ab5 Mon Sep 17 00:00:00 2001 From: Roland Jax Date: Sat, 15 Mar 2014 20:02:53 +0100 Subject: [PATCH] factor added for uin, sin, ulg, slg, flt --- lib/ebus-cmd.c | 22 ++++- src/cycdata.hpp | 43 ++++++++++ src/network.cpp | 208 ++++++++++++++++++++++++++++++++++++++++++++++++ src/network.hpp | 77 ++++++++++++++++++ 4 files changed, 346 insertions(+), 4 deletions(-) create mode 100644 src/cycdata.hpp create mode 100644 src/network.cpp create mode 100644 src/network.hpp diff --git a/lib/ebus-cmd.c b/lib/ebus-cmd.c index 44bf0177..90bc6f16 100644 --- a/lib/ebus-cmd.c +++ b/lib/ebus-cmd.c @@ -389,8 +389,11 @@ eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf) } else if (strncasecmp(com[id].elem[elem].d_type, "uin", 3) == 0) { if (p1 > 0 && p2 > 0) { unsigned int uin; + float ff; uin = msg[p1] + (msg[p2] << 8); - sprintf(buf, "%u", uin); + + ff = uin * com[id].elem[elem].d_fac; + sprintf(buf, "%f", ff); } else { goto on_error; } @@ -398,8 +401,11 @@ eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf) } else if (strncasecmp(com[id].elem[elem].d_type, "sin", 3) == 0) { if (p1 > 0 && p2 > 0) { int sin; + float ff; sin = msg[p1] + (msg[p2] << 8); - sprintf(buf, "%d", sin); + + ff = sin * com[id].elem[elem].d_fac; + sprintf(buf, "%f", ff); } else { goto on_error; } @@ -407,8 +413,11 @@ eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf) } else if (strncasecmp(com[id].elem[elem].d_type, "ulg", 3) == 0) { if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) { unsigned long ulg; + float ff; ulg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24); - sprintf(buf, "%lu", ulg); + + ff = ulg * com[id].elem[elem].d_fac; + sprintf(buf, "%f", ff); } else { goto on_error; } @@ -416,8 +425,11 @@ eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf) } else if (strncasecmp(com[id].elem[elem].d_type, "slg", 3) == 0) { if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) { long slg; + float ff; slg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24); - sprintf(buf, "%ld", slg); + + ff = slg * com[id].elem[elem].d_fac; + sprintf(buf, "%f", ff); } else { goto on_error; } @@ -426,6 +438,8 @@ eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf) if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) { float ff; ff = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24); + + ff *= com[id].elem[elem].d_fac; sprintf(buf, "%f", ff); } else { goto on_error; diff --git a/src/cycdata.hpp b/src/cycdata.hpp new file mode 100644 index 00000000..8aff3782 --- /dev/null +++ b/src/cycdata.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) Roland Jax 2014 + * + * This file is part of ebusd. + * + * ebusd 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. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef CYCDATA_HPP__ +#define CYCDATA_HPP__ + +#include "ebusloop.hpp" +#include "thread.hpp" +#include + +class CYCData : public Thread +{ + +public: + CYCData(EBusLoop* ebusloop) : m_ebusloop(ebusloop), m_stop(false) {} + //~ ~CYCData(); + + void* run(); + void stop() { m_stop = true; } + +private: + EBusLoop* m_ebusloop; + bool m_stop; + +}; + +#endif // CYCDATA_HPP__ diff --git a/src/network.cpp b/src/network.cpp new file mode 100644 index 00000000..4465d33e --- /dev/null +++ b/src/network.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (C) Roland Jax 2014 + * + * This file is part of ebusd. + * + * ebusd 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. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "network.hpp" +#include "logger.hpp" +#include +#include +#include + +extern LogDivider& L; + +void Connection::addResult(Message message) +{ + Message* tmp = new Message(Message(message)); + m_result.add(tmp); +} + +void* Connection::run() +{ + m_running = true; + + int maxfd; + fd_set checkfds; + struct timeval timeout; + + FD_ZERO(&checkfds); + FD_SET(m_notify.notifyFD(), &checkfds); + FD_SET(m_socket->getFD(), &checkfds); + + (m_notify.notifyFD() > m_socket->getFD()) ? + (maxfd = m_notify.notifyFD()) : (maxfd = m_socket->getFD()); + + for (;;) { + fd_set readfds; + int ret; + + // set select timeout 10 secs + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + // set readfds to inital checkfds + readfds = checkfds; + + ret = select(maxfd + 1, &readfds, NULL, NULL, &timeout); + if (ret == 0) { + continue; + } + + // new data from notify + if (FD_ISSET(m_notify.notifyFD(), &readfds)) { + delete m_socket; + break; + } + + // new data from socket + if (FD_ISSET(m_socket->getFD(), &readfds)) { + char data[256]; + size_t datalen; + + datalen = m_socket->recv(data, sizeof(data)-1); + + // removed closed socket + if (datalen <= 0) { + delete m_socket; + m_running = false; + break; + } + + // send data + if (datalen < sizeof(data)) { + data[datalen] = '\0'; + m_data->add(new Message(data, this)); + } + + // wait for result + Message* message = m_result.remove(); + + std::string result(message->getData()); + m_socket->send(result.c_str(), result.size()); + + delete message; + + } + + } + + return NULL; +} + + + +Network::Network(int port, std::string ip) : m_listening(false), m_running(false) +{ + // Start Listener + m_Listener = new TCPListener(port, ip.c_str()); + if (m_Listener && m_Listener->start() == 0) + m_listening = true; + +} + +Network::~Network() +{ + while (m_connections.empty() == false) { + Connection* connection = m_connections.back(); + m_connections.pop_back(); + connection->stop(); + connection->join(); + delete connection; + } + + if (m_running == true) + stop(); + + delete m_Listener; +} + +void* Network::run() +{ + if (m_listening == false) + return NULL; + + m_running = true; + + int maxfd; + fd_set checkfds; + struct timeval timeout; + + FD_ZERO(&checkfds); + FD_SET(m_notify.notifyFD(), &checkfds); + FD_SET(m_Listener->getFD(), &checkfds); + + (m_notify.notifyFD() > m_Listener->getFD()) ? + (maxfd = m_notify.notifyFD()) : (maxfd = m_Listener->getFD()); + + for (;;) { + fd_set readfds; + int ret; + + // set select timeout 1 secs + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + // set readfds to inital checkfds + readfds = checkfds; + + ret = select(maxfd + 1, &readfds, NULL, NULL, &timeout); + if (ret == 0) { + cleanConnections(); + continue; + } + + // new data from notify + if (FD_ISSET(m_notify.notifyFD(), &readfds)) { + m_running = false; + break; + } + + // new data from socket + if (FD_ISSET(m_Listener->getFD(), &readfds)) { + TCPSocket* socket = m_Listener->newSocket(); + if (socket == NULL) + continue; + + Connection* connection = new Connection(socket, m_queue); + if (connection == NULL) + continue; + + std::ostringstream name; + name << "netConnection"; + connection->start(name.str().c_str()); + m_connections.push_back(connection); + + } + + } + + return NULL; +} + +void Network::cleanConnections() +{ + std::list::iterator c_it; + for (c_it = m_connections.begin(); c_it != m_connections.end(); c_it++) { + if ((*c_it)->isRunning() == false) { + Connection* connection = *c_it; + c_it = m_connections.erase(c_it); + delete connection; + L.log(Conn, Debug, "dead connection removed - %d", m_connections.size()); + } + } +} + diff --git a/src/network.hpp b/src/network.hpp new file mode 100644 index 00000000..8cfbd522 --- /dev/null +++ b/src/network.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) Roland Jax 2014 + * + * This file is part of ebusd. + * + * ebusd 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. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef NETWORK_HPP__ +#define NETWORK_HPP__ + +#include "tcpsocket.hpp" +#include "wqueue.hpp" +#include "thread.hpp" +#include "notify.hpp" +#include "baseloop.hpp" +#include +#include + +class Connection : public Thread +{ + +public: + Connection(TCPSocket* socket, WQueue* data) + : m_socket(socket), m_data(data), m_running(false) {} + + void addResult(Message message); + + void* run(); + void stop() const { m_notify.notify(); } + bool isRunning() const { return m_running; } + +private: + TCPSocket* m_socket; + WQueue* m_data; + WQueue m_result; + Notify m_notify; + bool m_running; + +}; + +class Network : public Thread +{ + +public: + Network(int port, std::string ip); + ~Network(); + + void addQueue(WQueue* queue) { m_queue = queue; } + + void* run(); + void stop() const { m_notify.notify(); usleep(100000); } + +private: + std::list m_connections; + WQueue* m_queue; + TCPListener* m_Listener; + Notify m_notify; + bool m_listening; + bool m_running; + + void cleanConnections(); + +}; + +#endif // NETWORK_HPP__