PICloud with streampacker

This commit is contained in:
2021-04-07 14:38:32 +03:00
parent fcf9f0f80e
commit 1fd9851068
13 changed files with 90 additions and 67 deletions

View File

@@ -358,7 +358,7 @@ if (NOT CROSSTOOLS)
pip_find_lib(sodium) pip_find_lib(sodium)
if(sodium_FOUND) if(sodium_FOUND)
pip_module(crypt "sodium" "PIP crypt support" "" "") pip_module(crypt "sodium" "PIP crypt support" "" "")
pip_module(cloud "pip_crypt" "PIP cloud support" "" "") pip_module(cloud "pip_io_utils" "PIP cloud support" "" "")
endif() endif()

View File

@@ -1,6 +1,6 @@
#include "picloudbase.h" #include "picloudbase.h"
PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client) { PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(&eth), tcp(&streampacker) {
} }

View File

@@ -21,10 +21,19 @@
#include "picloudtcp.h" #include "picloudtcp.h"
PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) { PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() {
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();});
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
CONNECTL(&eth, disconnected, [this](bool){
piCoutObj << "disconnected";
opened_ = false;
is_connected = false;
cond_connect.notifyOne();
piMSleep(100);
});
} }
@@ -49,17 +58,17 @@ bool PICloudClient::openDevice() {
piCout << "PICloudClient open device" << path(); piCout << "PICloudClient open device" << path();
bool op = eth.connect(path(), false); bool op = eth.connect(path(), false);
if (op) { if (op) {
CONNECTL(&eth, connected, [this](){tcp.sendStart(&eth);}); mutex_buff.lock();
CONNECTU(&eth, threadedReadEvent, this, readed);
CONNECTL(&eth, disconnected, [this](bool){
opened_ = false;
eth.close();
piCoutObj << "disconnected";// << !isOpened() << isClosed();
piMSleep(100);
});
eth.startThreadedRead(); eth.startThreadedRead();
tcp.sendStart(&eth); bool conn_ok = cond_connect.waitFor(mutex_buff, (int)eth.readTimeout(), [this](){return isConnected();});
return true; piCoutObj << "conn_ok" << conn_ok;
mutex_buff.unlock();
if (!conn_ok) {
eth.stop();
eth.close();
piMSleep(100);
}
return isConnected();
} else { } else {
eth.close(); eth.close();
return false; return false;
@@ -92,14 +101,16 @@ int PICloudClient::writeDevice(const void * data, int max_size) {
} }
void PICloudClient::readed(uchar *data, int size) { void PICloudClient::_readed(PIByteArray & ba) {
PIByteArray ba(data, size);
mutex_buff.lock(); mutex_buff.lock();
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
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) == 0) is_connected = true; if (tcp.parseConnect(ba) == 1) {
is_connected = true;
cond_connect.notifyOne();
}
break; break;
case PICloud::TCP::Disconnect: case PICloud::TCP::Disconnect:
is_connected = false; is_connected = false;
@@ -107,7 +118,7 @@ void PICloudClient::readed(uchar *data, int size) {
eth.close(); eth.close();
break; break;
case PICloud::TCP::Data: case PICloud::TCP::Data:
buff.append(data, size); buff.append(ba);
cond_buff.notifyOne(); cond_buff.notifyOne();
break; break;
default: default:

View File

@@ -21,10 +21,17 @@
PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() { PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), PICloudBase() {
PIString name = "PCS_" + PIString::fromNumber(randomi()%1000); PIString server_name = "PCS_" + PIString::fromNumber(randomi()%1000);
tcp.setRole(PICloud::TCP::Server); tcp.setRole(PICloud::TCP::Server);
tcp.setServerName(name); tcp.setServerName(server_name);
setName("cloud_server__" + name); setName("cloud_server__" + server_name);
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
CONNECTL(&eth, connected, [this](){tcp.sendStart();});
CONNECTL(&eth, disconnected, [this](bool){
piCoutObj << "disconnected";
opened_ = false;
piMSleep(100);
});
} }
@@ -49,15 +56,7 @@ bool PICloudServer::openDevice() {
piCout << "PICloudServer open device" << path(); piCout << "PICloudServer open device" << path();
bool op = eth.connect(path(), false); bool op = eth.connect(path(), false);
if (op) { if (op) {
CONNECTU(&eth, threadedReadEvent, this, readed);
CONNECTL(&eth, connected, [this](){tcp.sendStart(&eth);});
CONNECTL(&eth, disconnected, [this](bool){
opened_ = false;
eth.close();
piCoutObj << "disconnected" << !isOpened() << isClosed();
});
eth.startThreadedRead(); eth.startThreadedRead();
tcp.sendStart(&eth);
return true; return true;
} }
eth.close(); eth.close();
@@ -87,12 +86,12 @@ int PICloudServer::writeDevice(const void * data, int max_size) {
void PICloudServer::clientDisconnect(uint client_id) { void PICloudServer::clientDisconnect(uint client_id) {
tcp.sendDisconnected(&eth, client_id); tcp.sendDisconnected(client_id);
} }
int PICloudServer::sendData(const PIByteArray & data, uint client_id) { int PICloudServer::sendData(const PIByteArray & data, uint client_id) {
return tcp.sendData(&eth, data, client_id); return tcp.sendData(data, client_id);
} }
@@ -138,8 +137,7 @@ void PICloudServer::Client::pushBuffer(const PIByteArray & ba) {
} }
void PICloudServer::readed(uchar *data, int size) { void PICloudServer::_readed(PIByteArray & ba) {
PIByteArray ba(data, size);
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
if (hdr.second == tcp.role()) { if (hdr.second == tcp.role()) {
switch (hdr.first) { switch (hdr.first) {
@@ -147,7 +145,7 @@ void PICloudServer::readed(uchar *data, int size) {
uint id = tcp.parseConnect(ba); uint id = tcp.parseConnect(ba);
Client * oc = index_clients.value(id, nullptr); Client * oc = index_clients.value(id, nullptr);
if (oc) { if (oc) {
tcp.sendDisconnected(&eth, id); tcp.sendDisconnected(id);
} else { } else {
Client * c = new Client(this, id); Client * c = new Client(this, id);
clients << c; clients << c;

View File

@@ -21,6 +21,7 @@
#include "picrypt.h" #include "picrypt.h"
#include "pichunkstream.h" #include "pichunkstream.h"
#include "piethernet.h" #include "piethernet.h"
#include "pistreampacker.h"
const char hash_def_key[] = "_picrypt_"; const char hash_def_key[] = "_picrypt_";
@@ -31,9 +32,9 @@ PICloud::TCP::Header::Header() {
} }
PICloud::TCP::TCP() { PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) {
}
}
void PICloud::TCP::setRole(PICloud::TCP::Role r) { void PICloud::TCP::setRole(PICloud::TCP::Role r) {
header.role = r; header.role = r;
@@ -45,53 +46,55 @@ void PICloud::TCP::setServerName(const PIString & server_name) {
} }
void PICloud::TCP::sendStart(PIEthernet * eth) { void PICloud::TCP::sendStart() {
piCout << "sendStart";
header.type = PICloud::TCP::Connect; header.type = PICloud::TCP::Connect;
PIByteArray ba; PIByteArray ba;
ba << header << sname; ba << header << sname;
eth->send(ba); streampacker->send(ba);
} }
void PICloud::TCP::sendConnected(PIEthernet * eth, uint client_id) { 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;
eth->send(ba); streampacker->send(ba);
} }
void PICloud::TCP::sendDisconnected(PIEthernet * eth, uint client_id) { 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;
eth->send(ba); streampacker->send(ba);
} }
void PICloud::TCP::sendData(PIEthernet * eth, const PIByteArray & data) { void PICloud::TCP::sendData(const PIByteArray & data) {
header.type = PICloud::TCP::Data; header.type = PICloud::TCP::Data;
PIByteArray ba; PIByteArray ba;
ba << header; ba << header;
ba.append(data); ba.append(data);
// piCout << "sendData" << ba.toHex(); // piCout << "sendData" << ba.toHex();
eth->send(ba); streampacker->send(ba);
} }
int PICloud::TCP::sendData(PIEthernet * eth, const PIByteArray & data, uint client_id) { int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) {
header.type = PICloud::TCP::Data; header.type = PICloud::TCP::Data;
PIByteArray ba; PIByteArray ba;
ba << header << client_id; ba << header << client_id;
ba.append(data); ba.append(data);
if (eth->send(ba)) return data.size_s(); streampacker->send(ba);
else return -1; return data.size_s();
} }
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 = Invalid; ret.first = InvalidType;
ret.second = InvalidRole;
if (ba.size() < sizeof(Header)) return ret; if (ba.size() < sizeof(Header)) return ret;
PICloud::TCP::Header hdr; PICloud::TCP::Header hdr;
ba >> hdr; ba >> hdr;

View File

@@ -25,6 +25,7 @@
#include "picloudtcp.h" #include "picloudtcp.h"
#include "piethernet.h" #include "piethernet.h"
#include "pistreampacker.h"
class PICloudBase class PICloudBase
@@ -34,6 +35,7 @@ public:
protected: protected:
PIEthernet eth; PIEthernet eth;
PIStreamPacker streampacker;
PICloud::TCP tcp; PICloud::TCP tcp;
}; };

View File

@@ -41,14 +41,17 @@ public:
protected: protected:
bool openDevice(); bool openDevice();
bool closeDevice(); bool closeDevice();
bool isConnected() const {return is_connected;}
int readDevice(void * read_to, int max_size); int readDevice(void * read_to, int max_size);
int writeDevice(const void * data, int max_size); int writeDevice(const void * data, int max_size);
private: private:
EVENT_HANDLER2(void, readed, uchar * , data, int, size); EVENT_HANDLER1(void, _readed, PIByteArray &, data);
PIByteArray buff; PIByteArray buff;
PIMutex mutex_buff; PIMutex mutex_buff;
PIMutex mutex_connect;
PIConditionVariable cond_buff; PIConditionVariable cond_buff;
PIConditionVariable cond_connect;
std::atomic_bool is_connected; std::atomic_bool is_connected;
}; };

View File

@@ -66,7 +66,7 @@ protected:
int writeDevice(const void * data, int max_size); int writeDevice(const void * data, int max_size);
private: private:
EVENT_HANDLER2(void, readed, uchar * , data, int, size); EVENT_HANDLER1(void, _readed, PIByteArray &, ba);
void clientDisconnect(uint client_id); void clientDisconnect(uint client_id);
int sendData(const PIByteArray & data, uint client_id); int sendData(const PIByteArray & data, uint client_id);

View File

@@ -28,6 +28,7 @@
class PIEthernet; class PIEthernet;
class PIStreamPacker;
namespace PICloud { namespace PICloud {
@@ -40,27 +41,28 @@ public:
}; };
enum Role { enum Role {
InvalidRole = 0,
Server = 1, Server = 1,
Client = 2, Client = 2,
}; };
enum Type { enum Type {
Invalid = 0, InvalidType = 0,
Connect = 1, Connect = 1,
Disconnect = 2, Disconnect = 2,
Data = 3, Data = 3,
}; };
TCP(); TCP(PIStreamPacker * s);
void setRole(Role r); void setRole(Role r);
Role role() const {return (Role)header.role;} Role role() const {return (Role)header.role;}
void setServerName(const PIString & server_name); void setServerName(const PIString & server_name);
void sendStart(PIEthernet * eth); void sendStart();
void sendConnected(PIEthernet * eth, uint client_id); void sendConnected(uint client_id);
void sendDisconnected(PIEthernet * eth, uint client_id); void sendDisconnected(uint client_id);
void sendData(PIEthernet * eth, const PIByteArray & data); void sendData(const PIByteArray & data);
int sendData(PIEthernet * eth, const PIByteArray & data, uint client_id); int sendData(const PIByteArray & data, uint client_id);
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
PIByteArray parseData(PIByteArray & ba); PIByteArray parseData(PIByteArray & ba);
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba); PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
@@ -78,6 +80,7 @@ private:
Header header; Header header;
PIString sname; PIString sname;
PIStreamPacker * streampacker;
}; };
} }

View File

@@ -91,7 +91,7 @@ public:
//! Returns \a Progress info about receiving //! Returns \a Progress info about receiving
Progress progressReceive() const; Progress progressReceive() const;
EVENT1(packetReceiveEvent, PIByteArray, data) EVENT1(packetReceiveEvent, PIByteArray &, data)
EVENT1(sendRequest, PIByteArray, data) EVENT1(sendRequest, PIByteArray, data)
//! \handlers //! \handlers

View File

@@ -21,6 +21,7 @@ PIString CloudServer::serverName() const {
void CloudServer::addClient(DispatcherClient * c) { void CloudServer::addClient(DispatcherClient * c) {
clients << c; clients << c;
index_clients.insert(c->clientId(), c); index_clients.insert(c->clientId(), c);
c->sendConnected();
} }

View File

@@ -2,9 +2,9 @@
#include "picloudtcp.h" #include "picloudtcp.h"
DispatcherClient::DispatcherClient(PIEthernet * eth_, int id) : eth(eth_), authorised(false), client_id(id) { DispatcherClient::DispatcherClient(PIEthernet * eth_, int id) : authorised(false), eth(eth_), streampacker(eth_), tcp(&streampacker), client_id(id) {
CONNECTU(&disconnect_tm, tickEvent, eth, close); CONNECTU(&disconnect_tm, tickEvent, eth, close);
CONNECTU(eth, threadedReadEvent, 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" << eth->sendAddress();
} }
@@ -31,18 +31,19 @@ void DispatcherClient::close() {
void DispatcherClient::sendConnected() { void DispatcherClient::sendConnected() {
tcp.sendConnected(eth, client_id); piCoutObj << "sendConnected";
tcp.sendConnected(1);
} }
void DispatcherClient::sendData(const PIByteArray & data) { void DispatcherClient::sendData(const PIByteArray & data) {
if (tcp.role() == PICloud::TCP::Client) tcp.sendData(eth, data); if (tcp.role() == PICloud::TCP::Client) tcp.sendData(data);
else piCoutObj << "error sendData, invalid role"; else piCoutObj << "error sendData, invalid role";
} }
void DispatcherClient::sendDataToClient(const PIByteArray & data, uint client_id) { void DispatcherClient::sendDataToClient(const PIByteArray & data, uint client_id) {
if (tcp.role() == PICloud::TCP::Server) tcp.sendData(eth, data, client_id); if (tcp.role() == PICloud::TCP::Server) tcp.sendData(data, client_id);
else piCoutObj << "error sendDataToClient, invalid role"; else piCoutObj << "error sendDataToClient, invalid role";
} }
@@ -53,11 +54,10 @@ void DispatcherClient::disconnected(bool withError) {
} }
void DispatcherClient::readed(uchar *data, int size) { void DispatcherClient::readed(PIByteArray & ba) {
// piCout << size; // piCout << size;
PIByteArray ba(data, size);
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba); PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
if (hdr.first == PICloud::TCP::Invalid) { if (hdr.first == PICloud::TCP::InvalidType) {
disconnected(true); disconnected(true);
return; return;
} }

View File

@@ -3,6 +3,7 @@
#include "piethernet.h" #include "piethernet.h"
#include "picloudtcp.h" #include "picloudtcp.h"
#include "pistreampacker.h"
class DispatcherClient: public PIObject { class DispatcherClient: public PIObject {
@@ -23,12 +24,13 @@ public:
EVENT1(dataReaded, PIByteArray, ba) EVENT1(dataReaded, PIByteArray, ba)
private: private:
EVENT_HANDLER2(void, readed, uchar * , data, int, size); EVENT_HANDLER1(void, readed, PIByteArray &, data);
EVENT_HANDLER1(void, disconnected, bool, withError); EVENT_HANDLER1(void, disconnected, bool, withError);
PIEthernet * eth;
PITimer disconnect_tm; PITimer disconnect_tm;
bool authorised; bool authorised;
PIEthernet * eth;
PIStreamPacker streampacker;
PICloud::TCP tcp; PICloud::TCP tcp;
uint client_id; uint client_id;
}; };