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