Bläddra i källkod

add JsonCPP to CMakeLists, add iomanager to seperate IO from main, implement basic connectivity with server via iomanager

Missingmew 5 år sedan
förälder
incheckning
c328e3f62a

+ 6 - 4
cli/CMakeLists.txt

@@ -5,15 +5,17 @@ set (CMAKE_BUILD_TYPE debug)
 
 project(ccats-cli)
 
-add_executable(ccats-cli src/main.cpp)
+add_executable(ccats-cli src/main.cpp src/iomanager.cpp src/machineiomanager.cpp)
 
-# use pkf-config to find readline as it doesnt provide cmake files
+# use pkg-config to find readline as it doesnt provide cmake files
 find_package(PkgConfig REQUIRED)
 pkg_check_modules(READLINE REQUIRED readline)
+pkg_check_modules(JSONCPP REQUIRED jsoncpp)
 
 find_package(Threads)
 find_package(Boost 1.67 REQUIRED COMPONENTS system program_options)
 
 
-include_directories(${Boost_INCLUDE_DIR})
-target_link_libraries(ccats-cli PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${READLINE_LIBRARIES})
+include_directories(${Boost_INCLUDE_DIR} include)
+
+target_link_libraries(ccats-cli PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} ${READLINE_LIBRARIES} ${JSONCPP_LIBRARIES})

+ 28 - 0
cli/include/iomanager.hpp

@@ -0,0 +1,28 @@
+#ifndef IOMANAGER_HPP
+#define IOMANAGER_HPP
+
+#include <string>
+#include <boost/asio.hpp>
+
+using boost::asio::ip::tcp;
+
+class IoManager {
+protected:
+	boost::asio::streambuf recvbuf;
+	boost::asio::io_service ios;
+	tcp::socket *tcpsock;
+	boost::system::error_code errcode;
+	std::string *ipstring;
+	int port;
+public:
+	// Basic constructor
+	IoManager(char *ipcstring);
+	// destructor to clean up all generic stuff
+	~IoManager();
+	// enters loop to handle further interaction based on derived class
+	virtual void run() = 0;
+	// tries to establish connection, returns false on error
+	bool connect();
+};
+
+#endif

+ 15 - 0
cli/include/machineiomanager.hpp

@@ -0,0 +1,15 @@
+#ifndef MACHINEIOMANAGER_HPP
+#define MACHINEIOMANAGER_HPP
+
+#include "iomanager.hpp"
+
+class MachineIoManager : public IoManager {
+
+public:
+	// MachineIoManager(char *ipstring) : IoManager(ipstring) {};
+	using IoManager::IoManager;
+	// enters loop to handle machine based interaction (other frontends)
+	void run();
+};
+
+#endif

+ 15 - 0
cli/include/useriomanager.hpp

@@ -0,0 +1,15 @@
+#ifndef USERIOMANAGER_HPP
+#define USERIOMANAGER_HPP
+
+#include "iomanager.hpp"
+
+class UserIoManager : IoManager {
+
+public:
+	// UserIoManager(char *ipstring) : IoManager(ipstring) {};
+	using IoManager::IoManager;
+	// enters loop to handle user based interaction (from the terminal)
+	void run();
+};
+
+#endif

+ 102 - 0
cli/src/iomanager.cpp

@@ -0,0 +1,102 @@
+#include <iomanager.hpp>
+
+#include <iostream>
+#include <jsoncpp/json/json.h>
+
+using boost::asio::buffer;
+
+IoManager::IoManager(char *ipcstring) {
+	ipstring = new std::string(ipcstring);
+	port = 1234;
+	tcpsock = new tcp::socket(ios);
+}
+
+bool IoManager::connect() {
+	tcp::endpoint *ep;
+	Json::Value root, checkok;
+	const char *recvjson;
+	std::string jsonerror;
+	
+	Json::CharReaderBuilder rbuilder;
+	const std::unique_ptr<Json::CharReader> reader(rbuilder.newCharReader());
+	Json::StreamWriterBuilder wbuilder;
+	// builder["indentation"] = ""; // If you want whitespace-less output
+	// const std::string output = Json::writeString(wbuilder, root);
+	
+	ep = new tcp::endpoint(boost::asio::ip::address::from_string(*ipstring), 1234);
+	
+	
+	// establish connection
+	std::cerr << "connecting to " << *ipstring << std::endl;
+	tcpsock->connect(*ep, errcode);
+	if(errcode) {
+		std::cerr << "couldnt connect to " << *ipstring << std::endl
+			  << errcode.message() << std::endl;
+		return false;
+	}
+	
+	printf("connect ok\n");
+	fflush(stdout);
+	
+	// send version check
+	// TODO make client version global
+	root["version"] = "0.1";
+	
+	std::cout << root << std::endl;
+	
+	boost::asio::write(*tcpsock, buffer(Json::writeString(wbuilder, root)), errcode);
+	if(errcode) {
+		std::cerr << "couldnt send version check" << std::endl
+			  << errcode.message() << std::endl;
+		return false;
+	}
+	
+	printf("send ok\n");
+	fflush(stdout);
+	
+	// recieve answer to version check
+	boost::asio::read(*tcpsock, recvbuf, boost::asio::transfer_all(), errcode);
+	if (errcode && errcode != boost::asio::error::eof) {
+		std::cerr << "couldnt recieve version check" << std::endl
+			  << errcode.message() << std::endl;
+		return false;
+	}
+	
+	printf("recieve ok\n");
+	fflush(stdout);
+	
+	// parse json
+	recvjson = boost::asio::buffer_cast<const char *>(recvbuf.data());
+	if (!reader->parse(recvjson, recvjson + recvbuf.size(), &root, &jsonerror)) {
+		std::cerr << "couldnt parse recieved json" << std::endl
+			  << jsonerror << std::endl;
+		return false;
+	}
+	
+	printf("parse ok\n");
+	fflush(stdout);
+	
+	// check if version check was ok
+	checkok = root["accept"];
+	if(checkok.type() != Json::ValueType::booleanValue || !checkok) {
+		// TODO make client version global
+		std::cerr << "version check failed. client version is " << "0.1" << std::endl
+			  << "server reports version " << root["version"] << std::endl;
+		return false;
+	}
+	
+	printf("check ok\n");
+	fflush(stdout);
+	
+	// clean up
+	delete ep;
+	
+	return true;
+}
+
+IoManager::~IoManager() {
+	tcpsock->close();
+	
+	delete ipstring;
+	delete tcpsock;
+}

+ 8 - 0
cli/src/machineiomanager.cpp

@@ -0,0 +1,8 @@
+#include <machineiomanager.hpp>
+
+#include <iostream>
+#include <jsoncpp/json/json.h>
+
+void MachineIoManager::run() {
+	std::cout << "MachineIoManager::run() says hello!" << std::endl;
+}

+ 13 - 2
cli/src/main.cpp

@@ -1,4 +1,7 @@
+#include <machineiomanager.hpp>
+
 #include <boost/program_options.hpp>
+#include <boost/asio.hpp>
 #include <cctype>
 #include <iostream>
 #include <string>
@@ -78,8 +81,9 @@ int main(int argc, char **argv) {
   bpo::variables_map vm;
   unsigned int machine = 0;
   const char *file = NULL;
+  IoManager *ioman;
   
-  if(argc < 2) {
+  if(argc < 2 || !std::strncmp(argv[1], "--help", 6)) {
 	show_help(argv[0]);
 	  std::cout << desc;
 	  return 1;
@@ -113,5 +117,12 @@ int main(int argc, char **argv) {
     std::fprintf(stderr, "%s\n", ex.what());
   }
   std::printf("ip %s machine mode is %d file is %s\n", argv[1], machine, file?file:"");
-  std::printf("read line %s\n", readline("fancprompt "));
+  //~ std::printf("read line %s\n", readline("fancprompt "));
+  
+  ioman = new MachineIoManager(argv[1]);
+  // ‘MachineIoManager::MachineIoManager(char*&)’
+  if(ioman->connect()) {
+	  ioman->run();
+  }
+  std::printf("done\n");
 }

+ 8 - 0
cli/src/useriomanager.cpp

@@ -0,0 +1,8 @@
+#include <useriomanager.hpp>
+
+#include <iostream>
+#include <jsoncpp/json/json.h>
+
+void UserIoManager::run() {
+	std::cout << "UserIoManager::run() says hello!" << std::endl;
+}