diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index 2c2bef29..b35c7a82 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -18,9 +18,12 @@ */ #include "picloudclient.h" +#include "picloudtcp.h" PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) { + tcp.setRole(PICloud::TCP::Client); + setName("cloud_client"); } @@ -30,15 +33,32 @@ PICloudClient::~PICloudClient() { } +void PICloudClient::setServerName(const PIString & server_name) { + setName("cloud_client__" + server_name); + tcp.setServerName(server_name); +} + + bool PICloudClient::openDevice() { + piCout << "PICloudClient open device" << path(); + bool op = eth.connect(path(), false); + if (op) { + CONNECTL(ð, disconnected, [this](bool){opened_ = false;}); + CONNECTU(ð, threadedReadEvent, this, readed); + eth.startThreadedRead(); + tcp.sendStart(ð); + return true; + } + eth.close(); return false; } bool PICloudClient::closeDevice() { - return false; + return eth.close(); } + int PICloudClient::readDevice(void * read_to, int max_size) { return eth.read(read_to, max_size); } @@ -47,3 +67,8 @@ int PICloudClient::readDevice(void * read_to, int max_size) { int PICloudClient::writeDevice(const void * data, int max_size) { return eth.write(data, max_size); } + + +void PICloudClient::readed(uchar *data, int size) { + +} diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index fb7cb68c..64415822 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -21,6 +21,10 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) { + PIString name = "cloud_server_" + PIString::fromNumber(randomi()%1000); + tcp.setRole(PICloud::TCP::Server); + tcp.setServerName(name); + setName(name); } @@ -36,8 +40,9 @@ bool PICloudServer::openDevice() { if (op) { CONNECTL(ð, disconnected, [this](bool){opened_ = false;}); CONNECTU(ð, threadedReadEvent, this, readed); + CONNECTL(ð, connected, [this](){tcp.sendStart(ð);}); eth.startThreadedRead(); - sendStart(); + tcp.sendStart(ð); return true; } eth.close(); @@ -60,12 +65,6 @@ int PICloudServer::writeDevice(const void * data, int max_size) { } -void PICloudServer::sendStart() { - -} - - - PICloudServer::Client::Client(PICloudServer * srv) : server(srv) { } diff --git a/libs/cloud/picloudtcp.cpp b/libs/cloud/picloudtcp.cpp index 905b7980..42864ab0 100644 --- a/libs/cloud/picloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -20,23 +20,70 @@ #include "picloudtcp.h" #include "picrypt.h" #include "pichunkstream.h" +#include "piethernet.h" const char hash_def_key[] = "_picrypt_"; -PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v) { - s << v.version << v.type << v.sname; - return s; -} - - -PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v) { - s >> v.version >> v.type >> v.sname; - return s; +PICloud::TCP::Header::Header() { + version = Version_1; } PICloud::TCP::TCP() { } + +void PICloud::TCP::setRole(PICloud::TCP::Role r) { + header.role = r; +} + + +void PICloud::TCP::setServerName(const PIString & server_name) { + sname = server_name; +} + + +void PICloud::TCP::sendStart(PIEthernet * eth) { + header.type = PICloud::TCP::Connect; + PIByteArray ba; + ba << header << sname; + eth->send(ba); +} + + +PIPair PICloud::TCP::parseHeader(PIByteArray & ba) { + PIPair ret; + ret.first = Invalid; + if (ba.size() < sizeof(Header)) return ret; + PICloud::TCP::Header hdr; + ba >> hdr; + if (hdr.version != header.version) { + piCout << "[PICloud]" << "invalid TCP version!"; + return ret; + } + ret.first = (Type)hdr.type; + ret.second = (Role)hdr.role; + return ret; +} + + +PIByteArray PICloud::TCP::parseData(PIByteArray & ba) { + if (header.role == Server) { + PIString client; + ba >> client; + return ba; + } + if (header.role == Client) { + return ba; + } + return PIByteArray(); +} + + +PIString PICloud::TCP::parseConnect(PIByteArray & ba) { + PIString ret; + ba >> ret; + return ret; +} diff --git a/libs/main/cloud/picloudclient.h b/libs/main/cloud/picloudclient.h index cbf4c069..27e86303 100644 --- a/libs/main/cloud/picloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -23,7 +23,7 @@ #ifndef PICLOUDCLIENT_H #define PICLOUDCLIENT_H -#include "pip_cloud_export.h" +#include "picloudtcp.h" #include "piethernet.h" @@ -35,15 +35,19 @@ public: explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); virtual ~PICloudClient(); + void setServerName(const PIString & server_name); + protected: bool openDevice(); bool closeDevice(); - -private: int readDevice(void * read_to, int max_size); int writeDevice(const void * data, int max_size); +private: + EVENT_HANDLER2(void, readed, uchar * , data, int, size); + PIEthernet eth; + PICloud::TCP tcp; }; #endif // PICLOUDCLIENT_H diff --git a/libs/main/cloud/picloudserver.h b/libs/main/cloud/picloudserver.h index 32f05a8f..a432481b 100644 --- a/libs/main/cloud/picloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -23,7 +23,7 @@ #ifndef PICLOUDSERVER_H #define PICLOUDSERVER_H -#include "pip_cloud_export.h" +#include "picloudtcp.h" #include "piethernet.h" @@ -55,11 +55,10 @@ protected: private: EVENT_HANDLER2(void, readed, uchar * , data, int, size); - void sendStart(); PIEthernet eth; PIVector clients; - + PICloud::TCP tcp; }; #endif // PICLOUDSERVER_H diff --git a/libs/main/cloud/picloudtcp.h b/libs/main/cloud/picloudtcp.h index 9c22289e..8f533ff6 100644 --- a/libs/main/cloud/picloudtcp.h +++ b/libs/main/cloud/picloudtcp.h @@ -27,38 +27,51 @@ #include "pistring.h" +class PIEthernet; + namespace PICloud { -enum Version { - Version_1 = 1, -}; - -enum HeaderType { - Server = 1, - Client = 2, -}; - -struct PIP_CLOUD_EXPORT Header { - Header() { - version = Version_1; - } - uchar version; // PICloud::Version - uchar type; // PICloud::HeaderType - PIString sname; // server name -}; class PIP_CLOUD_EXPORT TCP { public: + enum Version { + Version_1 = 1, + }; + + enum Role { + Server = 1, + Client = 2, + }; + + enum Type { + Invalid = 0, + Connect = 1, + Disconnect = 2, + Data = 3, + }; + TCP(); + void setRole(Role r); + void setServerName(const PIString & server_name); + + void sendStart(PIEthernet * eth); + PIPair parseHeader(PIByteArray & ba); + PIByteArray parseData(PIByteArray & ba); + PIString parseConnect(PIByteArray & ba); private: + struct Header { + Header(); + uchar version; // PICloud::Version + uchar type; // PICloud::Type + uchar role; // PICloud::Role + }; + Header header; + PIString sname; }; } -PIP_CLOUD_EXPORT PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v); -PIP_CLOUD_EXPORT PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v); - #endif // PICLOUDTCP_H diff --git a/main.cpp b/main.cpp index 4485f0aa..24975a80 100644 --- a/main.cpp +++ b/main.cpp @@ -1,37 +1,20 @@ #include "pip.h" -int main() { - PIVector indexes; - PIEvaluator eval; - int dims = 3; - indexes << eval.setVariable("l", complexd(1.)); - indexes << eval.setVariable("mc", complexd(1.)); - for (int i = 0; i < dims; ++i) { - indexes << eval.setVariable("t" + PIString::fromNumber(i), complexd(1.)); - indexes << eval.setVariable("tv" + PIString::fromNumber(i), complexd(1.)); +int main(int argc, char * argv[]) { + PICLI cli(argc, argv); + cli.addArgument("connect", true); + PICloudClient c("127.0.0.1:10101"); + PICloudServer s("127.0.0.1:10101"); + if (cli.hasArgument("connect")) { + c.setServerName(cli.argumentValue("connect")); + c.startThreadedRead(); + } else { + s.startThreadedRead(); } - for (int i = 0; i < dims; ++i) { - indexes << eval.setVariable("m" + PIString::fromNumber(i), complexd(1.)); - indexes << eval.setVariable("mv" + PIString::fromNumber(i), complexd(1.)); - } - piCout << indexes; - - indexes.clear(); - indexes << eval.setVariable("l", complexd(1.)); - indexes << eval.setVariable("mc", complexd(1.)); - for (int i = 0; i < dims; ++i) { - indexes << eval.setVariable("t" + PIString::fromNumber(i), complexd(1.)); - indexes << eval.setVariable("tv" + PIString::fromNumber(i), complexd(1.)); - } - for (int i = 0; i < dims; ++i) { - indexes << eval.setVariable("m" + PIString::fromNumber(i), complexd(1.)); - indexes << eval.setVariable("mv" + PIString::fromNumber(i), complexd(1.)); - } - piCout << indexes; - - PIEvaluator * eval_x = new PIEvaluator(); - piCout << eval_x->setVariable("t"); - piCout << eval_x->setVariable("t"); + PIKbdListener ls; + ls.enableExitCapture(PIKbdListener::F10); + ls.start(); + WAIT_FOR_EXIT return 0; } diff --git a/utils/cloud_dispatcher/cloudserver.cpp b/utils/cloud_dispatcher/cloudserver.cpp index 01ff10d1..f114ea8c 100644 --- a/utils/cloud_dispatcher/cloudserver.cpp +++ b/utils/cloud_dispatcher/cloudserver.cpp @@ -1,7 +1,8 @@ #include "cloudserver.h" -CloudServer::CloudServer(DispatcherClient * c) : server(c) { - +CloudServer::CloudServer(DispatcherClient * c, const PIString & sname) : server(c) { + setName(sname); + server_name = sname; } @@ -12,13 +13,30 @@ CloudServer::~CloudServer() { } +PIString CloudServer::serverName() const { + return server_name; +} + + void CloudServer::addClient(DispatcherClient * c) { clients << c; } + +void CloudServer::removeClient(DispatcherClient * c) { + clients.removeOne(c); +} + + +PIVector CloudServer::getClients() { + return clients; +} + + void CloudServer::printStatus() { piCout << " " << "Clients for" << server->address() << ":"; for (auto c: clients) { piCout << " " << c->address(); } } + diff --git a/utils/cloud_dispatcher/cloudserver.h b/utils/cloud_dispatcher/cloudserver.h index be44352a..5a169bd5 100644 --- a/utils/cloud_dispatcher/cloudserver.h +++ b/utils/cloud_dispatcher/cloudserver.h @@ -7,14 +7,18 @@ class CloudServer : public PIObject { PIOBJECT(CloudServer) public: - CloudServer(DispatcherClient * c); + CloudServer(DispatcherClient * c, const PIString & sname); ~CloudServer(); + PIString serverName() const; void addClient(DispatcherClient * c); + void removeClient(DispatcherClient * c); + PIVector getClients(); EVENT_HANDLER0(void, printStatus); private: DispatcherClient * server; PIVector clients; + PIString server_name; }; #endif // CLOUDSERVER_H diff --git a/utils/cloud_dispatcher/dispatcherclient.cpp b/utils/cloud_dispatcher/dispatcherclient.cpp index b9cdfd64..1995c25a 100644 --- a/utils/cloud_dispatcher/dispatcherclient.cpp +++ b/utils/cloud_dispatcher/dispatcherclient.cpp @@ -4,10 +4,14 @@ DispatcherClient::DispatcherClient(PIEthernet * eth_) : eth(eth_), authorised(false) { CONNECTU(&disconnect_tm, tickEvent, eth, close); - eth->startThreadedRead(); CONNECTU(eth, threadedReadEvent, this, readed); CONNECTU(eth, disconnected, this, disconnected); piCoutObj << "client connected" << eth->sendAddress(); +} + + +void DispatcherClient::start() { + eth->startThreadedRead(); disconnect_tm.start(10000); } @@ -33,18 +37,40 @@ void DispatcherClient::disconnected(bool withError) { void DispatcherClient::readed(uchar *data, int size) { + piCout << size; PIByteArray ba(data, size); + PIPair hdr = tcp.parseHeader(ba); + if (hdr.first == PICloud::TCP::Invalid) { + disconnected(true); + return; + } if (authorised) { - dataReaded(ba); - } else { - if (ba.size() < 4) return; - PICloud::Header hdr; - ba >> hdr; - if ((PICloud::HeaderType)hdr.type == PICloud::Server) { - registerServer(hdr.sname, this); + switch (hdr.first) { + case PICloud::TCP::Connect: + return; + case PICloud::TCP::Disconnect: + disconnected(false); + return; + case PICloud::TCP::Data: + dataReaded(tcp.parseData(ba)); + return; + default: + disconnected(true); + return; } - if ((PICloud::HeaderType)hdr.type == PICloud::Client) { - registerClient(hdr.sname, this); + } else { + switch (hdr.first) { + case PICloud::TCP::Connect: { + PIString sn = tcp.parseConnect(ba); + if (hdr.second == PICloud::TCP::Server) registerServer(sn, this); + if (hdr.second == PICloud::TCP::Client) registerClient(sn, this); + return;} + case PICloud::TCP::Disconnect: + disconnected(false); + return; + default: + disconnected(true); + return; } } } diff --git a/utils/cloud_dispatcher/dispatcherclient.h b/utils/cloud_dispatcher/dispatcherclient.h index 99f7cc62..22d3cce6 100644 --- a/utils/cloud_dispatcher/dispatcherclient.h +++ b/utils/cloud_dispatcher/dispatcherclient.h @@ -2,12 +2,14 @@ #define DISPATCHERCLIENT_H #include "piethernet.h" +#include "picloudtcp.h" class DispatcherClient: public PIObject { PIOBJECT(DispatcherClient) public: DispatcherClient(PIEthernet * eth_); + void start(); ~DispatcherClient(); EVENT1(disconnectEvent, DispatcherClient *, client) EVENT2(registerServer, PIString, sname, DispatcherClient *, client) @@ -23,6 +25,7 @@ private: PIEthernet * eth; PITimer disconnect_tm; bool authorised; + PICloud::TCP tcp; }; diff --git a/utils/cloud_dispatcher/dispatcherserver.cpp b/utils/cloud_dispatcher/dispatcherserver.cpp index 4b5a50cf..702af9f9 100644 --- a/utils/cloud_dispatcher/dispatcherserver.cpp +++ b/utils/cloud_dispatcher/dispatcherserver.cpp @@ -35,9 +35,26 @@ void DispatcherServer::printStatus() { void DispatcherServer::disconnectClient(DispatcherClient *client) { + if (!clients.contains(client)) { + piCoutObj << "INVALID client" << client; + return; + } piCoutObj << "remove client" << client; map_mutex.lock(); clients.removeOne(client); + CloudServer * cs = index_c_servers.value(client, nullptr); + if (cs) { + PIVector cscv = cs->getClients(); + for(auto csc : cscv) { + csc->close(); + clients.removeOne(csc); + delete csc; + } + c_servers.remove(cs->serverName()); + } + CloudServer * cc = index_c_clients.value(client, nullptr); + if (cc) cc->removeClient(client); + client->close(); map_mutex.unlock(); delete client; } @@ -48,17 +65,24 @@ void DispatcherServer::newConnection(PIEthernet *cl) { CONNECTU(client, disconnectEvent, this, disconnectClient); CONNECTL(client, registerServer, [this](PIString sname, DispatcherClient * c){ map_mutex.lock(); - c_servers.insert(sname, new CloudServer(c)); + piCoutObj << "add new Server ->" << sname; + CloudServer * cs = new CloudServer(c, sname); + c_servers.insert(sname, cs); + index_c_servers.insert(c, cs); map_mutex.unlock(); }); CONNECTL(client, registerClient, [this](PIString sname, DispatcherClient * c){ map_mutex.lock(); - if (c_servers.contains(sname)) { - c_servers[sname]->addClient(c); + CloudServer * cs = c_servers.value(sname, nullptr); + if (cs) { + piCoutObj << "add new Client to Server ->" << sname; + cs->addClient(c); + index_c_clients.insert(c, cs); } map_mutex.unlock(); }); piCoutObj << "add client" << client; + client->start(); map_mutex.lock(); clients.push_back(client); map_mutex.unlock(); diff --git a/utils/cloud_dispatcher/dispatcherserver.h b/utils/cloud_dispatcher/dispatcherserver.h index 7fba7ef4..c4161aba 100644 --- a/utils/cloud_dispatcher/dispatcherserver.h +++ b/utils/cloud_dispatcher/dispatcherserver.h @@ -18,6 +18,8 @@ private: PIEthernet eth; PIVector clients; PIMap c_servers; + PIMap index_c_servers; + PIMap index_c_clients; PITimer status_timer; PIMutex map_mutex; };