27 Commits

Author SHA1 Message Date
3b0a1c70fe documentation fix 2021-09-03 17:12:46 +03:00
186e07e45d PICodeInfo::EnumInfo toPIVariantEnum 2021-09-03 16:19:57 +03:00
047cff7d6e version 2021-09-03 12:42:29 +03:00
305275e3ac PICodeParser namespaces fix 2021-09-03 11:39:26 +03:00
efb0d5f4f9 PICodeParser predefined PIP macros 2021-09-03 11:20:38 +03:00
991a074538 version 2.30
PIStreamPacker remove progresses
picloud various fixes
2021-09-01 23:48:13 +03:00
f82b6c12ee cloud_dispatcher patch 2021-09-01 22:43:40 +03:00
00edfa4ef0 cloud data send optimize 2021-09-01 17:48:58 +03:00
35a3ce6402 picloudtcp.cpp revert some mutex 2021-09-01 10:56:11 +03:00
be3ce454a0 picloud multithread fix 2021-08-31 19:40:22 +03:00
4c85206cfa version 2021-08-23 14:07:45 +03:00
5ecdcbe46e Merge pull request 'cloud_debug' (#78) from cloud_debug into master
Reviewed-on: https://git.shs.tools/SHS/pip/pulls/78
2021-08-23 13:58:08 +03:00
c937d7251a it works 2021-08-23 13:56:21 +03:00
1cc46468c1 fail 2021-08-20 18:30:19 +03:00
5cc8ef1eb0 fail reconnect 2021-08-20 18:25:59 +03:00
99e135caa2 PICloudClient disconnect 2021-08-20 17:22:25 +03:00
9de7045d63 picloud revert to condvars and fix 2021-08-20 16:36:28 +03:00
0e65151e9f PIEthernet error 232
PICloud many fixes
PIBroadcast recursive fix
2021-08-20 10:55:47 +03:00
3c20728210 version 2021-08-19 18:29:05 +03:00
4c0530d89a picloud ping and fix big bugs 2021-08-19 18:13:05 +03:00
f5af8a1da9 disable autostart pibroadcast 2021-08-19 15:02:30 +03:00
44b9c37391 PICloudClient now soft stop thread when closed
last cmake changes
2021-08-16 22:30:56 +03:00
97b0b6fc0c picloud hash key 2021-08-12 22:05:02 +03:00
1a2e9afaef PIVector compare operators 2021-08-12 21:52:14 +03:00
39a3a23a24 PIByteArray compare operators 2021-08-12 21:41:22 +03:00
ee131921a0 add PIByteArray operator <, fix picloud 2021-08-12 20:22:43 +03:00
f8818c8537 picloud patch 2021-08-12 19:50:17 +03:00
35 changed files with 419 additions and 261 deletions

View File

@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip) project(pip)
set(pip_MAJOR 2) set(pip_MAJOR 2)
set(pip_MINOR 28) set(pip_MINOR 31)
set(pip_REVISION 1) set(pip_REVISION 0)
set(pip_SUFFIX ) set(pip_SUFFIX )
set(pip_COMPANY SHS) set(pip_COMPANY SHS)
set(pip_DOMAIN org.SHS) set(pip_DOMAIN org.SHS)
@@ -284,7 +284,7 @@ endif()
if(APPLE) if(APPLE)
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE) add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
endif() 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) include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include)
#message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include") #message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include")
#message("${ANDROID_NDK}/sysroot/usr/include") #message("${ANDROID_NDK}/sysroot/usr/include")
@@ -567,8 +567,8 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
list(APPEND DOXY_INPUT "\"${F}\"") list(APPEND DOXY_INPUT "\"${F}\"")
endforeach(F) endforeach(F)
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"") string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"")
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}") string(REPLACE ";" " " DOXY_INCLUDE_PATH "${PIP_INCLUDES}")
string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS") string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS}")
add_documentation(doc doc/Doxyfile.in) add_documentation(doc doc/Doxyfile.in)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL)
endif() endif()

View File

@@ -2164,7 +2164,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = ${DOXY_DEFINES} PREDEFINED = DOXYGEN PIOBJECT PIOBJECT_SUBCLASS PIIODEVICE NO_COPY_CLASS ${DOXY_DEFINES}
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this

View File

@@ -2,7 +2,7 @@
PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(&eth), tcp(&streampacker) { PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(&eth), tcp(&streampacker) {
eth.setDebug(false);
} }

View File

@@ -25,29 +25,36 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode)
tcp.setRole(PICloud::TCP::Client); tcp.setRole(PICloud::TCP::Client);
setName("cloud_client"); setName("cloud_client");
is_connected = false; is_connected = false;
CONNECTL(&eth, connected, [this](){tcp.sendStart();}); is_deleted = false;
// setReopenEnabled(false);
CONNECTL(&eth, connected, [this](){opened_ = true; tcp.sendStart();});
CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
CONNECTL(&eth, disconnected, [this](bool){ CONNECTL(&eth, disconnected, [this](bool){
piCoutObj << "disconnected"; if (is_deleted) return;
bool need_disconn = is_connected;
//piCoutObj << "eth disconnected";
static_cast<PIThread*>(&eth)->stop();
opened_ = false; opened_ = false;
is_connected = false; internalDisconnect();
cond_connect.notifyOne(); if (need_disconn)
cond_buff.notifyOne(); disconnected();
piMSleep(100); //piCoutObj << "eth disconnected done";
}); });
} }
PICloudClient::~PICloudClient() { PICloudClient::~PICloudClient() {
eth.close(); //piCoutObj << "~PICloudClient()";
if (is_connected) { PIThread::stop();
is_connected = false; //eth.close();
disconnected(); //if (is_connected) disconnected();
cond_buff.notifyOne();
cond_connect.notifyOne();
}
close(); 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() { bool PICloudClient::openDevice() {
// piCout << "PICloudClient open device" << path(); //piCoutObj << "open";// << path();
bool op = eth.connect(PIEthernet::Address::resolve(path()), false); bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
if (op) { if (op) {
mutex_buff.lock(); mutex_connect.lock();
eth.startThreadedRead(); eth.startThreadedRead();
bool conn_ok = cond_connect.waitFor(mutex_buff, (int)eth.readTimeout(), [this](){return isConnected();}); //piCoutObj << "connecting...";
piCoutObj << "conn_ok" << conn_ok; bool conn_ok = cond_connect.waitFor(mutex_connect, (int)eth.readTimeout());
mutex_buff.unlock(); //piCoutObj << "conn_ok" << conn_ok << is_connected;
mutex_connect.unlock();
if (!conn_ok) { if (!conn_ok) {
mutex_connect.lock();
eth.stop(); eth.stop();
eth.close(); eth.close();
piMSleep(100); mutex_connect.unlock();
} }
return isConnected(); return is_connected;
} else { } else {
eth.close(); //eth.close();
return false; return false;
} }
} }
bool PICloudClient::closeDevice() { bool PICloudClient::closeDevice() {
//PIThread::stop();
if (is_connected) { if (is_connected) {
is_connected = false; internalDisconnect();
disconnected();
cond_buff.notifyOne();
cond_connect.notifyOne();
} }
eth.stop(); eth.stop();
if (eth.isOpened()) eth.close(); eth.close();
return true; return true;
} }
int PICloudClient::readDevice(void * read_to, int max_size) { int PICloudClient::readDevice(void * read_to, int max_size) {
if (is_deleted) return -1;
//piCoutObj << "readDevice"; //piCoutObj << "readDevice";
if (!is_connected) return -1; if (!is_connected && eth.isClosed()) openDevice();
int sz = -1;
mutex_buff.lock(); mutex_buff.lock();
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();}); cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
int sz = piMini(max_size, buff.size()); if (is_connected) {
sz = piMini(max_size, buff.size());
memcpy(read_to, buff.data(), sz); memcpy(read_to, buff.data(), sz);
buff.remove(0, sz); buff.remove(0, sz);
}
mutex_buff.unlock(); mutex_buff.unlock();
if (!is_connected) opened_ = false;
//piCoutObj << "readDevice done" << sz;
return sz; return sz;
} }
int PICloudClient::writeDevice(const void * data, int size) { int PICloudClient::writeDevice(const void * data, int size) {
if (is_deleted) return -1;
// piCoutObj << "writeDevice"; // piCoutObj << "writeDevice";
return tcp.sendData(PIByteArray(data, size)); 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) { void PICloudClient::_readed(PIByteArray & ba) {
mutex_buff.lock(); if (is_deleted) return;
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
//piCoutObj << "_readed" << ba.size() << hdr.first << hdr.second;
if (hdr.second == tcp.role()) { if (hdr.second == tcp.role()) {
switch (hdr.first) { switch (hdr.first) {
case PICloud::TCP::Connect: case PICloud::TCP::Connect:
if (tcp.parseConnect(ba) == 1) { if (tcp.parseConnect(ba) == 1) {
mutex_connect.lock();
is_connected = true; is_connected = true;
connected(); mutex_connect.unlock();
cond_connect.notifyOne(); cond_connect.notifyOne();
connected();
} }
break; break;
case PICloud::TCP::Disconnect: case PICloud::TCP::Disconnect:
is_connected = false; static_cast<PIThread*>(&eth)->stop();
eth.stop(); opened_ = false;
eth.close(); eth.close();
disconnected();
break; break;
case PICloud::TCP::Data: case PICloud::TCP::Data:
if (is_connected) { if (is_connected) {
mutex_buff.lock();
buff.append(ba); buff.append(ba);
mutex_buff.unlock();
cond_buff.notifyOne(); cond_buff.notifyOne();
} }
break; break;
@@ -145,7 +172,7 @@ void PICloudClient::_readed(PIByteArray & ba) {
} }
//piCoutObj << "readed" << ba.toHex(); //piCoutObj << "readed" << ba.toHex();
} }
mutex_buff.unlock(); while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); // FIXME: sleep here is bad
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); //piCoutObj << "_readed done";
} }

View File

@@ -26,12 +26,17 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode)
tcp.setServerName(server_name); tcp.setServerName(server_name);
setName("cloud_server__" + server_name); setName("cloud_server__" + server_name);
CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
CONNECTL(&eth, connected, [this](){tcp.sendStart();}); CONNECTL(&eth, connected, [this](){opened_ = true; piCoutObj << "connected"; tcp.sendStart();});
CONNECTL(&eth, disconnected, [this](bool){ CONNECTL(&eth, disconnected, [this](bool){
piCoutObj << "disconnected"; piCoutObj << "disconnected";
static_cast<PIThread*>(&eth)->stop();
opened_ = false; opened_ = false;
ping_timer.stop(false);
piMSleep(100); 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() { bool PICloudServer::openDevice() {
piCout << "PICloudServer open device" << path(); //piCout << "PICloudServer open device" << path();
bool op = eth.connect(PIEthernet::Address::resolve(path()), false); bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
if (op) { if (op) {
eth.startThreadedRead(); eth.startThreadedRead();
ping_timer.start(5000);
return true; return true;
} }
ping_timer.stop(false);
eth.close(); eth.close();
return false; return false;
} }
@@ -67,6 +74,7 @@ bool PICloudServer::openDevice() {
bool PICloudServer::closeDevice() { bool PICloudServer::closeDevice() {
eth.stop(); eth.stop();
ping_timer.stop(false);
clients_mutex.lock(); clients_mutex.lock();
for (auto c : clients_) { for (auto c : clients_) {
c->close(); c->close();
@@ -82,7 +90,8 @@ bool PICloudServer::closeDevice() {
int PICloudServer::readDevice(void * read_to, int max_size) { int PICloudServer::readDevice(void * read_to, int max_size) {
//piCoutObj << "readDevice"; //piCoutObj << "readDevice";
piMSleep(eth.readTimeout()); if (!opened_) openDevice();
else piMSleep(eth.readTimeout());
return -1; return -1;
} }
@@ -126,22 +135,26 @@ bool PICloudServer::Client::openDevice() {
bool PICloudServer::Client::closeDevice() { bool PICloudServer::Client::closeDevice() {
PIThread::stop(false);
if (is_connected) { if (is_connected) {
server->clientDisconnect(client_id); server->clientDisconnect(client_id);
is_connected = false; is_connected = false;
cond_buff.notifyOne();
} }
cond_buff.notifyOne();
return true; return true;
} }
int PICloudServer::Client::readDevice(void * read_to, int max_size) { int PICloudServer::Client::readDevice(void * read_to, int max_size) {
if (!is_connected) return -1; if (!is_connected) return -1;
int sz = -1;
mutex_buff.lock(); mutex_buff.lock();
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();}); cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
int sz = piMini(max_size, buff.size()); if (is_connected) {
sz = piMini(max_size, buff.size());
memcpy(read_to, buff.data(), sz); memcpy(read_to, buff.data(), sz);
buff.remove(0, sz); buff.remove(0, sz);
}
mutex_buff.unlock(); mutex_buff.unlock();
return sz; return sz;
} }
@@ -158,7 +171,7 @@ void PICloudServer::Client::pushBuffer(const PIByteArray & ba) {
buff.append(ba); buff.append(ba);
cond_buff.notifyOne(); cond_buff.notifyOne();
mutex_buff.unlock(); 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) { if (oc) {
tcp.sendDisconnected(id); tcp.sendDisconnected(id);
} else { } else {
piCoutObj << "new Client" << id; //piCoutObj << "new Client" << id;
Client * c = new Client(this, id); Client * c = new Client(this, id);
CONNECTU(c, deleted, this, clientDeleted); CONNECTU(c, deleted, this, clientDeleted);
clients_mutex.lock(); clients_mutex.lock();
@@ -186,7 +199,7 @@ void PICloudServer::_readed(PIByteArray & ba) {
} break; } break;
case PICloud::TCP::Disconnect: { case PICloud::TCP::Disconnect: {
uint id = tcp.parseDisconnect(ba); uint id = tcp.parseDisconnect(ba);
piCoutObj << "remove Client" << id; //piCoutObj << "remove Client" << id;
clients_mutex.lock(); clients_mutex.lock();
Client * oc = index_clients.value(id, nullptr); Client * oc = index_clients.value(id, nullptr);
clients_mutex.unlock(); clients_mutex.unlock();

View File

@@ -24,7 +24,7 @@
#include "pistreampacker.h" #include "pistreampacker.h"
const char hash_def_key[] = "_picrypt_"; const char hash_cloud_key[] = "_picloud_";
PICloud::TCP::Header::Header() { PICloud::TCP::Header::Header() {
@@ -33,7 +33,7 @@ PICloud::TCP::Header::Header() {
PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) { PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) {
streampacker->setMaxPacketSize(63*1024);
} }
void PICloud::TCP::setRole(PICloud::TCP::Role r) { 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_) { void PICloud::TCP::setServerName(const PIString & server_name_) {
server_name = 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; PIByteArray ba;
ba << header; ba << header;
ba.append(suuid); ba.append(suuid);
//mutex_send.lock();
streampacker->send(ba); streampacker->send(ba);
//mutex_send.unlock();
} }
@@ -70,7 +72,9 @@ void PICloud::TCP::sendConnected(uint client_id) {
header.type = PICloud::TCP::Connect; header.type = PICloud::TCP::Connect;
PIByteArray ba; PIByteArray ba;
ba << header << client_id; ba << header << client_id;
// mutex_send.lock();
streampacker->send(ba); streampacker->send(ba);
// mutex_send.unlock();
} }
@@ -78,7 +82,9 @@ void PICloud::TCP::sendDisconnected(uint client_id) {
header.type = PICloud::TCP::Disconnect; header.type = PICloud::TCP::Disconnect;
PIByteArray ba; PIByteArray ba;
ba << header << client_id; ba << header << client_id;
// mutex_send.lock();
streampacker->send(ba); streampacker->send(ba);
// mutex_send.unlock();
} }
@@ -87,8 +93,10 @@ int PICloud::TCP::sendData(const PIByteArray & data) {
PIByteArray ba; PIByteArray ba;
ba << header; ba << header;
ba.append(data); ba.append(data);
// piCout << "sendData" << ba.toHex(); // piCout << "[PICloud::TCP] sendData" << ba.toHex();
mutex_send.lock();
streampacker->send(ba); streampacker->send(ba);
mutex_send.unlock();
return data.size_s(); return data.size_s();
} }
@@ -98,11 +106,24 @@ int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) {
PIByteArray ba; PIByteArray ba;
ba << header << client_id; ba << header << client_id;
ba.append(data); ba.append(data);
mutex_send.lock();
streampacker->send(ba); streampacker->send(ba);
mutex_send.unlock();
return data.size_s(); 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> PICloud::TCP::parseHeader(PIByteArray & ba) {
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret; PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret;
ret.first = InvalidType; ret.first = InvalidType;
@@ -120,11 +141,8 @@ PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteA
} }
PIByteArray PICloud::TCP::parseData(PIByteArray & ba) { bool PICloud::TCP::canParseData(PIByteArray & ba) {
if (header.role == Client) { return header.role == Client;
return ba;
}
return PIByteArray();
} }
@@ -133,7 +151,7 @@ PIPair<uint, PIByteArray> PICloud::TCP::parseDataServer(PIByteArray & ba) {
ret.first = 0; ret.first = 0;
if (header.role == Server) { if (header.role == Server) {
ba >> ret.first; ba >> ret.first;
ret.second = ba; ret.second.swap(ba);
} }
return ret; return ret;
} }

View File

@@ -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() { size_t PICrypt::sizeHash() {
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
return crypto_generichash_BYTES; return crypto_generichash_BYTES;

View File

@@ -53,8 +53,6 @@ PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() {
_started = false; _started = false;
_send_only = send_only; _send_only = send_only;
_reinit = true; _reinit = true;
//initMcast(PIEthernet::allAddresses());
PIThread::start(3000);
} }
@@ -140,7 +138,6 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
piForeachC (PIEthernet::Address & a, al) { piForeachC (PIEthernet::Address & a, al) {
PIEthernet * ce = 0; PIEthernet * ce = 0;
//piCout << "mcast try" << a; //piCout << "mcast try" << a;
if (_channels[Multicast]) { if (_channels[Multicast]) {
ce = new PIEthernet(); ce = new PIEthernet();
ce->setDebug(false); ce->setDebug(false);
@@ -184,7 +181,6 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
eth_mcast << ce; eth_mcast << ce;
} }
} }
} }
if (_channels[Loopback]) { if (_channels[Loopback]) {
@@ -207,11 +203,14 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
void PIBroadcast::send(const PIByteArray & data) { void PIBroadcast::send(const PIByteArray & data) {
if (!isRunning()) {
reinit();
PIThread::start(3000);
}
PIByteArray cd = cryptData(data); PIByteArray cd = cryptData(data);
if (cd.isEmpty()) return; if (cd.isEmpty()) return;
PIMutexLocker ml(mcast_mutex); PIMutexLocker ml(mcast_mutex);
piForeach (PIEthernet * e, eth_mcast) piForeach (PIEthernet * e, eth_mcast) e->send(cd);
e->send(cd);
if (eth_lo) { if (eth_lo) {
for (int i = 0; i < lo_pcnt; ++i) { for (int i = 0; i < lo_pcnt; ++i) {
eth_lo->send("127.0.0.1", lo_port + i, cd); eth_lo->send("127.0.0.1", lo_port + i, cd);
@@ -221,30 +220,31 @@ void PIBroadcast::send(const PIByteArray & data) {
void PIBroadcast::startRead() { void PIBroadcast::startRead() {
if (!isRunning()) {
_started = false;
reinit();
PIThread::start(3000);
}
if (_send_only) return; if (_send_only) return;
PIMutexLocker ml(mcast_mutex); PIMutexLocker ml(mcast_mutex);
piForeach (PIEthernet * e, eth_mcast) piForeach (PIEthernet * e, eth_mcast) e->startThreadedRead();
e->startThreadedRead(); if (eth_lo) eth_lo->startThreadedRead();
if (eth_lo)
eth_lo->startThreadedRead();
_started = true; _started = true;
} }
void PIBroadcast::stopRead() { void PIBroadcast::stopRead() {
if (isRunning()) stop();
PIMutexLocker ml(mcast_mutex); PIMutexLocker ml(mcast_mutex);
piForeach (PIEthernet * e, eth_mcast) piForeach (PIEthernet * e, eth_mcast) e->stopThreadedRead();
e->stopThreadedRead(); if (eth_lo) eth_lo->stopThreadedRead();
if (eth_lo)
eth_lo->stopThreadedRead();
_started = false; _started = false;
} }
void PIBroadcast::reinit() { void PIBroadcast::reinit() {
initAll(PIEthernet::allAddresses()); initAll(PIEthernet::allAddresses());
if (_started) if (_started) startRead();
startRead();
} }
@@ -261,8 +261,6 @@ void PIBroadcast::run() {
mcast_mutex.lock(); mcast_mutex.lock();
bool r = _reinit, ac = (al != prev_al); bool r = _reinit, ac = (al != prev_al);
mcast_mutex.unlock(); mcast_mutex.unlock();
if (ac || r) if (ac || r) reinit();
reinit(); if (ac) addressesChanged();
if (ac)
addressesChanged();
} }

View File

@@ -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) { void PIStreamPacker::send(const PIByteArray & data) {
if (data.isEmpty()) return; if (data.isEmpty()) return;
PIByteArray cd; PIByteArray cd;
@@ -94,31 +101,12 @@ void PIStreamPacker::send(const PIByteArray & data) {
hdr << int(cd.size_s()); hdr << int(cd.size_s());
cd.insert(0, hdr); cd.insert(0, hdr);
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0; 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) { for (int i = 0; i < pcnt; ++i) {
if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst); if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst);
else part = PIByteArray(cd.data(pst), max_packet_size); else part = PIByteArray(cd.data(pst), max_packet_size);
//piCout << "send" << part.size(); //piCout << "send" << part.size();
sendRequest(part); sendRequest(part);
pst += max_packet_size; 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; packet_size = sz;
if (packet_size == 0) if (packet_size == 0)
packet_size = -1; 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; continue;
} else { } else {
int ps = piMini(stream.size_s(), packet_size - packet.size_s()); int ps = piMini(stream.size_s(), packet_size - packet.size_s());
packet.append(stream.data(), ps); 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); stream.remove(0, ps);
if (packet.size_s() == packet_size) { if (packet.size_s() == packet_size) {
PIByteArray cd; PIByteArray cd;
@@ -211,9 +187,6 @@ void PIStreamPacker::received(const PIByteArray & data) {
} }
packet.clear(); packet.clear();
packet_size = -1; 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(dev, threadedReadEvent, this, received);
CONNECTU(this, sendRequest, dev, write); 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.;
}

View File

@@ -52,12 +52,15 @@ protected:
private: private:
EVENT_HANDLER1(void, _readed, PIByteArray &, data); EVENT_HANDLER1(void, _readed, PIByteArray &, data);
void internalDisconnect();
PIByteArray buff; PIByteArray buff;
PIMutex mutex_buff; PIMutex mutex_buff;
PIMutex mutex_connect; PIMutex mutex_connect;
PIConditionVariable cond_buff; PIConditionVariable cond_buff;
PIConditionVariable cond_connect; PIConditionVariable cond_connect;
std::atomic_bool is_connected; std::atomic_bool is_connected;
std::atomic_bool is_deleted;
}; };
#endif // PICLOUDCLIENT_H #endif // PICLOUDCLIENT_H

View File

@@ -78,6 +78,7 @@ private:
PIVector<Client *> clients_; PIVector<Client *> clients_;
PIMap<uint, Client *> index_clients; PIMap<uint, Client *> index_clients;
PITimer ping_timer;
mutable PIMutex clients_mutex; mutable PIMutex clients_mutex;
}; };

View File

@@ -25,6 +25,7 @@
#include "pip_cloud_export.h" #include "pip_cloud_export.h"
#include "pistring.h" #include "pistring.h"
#include "pimutex.h"
class PIEthernet; class PIEthernet;
@@ -52,6 +53,7 @@ public:
Connect = 1, Connect = 1,
Disconnect = 2, Disconnect = 2,
Data = 3, Data = 3,
Ping = 4,
}; };
TCP(PIStreamPacker * s); TCP(PIStreamPacker * s);
@@ -65,8 +67,9 @@ public:
void sendDisconnected(uint client_id); void sendDisconnected(uint client_id);
int sendData(const PIByteArray & data); int sendData(const PIByteArray & data);
int sendData(const PIByteArray & data, uint client_id); int sendData(const PIByteArray & data, uint client_id);
void sendPing();
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
PIByteArray parseData(PIByteArray & ba); bool canParseData(PIByteArray & ba);
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba); PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
PIByteArray parseConnect_d(PIByteArray & ba); PIByteArray parseConnect_d(PIByteArray & ba);
uint parseConnect(PIByteArray & ba); uint parseConnect(PIByteArray & ba);
@@ -84,6 +87,8 @@ private:
PIByteArray suuid; PIByteArray suuid;
PIString server_name; PIString server_name;
PIStreamPacker * streampacker; PIStreamPacker * streampacker;
PIMutex mutex_send;
}; };
} }

View File

@@ -37,6 +37,14 @@ int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
} }
PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() {
PIVariantTypes::Enum en(name);
for (auto m: members) en << m.toPIVariantEnumerator();
if (!en.isEmpty()) en.selectValue(members.front().value);
return en;
}
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo; PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo; PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
PIMap<PIString, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions; PIMap<PIString, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions;

View File

@@ -25,6 +25,8 @@
#define PICODEINFO_H #define PICODEINFO_H
#include "pistringlist.h" #include "pistringlist.h"
#include "pivarianttypes.h"
class PIVariant; class PIVariant;
@@ -77,6 +79,7 @@ struct PIP_EXPORT ClassInfo {
struct PIP_EXPORT EnumeratorInfo { struct PIP_EXPORT EnumeratorInfo {
EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;} EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
PIVariantTypes::Enumerator toPIVariantEnumerator() {return PIVariantTypes::Enumerator(value, name);}
MetaMap meta; MetaMap meta;
PIString name; PIString name;
int value; int value;
@@ -85,6 +88,7 @@ struct PIP_EXPORT EnumeratorInfo {
struct PIP_EXPORT EnumInfo { struct PIP_EXPORT EnumInfo {
PIString memberName(int value) const; PIString memberName(int value) const;
int memberValue(const PIString & name) const; int memberValue(const PIString & name) const;
PIVariantTypes::Enum toPIVariantEnum();
MetaMap meta; MetaMap meta;
PIString name; PIString name;
PIVector<PICodeInfo::EnumeratorInfo> members; PIVector<PICodeInfo::EnumeratorInfo> members;

View File

@@ -190,10 +190,39 @@ void PICodeParser::clear() {
piForeachC (PIString & d, defs) piForeachC (PIString & d, defs)
defines << Define(d, ""); defines << Define(d, "");
defines << Define(PIStringAscii("PICODE"), "") << custom_defines; 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("PIIODEVICE"), "", PIStringList() << "name")
<< Macro(PIStringAscii("NO_COPY_CLASS"), "", PIStringList() << "name")
<< Macro(PIStringAscii("PRIVATE_DECLARATION"))
<< 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) { bool PICodeParser::parseFileContent(PIString & fc, bool main) {
static const PIString s_ns = PIStringAscii("::");
static const PIString s_bo = PIStringAscii("{\n"); static const PIString s_bo = PIStringAscii("{\n");
static const PIString s_bc = PIStringAscii("\n}\n"); static const PIString s_bc = PIStringAscii("\n}\n");
static const PIString s_class = PIStringAscii("class"); static const PIString s_class = PIStringAscii("class");
@@ -280,7 +309,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
replaceMeta(pfc); replaceMeta(pfc);
//piCout << NewLine << "file" << cur_file << pfc; //piCout << PICoutManipulators::NewLine << "file" << cur_file << pfc;
int pl = -1; int pl = -1;
while (!pfc.isEmpty()) { while (!pfc.isEmpty()) {
pfc.trim(); pfc.trim();
@@ -288,7 +317,12 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
if (pl == nl) break; if (pl == nl) break;
pl = nl; pl = nl;
if (pfc.left(9) == s_namespace) { 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; continue;
} }
if (pfc.left(8) == s_template) { if (pfc.left(8) == s_template) {
@@ -417,7 +451,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
int ps = -1; int ps = -1;
bool def = false; bool def = false;
PIString prev_namespace = cur_namespace, stmp; 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 << "parse class" << ce->name << "namespace" << cur_namespace;
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace; //piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
while (!fc.isEmpty()) { while (!fc.isEmpty()) {
@@ -1074,9 +1108,19 @@ bool PICodeParser::parseDirective(PIString d) {
if (mname == s_PIMETA) return true; if (mname == s_PIMETA) return true;
if (d.left(1) == PIChar('(')) { // macro if (d.left(1) == PIChar('(')) { // macro
PIStringList args = d.takeRange('(', ')').split(',').trim(); 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); macros << Macro(mname, d.trim(), args);
} else { // define } else { // define
d.trim(); d.trim();
for (int i = 0; i < defines.size_s(); ++i)
if (defines[i].first == mname) {
defines.remove(i);
break;
}
defines << Define(mname, d); defines << Define(mname, d);
evaluator.setVariable(mname, complexd_1); evaluator.setVariable(mname, complexd_1);
} }

View File

@@ -25,7 +25,7 @@
#include "pithread.h" #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 class PIP_EXPORT PIKbdListener: public PIThread

View File

@@ -190,10 +190,16 @@ public:
return true; return true;
} }
inline bool operator !=(const PIDeque<T> & t) const {return !(*this == t);} 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 { inline bool operator >(const PIDeque<T> & t) const {
if (pid_size != t.pid_size) return pid_size > t.pid_size; if (pid_size != t.pid_size) return pid_size > t.pid_size;
for (size_t i = 0; i < pid_size; ++i) 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; return false;
} }
inline bool contains(const T & v) const { inline bool contains(const T & v) const {

View File

@@ -191,6 +191,18 @@ public:
return true; return true;
} }
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);} 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 { inline bool contains(const T & v) const {
for (size_t i = 0; i < piv_size; ++i) for (size_t i = 0; i < piv_size; ++i)
if (v == piv_data[i]) if (v == piv_data[i])

View File

@@ -190,34 +190,39 @@ public:
//! \relatesalso PIByteArray @brief Byte arrays compare operator //! \relatesalso PIByteArray @brief Byte arrays compare operator
inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) { inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {
if (v0.size() == v1.size()) { if (v0.size() == v1.size()) {
for (uint i = 0; i < v0.size(); ++i) if (v0.isEmpty()) return false;
if (v0[i] != v1[i]) return memcmp(v0.data(), v1.data(), v0.size()) < 0;
return v0[i] < v1[i];
return false;
} }
return v0.size() < v1.size(); return v0.size() < v1.size();
} }
//! \relatesalso PIByteArray @brief Byte arrays compare operator //! \relatesalso PIByteArray @brief Byte arrays compare operator
inline bool operator ==(PIByteArray & f, PIByteArray & s) { inline bool operator >(const PIByteArray & v0, const PIByteArray & v1) {
if (f.size_s() != s.size_s()) if (v0.size() == v1.size()) {
return false; if (v0.isEmpty()) return false;
for (int i = 0; i < f.size_s(); ++i) return memcmp(v0.data(), v1.data(), v0.size()) > 0;
if (f[i] != s[i]) }
return false; return v0.size() > v1.size();
return true;
} }
//! \relatesalso PIByteArray @brief Byte arrays compare operator //! \relatesalso PIByteArray @brief Byte arrays compare operator
inline bool operator !=(PIByteArray & f, PIByteArray & s) { inline bool operator ==(const PIByteArray & v0, const PIByteArray & v1) {
if (f.size_s() != s.size_s()) if (v0.size() == v1.size()) {
return true; if (v0.isEmpty()) return true;
for (int i = 0; i < f.size_s(); ++i) return memcmp(v0.data(), v1.data(), v0.size()) == 0;
if (f[i] != s[i]) }
return true;
return false; 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 #ifdef PIP_STD_IOSTREAM
//! \relatesalso PIByteArray @brief Output to std::ostream operator //! \relatesalso PIByteArray @brief Output to std::ostream operator
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba); inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);

View File

@@ -700,8 +700,7 @@ PIObject::Deleter::Deleter() {
stopping = started = posted = false; stopping = started = posted = false;
CONNECTL(&(PRIVATE->thread), started, [this](){proc();}); CONNECTL(&(PRIVATE->thread), started, [this](){proc();});
PRIVATE->thread.startOnce(); PRIVATE->thread.startOnce();
while (!started) while (!started) piMSleep(1);
piMSleep(1);
} }
@@ -710,8 +709,7 @@ PIObject::Deleter::~Deleter() {
stopping = true; stopping = true;
PRIVATE->cond_var.notifyAll(); PRIVATE->cond_var.notifyAll();
#ifndef WINDOWS #ifndef WINDOWS
while (PRIVATE->thread.isRunning()) while (PRIVATE->thread.isRunning()) piMSleep(1);
piMSleep(1);
#endif #endif
deleteAll(); deleteAll();
//piCout << "~Deleter ok"; //piCout << "~Deleter ok";
@@ -774,12 +772,9 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
//piCout << "[Deleter] delete" << (uintptr_t)o << "..."; //piCout << "[Deleter] delete" << (uintptr_t)o << "...";
if (o->isPIObject()) { if (o->isPIObject()) {
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ..."; //piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
while (o->isInEvent()) { while (o->isInEvent()) piMSleep(1);
piMSleep(1);
}
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done"; //piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
if (o->isPIObject()) if (o->isPIObject()) delete o;
delete o;
} }
//piCout << "[Deleter] delete" << (uintptr_t)o << "done"; //piCout << "[Deleter] delete" << (uintptr_t)o << "done";
} }

View File

@@ -99,9 +99,6 @@ struct PIP_EXPORT Enum {
* @brief Make vector of Enum names * @brief Make vector of Enum names
*/ */
PIStringList names() const; PIStringList names() const;
PIString enum_name;
PIString selected;
PIVector<Enumerator> enum_list;
/** /**
* @brief Add PIVariantTypes::Enumerator to Enum * @brief Add PIVariantTypes::Enumerator to Enum
@@ -119,6 +116,15 @@ struct PIP_EXPORT Enum {
* @brief Add PIVariantTypes::Enumerator element for each name in vector * @brief Add PIVariantTypes::Enumerator element for each name in vector
*/ */
Enum & operator <<(const PIStringList & v); Enum & operator <<(const PIStringList & v);
/**
* @brief Return true if Enum is empty
*/
bool isEmpty() const {return enum_list.isEmpty();}
PIString enum_name;
PIString selected;
PIVector<Enumerator> enum_list;
}; };
struct PIP_EXPORT File { struct PIP_EXPORT File {

View File

@@ -58,6 +58,9 @@ public:
//! Generate hash from bytearray //! Generate hash from bytearray
static PIByteArray hash(const PIByteArray & data); 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 //! Returns hash size
static size_t sizeHash(); static size_t sizeHash();

View File

@@ -181,7 +181,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
pausemutex.lock(); pausemutex.lock();
if (is_pause) { if (is_pause) {
pausemutex.unlock(); pausemutex.unlock();
piMSleep(100); piMSleep(100); // TODO: rewrite with condvar
return false; return false;
} else if (pause_time > PISystemTime()) { } else if (pause_time > PISystemTime()) {
startlogtime += pause_time; startlogtime += pause_time;
@@ -204,22 +204,22 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
int dtc; int dtc;
if (is_started) { if (is_started) {
if (is_pause) { if (is_pause) {
piMSleep(100); piMSleep(100); // TODO: rewrite with condvar
return false; return false;
} }
if (delay > 0) { if (delay > 0) {
cdelay = delay * play_speed; cdelay = delay * play_speed;// TODO: rewrite with condvar
dtc = int(cdelay) /100; dtc = int(cdelay) / 100;// TODO: rewrite with condvar
if (play_speed <= 0.) dtc = 2; if (play_speed <= 0.) dtc = 2;
//piCout << play_speed << dtc; //piCout << play_speed << dtc;
for (int j=0; j<dtc; j++) { for (int j=0; j<dtc; j++) {
cdelay = delay * play_speed; cdelay = delay * play_speed;// TODO: rewrite with condvar
dtc = int(cdelay) /100; dtc = int(cdelay) / 100;// TODO: rewrite with condvar
piMSleep(100); piMSleep(100);// TODO: rewrite with condvar
if (play_speed <= 0.) {dtc = 2; j = 0;} if (play_speed <= 0.) {dtc = 2; j = 0;}
//piCout << " " << play_speed << dtc << j; //piCout << " " << play_speed << dtc << j;
} }
cdelay = cdelay - dtc*100; cdelay = cdelay - dtc*100;// TODO: rewrite with condvar
PISystemTime::fromMilliseconds(cdelay).sleep(); PISystemTime::fromMilliseconds(cdelay).sleep();
} }
} else is_started = true; } else is_started = true;
@@ -228,7 +228,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
case PlayStaticDelay: case PlayStaticDelay:
if (is_started) { if (is_started) {
if (is_pause) { if (is_pause) {
piMSleep(100); piMSleep(100);// TODO: rewrite with condvar
return false; return false;
} }
play_delay.sleep(); play_delay.sleep();

View File

@@ -993,6 +993,7 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) {
PIEthernet::InterfaceList PIEthernet::interfaces() { PIEthernet::InterfaceList PIEthernet::interfaces() {
//piCout << "PIEthernet::interfaces()";
PIEthernet::InterfaceList il; PIEthernet::InterfaceList il;
Interface ci; Interface ci;
ci.index = -1; ci.index = -1;
@@ -1039,8 +1040,16 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
} }
pAdapter = pAdapter->Next; 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; piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
}
}
if (pAdapterInfo) if (pAdapterInfo)
HeapFree(GetProcessHeap(), 0, (pAdapterInfo)); HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
#else #else

View File

@@ -239,7 +239,7 @@ void PIIODevice::check_start(void * data, int delim) {
//cout << "check " << tread_started_ << endl; //cout << "check " << tread_started_ << endl;
if (open()) { if (open()) {
thread_started_ = true; thread_started_ = true;
timer.stop(); timer.stop(false);
} }
} }

View File

@@ -36,22 +36,6 @@ public:
//! Contructs packer and try to assign \"dev\" //! Contructs packer and try to assign \"dev\"
PIStreamPacker(PIIODevice * dev = 0); 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 //! Set maximum size of single packet
void setMaxPacketSize(int max_size) {max_packet_size = max_size;} void setMaxPacketSize(int max_size) {max_packet_size = max_size;}
@@ -83,6 +67,8 @@ public:
bool cryptSizeEnabled() const {return crypt_size;} bool cryptSizeEnabled() const {return crypt_size;}
void setCryptSizeEnabled(bool on); void setCryptSizeEnabled(bool on);
void clear();
//! Prepare data for send and raise \a sendRequest() events //! Prepare data for send and raise \a sendRequest() events
void send(const PIByteArray & data); void send(const PIByteArray & data);
@@ -97,12 +83,6 @@ public:
//! and \a sendRequest() event to \"dev\" \a PIIODevice::write() handler //! and \a sendRequest() event to \"dev\" \a PIIODevice::write() handler
void assignDevice(PIIODevice * dev); 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(packetReceiveEvent, PIByteArray &, data)
EVENT1(sendRequest, PIByteArray, data) EVENT1(sendRequest, PIByteArray, data)
@@ -139,7 +119,6 @@ private:
int packet_size, crypt_frag_size; int packet_size, crypt_frag_size;
ushort packet_sign; ushort packet_sign;
int max_packet_size, size_crypted_size; int max_packet_size, size_crypted_size;
Progress prog_s, prog_r;
mutable PIMutex prog_s_mutex, prog_r_mutex; mutable PIMutex prog_s_mutex, prog_r_mutex;
}; };

View File

@@ -259,7 +259,7 @@ uint PISystemInfo::machineID() {
if (ret == 0) { if (ret == 0) {
CRC_32 crc = standardCRC_32(); CRC_32 crc = standardCRC_32();
ret = crc.calculate(machineKey().toByteArray()); ret = crc.calculate(machineKey().toByteArray());
piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret; //piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret;
} }
return ret; return ret;
} }

View File

@@ -2,6 +2,8 @@
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
PIByteArray rnd;
rnd.resize(1024*1024, 'x');
PICLI cli(argc, argv); PICLI cli(argc, argv);
PITimer tm; PITimer tm;
cli.addArgument("connect", true); cli.addArgument("connect", true);
@@ -28,18 +30,25 @@ int main(int argc, char * argv[]) {
})); }));
CONNECTL(&c, threadedReadEvent, ([&](uchar * readed, int size){ CONNECTL(&c, threadedReadEvent, ([&](uchar * readed, int size){
PIByteArray ba(readed, size); PIByteArray ba(readed, size);
if (size < 1024) {
PIString str = PIString(ba); PIString str = PIString(ba);
piCout << "[Client] data:" << str; piCout << "[Client] data:" << str;
if (str == "ping_S") c.write(PIString("pong_S").toByteArray()); 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){ CONNECTL(&s, newConnection, ([&](PICloudServer::Client * cl){
piCout << "[Server] new client:" << cl; piCout << "[Server] new client:" << cl;
clients << 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); PIByteArray ba(readed, size);
PIString str = PIString(ba); PIString str = PIString(ba);
piCout << "[Server] data from" << cl << ":" << str; 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](){ CONNECTL(cl, closed, ([&clients, cl](){
cl->stop(); cl->stop();

View File

@@ -22,5 +22,6 @@ if (NOT DEFINED ANDROID_PLATFORM)
DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR} DEPLOY_DIR ${CMAKE_CURRENT_BINARY_DIR}
DESTINATION ${ROOT_DIR}/release DESTINATION ${ROOT_DIR}/release
DEB_ADD_SERVICE DEB_ADD_SERVICE
ADD_MANIFEST
) )
endif() endif()

View File

@@ -4,9 +4,12 @@ CloudServer::CloudServer(DispatcherClient * c, const PIByteArray & sname) : serv
setName(sname.toHex()); setName(sname.toHex());
server_uuid = sname; server_uuid = sname;
CONNECTL(c, dataReadedServer, ([this](uint id, PIByteArray & ba){ CONNECTL(c, dataReadedServer, ([this](uint id, PIByteArray & ba){
last_ping.reset();
DispatcherClient * cl = index_clients.value(id, nullptr); DispatcherClient * cl = index_clients.value(id, nullptr);
if (cl) cl->sendData(ba); 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) { void CloudServer::addClient(DispatcherClient * c) {
last_ping.reset();
clients << c; clients << c;
index_clients.insert(c->clientId(), c); uint cid = c->clientId();
index_clients.insert(cid, c);
c->sendConnected(1); c->sendConnected(1);
server->sendConnected(c->clientId()); server->sendConnected(cid);
CONNECTL(c, dataReaded, ([this, c](PIByteArray & ba){ CONNECTL(c, dataReaded, ([this, cid](PIByteArray & ba){
// piCoutObj << c->clientId() << "dataReaded"; // piCoutObj << c->clientId() << "dataReaded";
if (clients.contains(c)) { server->sendDataToClient(ba, cid);
server->sendDataToClient(ba, c->clientId());
}
})); }));
} }
void CloudServer::removeClient(DispatcherClient * c) { void CloudServer::removeClient(DispatcherClient * c) {
last_ping.reset();
clients.removeOne(c); clients.removeOne(c);
index_clients.removeOne(c->clientId()); index_clients.removeOne(c->clientId());
server->sendDisconnected(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() { void CloudServer::printStatus() {
piCout << " " << "Clients for" << server->address() << server_uuid.toHex() << ":"; piCout << " " << "Clients for" << server->address() << server_uuid.toHex() << ":";
for (auto c: clients) { for (auto c: clients) {

View File

@@ -15,12 +15,14 @@ public:
PIVector<DispatcherClient*> getClients(); PIVector<DispatcherClient*> getClients();
EVENT_HANDLER0(void, printStatus); EVENT_HANDLER0(void, printStatus);
const DispatcherClient * getConnection() const {return server;} const DispatcherClient * getConnection() const {return server;}
double lastPing();
private: private:
DispatcherClient * server; DispatcherClient * server;
PIVector<DispatcherClient*> clients; PIVector<DispatcherClient*> clients;
PIMap<uint, DispatcherClient*> index_clients; PIMap<uint, DispatcherClient*> index_clients;
PIByteArray server_uuid; PIByteArray server_uuid;
PITimeMeasurer last_ping;
}; };
#endif // CLOUDSERVER_H #endif // CLOUDSERVER_H

View File

@@ -6,7 +6,7 @@ DispatcherClient::DispatcherClient(PIEthernet * eth_, int id) : authorised(false
CONNECTU(&disconnect_tm, tickEvent, eth, close); CONNECTU(&disconnect_tm, tickEvent, eth, close);
CONNECTU(&streampacker, packetReceiveEvent, this, readed); CONNECTU(&streampacker, packetReceiveEvent, this, readed);
CONNECTU(eth, disconnected, this, disconnected); 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() { void DispatcherClient::close() {
static_cast<PIThread*>(eth)->stop(false);
eth->close();
}
void DispatcherClient::terminate() {
eth->stop();
eth->close(); eth->close();
} }
@@ -65,10 +72,11 @@ void DispatcherClient::disconnected(bool withError) {
void DispatcherClient::readed(PIByteArray & ba) { void DispatcherClient::readed(PIByteArray & ba) {
// piCout << size;
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
// piCoutObj << "readed" << hdr.first << hdr.second;
if (hdr.first == PICloud::TCP::InvalidType) { if (hdr.first == PICloud::TCP::InvalidType) {
disconnected(true); disconnected(true);
piCoutObj << "invalid message";
return; return;
} }
if (authorised) { if (authorised) {
@@ -80,10 +88,9 @@ void DispatcherClient::readed(PIByteArray & ba) {
disconnected(false); disconnected(false);
return; return;
case PICloud::TCP::Data: case PICloud::TCP::Data:
// piCoutObj << "TCP::Data"; //piCoutObj << "TCP::Data" << tcp.role();
if (tcp.role() == PICloud::TCP::Client) { if (tcp.role() == PICloud::TCP::Client) {
PIByteArray data = tcp.parseData(ba); if (tcp.canParseData(ba)) dataReaded(ba);
if (!data.isEmpty()) dataReaded(data);
else piCoutObj << "invalid data from client"; else piCoutObj << "invalid data from client";
} }
if (tcp.role() == PICloud::TCP::Server) { if (tcp.role() == PICloud::TCP::Server) {
@@ -92,11 +99,15 @@ void DispatcherClient::readed(PIByteArray & ba) {
else piCoutObj << "invalid data from server"; else piCoutObj << "invalid data from server";
} }
return; return;
case PICloud::TCP::Ping:
pingReceived();
return;
default: default:
piCoutObj << "unknown data";
//disconnected(true); //disconnected(true);
return; return;
} }
} } else piCoutObj << "invalid role";
} else { } else {
switch (hdr.first) { switch (hdr.first) {
case PICloud::TCP::Connect: { case PICloud::TCP::Connect: {
@@ -104,7 +115,8 @@ void DispatcherClient::readed(PIByteArray & ba) {
PIByteArray sn = tcp.parseConnect_d(ba); PIByteArray sn = tcp.parseConnect_d(ba);
if (hdr.second == PICloud::TCP::Server) registerServer(sn, this); if (hdr.second == PICloud::TCP::Server) registerServer(sn, this);
if (hdr.second == PICloud::TCP::Client) registerClient(sn, this); if (hdr.second == PICloud::TCP::Client) registerClient(sn, this);
return;} return;
}
case PICloud::TCP::Disconnect: case PICloud::TCP::Disconnect:
disconnected(false); disconnected(false);
return; return;

View File

@@ -13,6 +13,7 @@ public:
~DispatcherClient(); ~DispatcherClient();
void start(); void start();
void close(); void close();
void terminate();
void sendConnected(uint client_id); void sendConnected(uint client_id);
void sendDisconnected(uint client_id); void sendDisconnected(uint client_id);
void sendData(const PIByteArray & data); void sendData(const PIByteArray & data);
@@ -27,6 +28,7 @@ public:
EVENT2(registerClient, const PIByteArray &, sname, DispatcherClient *, client) EVENT2(registerClient, const PIByteArray &, sname, DispatcherClient *, client)
EVENT1(dataReaded, PIByteArray &, ba) EVENT1(dataReaded, PIByteArray &, ba)
EVENT2(dataReadedServer, uint, id, PIByteArray &, ba) EVENT2(dataReadedServer, uint, id, PIByteArray &, ba)
EVENT0(pingReceived)
private: private:
EVENT_HANDLER1(void, readed, PIByteArray &, data); EVENT_HANDLER1(void, readed, PIByteArray &, data);

View File

@@ -7,6 +7,7 @@ DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::T
max_connections = 1000; max_connections = 1000;
eth.setParameter(PIEthernet::ReuseAddress); eth.setParameter(PIEthernet::ReuseAddress);
eth.setReadAddress(addr); eth.setReadAddress(addr);
// eth.setDebug(false);
CONNECTU(&eth, newConnection, this, newConnection); CONNECTU(&eth, newConnection, this, newConnection);
CONNECTU(&timeout_timer, tickEvent, this, cleanClients); CONNECTU(&timeout_timer, tickEvent, this, cleanClients);
} }
@@ -43,22 +44,38 @@ void DispatcherServer::picoutStatus() {
void DispatcherServer::cleanClients() { void DispatcherServer::cleanClients() {
PIVector<DispatcherClient*> rm;
map_mutex.lock(); map_mutex.lock();
for (auto c: rmrf_clients) {
delete c;
}
rmrf_clients.clear();
for (auto c: clients) { for (auto c: clients) {
if (!index_c_servers.contains(c) && !index_c_clients.contains(c)) { if (!index_c_servers.contains(c) && !index_c_clients.contains(c)) {
if (rm_clients.contains(c)) rm << c; if (!rm_clients.contains(c)) rm_clients << c;
else rm_clients << c;
} else rm_clients.removeAll(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) { 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(); 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()); 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(); map_mutex.unlock();
} }
@@ -158,37 +181,39 @@ void DispatcherServer::disconnectClient(DispatcherClient *client) {
//piCoutObj << "INVALID client" << client; //piCoutObj << "INVALID client" << client;
return; return;
} }
piCoutObj << "remove client" << client->clientId(); piCoutObj << "remove" << client->clientId();
map_mutex.lock(); map_mutex.lock();
clients.removeOne(client); clients.removeAll(client);
rm_clients.removeAll(client);
CloudServer * cs = index_c_servers.value(client, nullptr); CloudServer * cs = index_c_servers.value(client, nullptr);
if (cs) { if (cs) {
piCoutObj << "remove Server" << client->clientId();
PIVector<DispatcherClient *> cscv = cs->getClients(); PIVector<DispatcherClient *> cscv = cs->getClients();
for(auto csc : cscv) { for(auto csc : cscv) {
clients.removeOne(csc); clients.removeAll(csc);
index_c_clients.removeOne(csc); index_c_clients.remove(csc);
cs->removeClient(csc); cs->removeClient(csc);
csc->close(); csc->close();
csc->deleteLater(); rmrf_clients << csc;
} }
c_servers.remove(cs->serverUUID()); c_servers.remove(cs->serverUUID());
index_c_servers.removeOne(client); index_c_servers.remove(client);
delete cs; delete cs;
} }
CloudServer * cc = index_c_clients.value(client, nullptr); CloudServer * cc = index_c_clients.value(client, nullptr);
if (cc) { if (cc) {
piCoutObj << "remove Client" << client->clientId();
cc->removeClient(client); cc->removeClient(client);
index_c_clients.removeOne(client); index_c_clients.remove(client);
} }
client->close(); client->close();
rmrf_clients << client;
map_mutex.unlock(); map_mutex.unlock();
client->deleteLater();
} }
void DispatcherServer::newConnection(PIEthernet *cl) { void DispatcherServer::newConnection(PIEthernet *cl) {
if (clients.size_s() >= max_connections) { if (clients.size() >= max_connections) {
cl->close();
delete cl; delete cl;
return; return;
} }
@@ -199,6 +224,7 @@ void DispatcherServer::newConnection(PIEthernet *cl) {
CloudServer * cs = c_servers.value(sname, nullptr); CloudServer * cs = c_servers.value(sname, nullptr);
if (cs) { if (cs) {
rm_clients << c; rm_clients << c;
piCoutObj << "dublicate Server ->" << sname.toHex();
} else { } else {
piCoutObj << "add new Server ->" << sname.toHex(); piCoutObj << "add new Server ->" << sname.toHex();
CloudServer * cs = new CloudServer(c, sname); CloudServer * cs = new CloudServer(c, sname);
@@ -213,11 +239,12 @@ void DispatcherServer::newConnection(PIEthernet *cl) {
CloudServer * cs = c_servers.value(sname, nullptr); CloudServer * cs = c_servers.value(sname, nullptr);
if (cs) { if (cs) {
piCoutObj << "add new Client to Server ->" << sname.toHex(); piCoutObj << "add new Client to Server ->" << sname.toHex();
c->authorise(true);
cs->addClient(c); cs->addClient(c);
index_c_clients.insert(c, cs); index_c_clients.insert(c, cs);
c->authorise(true);
} else { } else {
rm_clients << c; rm_clients << c;
piCoutObj << "Client can't connect to Server ->" << sname.toHex();
} }
map_mutex.unlock(); map_mutex.unlock();
}); });

View File

@@ -34,6 +34,7 @@ private:
PIMap<const DispatcherClient *, CloudServer *> index_c_servers; PIMap<const DispatcherClient *, CloudServer *> index_c_servers;
PIMap<const DispatcherClient *, CloudServer *> index_c_clients; PIMap<const DispatcherClient *, CloudServer *> index_c_clients;
PIVector<DispatcherClient*> rm_clients; PIVector<DispatcherClient*> rm_clients;
PIVector<DispatcherClient*> rmrf_clients;
PITimer timeout_timer; PITimer timeout_timer;
PIMutex map_mutex; PIMutex map_mutex;
uint client_gid; uint client_gid;