Compare commits
25 Commits
zmq
...
047cff7d6e
| Author | SHA1 | Date | |
|---|---|---|---|
| 047cff7d6e | |||
| 305275e3ac | |||
| efb0d5f4f9 | |||
| 991a074538 | |||
| f82b6c12ee | |||
| 00edfa4ef0 | |||
| 35a3ce6402 | |||
| be3ce454a0 | |||
| 4c85206cfa | |||
| 5ecdcbe46e | |||
| c937d7251a | |||
| 1cc46468c1 | |||
| 5cc8ef1eb0 | |||
| 99e135caa2 | |||
| 9de7045d63 | |||
| 0e65151e9f | |||
| 3c20728210 | |||
| 4c0530d89a | |||
| f5af8a1da9 | |||
| 44b9c37391 | |||
| 97b0b6fc0c | |||
| 1a2e9afaef | |||
| 39a3a23a24 | |||
| ee131921a0 | |||
| f8818c8537 |
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||
project(pip)
|
||||
set(pip_MAJOR 2)
|
||||
set(pip_MINOR 28)
|
||||
set(pip_MINOR 30)
|
||||
set(pip_REVISION 1)
|
||||
set(pip_SUFFIX )
|
||||
set(pip_COMPANY SHS)
|
||||
@@ -284,7 +284,7 @@ endif()
|
||||
if(APPLE)
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
|
||||
endif()
|
||||
if ((NOT DEFINED LIBPROJECT) AND (DEFINED ANDROID_PLATFORM))
|
||||
if ((NOT DEFINED SHSTKPROJECT) AND (DEFINED ANDROID_PLATFORM))
|
||||
include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include)
|
||||
#message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include")
|
||||
#message("${ANDROID_NDK}/sysroot/usr/include")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(ð), tcp(&streampacker) {
|
||||
|
||||
eth.setDebug(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,29 +25,36 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode)
|
||||
tcp.setRole(PICloud::TCP::Client);
|
||||
setName("cloud_client");
|
||||
is_connected = false;
|
||||
CONNECTL(ð, connected, [this](){tcp.sendStart();});
|
||||
is_deleted = false;
|
||||
// setReopenEnabled(false);
|
||||
CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();});
|
||||
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
||||
CONNECTL(ð, disconnected, [this](bool){
|
||||
piCoutObj << "disconnected";
|
||||
if (is_deleted) return;
|
||||
bool need_disconn = is_connected;
|
||||
//piCoutObj << "eth disconnected";
|
||||
static_cast<PIThread*>(ð)->stop();
|
||||
opened_ = false;
|
||||
is_connected = false;
|
||||
cond_connect.notifyOne();
|
||||
cond_buff.notifyOne();
|
||||
piMSleep(100);
|
||||
internalDisconnect();
|
||||
if (need_disconn)
|
||||
disconnected();
|
||||
//piCoutObj << "eth disconnected done";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
PICloudClient::~PICloudClient() {
|
||||
eth.close();
|
||||
if (is_connected) {
|
||||
is_connected = false;
|
||||
disconnected();
|
||||
cond_buff.notifyOne();
|
||||
cond_connect.notifyOne();
|
||||
}
|
||||
//piCoutObj << "~PICloudClient()";
|
||||
PIThread::stop();
|
||||
//eth.close();
|
||||
//if (is_connected) disconnected();
|
||||
close();
|
||||
stop();
|
||||
//piCoutObj << "~PICloudClient() closed";
|
||||
internalDisconnect();
|
||||
// stop(false);
|
||||
is_deleted = true;
|
||||
internalDisconnect();
|
||||
//piCoutObj << "~PICloudClient() done";
|
||||
}
|
||||
|
||||
|
||||
@@ -63,80 +70,100 @@ void PICloudClient::setKeepConnection(bool on) {
|
||||
|
||||
|
||||
bool PICloudClient::openDevice() {
|
||||
// piCout << "PICloudClient open device" << path();
|
||||
//piCoutObj << "open";// << path();
|
||||
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
||||
if (op) {
|
||||
mutex_buff.lock();
|
||||
mutex_connect.lock();
|
||||
eth.startThreadedRead();
|
||||
bool conn_ok = cond_connect.waitFor(mutex_buff, (int)eth.readTimeout(), [this](){return isConnected();});
|
||||
piCoutObj << "conn_ok" << conn_ok;
|
||||
mutex_buff.unlock();
|
||||
//piCoutObj << "connecting...";
|
||||
bool conn_ok = cond_connect.waitFor(mutex_connect, (int)eth.readTimeout());
|
||||
//piCoutObj << "conn_ok" << conn_ok << is_connected;
|
||||
mutex_connect.unlock();
|
||||
if (!conn_ok) {
|
||||
mutex_connect.lock();
|
||||
eth.stop();
|
||||
eth.close();
|
||||
piMSleep(100);
|
||||
mutex_connect.unlock();
|
||||
}
|
||||
return isConnected();
|
||||
return is_connected;
|
||||
} else {
|
||||
eth.close();
|
||||
//eth.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PICloudClient::closeDevice() {
|
||||
//PIThread::stop();
|
||||
if (is_connected) {
|
||||
is_connected = false;
|
||||
disconnected();
|
||||
cond_buff.notifyOne();
|
||||
cond_connect.notifyOne();
|
||||
internalDisconnect();
|
||||
}
|
||||
eth.stop();
|
||||
if (eth.isOpened()) eth.close();
|
||||
eth.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int PICloudClient::readDevice(void * read_to, int max_size) {
|
||||
// piCoutObj << "readDevice";
|
||||
if (!is_connected) return -1;
|
||||
if (is_deleted) return -1;
|
||||
//piCoutObj << "readDevice";
|
||||
if (!is_connected && eth.isClosed()) openDevice();
|
||||
int sz = -1;
|
||||
mutex_buff.lock();
|
||||
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();});
|
||||
int sz = piMini(max_size, buff.size());
|
||||
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
|
||||
if (is_connected) {
|
||||
sz = piMini(max_size, buff.size());
|
||||
memcpy(read_to, buff.data(), sz);
|
||||
buff.remove(0, sz);
|
||||
}
|
||||
mutex_buff.unlock();
|
||||
if (!is_connected) opened_ = false;
|
||||
//piCoutObj << "readDevice done" << sz;
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
int PICloudClient::writeDevice(const void * data, int size) {
|
||||
if (is_deleted) return -1;
|
||||
// piCoutObj << "writeDevice";
|
||||
return tcp.sendData(PIByteArray(data, size));
|
||||
}
|
||||
|
||||
|
||||
void PICloudClient::internalDisconnect() {
|
||||
is_connected = false;
|
||||
cond_buff.notifyOne();
|
||||
cond_connect.notifyOne();
|
||||
streampacker.clear();
|
||||
buff.clear();
|
||||
}
|
||||
|
||||
|
||||
void PICloudClient::_readed(PIByteArray & ba) {
|
||||
mutex_buff.lock();
|
||||
if (is_deleted) return;
|
||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
||||
//piCoutObj << "_readed" << ba.size() << hdr.first << hdr.second;
|
||||
if (hdr.second == tcp.role()) {
|
||||
switch (hdr.first) {
|
||||
case PICloud::TCP::Connect:
|
||||
if (tcp.parseConnect(ba) == 1) {
|
||||
mutex_connect.lock();
|
||||
is_connected = true;
|
||||
connected();
|
||||
mutex_connect.unlock();
|
||||
cond_connect.notifyOne();
|
||||
connected();
|
||||
}
|
||||
break;
|
||||
case PICloud::TCP::Disconnect:
|
||||
is_connected = false;
|
||||
eth.stop();
|
||||
static_cast<PIThread*>(ð)->stop();
|
||||
opened_ = false;
|
||||
eth.close();
|
||||
disconnected();
|
||||
break;
|
||||
case PICloud::TCP::Data:
|
||||
if (is_connected) {
|
||||
mutex_buff.lock();
|
||||
buff.append(ba);
|
||||
mutex_buff.unlock();
|
||||
cond_buff.notifyOne();
|
||||
}
|
||||
break;
|
||||
@@ -145,7 +172,7 @@ void PICloudClient::_readed(PIByteArray & ba) {
|
||||
}
|
||||
//piCoutObj << "readed" << ba.toHex();
|
||||
}
|
||||
mutex_buff.unlock();
|
||||
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100);
|
||||
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); // FIXME: sleep here is bad
|
||||
//piCoutObj << "_readed done";
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,17 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode)
|
||||
tcp.setServerName(server_name);
|
||||
setName("cloud_server__" + server_name);
|
||||
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
||||
CONNECTL(ð, connected, [this](){tcp.sendStart();});
|
||||
CONNECTL(ð, connected, [this](){opened_ = true; piCoutObj << "connected"; tcp.sendStart();});
|
||||
CONNECTL(ð, disconnected, [this](bool){
|
||||
piCoutObj << "disconnected";
|
||||
static_cast<PIThread*>(ð)->stop();
|
||||
opened_ = false;
|
||||
ping_timer.stop(false);
|
||||
piMSleep(100);
|
||||
});
|
||||
CONNECTL(&ping_timer, tickEvent, [this] (void *, int){
|
||||
if (eth.isConnected()) tcp.sendPing();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -54,12 +59,14 @@ PIVector<PICloudServer::Client *> PICloudServer::clients() const {
|
||||
|
||||
|
||||
bool PICloudServer::openDevice() {
|
||||
piCout << "PICloudServer open device" << path();
|
||||
//piCout << "PICloudServer open device" << path();
|
||||
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
||||
if (op) {
|
||||
eth.startThreadedRead();
|
||||
ping_timer.start(5000);
|
||||
return true;
|
||||
}
|
||||
ping_timer.stop(false);
|
||||
eth.close();
|
||||
return false;
|
||||
}
|
||||
@@ -67,6 +74,7 @@ bool PICloudServer::openDevice() {
|
||||
|
||||
bool PICloudServer::closeDevice() {
|
||||
eth.stop();
|
||||
ping_timer.stop(false);
|
||||
clients_mutex.lock();
|
||||
for (auto c : clients_) {
|
||||
c->close();
|
||||
@@ -82,7 +90,8 @@ bool PICloudServer::closeDevice() {
|
||||
|
||||
int PICloudServer::readDevice(void * read_to, int max_size) {
|
||||
//piCoutObj << "readDevice";
|
||||
piMSleep(eth.readTimeout());
|
||||
if (!opened_) openDevice();
|
||||
else piMSleep(eth.readTimeout());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -126,22 +135,26 @@ bool PICloudServer::Client::openDevice() {
|
||||
|
||||
|
||||
bool PICloudServer::Client::closeDevice() {
|
||||
PIThread::stop(false);
|
||||
if (is_connected) {
|
||||
server->clientDisconnect(client_id);
|
||||
is_connected = false;
|
||||
cond_buff.notifyOne();
|
||||
}
|
||||
cond_buff.notifyOne();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int PICloudServer::Client::readDevice(void * read_to, int max_size) {
|
||||
if (!is_connected) return -1;
|
||||
int sz = -1;
|
||||
mutex_buff.lock();
|
||||
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();});
|
||||
int sz = piMini(max_size, buff.size());
|
||||
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
|
||||
if (is_connected) {
|
||||
sz = piMini(max_size, buff.size());
|
||||
memcpy(read_to, buff.data(), sz);
|
||||
buff.remove(0, sz);
|
||||
}
|
||||
mutex_buff.unlock();
|
||||
return sz;
|
||||
}
|
||||
@@ -158,7 +171,7 @@ void PICloudServer::Client::pushBuffer(const PIByteArray & ba) {
|
||||
buff.append(ba);
|
||||
cond_buff.notifyOne();
|
||||
mutex_buff.unlock();
|
||||
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100);
|
||||
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); // FIXME: sleep here is bad
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +187,7 @@ void PICloudServer::_readed(PIByteArray & ba) {
|
||||
if (oc) {
|
||||
tcp.sendDisconnected(id);
|
||||
} else {
|
||||
piCoutObj << "new Client" << id;
|
||||
//piCoutObj << "new Client" << id;
|
||||
Client * c = new Client(this, id);
|
||||
CONNECTU(c, deleted, this, clientDeleted);
|
||||
clients_mutex.lock();
|
||||
@@ -186,7 +199,7 @@ void PICloudServer::_readed(PIByteArray & ba) {
|
||||
} break;
|
||||
case PICloud::TCP::Disconnect: {
|
||||
uint id = tcp.parseDisconnect(ba);
|
||||
piCoutObj << "remove Client" << id;
|
||||
//piCoutObj << "remove Client" << id;
|
||||
clients_mutex.lock();
|
||||
Client * oc = index_clients.value(id, nullptr);
|
||||
clients_mutex.unlock();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "pistreampacker.h"
|
||||
|
||||
|
||||
const char hash_def_key[] = "_picrypt_";
|
||||
const char hash_cloud_key[] = "_picloud_";
|
||||
|
||||
|
||||
PICloud::TCP::Header::Header() {
|
||||
@@ -33,7 +33,7 @@ PICloud::TCP::Header::Header() {
|
||||
|
||||
|
||||
PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) {
|
||||
|
||||
streampacker->setMaxPacketSize(63*1024);
|
||||
}
|
||||
|
||||
void PICloud::TCP::setRole(PICloud::TCP::Role r) {
|
||||
@@ -43,7 +43,7 @@ void PICloud::TCP::setRole(PICloud::TCP::Role r) {
|
||||
|
||||
void PICloud::TCP::setServerName(const PIString & server_name_) {
|
||||
server_name = server_name_;
|
||||
suuid = PICrypt::hash(server_name_);
|
||||
suuid = PICrypt::hash(PIByteArray(server_name_.data(), server_name_.size()), (const unsigned char *)hash_cloud_key, sizeof(hash_cloud_key));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,9 @@ void PICloud::TCP::sendStart() {
|
||||
PIByteArray ba;
|
||||
ba << header;
|
||||
ba.append(suuid);
|
||||
//mutex_send.lock();
|
||||
streampacker->send(ba);
|
||||
//mutex_send.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +72,9 @@ void PICloud::TCP::sendConnected(uint client_id) {
|
||||
header.type = PICloud::TCP::Connect;
|
||||
PIByteArray ba;
|
||||
ba << header << client_id;
|
||||
// mutex_send.lock();
|
||||
streampacker->send(ba);
|
||||
// mutex_send.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +82,9 @@ void PICloud::TCP::sendDisconnected(uint client_id) {
|
||||
header.type = PICloud::TCP::Disconnect;
|
||||
PIByteArray ba;
|
||||
ba << header << client_id;
|
||||
// mutex_send.lock();
|
||||
streampacker->send(ba);
|
||||
// mutex_send.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +93,10 @@ int PICloud::TCP::sendData(const PIByteArray & data) {
|
||||
PIByteArray ba;
|
||||
ba << header;
|
||||
ba.append(data);
|
||||
// piCout << "sendData" << ba.toHex();
|
||||
// piCout << "[PICloud::TCP] sendData" << ba.toHex();
|
||||
mutex_send.lock();
|
||||
streampacker->send(ba);
|
||||
mutex_send.unlock();
|
||||
return data.size_s();
|
||||
}
|
||||
|
||||
@@ -98,11 +106,24 @@ int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) {
|
||||
PIByteArray ba;
|
||||
ba << header << client_id;
|
||||
ba.append(data);
|
||||
mutex_send.lock();
|
||||
streampacker->send(ba);
|
||||
mutex_send.unlock();
|
||||
return data.size_s();
|
||||
}
|
||||
|
||||
|
||||
void PICloud::TCP::sendPing() {
|
||||
header.type = PICloud::TCP::Ping;
|
||||
PIByteArray ba;
|
||||
ba << header;
|
||||
ba.append(suuid);
|
||||
mutex_send.lock();
|
||||
streampacker->send(ba);
|
||||
mutex_send.unlock();
|
||||
}
|
||||
|
||||
|
||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteArray & ba) {
|
||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret;
|
||||
ret.first = InvalidType;
|
||||
@@ -120,11 +141,8 @@ PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteA
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PICloud::TCP::parseData(PIByteArray & ba) {
|
||||
if (header.role == Client) {
|
||||
return ba;
|
||||
}
|
||||
return PIByteArray();
|
||||
bool PICloud::TCP::canParseData(PIByteArray & ba) {
|
||||
return header.role == Client;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +151,7 @@ PIPair<uint, PIByteArray> PICloud::TCP::parseDataServer(PIByteArray & ba) {
|
||||
ret.first = 0;
|
||||
if (header.role == Server) {
|
||||
ba >> ret.first;
|
||||
ret.second = ba;
|
||||
ret.second.swap(ba);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -169,6 +169,19 @@ PIByteArray PICrypt::hash(const PIByteArray & data) {
|
||||
}
|
||||
|
||||
|
||||
PIByteArray PICrypt::hash(const PIByteArray & data, const unsigned char *key, size_t keylen) {
|
||||
PIByteArray hash;
|
||||
#ifdef PIP_CRYPT
|
||||
if (!init()) return hash;
|
||||
hash.resize(crypto_generichash_BYTES);
|
||||
crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), key, keylen);
|
||||
#else
|
||||
PICRYPT_DISABLED_WARNING
|
||||
#endif
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
size_t PICrypt::sizeHash() {
|
||||
#ifdef PIP_CRYPT
|
||||
return crypto_generichash_BYTES;
|
||||
|
||||
@@ -53,8 +53,6 @@ PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() {
|
||||
_started = false;
|
||||
_send_only = send_only;
|
||||
_reinit = true;
|
||||
//initMcast(PIEthernet::allAddresses());
|
||||
PIThread::start(3000);
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +138,6 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
||||
piForeachC (PIEthernet::Address & a, al) {
|
||||
PIEthernet * ce = 0;
|
||||
//piCout << "mcast try" << a;
|
||||
|
||||
if (_channels[Multicast]) {
|
||||
ce = new PIEthernet();
|
||||
ce->setDebug(false);
|
||||
@@ -184,7 +181,6 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
||||
eth_mcast << ce;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_channels[Loopback]) {
|
||||
@@ -207,11 +203,14 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
||||
|
||||
|
||||
void PIBroadcast::send(const PIByteArray & data) {
|
||||
if (!isRunning()) {
|
||||
reinit();
|
||||
PIThread::start(3000);
|
||||
}
|
||||
PIByteArray cd = cryptData(data);
|
||||
if (cd.isEmpty()) return;
|
||||
PIMutexLocker ml(mcast_mutex);
|
||||
piForeach (PIEthernet * e, eth_mcast)
|
||||
e->send(cd);
|
||||
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);
|
||||
@@ -221,30 +220,31 @@ void PIBroadcast::send(const PIByteArray & data) {
|
||||
|
||||
|
||||
void PIBroadcast::startRead() {
|
||||
if (!isRunning()) {
|
||||
_started = false;
|
||||
reinit();
|
||||
PIThread::start(3000);
|
||||
}
|
||||
if (_send_only) return;
|
||||
PIMutexLocker ml(mcast_mutex);
|
||||
piForeach (PIEthernet * e, eth_mcast)
|
||||
e->startThreadedRead();
|
||||
if (eth_lo)
|
||||
eth_lo->startThreadedRead();
|
||||
piForeach (PIEthernet * e, eth_mcast) e->startThreadedRead();
|
||||
if (eth_lo) eth_lo->startThreadedRead();
|
||||
_started = true;
|
||||
}
|
||||
|
||||
|
||||
void PIBroadcast::stopRead() {
|
||||
if (isRunning()) stop();
|
||||
PIMutexLocker ml(mcast_mutex);
|
||||
piForeach (PIEthernet * e, eth_mcast)
|
||||
e->stopThreadedRead();
|
||||
if (eth_lo)
|
||||
eth_lo->stopThreadedRead();
|
||||
piForeach (PIEthernet * e, eth_mcast) e->stopThreadedRead();
|
||||
if (eth_lo) eth_lo->stopThreadedRead();
|
||||
_started = false;
|
||||
}
|
||||
|
||||
|
||||
void PIBroadcast::reinit() {
|
||||
initAll(PIEthernet::allAddresses());
|
||||
if (_started)
|
||||
startRead();
|
||||
if (_started) startRead();
|
||||
}
|
||||
|
||||
|
||||
@@ -261,8 +261,6 @@ void PIBroadcast::run() {
|
||||
mcast_mutex.lock();
|
||||
bool r = _reinit, ac = (al != prev_al);
|
||||
mcast_mutex.unlock();
|
||||
if (ac || r)
|
||||
reinit();
|
||||
if (ac)
|
||||
addressesChanged();
|
||||
if (ac || r) reinit();
|
||||
if (ac) addressesChanged();
|
||||
}
|
||||
|
||||
@@ -68,6 +68,13 @@ void PIStreamPacker::setCryptSizeEnabled(bool on) {
|
||||
}
|
||||
|
||||
|
||||
void PIStreamPacker::clear() {
|
||||
packet.clear();
|
||||
packet_size = -1;
|
||||
stream.clear();
|
||||
}
|
||||
|
||||
|
||||
void PIStreamPacker::send(const PIByteArray & data) {
|
||||
if (data.isEmpty()) return;
|
||||
PIByteArray cd;
|
||||
@@ -94,31 +101,12 @@ void PIStreamPacker::send(const PIByteArray & data) {
|
||||
hdr << int(cd.size_s());
|
||||
cd.insert(0, hdr);
|
||||
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
|
||||
if (pcnt > 1) {
|
||||
prog_s_mutex.lock();
|
||||
prog_s.active = true;
|
||||
prog_s.bytes_all = data.size_s();
|
||||
prog_s.bytes_current = 0;
|
||||
prog_s.progress = 0.;
|
||||
prog_s_mutex.unlock();
|
||||
}
|
||||
for (int i = 0; i < pcnt; ++i) {
|
||||
if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst);
|
||||
else part = PIByteArray(cd.data(pst), max_packet_size);
|
||||
//piCout << "send" << part.size();
|
||||
sendRequest(part);
|
||||
pst += max_packet_size;
|
||||
if (pcnt > 1) {
|
||||
prog_s_mutex.lock();
|
||||
prog_s.bytes_current += part.size_s();
|
||||
prog_s.progress = (double)prog_s.bytes_current / prog_s.bytes_all;
|
||||
prog_s_mutex.unlock();
|
||||
}
|
||||
}
|
||||
if (pcnt > 1) {
|
||||
prog_s_mutex.lock();
|
||||
prog_s.active = false;
|
||||
prog_s_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,22 +154,10 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
||||
packet_size = sz;
|
||||
if (packet_size == 0)
|
||||
packet_size = -1;
|
||||
else {
|
||||
prog_r_mutex.lock();
|
||||
prog_r.active = true;
|
||||
prog_r.bytes_all = packet_size;
|
||||
prog_r.bytes_current = 0;
|
||||
prog_r.progress = 0.;
|
||||
prog_r_mutex.unlock();
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
int ps = piMini(stream.size_s(), packet_size - packet.size_s());
|
||||
packet.append(stream.data(), ps);
|
||||
prog_r_mutex.lock();
|
||||
prog_r.bytes_current = packet.size_s();
|
||||
prog_r.progress = (double)prog_r.bytes_current / piMaxi(1, prog_r.bytes_all);
|
||||
prog_r_mutex.unlock();
|
||||
stream.remove(0, ps);
|
||||
if (packet.size_s() == packet_size) {
|
||||
PIByteArray cd;
|
||||
@@ -211,9 +187,6 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
||||
}
|
||||
packet.clear();
|
||||
packet_size = -1;
|
||||
prog_r_mutex.lock();
|
||||
prog_r.active = false;
|
||||
prog_r_mutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,30 +200,3 @@ void PIStreamPacker::assignDevice(PIIODevice * dev) {
|
||||
CONNECTU(dev, threadedReadEvent, this, received);
|
||||
CONNECTU(this, sendRequest, dev, write);
|
||||
}
|
||||
|
||||
|
||||
PIStreamPacker::Progress PIStreamPacker::progressSend() const {
|
||||
PIStreamPacker::Progress ret;
|
||||
prog_s_mutex.lock();
|
||||
ret = prog_s;
|
||||
prog_s_mutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIStreamPacker::Progress PIStreamPacker::progressReceive() const {
|
||||
PIStreamPacker::Progress ret;
|
||||
prog_r_mutex.lock();
|
||||
ret = prog_r;
|
||||
prog_r_mutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PIStreamPacker::Progress::Progress() {
|
||||
active = false;
|
||||
bytes_all = bytes_current = 0;
|
||||
progress = 0.;
|
||||
}
|
||||
|
||||
@@ -52,12 +52,15 @@ protected:
|
||||
|
||||
private:
|
||||
EVENT_HANDLER1(void, _readed, PIByteArray &, data);
|
||||
void internalDisconnect();
|
||||
|
||||
PIByteArray buff;
|
||||
PIMutex mutex_buff;
|
||||
PIMutex mutex_connect;
|
||||
PIConditionVariable cond_buff;
|
||||
PIConditionVariable cond_connect;
|
||||
std::atomic_bool is_connected;
|
||||
std::atomic_bool is_deleted;
|
||||
};
|
||||
|
||||
#endif // PICLOUDCLIENT_H
|
||||
|
||||
@@ -78,6 +78,7 @@ private:
|
||||
|
||||
PIVector<Client *> clients_;
|
||||
PIMap<uint, Client *> index_clients;
|
||||
PITimer ping_timer;
|
||||
mutable PIMutex clients_mutex;
|
||||
};
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "pip_cloud_export.h"
|
||||
#include "pistring.h"
|
||||
#include "pimutex.h"
|
||||
|
||||
|
||||
class PIEthernet;
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
Connect = 1,
|
||||
Disconnect = 2,
|
||||
Data = 3,
|
||||
Ping = 4,
|
||||
};
|
||||
|
||||
TCP(PIStreamPacker * s);
|
||||
@@ -65,8 +67,9 @@ public:
|
||||
void sendDisconnected(uint client_id);
|
||||
int sendData(const PIByteArray & data);
|
||||
int sendData(const PIByteArray & data, uint client_id);
|
||||
void sendPing();
|
||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
||||
PIByteArray parseData(PIByteArray & ba);
|
||||
bool canParseData(PIByteArray & ba);
|
||||
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
|
||||
PIByteArray parseConnect_d(PIByteArray & ba);
|
||||
uint parseConnect(PIByteArray & ba);
|
||||
@@ -84,6 +87,8 @@ private:
|
||||
PIByteArray suuid;
|
||||
PIString server_name;
|
||||
PIStreamPacker * streampacker;
|
||||
PIMutex mutex_send;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -190,10 +190,36 @@ void PICodeParser::clear() {
|
||||
piForeachC (PIString & d, defs)
|
||||
defines << Define(d, "");
|
||||
defines << Define(PIStringAscii("PICODE"), "") << custom_defines;
|
||||
macros << Macro(PIStringAscii("PIOBJECT"), "", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("PIOBJECT_PARENT"), "", PIStringList() << "parent")
|
||||
<< Macro(PIStringAscii("PIOBJECT_SUBCLASS"), "", PIStringList() << "name" << "parent")
|
||||
|
||||
<< Macro(PIStringAscii("EVENT" ), "void name();", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("EVENT0"), "void name();", PIStringList() << "name")
|
||||
<< Macro(PIStringAscii("EVENT1"), "void name(a0 n0);", PIStringList() << "name" << "a0" << "n0")
|
||||
<< Macro(PIStringAscii("EVENT2"), "void name(a0 n0, a1 n1);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1")
|
||||
<< Macro(PIStringAscii("EVENT3"), "void name(a0 n0, a1 n1, a2 n2);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||
<< Macro(PIStringAscii("EVENT4"), "void name(a0 n0, a1 n1, a2 n2, a3 n3);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER" ), "ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER0"), "ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER1"), "ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER2"), "ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER3"), "ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||
<< Macro(PIStringAscii("EVENT_HANDLER4"), "ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER" ), "virtual ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER0"), "virtual ret name()", PIStringList() << "ret" << "name")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER1"), "virtual ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER2"), "virtual ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER3"), "virtual ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||
<< Macro(PIStringAscii("EVENT_VHANDLER4"), "virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
static const PIString s_ns = PIStringAscii("::");
|
||||
static const PIString s_bo = PIStringAscii("{\n");
|
||||
static const PIString s_bc = PIStringAscii("\n}\n");
|
||||
static const PIString s_class = PIStringAscii("class");
|
||||
@@ -280,7 +306,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
|
||||
replaceMeta(pfc);
|
||||
|
||||
//piCout << NewLine << "file" << cur_file << pfc;
|
||||
//piCout << PICoutManipulators::NewLine << "file" << cur_file << pfc;
|
||||
int pl = -1;
|
||||
while (!pfc.isEmpty()) {
|
||||
pfc.trim();
|
||||
@@ -288,7 +314,12 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||
if (pl == nl) break;
|
||||
pl = nl;
|
||||
if (pfc.left(9) == s_namespace) {
|
||||
pfc.cutLeft(pfc.find('{') + 1);
|
||||
pfc.cutLeft(9);
|
||||
PIString prev_namespace = cur_namespace, ccmn;
|
||||
cur_namespace += pfc.takeCWord() + s_ns;
|
||||
ccmn = pfc.takeRange('{', '}');
|
||||
parseClass(0, ccmn);
|
||||
cur_namespace = prev_namespace;
|
||||
continue;
|
||||
}
|
||||
if (pfc.left(8) == s_template) {
|
||||
@@ -417,7 +448,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
|
||||
int ps = -1;
|
||||
bool def = false;
|
||||
PIString prev_namespace = cur_namespace, stmp;
|
||||
cur_namespace = ce->name + s_ns;
|
||||
cur_namespace += ce->name + s_ns;
|
||||
//piCout << "parse class" << ce->name << "namespace" << cur_namespace;
|
||||
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
|
||||
while (!fc.isEmpty()) {
|
||||
@@ -1074,9 +1105,19 @@ bool PICodeParser::parseDirective(PIString d) {
|
||||
if (mname == s_PIMETA) return true;
|
||||
if (d.left(1) == PIChar('(')) { // macro
|
||||
PIStringList args = d.takeRange('(', ')').split(',').trim();
|
||||
for (int i = 0; i < macros.size_s(); ++i)
|
||||
if (macros[i].name == mname) {
|
||||
macros.remove(i);
|
||||
break;
|
||||
}
|
||||
macros << Macro(mname, d.trim(), args);
|
||||
} else { // define
|
||||
d.trim();
|
||||
for (int i = 0; i < defines.size_s(); ++i)
|
||||
if (defines[i].first == mname) {
|
||||
defines.remove(i);
|
||||
break;
|
||||
}
|
||||
defines << Define(mname, d);
|
||||
evaluator.setVariable(mname, complexd_1);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "pithread.h"
|
||||
|
||||
#define WAIT_FOR_EXIT while (!PIKbdListener::exiting) piMSleep(PIP_MIN_MSLEEP*5);
|
||||
#define WAIT_FOR_EXIT while (!PIKbdListener::exiting) piMSleep(PIP_MIN_MSLEEP*5); // TODO: rewrite with condvar
|
||||
|
||||
|
||||
class PIP_EXPORT PIKbdListener: public PIThread
|
||||
|
||||
@@ -190,10 +190,16 @@ public:
|
||||
return true;
|
||||
}
|
||||
inline bool operator !=(const PIDeque<T> & t) const {return !(*this == t);}
|
||||
inline bool operator <(const PIDeque<T> & t) const {
|
||||
if (pid_size != t.pid_size) return pid_size < t.pid_size;
|
||||
for (size_t i = 0; i < pid_size; ++i)
|
||||
if ((*this)[i] != t[i]) return (*this)[i] < t[i];
|
||||
return false;
|
||||
}
|
||||
inline bool operator >(const PIDeque<T> & t) const {
|
||||
if (pid_size != t.pid_size) return pid_size > t.pid_size;
|
||||
for (size_t i = 0; i < pid_size; ++i)
|
||||
if (t[i] != (*this)[i]) return t[i] > (*this)[i];
|
||||
if ((*this)[i] != t[i]) return (*this)[i] > t[i];
|
||||
return false;
|
||||
}
|
||||
inline bool contains(const T & v) const {
|
||||
|
||||
@@ -191,6 +191,18 @@ public:
|
||||
return true;
|
||||
}
|
||||
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
|
||||
inline bool operator <(const PIVector<T> & t) const {
|
||||
if (piv_size != t.piv_size) return piv_size < t.piv_size;
|
||||
for (size_t i = 0; i < piv_size; ++i)
|
||||
if ((*this)[i] != t[i]) return (*this)[i] < t[i];
|
||||
return false;
|
||||
}
|
||||
inline bool operator >(const PIVector<T> & t) const {
|
||||
if (piv_size != t.piv_size) return piv_size > t.piv_size;
|
||||
for (size_t i = 0; i < piv_size; ++i)
|
||||
if ((*this)[i] != t[i]) return (*this)[i] > t[i];
|
||||
return false;
|
||||
}
|
||||
inline bool contains(const T & v) const {
|
||||
for (size_t i = 0; i < piv_size; ++i)
|
||||
if (v == piv_data[i])
|
||||
|
||||
@@ -190,34 +190,39 @@ public:
|
||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||
inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
for (uint i = 0; i < v0.size(); ++i)
|
||||
if (v0[i] != v1[i])
|
||||
return v0[i] < v1[i];
|
||||
return false;
|
||||
if (v0.isEmpty()) return false;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) < 0;
|
||||
}
|
||||
return v0.size() < v1.size();
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||
inline bool operator ==(PIByteArray & f, PIByteArray & s) {
|
||||
if (f.size_s() != s.size_s())
|
||||
return false;
|
||||
for (int i = 0; i < f.size_s(); ++i)
|
||||
if (f[i] != s[i])
|
||||
return false;
|
||||
return true;
|
||||
inline bool operator >(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return false;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) > 0;
|
||||
}
|
||||
return v0.size() > v1.size();
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||
inline bool operator !=(PIByteArray & f, PIByteArray & s) {
|
||||
if (f.size_s() != s.size_s())
|
||||
return true;
|
||||
for (int i = 0; i < f.size_s(); ++i)
|
||||
if (f[i] != s[i])
|
||||
return true;
|
||||
inline bool operator ==(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return true;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||
inline bool operator !=(const PIByteArray & v0, const PIByteArray & v1) {
|
||||
if (v0.size() == v1.size()) {
|
||||
if (v0.isEmpty()) return false;
|
||||
return memcmp(v0.data(), v1.data(), v0.size()) != 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef PIP_STD_IOSTREAM
|
||||
//! \relatesalso PIByteArray @brief Output to std::ostream operator
|
||||
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);
|
||||
|
||||
@@ -700,8 +700,7 @@ PIObject::Deleter::Deleter() {
|
||||
stopping = started = posted = false;
|
||||
CONNECTL(&(PRIVATE->thread), started, [this](){proc();});
|
||||
PRIVATE->thread.startOnce();
|
||||
while (!started)
|
||||
piMSleep(1);
|
||||
while (!started) piMSleep(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -710,8 +709,7 @@ PIObject::Deleter::~Deleter() {
|
||||
stopping = true;
|
||||
PRIVATE->cond_var.notifyAll();
|
||||
#ifndef WINDOWS
|
||||
while (PRIVATE->thread.isRunning())
|
||||
piMSleep(1);
|
||||
while (PRIVATE->thread.isRunning()) piMSleep(1);
|
||||
#endif
|
||||
deleteAll();
|
||||
//piCout << "~Deleter ok";
|
||||
@@ -774,12 +772,9 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
|
||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "...";
|
||||
if (o->isPIObject()) {
|
||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
|
||||
while (o->isInEvent()) {
|
||||
piMSleep(1);
|
||||
}
|
||||
while (o->isInEvent()) piMSleep(1);
|
||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
|
||||
if (o->isPIObject())
|
||||
delete o;
|
||||
if (o->isPIObject()) delete o;
|
||||
}
|
||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "done";
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
//! Generate hash from bytearray
|
||||
static PIByteArray hash(const PIByteArray & data);
|
||||
|
||||
//! Generate hash from bytearray
|
||||
static PIByteArray hash(const PIByteArray & data, const unsigned char * key, size_t keylen);
|
||||
|
||||
//! Returns hash size
|
||||
static size_t sizeHash();
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||
pausemutex.lock();
|
||||
if (is_pause) {
|
||||
pausemutex.unlock();
|
||||
piMSleep(100);
|
||||
piMSleep(100); // TODO: rewrite with condvar
|
||||
return false;
|
||||
} else if (pause_time > PISystemTime()) {
|
||||
startlogtime += pause_time;
|
||||
@@ -204,22 +204,22 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||
int dtc;
|
||||
if (is_started) {
|
||||
if (is_pause) {
|
||||
piMSleep(100);
|
||||
piMSleep(100); // TODO: rewrite with condvar
|
||||
return false;
|
||||
}
|
||||
if (delay > 0) {
|
||||
cdelay = delay * play_speed;
|
||||
dtc = int(cdelay) /100;
|
||||
cdelay = delay * play_speed;// TODO: rewrite with condvar
|
||||
dtc = int(cdelay) / 100;// TODO: rewrite with condvar
|
||||
if (play_speed <= 0.) dtc = 2;
|
||||
//piCout << play_speed << dtc;
|
||||
for (int j=0; j<dtc; j++) {
|
||||
cdelay = delay * play_speed;
|
||||
dtc = int(cdelay) /100;
|
||||
piMSleep(100);
|
||||
cdelay = delay * play_speed;// TODO: rewrite with condvar
|
||||
dtc = int(cdelay) / 100;// TODO: rewrite with condvar
|
||||
piMSleep(100);// TODO: rewrite with condvar
|
||||
if (play_speed <= 0.) {dtc = 2; j = 0;}
|
||||
//piCout << " " << play_speed << dtc << j;
|
||||
}
|
||||
cdelay = cdelay - dtc*100;
|
||||
cdelay = cdelay - dtc*100;// TODO: rewrite with condvar
|
||||
PISystemTime::fromMilliseconds(cdelay).sleep();
|
||||
}
|
||||
} else is_started = true;
|
||||
@@ -228,7 +228,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
||||
case PlayStaticDelay:
|
||||
if (is_started) {
|
||||
if (is_pause) {
|
||||
piMSleep(100);
|
||||
piMSleep(100);// TODO: rewrite with condvar
|
||||
return false;
|
||||
}
|
||||
play_delay.sleep();
|
||||
|
||||
@@ -993,6 +993,7 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) {
|
||||
|
||||
|
||||
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
//piCout << "PIEthernet::interfaces()";
|
||||
PIEthernet::InterfaceList il;
|
||||
Interface ci;
|
||||
ci.index = -1;
|
||||
@@ -1039,8 +1040,16 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
switch (ret) {
|
||||
case ERROR_NO_DATA: break;
|
||||
case ERROR_NOT_SUPPORTED:
|
||||
piCout << "[PIEthernet] GetAdaptersInfo not supported";
|
||||
break;
|
||||
default:
|
||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
||||
}
|
||||
}
|
||||
if (pAdapterInfo)
|
||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||
#else
|
||||
|
||||
@@ -239,7 +239,7 @@ void PIIODevice::check_start(void * data, int delim) {
|
||||
//cout << "check " << tread_started_ << endl;
|
||||
if (open()) {
|
||||
thread_started_ = true;
|
||||
timer.stop();
|
||||
timer.stop(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,22 +36,6 @@ public:
|
||||
//! Contructs packer and try to assign \"dev\"
|
||||
PIStreamPacker(PIIODevice * dev = 0);
|
||||
|
||||
//! Progress info
|
||||
struct PIP_IO_UTILS_EXPORT Progress {
|
||||
Progress();
|
||||
|
||||
//! Is send/receive in progress
|
||||
bool active;
|
||||
|
||||
//! Overall send/receive packet size
|
||||
int bytes_all;
|
||||
|
||||
//! Current send/receive size
|
||||
int bytes_current;
|
||||
|
||||
//! Current send/receive progress from 0 to 1
|
||||
double progress;
|
||||
};
|
||||
|
||||
//! Set maximum size of single packet
|
||||
void setMaxPacketSize(int max_size) {max_packet_size = max_size;}
|
||||
@@ -83,6 +67,8 @@ public:
|
||||
bool cryptSizeEnabled() const {return crypt_size;}
|
||||
void setCryptSizeEnabled(bool on);
|
||||
|
||||
void clear();
|
||||
|
||||
|
||||
//! Prepare data for send and raise \a sendRequest() events
|
||||
void send(const PIByteArray & data);
|
||||
@@ -97,12 +83,6 @@ public:
|
||||
//! and \a sendRequest() event to \"dev\" \a PIIODevice::write() handler
|
||||
void assignDevice(PIIODevice * dev);
|
||||
|
||||
//! Returns \a Progress info about sending
|
||||
Progress progressSend() const;
|
||||
|
||||
//! Returns \a Progress info about receiving
|
||||
Progress progressReceive() const;
|
||||
|
||||
EVENT1(packetReceiveEvent, PIByteArray &, data)
|
||||
EVENT1(sendRequest, PIByteArray, data)
|
||||
|
||||
@@ -139,7 +119,6 @@ private:
|
||||
int packet_size, crypt_frag_size;
|
||||
ushort packet_sign;
|
||||
int max_packet_size, size_crypted_size;
|
||||
Progress prog_s, prog_r;
|
||||
mutable PIMutex prog_s_mutex, prog_r_mutex;
|
||||
|
||||
};
|
||||
|
||||
@@ -259,7 +259,7 @@ uint PISystemInfo::machineID() {
|
||||
if (ret == 0) {
|
||||
CRC_32 crc = standardCRC_32();
|
||||
ret = crc.calculate(machineKey().toByteArray());
|
||||
piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret;
|
||||
//piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
13
main.cpp
13
main.cpp
@@ -2,6 +2,8 @@
|
||||
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
PIByteArray rnd;
|
||||
rnd.resize(1024*1024, 'x');
|
||||
PICLI cli(argc, argv);
|
||||
PITimer tm;
|
||||
cli.addArgument("connect", true);
|
||||
@@ -28,18 +30,25 @@ int main(int argc, char * argv[]) {
|
||||
}));
|
||||
CONNECTL(&c, threadedReadEvent, ([&](uchar * readed, int size){
|
||||
PIByteArray ba(readed, size);
|
||||
if (size < 1024) {
|
||||
PIString str = PIString(ba);
|
||||
piCout << "[Client] data:" << str;
|
||||
if (str == "ping_S") c.write(PIString("pong_S").toByteArray());
|
||||
} else piCout << "[Client] blob:" << size;
|
||||
}));
|
||||
CONNECTL(&c, connected, ([](){piCout << "connected";}));
|
||||
CONNECTL(&c, disconnected, ([](){piCout << "disconnected";}));
|
||||
CONNECTL(&s, newConnection, ([&](PICloudServer::Client * cl){
|
||||
piCout << "[Server] new client:" << cl;
|
||||
clients << cl;
|
||||
CONNECTL(cl, threadedReadEvent, ([&c, &s, cl](uchar * readed, int size){
|
||||
CONNECTL(cl, threadedReadEvent, ([&c, &s, cl, &rnd](uchar * readed, int size){
|
||||
PIByteArray ba(readed, size);
|
||||
PIString str = PIString(ba);
|
||||
piCout << "[Server] data from" << cl << ":" << str;
|
||||
if (str == "ping") cl->write(PIString("pong").toByteArray());
|
||||
if (str == "ping") {
|
||||
cl->write(PIString("pong").toByteArray());
|
||||
cl->write(rnd);
|
||||
}
|
||||
}));
|
||||
CONNECTL(cl, closed, ([&clients, cl](){
|
||||
cl->stop();
|
||||
|
||||
@@ -22,5 +22,6 @@ if (NOT DEFINED ANDROID_PLATFORM)
|
||||
DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DESTINATION ${ROOT_DIR}/release
|
||||
DEB_ADD_SERVICE
|
||||
ADD_MANIFEST
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -4,9 +4,12 @@ CloudServer::CloudServer(DispatcherClient * c, const PIByteArray & sname) : serv
|
||||
setName(sname.toHex());
|
||||
server_uuid = sname;
|
||||
CONNECTL(c, dataReadedServer, ([this](uint id, PIByteArray & ba){
|
||||
last_ping.reset();
|
||||
DispatcherClient * cl = index_clients.value(id, nullptr);
|
||||
if (cl) cl->sendData(ba);
|
||||
}));
|
||||
CONNECTL(c, pingReceived, [this]() {last_ping.reset();});
|
||||
last_ping.reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,20 +26,21 @@ PIByteArray CloudServer::serverUUID() const {
|
||||
|
||||
|
||||
void CloudServer::addClient(DispatcherClient * c) {
|
||||
last_ping.reset();
|
||||
clients << c;
|
||||
index_clients.insert(c->clientId(), c);
|
||||
uint cid = c->clientId();
|
||||
index_clients.insert(cid, c);
|
||||
c->sendConnected(1);
|
||||
server->sendConnected(c->clientId());
|
||||
CONNECTL(c, dataReaded, ([this, c](PIByteArray & ba){
|
||||
server->sendConnected(cid);
|
||||
CONNECTL(c, dataReaded, ([this, cid](PIByteArray & ba){
|
||||
// piCoutObj << c->clientId() << "dataReaded";
|
||||
if (clients.contains(c)) {
|
||||
server->sendDataToClient(ba, c->clientId());
|
||||
}
|
||||
server->sendDataToClient(ba, cid);
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
void CloudServer::removeClient(DispatcherClient * c) {
|
||||
last_ping.reset();
|
||||
clients.removeOne(c);
|
||||
index_clients.removeOne(c->clientId());
|
||||
server->sendDisconnected(c->clientId());
|
||||
@@ -48,6 +52,11 @@ PIVector<DispatcherClient *> CloudServer::getClients() {
|
||||
}
|
||||
|
||||
|
||||
double CloudServer::lastPing() {
|
||||
return last_ping.elapsed_s();
|
||||
}
|
||||
|
||||
|
||||
void CloudServer::printStatus() {
|
||||
piCout << " " << "Clients for" << server->address() << server_uuid.toHex() << ":";
|
||||
for (auto c: clients) {
|
||||
|
||||
@@ -15,12 +15,14 @@ public:
|
||||
PIVector<DispatcherClient*> getClients();
|
||||
EVENT_HANDLER0(void, printStatus);
|
||||
const DispatcherClient * getConnection() const {return server;}
|
||||
double lastPing();
|
||||
|
||||
private:
|
||||
DispatcherClient * server;
|
||||
PIVector<DispatcherClient*> clients;
|
||||
PIMap<uint, DispatcherClient*> index_clients;
|
||||
PIByteArray server_uuid;
|
||||
PITimeMeasurer last_ping;
|
||||
};
|
||||
|
||||
#endif // CLOUDSERVER_H
|
||||
|
||||
@@ -6,7 +6,7 @@ DispatcherClient::DispatcherClient(PIEthernet * eth_, int id) : authorised(false
|
||||
CONNECTU(&disconnect_tm, tickEvent, eth, close);
|
||||
CONNECTU(&streampacker, packetReceiveEvent, this, readed);
|
||||
CONNECTU(eth, disconnected, this, disconnected);
|
||||
piCoutObj << "client connected" << eth->sendAddress();
|
||||
piCoutObj << "client connected" << client_id << eth->sendAddress();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,13 @@ PIString DispatcherClient::address() {
|
||||
}
|
||||
|
||||
void DispatcherClient::close() {
|
||||
static_cast<PIThread*>(eth)->stop(false);
|
||||
eth->close();
|
||||
}
|
||||
|
||||
|
||||
void DispatcherClient::terminate() {
|
||||
eth->stop();
|
||||
eth->close();
|
||||
}
|
||||
|
||||
@@ -65,10 +72,11 @@ void DispatcherClient::disconnected(bool withError) {
|
||||
|
||||
|
||||
void DispatcherClient::readed(PIByteArray & ba) {
|
||||
// piCout << size;
|
||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
||||
// piCoutObj << "readed" << hdr.first << hdr.second;
|
||||
if (hdr.first == PICloud::TCP::InvalidType) {
|
||||
disconnected(true);
|
||||
piCoutObj << "invalid message";
|
||||
return;
|
||||
}
|
||||
if (authorised) {
|
||||
@@ -80,10 +88,9 @@ void DispatcherClient::readed(PIByteArray & ba) {
|
||||
disconnected(false);
|
||||
return;
|
||||
case PICloud::TCP::Data:
|
||||
// piCoutObj << "TCP::Data";
|
||||
//piCoutObj << "TCP::Data" << tcp.role();
|
||||
if (tcp.role() == PICloud::TCP::Client) {
|
||||
PIByteArray data = tcp.parseData(ba);
|
||||
if (!data.isEmpty()) dataReaded(data);
|
||||
if (tcp.canParseData(ba)) dataReaded(ba);
|
||||
else piCoutObj << "invalid data from client";
|
||||
}
|
||||
if (tcp.role() == PICloud::TCP::Server) {
|
||||
@@ -92,11 +99,15 @@ void DispatcherClient::readed(PIByteArray & ba) {
|
||||
else piCoutObj << "invalid data from server";
|
||||
}
|
||||
return;
|
||||
case PICloud::TCP::Ping:
|
||||
pingReceived();
|
||||
return;
|
||||
default:
|
||||
piCoutObj << "unknown data";
|
||||
//disconnected(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else piCoutObj << "invalid role";
|
||||
} else {
|
||||
switch (hdr.first) {
|
||||
case PICloud::TCP::Connect: {
|
||||
@@ -104,7 +115,8 @@ void DispatcherClient::readed(PIByteArray & ba) {
|
||||
PIByteArray sn = tcp.parseConnect_d(ba);
|
||||
if (hdr.second == PICloud::TCP::Server) registerServer(sn, this);
|
||||
if (hdr.second == PICloud::TCP::Client) registerClient(sn, this);
|
||||
return;}
|
||||
return;
|
||||
}
|
||||
case PICloud::TCP::Disconnect:
|
||||
disconnected(false);
|
||||
return;
|
||||
|
||||
@@ -13,6 +13,7 @@ public:
|
||||
~DispatcherClient();
|
||||
void start();
|
||||
void close();
|
||||
void terminate();
|
||||
void sendConnected(uint client_id);
|
||||
void sendDisconnected(uint client_id);
|
||||
void sendData(const PIByteArray & data);
|
||||
@@ -27,6 +28,7 @@ public:
|
||||
EVENT2(registerClient, const PIByteArray &, sname, DispatcherClient *, client)
|
||||
EVENT1(dataReaded, PIByteArray &, ba)
|
||||
EVENT2(dataReadedServer, uint, id, PIByteArray &, ba)
|
||||
EVENT0(pingReceived)
|
||||
|
||||
private:
|
||||
EVENT_HANDLER1(void, readed, PIByteArray &, data);
|
||||
|
||||
@@ -7,6 +7,7 @@ DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::T
|
||||
max_connections = 1000;
|
||||
eth.setParameter(PIEthernet::ReuseAddress);
|
||||
eth.setReadAddress(addr);
|
||||
// eth.setDebug(false);
|
||||
CONNECTU(ð, newConnection, this, newConnection);
|
||||
CONNECTU(&timeout_timer, tickEvent, this, cleanClients);
|
||||
}
|
||||
@@ -43,22 +44,38 @@ void DispatcherServer::picoutStatus() {
|
||||
|
||||
|
||||
void DispatcherServer::cleanClients() {
|
||||
PIVector<DispatcherClient*> rm;
|
||||
map_mutex.lock();
|
||||
for (auto c: rmrf_clients) {
|
||||
delete c;
|
||||
}
|
||||
rmrf_clients.clear();
|
||||
for (auto c: clients) {
|
||||
if (!index_c_servers.contains(c) && !index_c_clients.contains(c)) {
|
||||
if (rm_clients.contains(c)) rm << c;
|
||||
else rm_clients << c;
|
||||
if (!rm_clients.contains(c)) rm_clients << c;
|
||||
} else rm_clients.removeAll(c);
|
||||
}
|
||||
auto ss = c_servers.values();
|
||||
for (auto c: ss) {
|
||||
if (c->lastPing() > 15.0) {
|
||||
piCout << "remove Server by ping timeout" << c->getConnection()->clientId();
|
||||
rmrf_clients << const_cast<DispatcherClient *>(c->getConnection());
|
||||
}
|
||||
}
|
||||
for (auto c: rm_clients) {
|
||||
if (clients.contains(c)) rm << c;
|
||||
if (clients.contains(c)) {
|
||||
rmrf_clients << c;
|
||||
}
|
||||
}
|
||||
for (auto c: rmrf_clients) {
|
||||
clients.removeAll(c);
|
||||
if(index_c_servers.contains(c)) {
|
||||
c_servers.remove(c_servers.key(index_c_servers[c]));
|
||||
index_c_servers.remove(c);
|
||||
}
|
||||
index_c_clients.remove(c);
|
||||
rm_clients.removeAll(c);
|
||||
}
|
||||
map_mutex.unlock();
|
||||
for (auto c: rm) {
|
||||
c->close();
|
||||
// c->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +100,12 @@ void DispatcherServer::updateConnectionsTile(TileList * tl) {
|
||||
}
|
||||
tl->content << TileList::Row(c->address() + " " + role, PIScreenTypes::CellFormat());
|
||||
}
|
||||
for (auto c: rm_clients) {
|
||||
tl->content << TileList::Row("[deleting]" + c->address(), PIScreenTypes::CellFormat());
|
||||
}
|
||||
for (auto c: rmrf_clients) {
|
||||
tl->content << TileList::Row("[NULL]" + c->address(), PIScreenTypes::CellFormat());
|
||||
}
|
||||
map_mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -158,37 +181,39 @@ void DispatcherServer::disconnectClient(DispatcherClient *client) {
|
||||
//piCoutObj << "INVALID client" << client;
|
||||
return;
|
||||
}
|
||||
piCoutObj << "remove client" << client->clientId();
|
||||
piCoutObj << "remove" << client->clientId();
|
||||
map_mutex.lock();
|
||||
clients.removeOne(client);
|
||||
clients.removeAll(client);
|
||||
rm_clients.removeAll(client);
|
||||
CloudServer * cs = index_c_servers.value(client, nullptr);
|
||||
if (cs) {
|
||||
piCoutObj << "remove Server" << client->clientId();
|
||||
PIVector<DispatcherClient *> cscv = cs->getClients();
|
||||
for(auto csc : cscv) {
|
||||
clients.removeOne(csc);
|
||||
index_c_clients.removeOne(csc);
|
||||
clients.removeAll(csc);
|
||||
index_c_clients.remove(csc);
|
||||
cs->removeClient(csc);
|
||||
csc->close();
|
||||
csc->deleteLater();
|
||||
rmrf_clients << csc;
|
||||
}
|
||||
c_servers.remove(cs->serverUUID());
|
||||
index_c_servers.removeOne(client);
|
||||
index_c_servers.remove(client);
|
||||
delete cs;
|
||||
}
|
||||
CloudServer * cc = index_c_clients.value(client, nullptr);
|
||||
if (cc) {
|
||||
piCoutObj << "remove Client" << client->clientId();
|
||||
cc->removeClient(client);
|
||||
index_c_clients.removeOne(client);
|
||||
index_c_clients.remove(client);
|
||||
}
|
||||
client->close();
|
||||
rmrf_clients << client;
|
||||
map_mutex.unlock();
|
||||
client->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void DispatcherServer::newConnection(PIEthernet *cl) {
|
||||
if (clients.size_s() >= max_connections) {
|
||||
cl->close();
|
||||
if (clients.size() >= max_connections) {
|
||||
delete cl;
|
||||
return;
|
||||
}
|
||||
@@ -199,6 +224,7 @@ void DispatcherServer::newConnection(PIEthernet *cl) {
|
||||
CloudServer * cs = c_servers.value(sname, nullptr);
|
||||
if (cs) {
|
||||
rm_clients << c;
|
||||
piCoutObj << "dublicate Server ->" << sname.toHex();
|
||||
} else {
|
||||
piCoutObj << "add new Server ->" << sname.toHex();
|
||||
CloudServer * cs = new CloudServer(c, sname);
|
||||
@@ -213,11 +239,12 @@ void DispatcherServer::newConnection(PIEthernet *cl) {
|
||||
CloudServer * cs = c_servers.value(sname, nullptr);
|
||||
if (cs) {
|
||||
piCoutObj << "add new Client to Server ->" << sname.toHex();
|
||||
c->authorise(true);
|
||||
cs->addClient(c);
|
||||
index_c_clients.insert(c, cs);
|
||||
c->authorise(true);
|
||||
} else {
|
||||
rm_clients << c;
|
||||
piCoutObj << "Client can't connect to Server ->" << sname.toHex();
|
||||
}
|
||||
map_mutex.unlock();
|
||||
});
|
||||
|
||||
@@ -34,6 +34,7 @@ private:
|
||||
PIMap<const DispatcherClient *, CloudServer *> index_c_servers;
|
||||
PIMap<const DispatcherClient *, CloudServer *> index_c_clients;
|
||||
PIVector<DispatcherClient*> rm_clients;
|
||||
PIVector<DispatcherClient*> rmrf_clients;
|
||||
PITimer timeout_timer;
|
||||
PIMutex map_mutex;
|
||||
uint client_gid;
|
||||
|
||||
Reference in New Issue
Block a user