diff --git a/jus/Client.cpp b/jus/Client.cpp index 2120581..3d98fc7 100644 --- a/jus/Client.cpp +++ b/jus/Client.cpp @@ -4,4 +4,38 @@ * @license APACHE v2.0 (see license file) */ +#include +#include +jus::Client::Client() : + propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &jus::Client::onPropertyChangeIp), + propertyPort(this, "port", 1983, "Port to connect server", &jus::Client::onPropertyChangePort) { + m_interfaceClient.propertyIp.set(*propertyIp); + m_interfaceClient.propertyPort.set(*propertyPort); + m_interfaceClient.propertyServer.set(false); +} + +jus::Client::~Client() { + +} + +void jus::Client::onPropertyChangeIp() { + m_interfaceClient.propertyIp.set(*propertyIp); +} + +void jus::Client::onPropertyChangePort(){ + m_interfaceClient.propertyPort.set(*propertyPort); +} + + +void jus::Client::connect(){ + JUS_DEBUG("connect [START]"); + m_interfaceClient.connect(); + JUS_DEBUG("connect [STOP]"); +} + +void jus::Client::disconnect(){ + JUS_DEBUG("disconnect [START]"); + m_interfaceClient.disconnect(); + JUS_DEBUG("disconnect [STOP]"); +} \ No newline at end of file diff --git a/jus/Client.h b/jus/Client.h index 530ac1e..298fbcc 100644 --- a/jus/Client.h +++ b/jus/Client.h @@ -6,14 +6,24 @@ #pragma once #include +#include namespace jus { - class Client { + class Client : public eproperty::Interface { + public: + eproperty::Value propertyIp; + eproperty::Value propertyPort; private: jus::TcpString m_interfaceClient; public: - Client() {} - virtual ~Client() {} + Client(); + virtual ~Client(); + void connect(); + void disconnect(); + + private: + void onPropertyChangeIp(); + void onPropertyChangePort(); }; } diff --git a/jus/GateWayClient.cpp b/jus/GateWayClient.cpp index 84c2606..59f0ac3 100644 --- a/jus/GateWayClient.cpp +++ b/jus/GateWayClient.cpp @@ -17,10 +17,11 @@ jus::GateWayClient::~GateWayClient() { void jus::GateWayClient::start(const std::string& _ip, uint16_t _port) { m_interfaceClient.propertyIp.set(_ip); m_interfaceClient.propertyPort.set(_port); - + m_interfaceClient.propertyServer.set(true); + m_interfaceClient.connect(); } void jus::GateWayClient::stop() { - + m_interfaceClient.disconnect(); } diff --git a/jus/TcpString.cpp b/jus/TcpString.cpp index 5e61f7f..c6016ba 100644 --- a/jus/TcpString.cpp +++ b/jus/TcpString.cpp @@ -5,30 +5,74 @@ */ #include #include +#include jus::TcpString::TcpString() : + m_thread(nullptr), propertyIp(this, "ip", "127.0.0.1", "ip to open or connect server", &jus::TcpString::onPropertyChangeIp), propertyPort(this, "port", 1983, "Connection port of the server", &jus::TcpString::onPropertyChangePort), - propertyServer(this, "server", false, "is a server or not", &jus::TcpString::onPropertyChangeServer) { + propertyServer(this, "server", false, "is a server or not", &jus::TcpString::onPropertyChangeServer), + signalIsConnected(), + signalData() { m_connection.setHostNane(*propertyIp); m_connection.setPort(*propertyPort); m_connection.setServer(*propertyServer); + m_threadRunning = false; } jus::TcpString::~TcpString() { - + disconnect(); } -void jus::TcpString::connect(){ +void jus::TcpString::threadCallback() { + ethread::setName("TcpString-input"); + // Connect ... if (m_connection.link() == false) { JUS_ERROR("can not connect to the socket..."); + signalIsConnected.emit(false); + return; } -} - -void jus::TcpString::disconnect(){ + signalIsConnected.emit(true); + // get datas: + while (m_threadRunning == true) { + // READ section data: + std::string data = std::move(read()); + JUS_WARNING("Receive data: '" << data << "'"); + if (data.size() != 0) { + signalData.emit(data); + } + } + // disconnect ... if (m_connection.unlink() == false) { JUS_ERROR("can not disconnect to the socket..."); } + signalIsConnected.emit(false); + JUS_DEBUG("End of thread"); +} + +void jus::TcpString::connect(){ + JUS_DEBUG("connect [START]"); + m_threadRunning = true; + m_thread = new std::thread([&](void *){ this->threadCallback();}, nullptr); + if (m_thread == nullptr) { + m_threadRunning = false; + JUS_ERROR("creating callback thread!"); + return; + } + //ethread::setPriority(*m_receiveThread, -6); + JUS_DEBUG("connect [STOP]"); +} + +void jus::TcpString::disconnect(){ + JUS_DEBUG("disconnect [START]"); + if (m_thread != nullptr) { + m_threadRunning = false; + m_connection.unlink(); + m_thread->join(); + delete m_thread; + m_thread = nullptr; + } + JUS_DEBUG("disconnect [STOP]"); } int32_t jus::TcpString::write(const std::string& _data) { @@ -41,6 +85,7 @@ int32_t jus::TcpString::write(const std::string& _data) { } std::string jus::TcpString::read() { + // TODO : Do it better with a correct way to check data size ... std::string out; uint32_t size = 0; int32_t len = m_connection.read(&size, 4); @@ -49,7 +94,10 @@ std::string jus::TcpString::read() { } else { out.resize(size); len = m_connection.read(&out[0], size); - if (len != 4) { + if (len == 0) { + JUS_WARNING("Read No data"); + } else if (len != size) { + // TODO do it again ... JUS_ERROR("Protocol error occured .2."); } } diff --git a/jus/TcpString.h b/jus/TcpString.h index bfa35a1..f7e24b9 100644 --- a/jus/TcpString.h +++ b/jus/TcpString.h @@ -5,6 +5,7 @@ */ #pragma once #include +#include #include #include #include @@ -13,22 +14,27 @@ namespace jus { class TcpString : public eproperty::Interface { private: enet::Tcp m_connection; - std::unique_ptr m_receiveThread; + std::thread* m_thread; + bool m_threadRunning; public: eproperty::Value propertyIp; eproperty::Value propertyPort; eproperty::Value propertyServer; + esignal::Signal signalIsConnected; + esignal::Signal signalData; public: TcpString(); virtual ~TcpString(); void connect(); void disconnect(); int32_t write(const std::string& _data); + private: std::string read(); private: void onPropertyChangeIp(); void onPropertyChangePort(); void onPropertyChangeServer(); + void threadCallback(); }; } diff --git a/lutinParseSubFolders.txt b/lutinParseSubFolders.txt index 3f09102..d3e5a34 100644 --- a/lutinParseSubFolders.txt +++ b/lutinParseSubFolders.txt @@ -1 +1,2 @@ -tools/gateway \ No newline at end of file +tools/gateway +test/client \ No newline at end of file diff --git a/test/client/appl/debug.cpp b/test/client/appl/debug.cpp new file mode 100644 index 0000000..d4f07c5 --- /dev/null +++ b/test/client/appl/debug.cpp @@ -0,0 +1,12 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include + +int32_t appl::getLogId() { + static int32_t g_val = elog::registerInstance("jus-test-client"); + return g_val; +} diff --git a/test/client/appl/debug.h b/test/client/appl/debug.h new file mode 100644 index 0000000..d422118 --- /dev/null +++ b/test/client/appl/debug.h @@ -0,0 +1,40 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2016, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include + +namespace appl { + int32_t getLogId(); +}; + +#define APPL_BASE(info,data) ELOG_BASE(appl::getLogId(),info,data) + +#define APPL_PRINT(data) APPL_BASE(-1, data) +#define APPL_CRITICAL(data) APPL_BASE(1, data) +#define APPL_ERROR(data) APPL_BASE(2, data) +#define APPL_WARNING(data) APPL_BASE(3, data) +#ifdef DEBUG + #define APPL_INFO(data) APPL_BASE(4, data) + #define APPL_DEBUG(data) APPL_BASE(5, data) + #define APPL_VERBOSE(data) APPL_BASE(6, data) + #define APPL_TODO(data) APPL_BASE(4, "TODO : " << data) +#else + #define APPL_INFO(data) do { } while(false) + #define APPL_DEBUG(data) do { } while(false) + #define APPL_VERBOSE(data) do { } while(false) + #define APPL_TODO(data) do { } while(false) +#endif + +#define APPL_ASSERT(cond,data) \ + do { \ + if (!(cond)) { \ + APPL_CRITICAL(data); \ + assert(!#cond); \ + } \ + } while (0) + + diff --git a/test/client/appl/main.cpp b/test/client/appl/main.cpp new file mode 100644 index 0000000..d266d9b --- /dev/null +++ b/test/client/appl/main.cpp @@ -0,0 +1,47 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2014, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include + +#include + +int main(int _argc, const char *_argv[]) { + etk::init(_argc, _argv); + jus::Client client1; + for (int32_t iii=0; iii<_argc ; ++iii) { + std::string data = _argv[iii]; + if (etk::start_with(data, "--ip=") == true) { + client1.propertyIp.set(std::string(&data[5])); + } else if (etk::start_with(data, "--port=") == true) { + client1.propertyPort.set(etk::string_to_uint16_t(std::string(&data[7]))); + } else if ( data == "-h" + || data == "--help") { + APPL_PRINT(etk::getApplicationName() << " - help : "); + APPL_PRINT(" " << _argv[0] << " [options]"); + APPL_PRINT(" --ip=XXX Server connection IP (default: 1.7.0.0.1)"); + APPL_PRINT(" --port=XXX Server connection PORT (default: 1983)"); + return -1; + } + } + APPL_INFO("=================================="); + APPL_INFO("== JUS test client start =="); + APPL_INFO("=================================="); + client1.connect(); + int32_t iii=0; + while (iii < 5) { + usleep(500000); + APPL_INFO("Appl in waiting ... " << iii << "/5"); + iii++; + } + client1.disconnect(); + APPL_INFO("=================================="); + APPL_INFO("== JUS test client stop =="); + APPL_INFO("=================================="); + return 0; +} diff --git a/test/client/lutin_jus-test-client.py b/test/client/lutin_jus-test-client.py new file mode 100644 index 0000000..680aa78 --- /dev/null +++ b/test/client/lutin_jus-test-client.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +import lutin.module as module +import lutin.tools as tools + + +def get_type(): + return "BINARY" + +def get_sub_type(): + return "TOOLS" + +def get_desc(): + return "JUS generic gateway" + +def get_licence(): + return "APACHE-2" + +def get_compagny_type(): + return "com" + +def get_compagny_name(): + return "atria-soft" + +def get_maintainer(): + return ["Mr DUPIN Edouard "] + +def create(target, module_name): + my_module = module.Module(__file__, module_name, get_type()) + my_module.add_export_path(tools.get_current_path(__file__)) + my_module.add_module_depend(['jus']) + my_module.add_src_file([ + 'appl/debug.cpp', + 'appl/main.cpp' + ]) + return my_module + + +