From 452350fcd94e734052ff576470db37774672a802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Fri, 28 Sep 2018 07:22:36 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/pip@635 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5 --- src_io_utils/pibroadcast.cpp | 244 ++++++++++++++++++ src_io_utils/pimulticast.cpp | 181 ------------- .../io_utils/{pimulticast.h => pibroadcast.h} | 46 ++-- 3 files changed, 273 insertions(+), 198 deletions(-) create mode 100644 src_io_utils/pibroadcast.cpp delete mode 100644 src_io_utils/pimulticast.cpp rename src_main/io_utils/{pimulticast.h => pibroadcast.h} (64%) diff --git a/src_io_utils/pibroadcast.cpp b/src_io_utils/pibroadcast.cpp new file mode 100644 index 00000000..a9dfbffc --- /dev/null +++ b/src_io_utils/pibroadcast.cpp @@ -0,0 +1,244 @@ +/* + PIP - Platform Independent Primitives + Broadcast for all interfaces, including loopback + Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + + 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 . +*/ + +#include "pibroadcast.h" + +#define MULTICAST_TTL 4 + + +PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() { + _channels = All; + eth_lo = 0; + mcast_address.set("232.13.3.14", 14100); + lo_port = 14200; + lo_pcnt = 5; + _started = false; + _send_only = send_only; + _reinit = true; + //initMcast(PIEthernet::allAddresses()); + PIThread::start(3000); +} + + +PIBroadcast::~PIBroadcast() { + PIThread::stop(); + mcast_mutex.unlock(); + destroyAll(); +} + + +void PIBroadcast::setChannels(PIBroadcast::Channels ch) { + PIMutexLocker ml(mcast_mutex); + _channels = ch; + _reinit = true; +} + + +void PIBroadcast::setMulticastGroup(const PIString & mg) { + PIMutexLocker ml(mcast_mutex); + mcast_address.setIP(mg); + _reinit = true; +} + + +void PIBroadcast::setMulticastPort(ushort port) { + PIMutexLocker ml(mcast_mutex); + mcast_address.setPort(port); + _reinit = true; +} + + +void PIBroadcast::setMulticastAddress(const PIEthernet::Address & addr) { + PIMutexLocker ml(mcast_mutex); + mcast_address = addr; + _reinit = true; +} + + +void PIBroadcast::setBroadcastPort(ushort port) { + PIMutexLocker ml(mcast_mutex); + bcast_port = port; + _reinit = true; +} + + +void PIBroadcast::setLoopbackPort(ushort port) { + PIMutexLocker ml(mcast_mutex); + lo_port = port; + _reinit = true; +} + + +void PIBroadcast::setLoopbackPortsCount(int count) { + PIMutexLocker ml(mcast_mutex); + lo_pcnt = count; + _reinit = true; +} + + +void PIBroadcast::destroyAll() { + piForeach (PIEthernet * e, eth_mcast) { + e->stopThreadedRead(); + delete e; + } + eth_mcast.clear(); + if (eth_lo) { + eth_lo->stopThreadedRead(); + delete eth_lo; + eth_lo = 0; + } +} + + +void PIBroadcast::initAll(PIVector al) { + PIMutexLocker ml(mcast_mutex); + destroyAll(); + _reinit = false; + prev_al = al; + al.removeAll(PIEthernet::Address("127.0.0.1")); + al << mcast_address; + eth_mcast.clear(); + PIEthernet::InterfaceList ifaces = PIEthernet::interfaces(); + piForeachC (PIEthernet::Address & a, al) { + PIEthernet * ce = 0; + //piCout << "mcast try" << a; + + if (_channels[Multicast]) { + ce = new PIEthernet(); + ce->setDebug(false); + ce->setName("PIMulticast_" + a.toString()); + ce->setParameters(0); + ce->setSendAddress(mcast_address); + ce->setMulticastTTL(MULTICAST_TTL); + if (!_send_only) { + ce->setReadAddress(a.ipString(), mcast_address.port()); + ce->joinMulticastGroup(mcast_address.ipString()); + //piCout << "mcast " << ce->readAddress() << ce->sendAddress(); + if (ce->open()) { + eth_mcast << ce; + CONNECTU(ce, threadedReadEvent, this, mcastRead); + } else { + delete ce; + } + } else { + eth_mcast << ce; + } + } + + if (_channels[Broadcast]) { + ce = new PIEthernet(); + ce->setDebug(false); + ce->setName("PIMulticast_" + a.toString()); + ce->setParameters(PIEthernet::Broadcast); + const PIEthernet::Interface * cint = ifaces.getByAddress(a.ipString()); + PIEthernet::Address nm((cint == 0) ? "255.255.255.0" : cint->netmask); + ce->setSendAddress(PIEthernet::getBroadcast(a, nm).ipString(), bcast_port); + if (!_send_only) { + ce->setReadAddress(PIEthernet::Address(a.ip(), bcast_port)); + //piCout << "bcast " << ce->readAddress() << ce->sendAddress(); + if (ce->open()) { + eth_mcast << ce; + CONNECTU(ce, threadedReadEvent, this, mcastRead); + } else { + delete ce; + } + } else { + eth_mcast << ce; + } + } + + } + + if (_channels[Loopback]) { + eth_lo = new PIEthernet(); + eth_lo->setDebug(false); + eth_lo->setName("PIMulticast_loopback"); + if (!_send_only) { + eth_lo->setParameter(PIEthernet::ReuseAddress, false); + CONNECTU(eth_lo, threadedReadEvent, this, mcastRead); + for (int i = 0; i < lo_pcnt; ++i) { + eth_lo->setReadAddress("127.0.0.1", lo_port + i); + if (eth_lo->open()) { + //piCout << "bind local to" << (lo_port + i); + break; + } + } + } + } +} + + +void PIBroadcast::send(const PIByteArray & data) { + PIByteArray cd = cryptData(data); + if (cd.isEmpty()) return; + PIMutexLocker ml(mcast_mutex); + piForeach (PIEthernet * e, eth_mcast) + e->send(cd); + if (eth_lo) { + for (int i = 0; i < lo_pcnt; ++i) { + eth_lo->send("127.0.0.1", lo_port + i, cd); + } + } +} + + +void PIBroadcast::startRead() { + if (_send_only) return; + PIMutexLocker ml(mcast_mutex); + piForeach (PIEthernet * e, eth_mcast) + e->startThreadedRead(); + if (eth_lo) + eth_lo->startThreadedRead(); + _started = true; +} + + +void PIBroadcast::stopRead() { + PIMutexLocker ml(mcast_mutex); + piForeach (PIEthernet * e, eth_mcast) + e->stopThreadedRead(); + if (eth_lo) + eth_lo->stopThreadedRead(); + _started = false; +} + + +void PIBroadcast::reinit() { + initAll(PIEthernet::allAddresses()); + if (_started) + startRead(); +} + + +void PIBroadcast::mcastRead(uchar * data, int size) { + PIByteArray cd = decryptData(PIByteArray(data, size)); + if (cd.isEmpty()) return; + received(cd); + receiveEvent(cd); +} + + +void PIBroadcast::run() { + PIVector al = PIEthernet::allAddresses(); + mcast_mutex.lock(); + bool r = _reinit; + mcast_mutex.unlock(); + if (al != prev_al || r) + reinit(); +} diff --git a/src_io_utils/pimulticast.cpp b/src_io_utils/pimulticast.cpp deleted file mode 100644 index 6edc8e93..00000000 --- a/src_io_utils/pimulticast.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - PIP - Platform Independent Primitives - Multicast for all interfaces, including loopback - Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru - - 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 . -*/ - -#include "pimulticast.h" - -#define MULTICAST_TTL 4 - - -PIMulticast::PIMulticast(bool send_only): PIThread(), PIEthUtilBase() { - eth_lo = 0; - _send_only = send_only; - mcast_address.set("232.13.3.14", 14100); - lo_port = 14200; - lo_pcnt = 5; - _started = false; - _reinit = true; - //initMcast(PIEthernet::allAddresses()); - PIThread::start(3000); -} - - -PIMulticast::~PIMulticast() { - PIThread::stop(); - mcast_mutex.unlock(); - destroyAll(); -} - - -void PIMulticast::destroyAll() { - piForeach (PIEthernet * e, eth_mcast) { - e->stopThreadedRead(); - delete e; - } - eth_mcast.clear(); - if (eth_lo) { - eth_lo->stopThreadedRead(); - delete eth_lo; - eth_lo = 0; - } -} - - -void PIMulticast::initAll(PIVector al) { - PIMutexLocker ml(mcast_mutex); - destroyAll(); - _reinit = false; - prev_al = al; - al.removeAll(PIEthernet::Address("127.0.0.1")); - al << mcast_address; - eth_mcast.clear(); - PIEthernet::InterfaceList ifaces = PIEthernet::interfaces(); - piForeachC (PIEthernet::Address & a, al) { -// piCout << "mcast try" << a; - PIEthernet * ce = new PIEthernet(); - ce->setDebug(false); - ce->setName("PIMulticast_" + a.toString()); - ce->setParameters(0); - ce->setSendAddress(mcast_address); - ce->setMulticastTTL(MULTICAST_TTL); - if (!_send_only) { - ce->setReadAddress(a.ipString(), mcast_address.port()); - ce->joinMulticastGroup(mcast_address.ipString()); - // piCout << "mcast " << ce->readAddress() << ce->sendAddress(); - if (ce->open()) { - eth_mcast << ce; - CONNECTU(ce, threadedReadEvent, this, mcastRead); - } else { - delete ce; - } - } else { - eth_mcast << ce; - } - - ce = new PIEthernet(); - ce->setDebug(false); - ce->setName("PIMulticast_" + a.toString()); - ce->setParameters(PIEthernet::Broadcast); - const PIEthernet::Interface * cint = ifaces.getByAddress(a.ipString()); - PIEthernet::Address nm((cint == 0) ? "255.255.255.0" : cint->netmask); - ce->setSendAddress(PIEthernet::getBroadcast(a, nm).ipString(), bcast_port); - if (!_send_only) { - ce->setReadAddress(PIEthernet::Address(a.ip(), bcast_port)); - // piCout << "bcast " << ce->readAddress() << ce->sendAddress(); - if (ce->open()) { - eth_mcast << ce; - CONNECTU(ce, threadedReadEvent, this, mcastRead); - } else { - delete ce; - } - } else { - eth_mcast << ce; - } - } - eth_lo = new PIEthernet(); - eth_lo->setDebug(false); - eth_lo->setName("PIMulticast_loopback"); - if (!_send_only) { - eth_lo->setParameter(PIEthernet::ReuseAddress, false); - CONNECTU(eth_lo, threadedReadEvent, this, mcastRead); - for (int i = 0; i < lo_pcnt; ++i) { - eth_lo->setReadAddress("127.0.0.1", lo_port + i); - if (eth_lo->open()) { - // piCout << "bind local to" << (lo_port + i); - break; - } - } - } -} - - -void PIMulticast::send(const PIByteArray & data) { - PIByteArray cd = cryptData(data); - if (cd.isEmpty()) return; - PIMutexLocker ml(mcast_mutex); - piForeach (PIEthernet * e, eth_mcast) - e->send(cd); - if (eth_lo) { - for (int i = 0; i < lo_pcnt; ++i) { - eth_lo->send("127.0.0.1", lo_port + i, cd); - } - } -} - - -void PIMulticast::startRead() { - if (_send_only) return; - PIMutexLocker ml(mcast_mutex); - piForeach (PIEthernet * e, eth_mcast) - e->startThreadedRead(); - if (eth_lo) - eth_lo->startThreadedRead(); - _started = true; -} - - -void PIMulticast::stopRead() { - PIMutexLocker ml(mcast_mutex); - piForeach (PIEthernet * e, eth_mcast) - e->stopThreadedRead(); - if (eth_lo) - eth_lo->stopThreadedRead(); - _started = false; -} - - -void PIMulticast::reinit() { - initAll(PIEthernet::allAddresses()); - if (_started) - startRead(); -} - - -void PIMulticast::mcastRead(uchar * data, int size) { - PIByteArray cd = decryptData(PIByteArray(data, size)); - if (cd.isEmpty()) return; - received(cd); - receiveEvent(cd); -} - - -void PIMulticast::run() { - PIVector al = PIEthernet::allAddresses(); - if (al == prev_al) return; - reinit(); -} diff --git a/src_main/io_utils/pimulticast.h b/src_main/io_utils/pibroadcast.h similarity index 64% rename from src_main/io_utils/pimulticast.h rename to src_main/io_utils/pibroadcast.h index ff53fd53..3f743821 100644 --- a/src_main/io_utils/pimulticast.h +++ b/src_main/io_utils/pibroadcast.h @@ -1,9 +1,9 @@ -/*! \file pimulticast.h - * \brief Multicast for all interfaces, including loopback +/*! \file pibroadcast.h + * \brief Broadcast for all interfaces, including loopback */ /* PIP - Platform Independent Primitives - Multicast for all interfaces, including loopback + Broadcast for all interfaces, including loopback Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify @@ -20,33 +20,44 @@ along with this program. If not, see . */ -#ifndef PIMULTICAST_H -#define PIMULTICAST_H +#ifndef PIBROADCAST_H +#define PIBROADCAST_H #include "piethutilbase.h" #include "piethernet.h" -#define SMDEVICE_PORT 22555 -class PIMulticast: public PIThread, public PIEthUtilBase { - PIOBJECT(PIMulticast) +class PIBroadcast: public PIThread, public PIEthUtilBase { + PIOBJECT_SUBCLASS(PIBroadcast, PIThread) public: - PIMulticast(bool send_only = false); - ~PIMulticast(); - void setMulticastGroup(const PIString & mg) {mcast_address.setIP(mg);} + enum Channel { + Multicast = 0x01, + Broadcast = 0x02, + Loopback = 0x04, + All = 0xFFFF, + }; + typedef PIFlags Channels; + + PIBroadcast(bool send_only = false); + ~PIBroadcast(); + + void setChannels(Channels ch); + Channels channels() const {return _channels;} + + void setMulticastGroup(const PIString & mg); PIString multicastGroup() const {return mcast_address.ipString();} - void setMulticastPort(ushort port) {mcast_address.setPort(port);} + void setMulticastPort(ushort port); ushort multicastPort() const {return mcast_address.port();} - void setMulticastAddress(const PIEthernet::Address & addr) {mcast_address = addr;} + void setMulticastAddress(const PIEthernet::Address & addr); PIEthernet::Address multicastAddress() const {return mcast_address;} - void setBroadcastPort(ushort port) {bcast_port = port;} + void setBroadcastPort(ushort port); ushort broadcastPort() {return bcast_port;} - void setLoopbackPort(ushort port) {lo_port = port;} + void setLoopbackPort(ushort port); ushort loopbackPort() {return lo_port;} - void setLoopbackPortsCount(int count) {lo_pcnt = count;} + void setLoopbackPortsCount(int count); int loopbackPortsCount() const {return lo_pcnt;} void startRead(); @@ -65,6 +76,7 @@ private: void initAll(PIVector al); void run(); + Channels _channels; PIEthernet::Address mcast_address; PIMutex mcast_mutex; PIVector eth_mcast; @@ -76,4 +88,4 @@ private: }; -#endif // PIMULTICAST_H +#endif // PIBROADCAST_H