diff --git a/modules/java/dicom-java-lib/compile.sh b/modules/java/dicom-java-lib/compile.sh
new file mode 100755
index 0000000..f84656f
--- /dev/null
+++ b/modules/java/dicom-java-lib/compile.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+CP="../java-examples/lib/*:classes"
+SP=src/
+
+/bin/rm -f ../xtrabytes-dicom.jar
+/bin/rm -rf classes
+/bin/mkdir -p classes/
+
+javac -encoding utf8 -sourcepath "${SP}" -classpath "${CP}" -d classes/ src/*.java || exit 1
+
+echo "XtraBYtes DICOM java library compiled successfully"
+
+jar cf ../java-examples/lib/xtrabytes-dicom.jar -C classes . || exit 1
+/bin/rm -rf classes
+
+echo "XtraBYtes DICOM java library generated successfully"
diff --git a/modules/java/dicom-java-lib/src/XtraBYtesDICOM.java b/modules/java/dicom-java-lib/src/XtraBYtesDICOM.java
new file mode 100644
index 0000000..c8235eb
--- /dev/null
+++ b/modules/java/dicom-java-lib/src/XtraBYtesDICOM.java
@@ -0,0 +1,167 @@
+package XtraBYtes;
+
+import XtraBYtes.XtraBYtesDservlet;
+import XtraBYtes.XtraBYtesDsignals;
+
+import java.io.IOException;
+
+import org.json.simple.JSONObject;
+import org.json.simple.JSONArray;
+
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ResourceHandler;
+import org.eclipse.jetty.server.handler.DefaultHandler;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.servlet.ServletHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class XtraBYtesDICOM extends XtraBYtesDsignals {
+
+ public String ViewPageOverviewContent() { return ""; }
+
+ private static long HeartbeatTimestamp = 0;
+
+ public static void UpdateHeartbeatTimestamp(long timestamp) {
+ HeartbeatTimestamp = timestamp;
+ }
+
+ private String AcceptedMSG = "Module accepted";
+ private String AcceptedMSG2 = "STOP FLOOD!";
+
+ private JSONObject ModuleConnectionRequest = new JSONObject();
+
+ private Server DICOMserver;
+
+ // 0 = Invalid 1 = Connected 2 = Disconnected
+ private int ModuleStatus=0;
+
+ private boolean ModuleWatchdogStarted = false;
+
+ private ScheduledExecutorService CronThreads = Executors.newScheduledThreadPool(1);
+
+ private final Runnable ModuleWatchdog = new Runnable() {
+ public void run() {
+ if (( ModuleStatus == 1 ) && ((System.currentTimeMillis()-HeartbeatTimestamp)>2000)) {
+ ModuleStatus = 2;
+ System.out.print("Connection lost. Reconnecting.");
+ reconnect();
+ }
+ }
+ };
+
+ public boolean connect(String ModuleName, String ModuleID, int ModulePort, String[] Signals){
+
+ if (!ModuleWatchdogStarted) {
+ CronThreads.scheduleWithFixedDelay(ModuleWatchdog, 0, 1, TimeUnit.SECONDS);
+ ModuleWatchdogStarted = true;
+ }
+
+ ModuleConnectionRequest.put("DICOM","Module-Registration");
+ ModuleConnectionRequest.put("module-name",ModuleName);
+ ModuleConnectionRequest.put("module-id",ModuleID);
+ ModuleConnectionRequest.put("dicom-port",ModulePort);
+ JSONArray signal_wrapper = new JSONArray();
+ for (String signal: Signals) {
+ signal_wrapper.add(signal);
+ }
+ ModuleConnectionRequest.put("signals",signal_wrapper);
+
+ while (true) {
+ XtraBYtesDservlet listenner = new XtraBYtesDservlet();
+ JSONObject response = listenner.SendJsonQuery(ModuleConnectionRequest);
+ if ((AcceptedMSG.equals((String)response.get("DICOM"))) || (AcceptedMSG2.equals((String)response.get("DICOM")))) {
+ System.out.println("OK");
+ DICOMserver = new Server();
+ ServerConnector connector;
+ connector = new ServerConnector(DICOMserver);
+
+ connector.setPort(ModulePort);
+ connector.setHost("127.0.0.1");
+ connector.setIdleTimeout(15000);
+ connector.setReuseAddress(true);
+ DICOMserver.addConnector(connector);
+
+ HandlerList DICOMHandlers = new HandlerList();
+
+ ServletContextHandler DICOMHandler = new ServletContextHandler();
+
+ DICOMHandler.addServlet(XtraBYtesDservlet.class, "/dicom");
+
+ DICOMHandlers.addHandler(DICOMHandler);
+
+ DICOMHandlers.addHandler(new DefaultHandler());
+
+ DICOMserver.setHandler(DICOMHandlers);
+ DICOMserver.setStopAtShutdown(true);
+
+ try {
+ HeartbeatTimestamp = System.currentTimeMillis();
+ DICOMserver.start();
+ System.out.println(ModuleName + " DICOM server started at " + ModulePort + " port.");
+ ModuleStatus = 1;
+ return true;
+ } catch (Exception e) {
+ System.out.println("Failed to start DICOM server.");
+ return false;
+ }
+
+ } // if
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) { }
+ System.out.print(".");
+ }
+ }
+
+ private void reconnect() {
+ while (true) {
+ XtraBYtesDservlet listenner = new XtraBYtesDservlet();
+ JSONObject response = listenner.SendJsonQuery(ModuleConnectionRequest);
+ if ((AcceptedMSG.equals((String)response.get("DICOM"))) || (AcceptedMSG2.equals((String)response.get("DICOM")))) {
+ System.out.println("Reconnected.");
+ ModuleStatus = 1;
+ HeartbeatTimestamp = System.currentTimeMillis();
+ return;
+ }
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ex) { }
+ System.out.print(".");
+ }
+ }
+
+ public void startDICOM(String ModuleName, String ModuleID, int ModulePort, String[] Signals){
+
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ shutdown();
+ }
+ }));
+
+ try {
+ System.out.println("*** Starting XtraBYtes module.");
+ if (!connect( ModuleName, ModuleID, ModulePort, Signals )) throw new Exception("Module registration failed.");
+ System.out.println("*** XtraBYtes module started successfully.");
+ } catch (Exception e) {
+ System.out.println("*** ERROR: "+e.toString());
+ System.out.println("*** XtraBYtes module start FAILED.");
+ }
+
+ }
+
+ public void shutdown() {
+ CronThreads.shutdown();
+ System.out.println("*** XtraBYtes module stopped.");
+ }
+
+}
\ No newline at end of file
diff --git a/modules/java/dicom-java-lib/src/XtraBYtesDservlet.java b/modules/java/dicom-java-lib/src/XtraBYtesDservlet.java
new file mode 100644
index 0000000..cf44e75
--- /dev/null
+++ b/modules/java/dicom-java-lib/src/XtraBYtesDservlet.java
@@ -0,0 +1,129 @@
+package XtraBYtes;
+
+import XtraBYtes.XtraBYtesDICOM;
+
+import org.json.simple.JSONObject;
+import org.json.simple.JSONArray;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.*;
+import java.io.IOException;
+
+import javax.servlet.http.*;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.util.StringContentProvider;
+
+import java.net.*;
+import java.net.InetSocketAddress;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.MalformedURLException;
+
+
+public class XtraBYtesDservlet extends HttpServlet {
+
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
+
+ throws ServletException, IOException {
+ response.setContentType("text/html");
+ PrintWriter ServletOutputStream = response.getWriter();
+ ServletOutputStream.println("
" + "The specified method is not allowed." + "
");
+ }
+
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+
+ throws ServletException, IOException {
+ JSONObject JsonRequest = new JSONObject();
+ try {
+ JsonRequest = (JSONObject)new JSONParser().parse(request.getReader());
+
+ } catch (ParseException e) { e.printStackTrace(); }
+
+ response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, private");
+ response.setHeader("Pragma", "no-cache");
+ response.setDateHeader("Expires", 0);
+ response.setContentType("text/plain; charset=UTF-8");
+
+ JSONObject JsonResponse = new JSONObject();
+
+ switch ( (String) JsonRequest.get("DICOM") ) {
+ case "Heartbeat-Echo-Request": {
+ JsonResponse = DICOM_HeartbeatReq(JsonRequest);
+ } break;
+ case "view-page-overview-content": {
+ JsonResponse = DICOM_ViewPageOverviewContent(JsonRequest);
+ } break;
+
+ default: {
+ JsonResponse.put("error","Bad requestType.");
+ } break;
+ }
+
+ response.setContentType("text");
+ PrintWriter ServletOutputStream = response.getWriter();
+
+ ServletOutputStream.print(JsonResponse.toString());
+ }
+
+ public synchronized JSONObject SendJsonQuery(JSONObject request) {
+
+ JSONObject JSONresponse = new JSONObject();
+
+ try {
+ HttpClient client = new HttpClient();
+ client.setBindAddress(new InetSocketAddress( InetAddress.getByName("127.0.0.1") , 0 ));
+ client.start();
+ ContentResponse response = client.POST("http://127.0.0.1:3344/dicom")
+ .content(new StringContentProvider(request.toString()) , "application/json; charset=UTF-8")
+ .send();
+ client.stop();
+ if ( response.getStatus() == HttpURLConnection.HTTP_OK ) {
+ try {
+ JSONresponse = (JSONObject)new JSONParser().parse(response.getContentAsString());
+ } catch (Exception e) {
+ JSONresponse.put("Error","Failed parsing returned JSON object.");
+ }
+ }
+ } catch (Exception e) {
+ JSONresponse.put("Error","Communication error.");
+ }
+
+ return JSONresponse;
+ }
+
+
+ private JSONObject DICOM_HeartbeatReq( JSONObject JsonRequest ) {
+
+ JSONObject response = new JSONObject();
+
+ try {
+ response.put("DICOM", "Heartbeat-Echo-Reply");
+ XtraBYtesDICOM.UpdateHeartbeatTimestamp(System.currentTimeMillis());
+ } catch (Exception e) {
+ response.put("error",1);
+ }
+
+ return response;
+ }
+
+
+ public JSONObject DICOM_ViewPageOverviewContent( JSONObject JsonRequest ) {
+
+ JSONObject response = new JSONObject();
+
+ try {
+ response.put("DICOM", "view-page-overview-content");
+ response.put("view-page-overview-content", XtraBYtesDICOM.getSignalHandler().ViewPageOverviewContent());
+ } catch (Exception e) {
+ response.put("error",1);
+ }
+
+ return response;
+ }
+
+}
diff --git a/modules/java/dicom-java-lib/src/XtraBYtesDsignals.java b/modules/java/dicom-java-lib/src/XtraBYtesDsignals.java
new file mode 100644
index 0000000..6af462b
--- /dev/null
+++ b/modules/java/dicom-java-lib/src/XtraBYtesDsignals.java
@@ -0,0 +1,21 @@
+package XtraBYtes;
+
+import XtraBYtes.XtraBYtesDICOM;
+
+import org.json.simple.JSONObject;
+
+public abstract class XtraBYtesDsignals {
+
+ protected static XtraBYtesDsignals SignalHandler;
+
+ public static XtraBYtesDsignals getSignalHandler() {
+ return SignalHandler;
+ }
+
+ public void setSignalHandler(XtraBYtesDsignals sh) {
+ SignalHandler = sh;
+ }
+
+ public abstract String ViewPageOverviewContent();
+
+}
\ No newline at end of file
diff --git a/modules/java/java-examples/example1/compile.sh b/modules/java/java-examples/example1/compile.sh
new file mode 100755
index 0000000..7ecd6da
--- /dev/null
+++ b/modules/java/java-examples/example1/compile.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+CP="../lib/*:classes"
+SP=src/
+
+/bin/rm -f example1.jar
+/bin/rm -rf classes
+/bin/mkdir -p classes/
+
+javac -encoding utf8 -sourcepath "${SP}" -classpath "${CP}" -d classes/ src/*.java || exit 1
+
+echo "XtraBYtes example1 module compiled."
+
+jar cf example1.jar -C classes . || exit 1
+/bin/rm -rf classes
+
+echo "The xtrabytes-example1.jar generated successfully."
diff --git a/modules/java/java-examples/example1/example1.jar b/modules/java/java-examples/example1/example1.jar
new file mode 100644
index 0000000..bf292aa
Binary files /dev/null and b/modules/java/java-examples/example1/example1.jar differ
diff --git a/modules/java/java-examples/example1/run.bat b/modules/java/java-examples/example1/run.bat
new file mode 100644
index 0000000..97c9c9b
--- /dev/null
+++ b/modules/java/java-examples/example1/run.bat
@@ -0,0 +1,7 @@
+@ECHO OFF
+IF EXIST java (
+ start "XTRABYTES EXAMPLE1" java -cp example1.jar;lib\* XtraBYtes.Example1
+) ELSE (
+ ECHO Java software not found on your system. Please go to http://java.com/en/ to download a copy of Java.
+)
+
diff --git a/modules/java/java-examples/example1/run.sh b/modules/java/java-examples/example1/run.sh
new file mode 100755
index 0000000..be05628
--- /dev/null
+++ b/modules/java/java-examples/example1/run.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -cp example1.jar:../lib/* XtraBYtes.Example1
diff --git a/modules/java/java-examples/example1/src/Example1.java b/modules/java/java-examples/example1/src/Example1.java
new file mode 100644
index 0000000..9808188
--- /dev/null
+++ b/modules/java/java-examples/example1/src/Example1.java
@@ -0,0 +1,30 @@
+package XtraBYtes;
+
+import XtraBYtes.XtraBYtesDsignals;
+import XtraBYtes.XtraBYtesDICOM;
+
+public class Example1 {
+
+ public static class XBYsignals extends XtraBYtesDsignals {
+
+ public String ViewPageOverviewContent() {
+ return "Hello XtraBYtes ;-)";
+ }
+
+ }
+
+ public static void main(String[] args) {
+
+ XtraBYtesDICOM module = new XtraBYtesDICOM();
+ module.setSignalHandler((XtraBYtesDsignals)new XBYsignals());
+ module.startDICOM(
+ "Example1 Module", // Module name
+ "example1", // Module ID
+ 10001, // Module DICOM port
+ new String[]{ // Signals
+ "view-page-overview-content"
+ }
+ );
+ }
+
+}
diff --git a/modules/java/java-examples/example2/compile.sh b/modules/java/java-examples/example2/compile.sh
new file mode 100755
index 0000000..b51bbfc
--- /dev/null
+++ b/modules/java/java-examples/example2/compile.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+CP="../lib/*:classes"
+SP=src/
+
+/bin/rm -f example2.jar
+/bin/rm -rf classes
+/bin/mkdir -p classes/
+
+javac -encoding utf8 -sourcepath "${SP}" -classpath "${CP}" -d classes/ src/*.java || exit 1
+
+echo "XtraBYtes example2 module compiled."
+
+jar cf example2.jar -C classes . || exit 1
+/bin/rm -rf classes
+
+echo "The example2.jar generated successfully."
diff --git a/modules/java/java-examples/example2/example2.jar b/modules/java/java-examples/example2/example2.jar
new file mode 100644
index 0000000..1839745
Binary files /dev/null and b/modules/java/java-examples/example2/example2.jar differ
diff --git a/modules/java/java-examples/example2/run.bat b/modules/java/java-examples/example2/run.bat
new file mode 100644
index 0000000..8c880b3
--- /dev/null
+++ b/modules/java/java-examples/example2/run.bat
@@ -0,0 +1,7 @@
+@ECHO OFF
+IF EXIST java (
+ start "XTRABYTES EXAMPLE2" java -cp example2.jar;lib\* XtraBYtes.Example2
+) ELSE (
+ ECHO Java software not found on your system. Please go to http://java.com/en/ to download a copy of Java.
+)
+
diff --git a/modules/java/java-examples/example2/run.sh b/modules/java/java-examples/example2/run.sh
new file mode 100755
index 0000000..0addbc4
--- /dev/null
+++ b/modules/java/java-examples/example2/run.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -cp example2.jar:../lib/* XtraBYtes.Example2
diff --git a/modules/java/java-examples/example2/src/Example2.java b/modules/java/java-examples/example2/src/Example2.java
new file mode 100644
index 0000000..fa915c2
--- /dev/null
+++ b/modules/java/java-examples/example2/src/Example2.java
@@ -0,0 +1,39 @@
+package XtraBYtes;
+
+import XtraBYtes.XtraBYtesDsignals;
+import XtraBYtes.XtraBYtesDICOM;
+
+import java.util.Calendar;
+
+public class Example2 {
+
+ public static class XBYsignals extends XtraBYtesDsignals {
+
+ public String ViewPageOverviewContent() {
+
+ Calendar cal = Calendar.getInstance();
+ int hour = cal.get( Calendar.HOUR_OF_DAY );
+
+ if( hour > 5 && hour < 12 ) return "Good morning XBY!";
+ if( hour > 11 && hour < 17 ) return "Good afternoon XBY!";
+ if( hour > 17 && hour < 19 ) return "Good evening XBY!";
+ return "Good night XBY!";
+
+ }
+ }
+
+ public static void main(String[] args) {
+
+ XtraBYtesDICOM module = new XtraBYtesDICOM();
+ module.setSignalHandler((XtraBYtesDsignals)new XBYsignals());
+ module.startDICOM(
+ "Example2 Module", // Module name
+ "example2", // Module ID
+ 10002, // Module DICOM port
+ new String[]{ // Signals
+ "view-page-overview-content"
+ }
+ );
+ }
+
+}
diff --git a/modules/java/java-examples/lib/jetty-client-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-client-9.2.13.v20150730.jar
new file mode 100644
index 0000000..30e2a92
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-client-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-continuation-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-continuation-9.2.13.v20150730.jar
new file mode 100644
index 0000000..a04051f
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-continuation-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-http-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-http-9.2.13.v20150730.jar
new file mode 100644
index 0000000..e6ca1ed
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-http-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-io-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-io-9.2.13.v20150730.jar
new file mode 100644
index 0000000..3fd1d18
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-io-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-security-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-security-9.2.13.v20150730.jar
new file mode 100644
index 0000000..92428c3
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-security-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-server-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-server-9.2.13.v20150730.jar
new file mode 100644
index 0000000..070ef00
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-server-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-servlet-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-servlet-9.2.13.v20150730.jar
new file mode 100644
index 0000000..46604e1
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-servlet-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-servlets-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-servlets-9.2.13.v20150730.jar
new file mode 100644
index 0000000..311a6a0
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-servlets-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/jetty-util-9.2.13.v20150730.jar b/modules/java/java-examples/lib/jetty-util-9.2.13.v20150730.jar
new file mode 100644
index 0000000..93e97ad
Binary files /dev/null and b/modules/java/java-examples/lib/jetty-util-9.2.13.v20150730.jar differ
diff --git a/modules/java/java-examples/lib/json-simple-1.1.1.jar b/modules/java/java-examples/lib/json-simple-1.1.1.jar
new file mode 100644
index 0000000..66347a6
Binary files /dev/null and b/modules/java/java-examples/lib/json-simple-1.1.1.jar differ
diff --git a/modules/java/java-examples/lib/servlet-api-3.1.jar b/modules/java/java-examples/lib/servlet-api-3.1.jar
new file mode 100644
index 0000000..6b14c3d
Binary files /dev/null and b/modules/java/java-examples/lib/servlet-api-3.1.jar differ
diff --git a/modules/java/java-examples/lib/xtrabytes-dicom.jar b/modules/java/java-examples/lib/xtrabytes-dicom.jar
new file mode 100644
index 0000000..e6f7d4d
Binary files /dev/null and b/modules/java/java-examples/lib/xtrabytes-dicom.jar differ
diff --git a/src/dicom.cpp b/src/dicom.cpp
index 16774b5..50cfae3 100644
--- a/src/dicom.cpp
+++ b/src/dicom.cpp
@@ -3,3 +3,316 @@
// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
// Licensed under GNU General Public License Version 3 or later (the "GPL")
+// DICOM - Distributed Command Message
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dicom.h"
+#include "modules.h"
+
+MODULE_SIGNAL GetSignalByName(std::string SignalName) {
+ for (int signal = unknown_signal_first; signal != unknown_signal_last; ++signal) {
+ std::string TmpSignalName = GetSignalName((MODULE_SIGNAL)signal);
+ if(TmpSignalName.compare(SignalName)==0) return (MODULE_SIGNAL)signal;
+ }
+ return unknown_signal_last;
+}
+
+std::string GetSignalName(MODULE_SIGNAL signal) {
+ switch (signal) {
+ case unknown_signal_first :return "unknown-signal-first";
+ case system_blocks_newblock :return "system-blocks-newblock";
+ case view_page_overview_content :return "view-page-overview-content";
+ default:
+ return "unknown-signal";
+ }
+}
+
+DICOMserver::DICOMserver(const std::string& address, const std::string& port, std::size_t thread_pool_size)
+ : thread_pool_size_(thread_pool_size), signals_(io_service_), acceptor_(io_service_), new_DICOMconn_() {
+
+ signals_.add(SIGINT);
+ signals_.add(SIGTERM);
+ #if defined(SIGQUIT)
+ signals_.add(SIGQUIT);
+ #endif // defined(SIGQUIT)
+ signals_.async_wait(boost::bind(&DICOMserver::handle_stop, this));
+
+ boost::asio::ip::tcp::resolver resolver(io_service_);
+ boost::asio::ip::tcp::resolver::query query(address, port);
+ boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
+ acceptor_.open(endpoint.protocol());
+ acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ acceptor_.bind(endpoint);
+ acceptor_.listen();
+
+ start_accept();
+}
+
+void DICOMserver::start() {
+
+ std::vector > threads;
+ for (std::size_t i = 0; i < thread_pool_size_; ++i)
+ {
+ boost::shared_ptr thread(new boost::thread(
+ boost::bind(&boost::asio::io_service::run, &io_service_)));
+ threads.push_back(thread);
+ }
+
+ for (std::size_t i = 0; i < threads.size(); ++i)
+ threads[i]->join();
+
+}
+
+void DICOMserver::start_accept() {
+ new_DICOMconn_.reset(new DICOMconn(io_service_, request_handler_));
+ acceptor_.async_accept(new_DICOMconn_->socket(),
+ boost::bind(&DICOMserver::handle_accept, this,
+ boost::asio::placeholders::error));
+}
+
+void DICOMserver::handle_accept(const boost::system::error_code& e) {
+
+ if (!e) { new_DICOMconn_->start(); }
+ start_accept();
+}
+
+void DICOMserver::handle_stop() {
+
+ io_service_.stop();
+}
+
+request_handler::request_handler() {}
+
+void request_handler::handle_request(const HTTPrequest& req, reply& rep) {
+
+ bool error = false;
+
+ if (req.uri.compare("/dicom") != 0) {
+ rep.status = reply::bad_request;
+ return;
+ }
+
+ std::stringstream ss;
+ ss << req.data;
+ boost::property_tree::ptree JSONrequest;
+ boost::property_tree::read_json(ss, JSONrequest);
+ std::string DICOM = JSONrequest.get("DICOM");
+
+ bool DICOM_command_recognised = false;
+ if(!DICOM.compare("Module-Registration")) {
+ DICOM_command_recognised = true;
+ LogPrint(LL_LOG,"DICOM request: Module-Registration ("+JSONrequest.get("module-id")+")");
+ boost::property_tree::ptree JSONreply = XBY_Modules.ModuleRegistration(JSONrequest);
+ std::stringstream ss;
+ boost::property_tree::json_parser::write_json(ss, JSONreply);
+ rep.content=ss.str();
+ }
+
+ if (!DICOM_command_recognised) {
+ rep.content="{\"DICOM\":\"Bad command.\"}";
+ }
+
+ rep.status = reply::ok;
+
+ rep.headers.resize(2);
+ rep.headers[0].key = "Content-Length";
+ rep.headers[0].value = boost::lexical_cast(rep.content.size());
+ rep.headers[1].key = "Content-Type";
+ rep.headers[1].value = "application/json";
+}
+
+
+DICOMconn::DICOMconn(boost::asio::io_service& io_service, request_handler& handler)
+ : strand_(io_service), socket_(io_service), request_handler_(handler) { }
+
+boost::asio::ip::tcp::socket& DICOMconn::socket() {
+
+ return socket_;
+}
+
+void DICOMconn::start() {
+ socket_.async_read_some(boost::asio::buffer(buffer_),
+ strand_.wrap( boost::bind(&DICOMconn::handle_read, shared_from_this(),
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred)));
+}
+
+void DICOMconn::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) {
+
+ if (!e) {
+ boost::tribool result;
+
+ boost::tie(result, boost::tuples::ignore) = request_parser_.parse(
+ request_, buffer_.data(), buffer_.data() + bytes_transferred);
+
+ if (result) {
+ request_handler_.handle_request(request_, reply_);
+
+ boost::asio::async_write(socket_, reply_.to_buffers(),
+ strand_.wrap(
+ boost::bind(&DICOMconn::handle_write, shared_from_this(),
+ boost::asio::placeholders::error)));
+ } else if (!result) {
+ reply_.status = reply::bad_request;
+ boost::asio::async_write(socket_, reply_.to_buffers(),
+ strand_.wrap(
+ boost::bind(&DICOMconn::handle_write, shared_from_this(),
+ boost::asio::placeholders::error)));
+ } else {
+ socket_.async_read_some(boost::asio::buffer(buffer_),
+ strand_.wrap(
+ boost::bind(&DICOMconn::handle_read, shared_from_this(),
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred)));
+ }
+ }
+
+}
+
+void DICOMconn::handle_write(const boost::system::error_code& e) {
+ if (!e) {
+ boost::system::error_code ignored_ec;
+ socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
+ }
+}
+
+
+std::vector reply::to_buffers()
+{
+ std::vector buffers;
+
+ switch (status) {
+ case reply::ok:
+ buffers.push_back(boost::asio::buffer(HTTP_STATUS_STR_OK)); break;
+ case reply::bad_request:
+ buffers.push_back(boost::asio::buffer(HTTP_STATUS_STR_BAD_REQUEST)); break;
+ default:
+ buffers.push_back(boost::asio::buffer(HTTP_STATUS_STR_SERVER_ERROR));
+ }
+
+ for (std::size_t i = 0; i < headers.size(); ++i)
+ {
+ KeyValue& h = headers[i];
+ buffers.push_back(boost::asio::buffer(h.key));
+ buffers.push_back(boost::asio::buffer(KEY_VALUE_SEPARATOR_CHARS));
+ buffers.push_back(boost::asio::buffer(h.value));
+ buffers.push_back(boost::asio::buffer(CRLF_CHARS));
+ }
+ buffers.push_back(boost::asio::buffer(CRLF_CHARS));
+ buffers.push_back(boost::asio::buffer(content));
+ return buffers;
+}
+
+
+DICOMclient::DICOMclient( boost::asio::io_service& s ) :ios(s),sock(s) {
+ dc = new DICOMclient(s,this);
+}
+
+DICOMclient::DICOMclient( boost::asio::io_service& s, DICOMclient *c ) :ios(s),sock(s) {}
+
+DICOMclient::~DICOMclient() {}
+
+boost::property_tree::ptree DICOMclient::request( const std::string& json )
+ {
+
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ sock.close();
+ sock.connect( ep, error );
+ if( error ) {
+ throw boost::system::system_error(error);
+ }
+
+ boost::asio::streambuf request_buf;
+ std::ostream request_info(&request_buf);
+ request_info << "POST /dicom HTTP/1.1\n";
+ request_info << "Host: 127.0.0.1\n";
+ request_info << "Content-Type: application/json-rpc\n";
+ request_info << "Content-Length: "<ios);
+ tcp::resolver::query q("127.0.0.1",NumberToString(module->DICOMport));
+ tcp::resolver::iterator epi = resolver.resolve(q);
+ tcp::resolver::iterator end;
+
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ int tries = 0;
+ while( error && epi != end )
+ {
+ if (tries++ > 1) return;
+ dc->sock.close();
+ dc->sock.connect( *epi, error );
+ }
+ if( error ) { return; }
+ dc->ep = *epi;
+
+ boost::property_tree::ptree pt = dc->request("{\"DICOM\": \"Heartbeat-Echo-Request\" }");
+
+ module->LastHeartbeat = time(NULL);
+}
+
+
+boost::property_tree::ptree DICOMclient::ModuleRequest(XBYmodule* module, boost::property_tree::ptree *req) {
+
+ boost::property_tree::ptree reply;
+ tcp::resolver resolver(dc->ios);
+ tcp::resolver::query q("127.0.0.1",NumberToString(module->DICOMport));
+ tcp::resolver::iterator epi = resolver.resolve(q);
+ tcp::resolver::iterator end;
+
+ boost::system::error_code error = boost::asio::error::host_not_found;
+ int tries = 0;
+ while( error && epi != end )
+ {
+ if (tries++ > 1) return reply;
+ dc->sock.close();
+ dc->sock.connect( *epi, error );
+ }
+ if( error ) { return reply; }
+ dc->ep = *epi;
+
+ std::stringstream ss;
+ write_json(ss, *req);
+ reply = dc->request(ss.str());
+
+ return reply;
+}
\ No newline at end of file
diff --git a/src/dicom.h b/src/dicom.h
index 170526d..fd66a7d 100644
--- a/src/dicom.h
+++ b/src/dicom.h
@@ -3,8 +3,124 @@
// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
// Licensed under GNU General Public License Version 3 or later (the "GPL")
+// DICOM - Distributed Command Message
+
#ifndef XBY_DICOM_H
#define XBY_DICOM_H
+#ifdef _WIN32
+ #include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "util.h"
+
+class XBYmodule;
+
+using boost::asio::ip::tcp;
+
+enum MODULE_SIGNAL {
+ unknown_signal_first,
+ system_blocks_newblock,
+ view_page_overview_content,
+ unknown_signal_last
+};
+
+MODULE_SIGNAL GetSignalByName(std::string SignalName);
+std::string GetSignalName(MODULE_SIGNAL signal);
+
+struct reply {
+
+ enum status_type { ok = 200, bad_request = 400, internal_server_error = 500 } status;
+
+ std::vector headers;
+ std::string content;
+ std::vector to_buffers();
+
+};
+
+
+class request_handler : private boost::noncopyable {
+
+ public:
+ explicit request_handler();
+ void handle_request(const HTTPrequest& req, reply& rep);
+
+};
+
+class DICOMconn : public boost::enable_shared_from_this, private boost::noncopyable {
+
+ public:
+
+ explicit DICOMconn(boost::asio::io_service& io_service, request_handler& handler);
+ boost::asio::ip::tcp::socket& socket();
+ void start();
+
+ private:
+
+ void handle_read(const boost::system::error_code& e, std::size_t bytes_transferred);
+ void handle_write(const boost::system::error_code& e);
+
+ boost::asio::io_service::strand strand_;
+ boost::asio::ip::tcp::socket socket_;
+ request_handler& request_handler_;
+ boost::array buffer_;
+ HTTPrequest request_;
+ HTTP_RequestParser request_parser_;
+ reply reply_;
+};
+
+typedef boost::shared_ptr DICOMconn_ptr;
+
+class DICOMserver : private boost::noncopyable {
+
+ public:
+ explicit DICOMserver(const std::string& address, const std::string& port, std::size_t thread_pool_size);
+ void start();
+
+
+ private:
+ void start_accept();
+ void handle_accept(const boost::system::error_code& e);
+ void handle_stop();
+
+ std::size_t thread_pool_size_;
+ boost::asio::io_service io_service_;
+ boost::asio::signal_set signals_;
+ boost::asio::ip::tcp::acceptor acceptor_;
+ DICOMconn_ptr new_DICOMconn_;
+ request_handler request_handler_;
+
+};
+
+class DICOMclient {
+
+ public:
+ DICOMclient( boost::asio::io_service& s );
+ DICOMclient( boost::asio::io_service& s, DICOMclient *c );
+ ~DICOMclient();
+
+ boost::asio::io_service& ios;
+ tcp::socket sock;
+ tcp::endpoint ep;
+
+ boost::property_tree::ptree request( const std::string& json );
+ boost::property_tree::ptree ModuleRequest(XBYmodule* module, boost::property_tree::ptree *request);
+
+ void HeartbeatEchoRequest(XBYmodule* module);
+
+ private:
+ DICOMclient* dc;
+
+
+};
#endif // XBY_DICOM_H
diff --git a/src/gui.cpp b/src/gui.cpp
index 978a32f..cfbd0d3 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -4,30 +4,6 @@
// Licensed under GNU General Public License Version 3 or later (the "GPL")
-#include
-
-#include "gui.h"
-
-void GUI::displayNumConnections(int i) {
- if ( overviewPage != NULL ) {
- overviewPage->SetlabelAlerts(QString::number(i));
- }
-
-}
-
-void GUI::displayText(std::string text) {
- if ( overviewPage != NULL ) {
- overviewPage->SetlabelAlerts(QString::fromUtf8(text.c_str()));
- }
-
-}
-
-
-void GUI::initOverviewPage(OverviewPage *op ) {
- overviewPage = op;
-}
-
-GUI gui;
// XBridgeInterface xbridgeinterface;
diff --git a/src/gui.h b/src/gui.h
index e768593..546d650 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -6,20 +6,5 @@
#ifndef XBY_GUI_H
#define XBY_GUI_H
-#include "xtrabytesgui.h"
-#include "overviewpage.h"
-
-class GUI {
- public:
- void displayNumConnections(int i);
- void displayText(std::string text);
- void initOverviewPage(OverviewPage *op );
- private:
- OverviewPage *overviewPage;
- XBridgeModel *xbridgemodel;
-
-};
-
-extern GUI gui;
#endif // XBY_GUI_H
diff --git a/src/gui/forms/modulespage.ui b/src/gui/forms/modulespage.ui
new file mode 100644
index 0000000..a51d2c2
--- /dev/null
+++ b/src/gui/forms/modulespage.ui
@@ -0,0 +1,25 @@
+
+
+ ModulesPage
+
+
+ Form
+
+
+ -
+
+
+ true
+
+
+ background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #CCCCCC, stop:1 #FFFFFF); color:#000000
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gui/forms/overviewpage.ui b/src/gui/forms/overviewpage.ui
index b253219..99d34a0 100644
--- a/src/gui/forms/overviewpage.ui
+++ b/src/gui/forms/overviewpage.ui
@@ -7,7 +7,7 @@
-
-
+
true
diff --git a/src/gui/models/guimodel.cpp b/src/gui/models/guimodel.cpp
new file mode 100644
index 0000000..46bc74f
--- /dev/null
+++ b/src/gui/models/guimodel.cpp
@@ -0,0 +1,39 @@
+// XtraBYtes - The Proof of Signature Blocktech Superchain - http://xtrabytes.global
+// Copyright (c) 2017, Zoltan Szabo. All rights reserved.
+// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
+// Licensed under GNU General Public License Version 3 or later (the "GPL")
+
+#include "guimodel.h"
+#include "../gui.h"
+
+GuiModel::GuiModel(QObject *parent ) :
+ QObject(parent)
+{
+ ModelSignalsConnected = false;
+}
+
+void GuiModel::init(OverviewPage *overviewPage , ModulesPage *modulesPage ) {
+ GuiModel::overviewPage = overviewPage;
+ GuiModel::modulesPage = modulesPage;
+ ConnectModelSignals();
+ ModelSignalsConnected = true;
+}
+
+GuiModel::~GuiModel()
+{
+ if (ModelSignalsConnected) {
+ DisconnectModelSignals();
+ }
+
+}
+
+void GuiModel::ConnectModelSignals(){
+ connect( this, SIGNAL(ModuleListChanged()), modulesPage, SLOT(UpdateModuleWidgets()));
+ connect( this, SIGNAL(OverviewPageContentChanged()), overviewPage, SLOT(UpdateOverviewPageContent()));
+
+
+}
+
+void GuiModel::DisconnectModelSignals(){
+}
+
diff --git a/src/gui/models/guimodel.h b/src/gui/models/guimodel.h
new file mode 100644
index 0000000..78cec87
--- /dev/null
+++ b/src/gui/models/guimodel.h
@@ -0,0 +1,41 @@
+// XtraBYtes - The Proof of Signature Blocktech Superchain - http://xtrabytes.global
+// Copyright (c) 2017, Zoltan Szabo. All rights reserved.
+// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
+// Licensed under GNU General Public License Version 3 or later (the "GPL")
+
+#ifndef GUIMODEL_H
+#define GUIMODEL_H
+
+#include
+
+#include "../overviewpage.h"
+#include "../modulespage.h"
+
+
+class GuiModel : public QObject {
+
+ Q_OBJECT
+
+ public:
+ explicit GuiModel(QObject *parent = 0);
+ void init(OverviewPage *overviewPage , ModulesPage *modulesPage );
+ ~GuiModel();
+
+ private:
+ void ConnectModelSignals();
+ void DisconnectModelSignals();
+ bool ModelSignalsConnected;
+ OverviewPage *overviewPage;
+ ModulesPage *modulesPage;
+
+ signals:
+ void ModuleListChanged();
+ void OverviewPageContentChanged();
+
+};
+
+
+
+
+
+#endif // GUIMODEL_H
diff --git a/src/gui/models/m-xbridge.cpp b/src/gui/models/m-xbridge.cpp
deleted file mode 100644
index 19d3b9d..0000000
--- a/src/gui/models/m-xbridge.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// XtraBYtes - The Proof of Signature Blocktech Superchain - http://xtrabytes.global
-// Copyright (c) 2017, Zoltan Szabo. All rights reserved.
-// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
-// Licensed under GNU General Public License Version 3 or later (the "GPL")
-
-#include "m-xbridge.h"
-#include "../gui.h"
-#include "overviewpage.h"
-
-XBridgeModel::XBridgeModel(QObject *parent) :
- QObject(parent)
-{
- ConnectModelSignals();
-}
-
-XBridgeModel::~XBridgeModel()
-{
- DisconnectModelSignals();
-}
-
-void XBridgeModel::ConnectModelSignals(){
-}
-
-void XBridgeModel::DisconnectModelSignals(){
-}
-
-void XBridgeModel::update_numBlocks(int numBlocks)
-{
- emit changed_numBlocks(numBlocks);
-}
\ No newline at end of file
diff --git a/src/gui/models/m-xbridge.h b/src/gui/models/m-xbridge.h
deleted file mode 100644
index 148b6cd..0000000
--- a/src/gui/models/m-xbridge.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// XtraBYtes - The Proof of Signature Blocktech Superchain - http://xtrabytes.global
-// Copyright (c) 2017, Zoltan Szabo. All rights reserved.
-// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
-// Licensed under GNU General Public License Version 3 or later (the "GPL")
-
-#ifndef M_XBRIDGE_H
-#define M_XBRIDGE_H
-
-#include
-
-class XBridgeModel : public QObject {
-
- Q_OBJECT
-
- public:
- explicit XBridgeModel(QObject *parent = 0);
- ~XBridgeModel();
-
- private:
- void ConnectModelSignals();
- void DisconnectModelSignals();
-
- signals:
- void changed_numBlocks(int numBlocks);
-
- public slots:
- void update_numBlocks(int numBlocks);
-
-};
-
-
-
-
-
-#endif // M_XBRIDGE_H
diff --git a/src/gui/modulespage.cpp b/src/gui/modulespage.cpp
new file mode 100644
index 0000000..1872a3d
--- /dev/null
+++ b/src/gui/modulespage.cpp
@@ -0,0 +1,76 @@
+// XtraBYtes - The Proof of Signature Blocktech Superchain - http://xtrabytes.global
+// Copyright (c) 2017, Zoltan Szabo. All rights reserved.
+// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
+// Licensed under GNU General Public License Version 3 or later (the "GPL")
+
+#include "modulespage.h"
+#include "ui_modulespage.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+ModulesPage::ModulesPage(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ModulesPage)
+{
+ ui->setupUi(this);
+
+ modulelistlayout = new QGridLayout();
+ modulelistlayout->setMargin(10);
+ ui->contentLayout->addLayout(modulelistlayout);
+
+ //emit ModuleListChanged();
+
+ QHBoxLayout* bottomLayout = new QHBoxLayout();
+ QPushButton* btn1 = new QPushButton(QObject::tr("OK"));
+ bottomLayout->addStretch();
+ bottomLayout->addWidget(btn1);
+ bottomLayout->addStretch();
+ ui->contentLayout->addLayout(bottomLayout);
+
+
+}
+
+ModulesPage::~ModulesPage() {
+
+ std::map >::iterator itr = ModuleContainerWrapper.begin();
+ while (itr != ModuleContainerWrapper.end()) {
+ std::vector ModuleContainer = (*itr).second;
+ LogPrint(LL_LOG,"ModulesPage: "+ModuleContainer.back()->module->ModuleID+" removed.");
+ while(!ModuleContainer.empty()) {
+ delete ModuleContainer.back();
+ ModuleContainer.pop_back();
+ }
+ ModuleContainerWrapper.erase(itr++);
+ }
+
+
+ delete ui;
+}
+
+void ModulesPage::UpdateModuleWidgets() {
+
+ int i = 0;
+ for( std::vector::iterator itr = XBY_Modules.modules.begin(), itr_end = XBY_Modules.modules.end(); itr != itr_end; ++itr ) {
+
+ ModuleContainer *module_container = new ModuleContainer(*itr);
+ ModuleContainerWrapper[(*itr)->ModuleID].push_back( module_container );
+
+ modulelistlayout->addWidget(module_container->GetModuleDescription(),i,0);
+ modulelistlayout->addWidget(module_container->GetOnOffButtonAddr(),i,1);
+
+ i++;
+ }
+
+}
+
+
+
\ No newline at end of file
diff --git a/src/gui/modulespage.h b/src/gui/modulespage.h
new file mode 100644
index 0000000..732f837
--- /dev/null
+++ b/src/gui/modulespage.h
@@ -0,0 +1,105 @@
+// XtraBYtes - The Proof of Signature Blocktech Superchain - http://xtrabytes.global
+// Copyright (c) 2017, Zoltan Szabo. All rights reserved.
+// Copyright (c) 2017, XtraBYtes Founders and Developers ( see AUTHORS )
+// Licensed under GNU General Public License Version 3 or later (the "GPL")
+
+#ifndef MODULESPAGE_H
+#define MODULESPAGE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include