diff --git a/.idea/artifacts/SIPIntercom_jar.xml b/.idea/artifacts/SIPIntercom_jar.xml
new file mode 100644
index 0000000..15d61e4
--- /dev/null
+++ b/.idea/artifacts/SIPIntercom_jar.xml
@@ -0,0 +1,52 @@
+
+
+ $PROJECT_DIR$/out/artifacts/SIPIntercom_jar
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
new file mode 100644
index 0000000..d516610
--- /dev/null
+++ b/.idea/deployment.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/corundumstudio_socketio_netty.xml b/.idea/libraries/corundumstudio_socketio_netty.xml
new file mode 100644
index 0000000..08cf220
--- /dev/null
+++ b/.idea/libraries/corundumstudio_socketio_netty.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/webServers.xml b/.idea/webServers.xml
new file mode 100644
index 0000000..e98c3ed
--- /dev/null
+++ b/.idea/webServers.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Properties/config.properties b/Properties/config.properties
index e581083..f008b5a 100644
--- a/Properties/config.properties
+++ b/Properties/config.properties
@@ -1,6 +1,7 @@
WebUsername=admin
WebPassword=admin
WebListenPort = 8080
-SipServer=100.64.0.3
-SipUsername=100
-SipPassword=12345678
\ No newline at end of file
+SipServer=rdkartono.ddns.me
+SipPort=5060
+SipUsername=101
+SipPassword=password101
\ No newline at end of file
diff --git a/SIPIntercom.iml b/SIPIntercom.iml
index 7208ba6..44e6f58 100644
--- a/SIPIntercom.iml
+++ b/SIPIntercom.iml
@@ -15,5 +15,6 @@
+
\ No newline at end of file
diff --git a/libs/META-INF/MANIFEST.MF b/libs/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5ee19cb
--- /dev/null
+++ b/libs/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Main
+
diff --git a/src/Main.java b/src/Main.java
index af140a8..afaf54c 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -1,25 +1,23 @@
-import SBC.GpioInput;
-import SBC.GpioOutput;
-import SBC.NanopiDuo2;
+import SBC.*;
import SIP.SIP_Request;
import SIP.SIP_Response;
import SIP.jSIPClient;
import SIP.javaSipEvents;
-import Webpage.WebServer;
+import Webpage.*;
import code.common;
+import com.google.gson.JsonSyntaxException;
import org.pmw.tinylog.Logger;
import java.io.File;
import java.text.MessageFormat;
-import java.util.Properties;
-import java.util.Timer;
-import java.util.TimerTask;
+import java.util.*;
-import static code.common.currentDir;
+import static code.common.*;
public class Main {
private static jSIPClient client;
private static WebServer webserver;
+ private static SocketioServer socketioserver;
private static GpioInput callButton;
private static GpioInput hangupButton;
private static GpioOutput pilotLight;
@@ -27,12 +25,21 @@ public class Main {
private static GpioOutput callLight;
private static GpioOutput Buzzer;
private static Timer timer;
+ private static Timer system_monitoring_timer;
private static TimerTask callLightTask;
private static TimerTask BuzzerTask;
private static SIP_Request incomingRequest;
private static SIP_Request oncallRequest;
private static SIP_Response incomingResponse;
private static SIP_Response oncallResponse;
+ private static String SipStatus = "Idle";
+ private static int cpuTemperature;
+ private static RamInformation ramInformation;
+ private static ProcessorStatus[] previousCpuInfo;
+ private static final Map cpuUsage = new HashMap<>();
+ private static NetworkTransmitReceiveInfo[] previousNetworkInfo;
+ private static final Map networkTX = new HashMap<>();
+ private static final Map networkRX = new HashMap<>();
public static void main(String[] args) {
common.ExtractProperties(currentDir,"config.properties", false);
@@ -40,18 +47,6 @@ public class Main {
// Timer Section
timer = new Timer();
- callLightTask = new TimerTask() {
- @Override
- public void run() {
- if (callLight!=null && callLight.isInitialized()) callLight.BlinkON(100);
- }
- };
- BuzzerTask = new TimerTask() {
- @Override
- public void run() {
- if (Buzzer!=null && Buzzer.isInitialized()) Buzzer.BlinkON(500);
- }
- };
// SIP Section
client = new jSIPClient(config);
@@ -61,6 +56,7 @@ public class Main {
Logger.info("Registering to SIP Server, Request: {}",req);
Buzzer_Off();
callLight_Registering();
+ SipStatus = "Registering";
}
@Override
@@ -68,12 +64,16 @@ public class Main {
Logger.info("Registered to SIP Server, Response: {}",resp);
Buzzer_Off();
callLight_Idle();
+ Logger.info("Calling callLight idle from RegisterSuccesful");
+ SipStatus = "Idle";
+ CallTest("100");
}
@Override
public void RegisterFailed(SIP_Response resp) {
Logger.info("Failed to register to SIP Server, Response: {}",resp);
Buzzer_Off();
+ SipStatus = "Register Failed";
}
@Override
@@ -85,6 +85,7 @@ public class Main {
incomingResponse = resp;
oncallRequest = null;
oncallResponse = null;
+ SipStatus = "Incoming Call from "+req.CallID;
//client.AcceptIncomingCall(req);
}
@@ -92,9 +93,11 @@ public class Main {
public void RemoteHangUp(SIP_Request req) {
Logger.info("Remote Hangup, Request: {}",req);
callLight_Idle();
+ Logger.info("Calling callLight idle from RemoteHangUp");
Buzzer_Off();
client.HangUp();
+ SipStatus = "Remote Hangup from "+req.CallID;
incomingRequest = null;
incomingResponse = null;
oncallRequest = null;
@@ -105,79 +108,144 @@ public class Main {
@Override
public void Ringing(SIP_Response resp) {
Logger.info("Ringing, Response: {}",resp);
+ SipStatus = "Incoming Call from "+resp.CallID;
}
@Override
public void CalleePickup(SIP_Response resp) {
Logger.info("Callee Pickup, Response: {}",resp);
+ SipStatus = "Communication with "+resp.CallID;
}
});
- ReconnectSIP();
+ client.Connect();
// Web Server Section
webserver = new WebServer(config);
webserver.Start();
+ socketioserver = new SocketioServer("0.0.0.0", 9092);
+ socketioserver.Start();
+ socketioserver.setOnRequest(req ->{
+ // Ada request dari web
+ SocketioResponse resp;
+ if (networkLight!=null && networkLight.isInitialized()) networkLight.BlinkON(100);
+
+ switch(req.getRequest()){
+ case "setLogin":
+ try{
+ LoginSetting login = gson.fromJson(req.getData(), LoginSetting.class);
+ if (ValidString(login.Username) && ValidString(login.Password)){
+ config.setProperty("WebUsername", login.Username);
+ config.setProperty("WebPassword", login.Password);
+ if (SaveProperties(currentDir,"config.properties",config)){
+ resp = new SocketioResponse("success", "Login Setting");
+ } else throw new Exception("Failed to save properties");
+ } else throw new Exception("Invalid Username or Password");
+ } catch (JsonSyntaxException e){
+ resp = new SocketioResponse("error", "Invalid JSON");
+ } catch (Exception e){
+ resp = new SocketioResponse("error", e.getMessage());
+ }
+ break;
+ case "getLogin":
+ resp = SocketioResponse.fromLoginSetting("success", new LoginSetting(config.getProperty("WebUsername"), config.getProperty("WebPassword")));
+ break;
+ case "setSipSetting":
+ try{
+ SipSetting sip = gson.fromJson(req.getData(), SipSetting.class);
+ if (ValidString(sip.Server) && ValidString(sip.Username) && ValidString(sip.Password)){
+ config.setProperty("SipServer", sip.Server);
+ config.setProperty("SipPort", String.valueOf(sip.Port));
+ config.setProperty("SipUsername", sip.Username);
+ config.setProperty("SipPassword", sip.Password);
+ if (SaveProperties(currentDir,"config.properties",config)){
+ resp = new SocketioResponse("success", "SIP Setting");
+ } else throw new Exception("Failed to save properties");
+ } else throw new Exception("Invalid SIP Setting");
+ } catch (JsonSyntaxException e){
+ resp = new SocketioResponse("error", "Invalid JSON");
+ } catch (Exception e){
+ resp = new SocketioResponse("error", e.getMessage());
+ }
+ break;
+ case "getSipSetting":
+ resp = SocketioResponse.fromSipSetting("success", new SipSetting(config.getProperty("SipServer"), Integer.parseInt(config.getProperty("SipPort")), config.getProperty("SipUsername"), config.getProperty("SipPassword")));
+ break;
+ case "getSipStatus":
+ resp = new SocketioResponse("success", SipStatus);
+ break;
+ case "hangup":
+ if (incomingRequest!=null){
+ resp = new SocketioResponse("success", "Reject Incoming Call from "+incomingRequest.CallID);
+ hangupCall();
+ } else if (oncallRequest!=null){
+ resp = new SocketioResponse("success", "Hangup Call to "+oncallRequest.CallID);
+ hangupCall();
+ } else {
+ resp = new SocketioResponse("error", "No Call to Hangup");
+ }
+ break;
+ case "getRamInfo":
+ if (ramInformation!=null){
+ resp = SocketioResponse.fromRamInformation("success", ramInformation);
+ } else {
+ resp = new SocketioResponse("error", "Failed to get RAM Information");
+ }
+ break;
+ case "getCpuInfo":
+ if (cpuTemperature>0 && !cpuUsage.isEmpty()){
+ resp = SocketioResponse.fromCpuStatus("success", cpuTemperature, cpuUsage);
+ } else {
+ resp = new SocketioResponse("error", "Failed to get CPU Information");
+ }
+ break;
+ case "getNetworkInfo":
+ if (!networkTX.isEmpty() && !networkRX.isEmpty()){
+ resp = SocketioResponse.fromTxRxMap("success", networkTX, networkRX);
+ } else {
+ resp = new SocketioResponse("error", "Failed to get Network Information");
+ }
+ break;
+ case "call":
+ case "getDiskInfo":
+ resp = new SocketioResponse("error", "Not Implemented");
+ break;
+ default:
+ resp = new SocketioResponse("error", "Invalid Request");
+ break;
+ }
+ return resp;
+ });
// GPIO Section
+ // talk button = pin12
+ // hangup button = pin14
+ // Call light = pin 22
+ // Network light = pin 20
callButton = new GpioInput(NanopiDuo2.Pin12.gpionumber, true);
if (callButton.isInitialized()){
callButton.setOnLongPress(vv->{
Logger.info("Call Button Long Pressed");
- if (incomingRequest!=null && incomingResponse!=null){
- client.AcceptIncomingCall(incomingRequest);
- callLight_OnCall();
- Buzzer_OnCall();
- oncallRequest = incomingRequest;
- oncallResponse = incomingResponse;
- incomingRequest = null;
- incomingResponse = null;
- }
+ pickupCall();
});
callButton.setOnShortPress(vv->{
Logger.info("Call Button Short Pressed");
- if (incomingRequest!=null && incomingResponse!=null){
- client.AcceptIncomingCall(incomingRequest);
- callLight_OnCall();
- Buzzer_OnCall();
- oncallRequest = incomingRequest;
- oncallResponse = incomingResponse;
- incomingRequest = null;
- incomingResponse = null;
- }
+ pickupCall();
});
}
hangupButton = new GpioInput(NanopiDuo2.Pin14.gpionumber, true);
if (hangupButton.isInitialized()){
hangupButton.setOnShortPress(vv->{
Logger.info("Hangup Button Short Pressed");
- if (oncallRequest!=null || oncallResponse!=null){
- client.HangUp();
- oncallResponse = null;
- oncallRequest = null;
- } else if (incomingRequest!=null || incomingResponse!=null){
- client.RejectIncomingCall(incomingRequest);
- incomingRequest = null;
- incomingResponse = null;
- }
- callLight_Idle();
- Buzzer_Off();
+ hangupCall();
});
hangupButton.setOnLongPress(vv->{
Logger.info("Hangup Button Long Pressed");
- if (oncallRequest!=null || oncallResponse!=null){
- client.HangUp();
- oncallResponse = null;
- oncallRequest = null;
- } else if (incomingRequest!=null || incomingResponse!=null){
- client.RejectIncomingCall(incomingRequest);
- incomingRequest = null;
- incomingResponse = null;
- }
- callLight_Idle();
- Buzzer_Off();
+ hangupCall();
});
}
+
+ // belum ada pinout nya di PCB demo (04/12/2024)
pilotLight = new GpioOutput(NanopiDuo2.Pin16.gpionumber, true);
if (pilotLight.isInitialized()){
timer.scheduleAtFixedRate(new TimerTask() {
@@ -187,27 +255,72 @@ public class Main {
}
}, 0, 1000);
}
- networkLight = new GpioOutput(NanopiDuo2.Pin18.gpionumber, true);
- callLight = new GpioOutput(NanopiDuo2.Pin20.gpionumber, true);
- Buzzer = new GpioOutput(NanopiDuo2.Pin22.gpionumber, true);
+
+ networkLight = new GpioOutput(NanopiDuo2.Pin20.gpionumber, true);
+ callLight = new GpioOutput(NanopiDuo2.Pin22.gpionumber, true);
+
+ // belum ada pinout nya di PCB demo (04/12/2024)
+ Buzzer = new GpioOutput(NanopiDuo2.Pin18.gpionumber, true);
+
+ // Start System monitoring
+ init_system_monitoring();
// Shutdown Hook
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
Logger.info("Shutting down SIPIntercom");
if (client!=null) client.Disconnect();
if (webserver!=null) webserver.Stop();
+ if (socketioserver!=null) socketioserver.Stop();
if (callButton!=null && callButton.isInitialized()) callButton.Close();
if (hangupButton!=null && hangupButton.isInitialized()) hangupButton.Close();
if (pilotLight!=null && pilotLight.isInitialized()) pilotLight.Close();
if (networkLight!=null && networkLight.isInitialized()) networkLight.Close();
if (callLight!=null && callLight.isInitialized()) callLight.Close();
if (timer!=null) timer.cancel();
+ if (system_monitoring_timer!=null) system_monitoring_timer.cancel();
}));
}
+ /**
+ * Hangup call
+ */
+ private static void hangupCall() {
+ if (oncallRequest!=null || oncallResponse!=null){
+ client.HangUp();
+ oncallResponse = null;
+ oncallRequest = null;
+ } else if (incomingRequest!=null || incomingResponse!=null){
+ client.RejectIncomingCall(incomingRequest);
+ incomingRequest = null;
+ incomingResponse = null;
+ }
+ callLight_Idle();
+ Buzzer_Off();
+ SipStatus = "Idle";
+ }
+
+ /**
+ * Pickup incoming call
+ */
+ private static void pickupCall() {
+ if (incomingRequest!=null && incomingResponse!=null){
+ client.AcceptIncomingCall(incomingRequest);
+ callLight_OnCall();
+ Buzzer_OnCall();
+ oncallRequest = incomingRequest;
+ oncallResponse = incomingResponse;
+ incomingRequest = null;
+ incomingResponse = null;
+ SipStatus = "Communication with "+oncallRequest.CallID;
+ }
+ }
+ private static String CreateSipCallNumber(String extension){
+ return MessageFormat.format("sip:{0}@{1}", extension, client.getServerAddress());
+ }
+
@SuppressWarnings("unused")
private static void CallTest(String extension){
- String callnumber = MessageFormat.format("sip:{0}@{1}", extension, client.getServerAddress());
+ String callnumber = CreateSipCallNumber(extension);
if (client.Call(callnumber)){
Logger.info("Call to {} is successful",callnumber);
try{
@@ -240,27 +353,17 @@ public class Main {
} else Logger.error("File not found: {}",ff.getAbsolutePath());
}
- private static void ReconnectSIP(){
- if (client.Connect()){
- Logger.info("Connected to SIP Server");
- }
- else{
- Logger.error("Failed to connect to SIP Server");
- try {
- Thread.sleep(20*1000);
- } catch (InterruptedException ignored) {
- }
- ReconnectSIP();
- }
- }
-
/**
* Registering state, call light is blinking with 500ms interval
*/
private static void callLight_Registering(){
- if (callLightTask!=null) callLightTask.cancel();
+ if (callLightTask!=null) {
+ callLightTask.cancel();
+ callLightTask = null;
+ }
if (timer!=null){
timer.purge();
+ callLightTask = CreateCallLightTask();
timer.scheduleAtFixedRate(callLightTask, 0, 500);
}
}
@@ -269,9 +372,13 @@ public class Main {
* Idle state, call light is blinking with interval 3000ms
*/
private static void callLight_Idle(){
- if (callLightTask!=null) callLightTask.cancel();
+ if (callLightTask!=null) {
+ callLightTask.cancel();
+ callLightTask = null;
+ }
if (timer!=null){
timer.purge();
+ callLightTask = CreateCallLightTask();
timer.scheduleAtFixedRate(callLightTask, 0, 3000);
}
}
@@ -280,9 +387,13 @@ public class Main {
* Incoming call, call light is blinking with 1000ms interval
*/
private static void callLight_IncomingCall(){
- if (callLightTask!=null) callLightTask.cancel();
+ if (callLightTask!=null) {
+ callLightTask.cancel();
+ callLightTask = null;
+ }
if (timer!=null){
timer.purge();
+ callLightTask = CreateCallLightTask();
timer.scheduleAtFixedRate(callLightTask, 0, 1000);
}
}
@@ -291,7 +402,10 @@ public class Main {
* On call, call light is on
*/
private static void callLight_OnCall(){
- if (callLightTask!=null) callLightTask.cancel();
+ if (callLightTask!=null) {
+ callLightTask.cancel();
+ callLightTask = null;
+ }
if (timer!=null) timer.purge();
callLight.SetValue(true);
}
@@ -300,9 +414,13 @@ public class Main {
* Incoming call, buzzer is beeping with 1000ms interval
*/
private static void Buzzer_IncomingCall(){
- if (BuzzerTask!=null) BuzzerTask.cancel();
+ if (BuzzerTask!=null) {
+ BuzzerTask.cancel();
+ BuzzerTask = null;
+ }
if (timer!=null){
timer.purge();
+ BuzzerTask = CreateBuzzerTask();
timer.scheduleAtFixedRate(BuzzerTask, 0, 1000);
}
}
@@ -311,14 +429,97 @@ public class Main {
* On-call, buzzer is off
*/
private static void Buzzer_OnCall(){
- if (BuzzerTask!=null) BuzzerTask.cancel();
+ if (BuzzerTask!=null) {
+ BuzzerTask.cancel();
+ BuzzerTask = null;
+ }
if (timer!=null) timer.purge();
- Buzzer.SetValue(false);
+ if (Buzzer!=null) Buzzer.SetValue(false);
}
private static void Buzzer_Off(){
- if (BuzzerTask!=null) BuzzerTask.cancel();
+ if (BuzzerTask!=null) {
+ BuzzerTask.cancel();
+ BuzzerTask = null;
+ }
if (timer!=null) timer.purge();
- Buzzer.SetValue(false);
+ if (Buzzer!=null) Buzzer.SetValue(false);
}
+
+ private static TimerTask CreateBuzzerTask(){
+ return new TimerTask() {
+ @Override
+ public void run() {
+ if (Buzzer!=null && Buzzer.isInitialized()) Buzzer.BlinkON(500);
+ }
+ };
+ }
+
+ private static TimerTask CreateCallLightTask(){
+ return new TimerTask() {
+ @Override
+ public void run() {
+ if (callLight!=null && callLight.isInitialized()) callLight.BlinkON(100);
+ }
+ };
+ }
+
+ private static void init_system_monitoring(){
+ TimerTask tt = new TimerTask() {
+ @Override
+ public void run() {
+ cpuTemperature = SystemInformation.getCPUTemperature();
+ ramInformation = SystemInformation.getRAMInformation();
+ ProcessorStatus[] cpuinfo = SystemInformation.getProcStat();
+ if (cpuinfo.length>0){
+ if (previousCpuInfo==null || !Objects.equals(previousCpuInfo.length, cpuinfo.length)){
+ previousCpuInfo = cpuinfo;
+ } else {
+ for(int ii=0;ii0){
+ if (previousNetworkInfo==null || !Objects.equals(previousNetworkInfo.length, ntri.length)){
+ previousNetworkInfo = ntri;
+ } else {
+ for(int ii=0;ii0){
+ long bytesDiff = bytesReceived - prev.bytesReceived;
+ if (ValidString(unit)) unit = unit.toUpperCase();
+ Double speed = ConvertToUnit(unit, timeDiff, bytesDiff);
+ if (speed != null) return speed;
+ }
+ }
+ }
+ return 0;
+ }
+
+ @Nullable
+ private Double ConvertToUnit(String unit, long timeDiff, long bytesDiff) {
+ if (bytesDiff>0){
+ double speed = ((double) bytesDiff / timeDiff) * 1000;
+ switch (unit) {
+ case "KB" :
+ return (speed / 1024);
+ case "MB" :
+ return (speed / 1024 / 1024);
+ case "GB" :
+ return (speed / 1024 / 1024 / 1024);
+ default :
+ return speed;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Calculate the upload speed
+ * @param prev Previous NetworkTransmitReceiveInfo
+ * @param unit Speed unit (KB, MB, GB)
+ * @return Upload speed in {unit}/second
+ */
+ public double TxSpeed(NetworkTransmitReceiveInfo prev, String unit){
+ if (prev!=null){
+ if (Objects.equals(prev.name, name)){
+ long timeDiff = timetick - prev.timetick;
+ if (timeDiff>0){
+ long bytesDiff = bytesTransmitted - prev.bytesTransmitted;
+ if (ValidString(unit)) unit = unit.toUpperCase();
+ Double speed = ConvertToUnit(unit, timeDiff, bytesDiff);
+ if (speed != null) return speed;
+ }
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/SBC/ProcessorStatus.java b/src/SBC/ProcessorStatus.java
new file mode 100644
index 0000000..355c041
--- /dev/null
+++ b/src/SBC/ProcessorStatus.java
@@ -0,0 +1,45 @@
+package SBC;
+
+public class ProcessorStatus {
+ public String name;
+ public int user;
+ public int nice;
+ public int system;
+ public int idle;
+ public int iowait;
+ public int irq;
+ public int softirq;
+ public int steal;
+ public int guest;
+ public int guest_nice;
+
+ /**
+ * Calculate total CPU time
+ * @return Total CPU time
+ */
+ public int total_time(){
+ return user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice;
+ }
+
+ /**
+ * Calculate idle CPU time
+ * @return Idle CPU time
+ */
+ public int idle_time(){
+ return idle + iowait;
+ }
+
+ /**
+ * Calculate CPU usage percentage
+ * @param prev Previous CPU information
+ * @return CPU usage percentage 0 - 100
+ */
+ public int cpu_usage(ProcessorStatus prev){
+ if (prev!=null){
+ int total_diff = total_time() - prev.total_time();
+ int idle_diff = idle_time() - prev.idle_time();
+ return (int)(100.0 * (total_diff - idle_diff) / total_diff);
+ }
+ return 0;
+ }
+}
diff --git a/src/SBC/RamInformation.java b/src/SBC/RamInformation.java
new file mode 100644
index 0000000..d9fc08c
--- /dev/null
+++ b/src/SBC/RamInformation.java
@@ -0,0 +1,12 @@
+package SBC;
+
+public class RamInformation {
+ public int totalKB;
+ public int usedKB;
+ public int availableKB;
+ public int swapTotalKB;
+ public int swapFreeKB;
+ public double RamUsagePercentage(){
+ return (double) usedKB / totalKB * 100;
+ }
+}
diff --git a/src/SBC/SystemInformation.java b/src/SBC/SystemInformation.java
new file mode 100644
index 0000000..8d6541e
--- /dev/null
+++ b/src/SBC/SystemInformation.java
@@ -0,0 +1,179 @@
+package SBC;
+
+import com.sun.jna.Platform;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SystemInformation {
+
+
+
+ public static int getCPUTemperature() {
+ if (Platform.isLinux()){
+ File ff = new File("/sys/class/thermal/thermal_zone0/temp");
+ if (ff.isFile() && ff.canRead()){
+ try{
+ String value = new String(Files.readAllBytes(ff.toPath())).trim();
+ return Integer.parseInt(value) / 1000;
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ return 0;
+ }
+
+ public static NetworkTransmitReceiveInfo[] getNetworkTransmitReceiveInfo(){
+ if (Platform.isLinux()){
+ File ff = new File("/proc/net/dev");
+ if (ff.isFile() && ff.canRead()){
+ List result = new ArrayList<>();
+ final Pattern pattern = Pattern.compile("\\s+(.*):\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
+ try{
+ String[] lines = Files.readAllLines(ff.toPath()).toArray(new String[0]);
+ for (String line : lines){
+ Matcher m = pattern.matcher(line);
+ if (m.find()){
+ NetworkTransmitReceiveInfo info = new NetworkTransmitReceiveInfo();
+ info.name = m.group(1).trim();
+ info.bytesReceived = Long.parseLong(m.group(2));
+ info.packetsReceived = Long.parseLong(m.group(3));
+ info.errorsReceived = Long.parseLong(m.group(4));
+ info.droppedReceived = Long.parseLong(m.group(5));
+ info.fifoReceived = Long.parseLong(m.group(6));
+ info.frameReceived = Long.parseLong(m.group(7));
+ info.compressedReceived = Long.parseLong(m.group(8));
+ info.multicastReceived = Long.parseLong(m.group(9));
+ info.bytesTransmitted = Long.parseLong(m.group(10));
+ info.packetsTransmitted = Long.parseLong(m.group(11));
+ info.errorsTransmitted = Long.parseLong(m.group(12));
+ info.droppedTransmitted = Long.parseLong(m.group(13));
+ info.fifoTransmitted = Long.parseLong(m.group(14));
+ info.collsTransmitted = Long.parseLong(m.group(15));
+ info.carrierTransmitted = Long.parseLong(m.group(16));
+ info.compressedTransmitted = Long.parseLong(m.group(17));
+ info.timetick = System.currentTimeMillis();
+ result.add(info);
+ }
+ }
+ } catch (Exception ignored) {
+
+ }
+ return result.toArray(new NetworkTransmitReceiveInfo[0]);
+ }
+ }
+ return new NetworkTransmitReceiveInfo[0];
+ }
+
+ public static CpuInfo getCPUInfo(){
+ CpuInfo result = new CpuInfo();
+ if (Platform.isLinux()){
+ File ff = new File("/proc/cpuinfo");
+ if (ff.isFile() && ff.canRead()){
+ final Pattern pattern = Pattern.compile( "\\s*(.*):\\s*(.*)");
+ try{
+ String[] lines = Files.readAllLines(ff.toPath()).toArray(new String[0]);
+ for (String line : lines){
+ Matcher m = pattern.matcher(line);
+ if (m.find()){
+ String key = m.group(1).trim();
+ String value = m.group(2).trim();
+ switch (key){
+ case "processor":
+ result.processorCount++;
+ break;
+ case "Revision":
+ result.revision = value;
+ break;
+ case "Serial":
+ result.serial = value;
+ break;
+ case "Model":
+ result.model = value;
+ break;
+ }
+ }
+ }
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ return result;
+ }
+
+ public static ProcessorStatus[] getProcStat(){
+ if (Platform.isLinux()){
+ File ff = new File("/proc/stat");
+ if (ff.isFile() && ff.canRead()){
+ final Pattern pattern = Pattern.compile( "(cpu\\d?)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\d+)");
+ List result = new ArrayList<>();
+ try{
+ String[] lines = Files.readAllLines(ff.toPath()).toArray(new String[0]);
+ for (String line : lines){
+ Matcher m = pattern.matcher(line);
+ if (m.find()){
+ ProcessorStatus info = new ProcessorStatus();
+ info.name = m.group(1).trim();
+ info.user = Integer.parseInt(m.group(2));
+ info.nice = Integer.parseInt(m.group(3));
+ info.system = Integer.parseInt(m.group(4));
+ info.idle = Integer.parseInt(m.group(5));
+ info.iowait = Integer.parseInt(m.group(6));
+ info.irq = Integer.parseInt(m.group(7));
+ info.softirq = Integer.parseInt(m.group(8));
+ info.steal = Integer.parseInt(m.group(9));
+ info.guest = Integer.parseInt(m.group(10));
+ info.guest_nice = Integer.parseInt(m.group(11));
+ result.add(info);
+ }
+ }
+ return result.toArray(new ProcessorStatus[0]);
+ } catch (Exception ignored) {
+ }
+ }
+ }
+ return new ProcessorStatus[0];
+ }
+
+ public static RamInformation getRAMInformation(){
+
+ RamInformation result = new RamInformation();
+ if (Platform.isLinux()){
+ File ff = new File("/proc/meminfo");
+ if (ff.isFile() && ff.canRead()){
+ final Pattern pattern = Pattern.compile("(.*):\\s+(\\d+).kB");
+ try{
+ String[] lines = Files.readAllLines(ff.toPath()).toArray(new String[0]);
+ for (String line : lines) {
+ Matcher m = pattern.matcher(line);
+ if (m.find()){
+ String key = m.group(1);
+ int value = Integer.parseInt(m.group(2));
+ switch (key){
+ case "MemTotal":
+ result.totalKB = value;
+ break;
+ case "MemAvailable":
+ result.availableKB = value;
+ break;
+ case "SwapTotal":
+ result.swapTotalKB = value;
+ break;
+ case "SwapFree":
+ result.swapFreeKB = value;
+ break;
+ }
+ }
+ }
+ } catch (Exception ignored) {
+ }
+ result.usedKB = result.totalKB - result.availableKB;
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/SIP/jSIPClient.java b/src/SIP/jSIPClient.java
index b8fe6a1..3090b11 100644
--- a/src/SIP/jSIPClient.java
+++ b/src/SIP/jSIPClient.java
@@ -67,6 +67,7 @@ public class jSIPClient {
cc.setDomain(serverAddress);
cc.setUserPart(Username);
cc.setPassword(Password);
+ cc.SetLocalInetAddress("0.0.0.0");
em = new EventManager(cc);
return false;
@@ -616,9 +617,9 @@ public class jSIPClient {
private void load_config(Properties prop) {
- serverAddress = GetProperties_StringValue(prop,"SipServer","100.64.0.3");
- Username = GetProperties_StringValue(prop,"SipUsername","user1");
- Password = GetProperties_StringValue(prop,"SipPassword","12345678");
+ serverAddress = GetProperties_StringValue(prop,"SipServer","rdkartono.ddns.me");
+ Username = GetProperties_StringValue(prop,"SipUsername","101");
+ Password = GetProperties_StringValue(prop,"SipPassword","password101");
Logger.info("SipServer: "+serverAddress);
Logger.info("SipUsername: "+Username);
Logger.info("SipPassword: "+Password);
diff --git a/src/Webpage/LoginSetting.java b/src/Webpage/LoginSetting.java
new file mode 100644
index 0000000..606f1a0
--- /dev/null
+++ b/src/Webpage/LoginSetting.java
@@ -0,0 +1,10 @@
+package Webpage;
+
+public class LoginSetting {
+ public String Username;
+ public String Password;
+ public LoginSetting(String username, String password){
+ Username = username;
+ Password = password;
+ }
+}
diff --git a/src/Webpage/SipSetting.java b/src/Webpage/SipSetting.java
new file mode 100644
index 0000000..cd07e8a
--- /dev/null
+++ b/src/Webpage/SipSetting.java
@@ -0,0 +1,15 @@
+package Webpage;
+
+public class SipSetting {
+ public String Server;
+ public int Port;
+ public String Username;
+ public String Password;
+
+ public SipSetting(String server, int port, String username, String password){
+ this.Server = server;
+ this.Port = port;
+ this.Username = username;
+ this.Password = password;
+ }
+}
diff --git a/src/Webpage/SocketioRequest.java b/src/Webpage/SocketioRequest.java
new file mode 100644
index 0000000..c434b4d
--- /dev/null
+++ b/src/Webpage/SocketioRequest.java
@@ -0,0 +1,26 @@
+package Webpage;
+
+import lombok.Getter;
+
+import static code.common.gson;
+
+@Getter
+public class SocketioRequest {
+ private final String request;
+ private final String data;
+
+ public SocketioRequest(){
+ request = "";
+ data = "";
+ }
+
+ public SocketioRequest(String request, String data){
+ this.request = request;
+ this.data = data;
+ }
+
+ @Override
+ public String toString(){
+ return gson.toJson(this);
+ }
+}
diff --git a/src/Webpage/SocketioResponse.java b/src/Webpage/SocketioResponse.java
new file mode 100644
index 0000000..f43e39e
--- /dev/null
+++ b/src/Webpage/SocketioResponse.java
@@ -0,0 +1,75 @@
+package Webpage;
+
+import SBC.RamInformation;
+import com.google.gson.JsonObject;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+import static code.common.gson;
+
+@Getter
+@Setter
+public class SocketioResponse {
+ private String response;
+ private String data;
+
+ public SocketioResponse(){
+ response = "";
+ data = "";
+ }
+
+ public SocketioResponse(String response, String data){
+ this.response = response;
+ this.data = data;
+ }
+
+ @Override
+ public String toString(){
+ return gson.toJson(this);
+ }
+
+ public static SocketioResponse fromLoginSetting(String response, LoginSetting loginSetting){
+ SocketioResponse socketioResponse = new SocketioResponse();
+ socketioResponse.setResponse(response);
+ socketioResponse.setData(gson.toJson(loginSetting));
+ return socketioResponse;
+ }
+
+ public static SocketioResponse fromSipSetting(String response, SipSetting sipSetting){
+ SocketioResponse socketioResponse = new SocketioResponse();
+ socketioResponse.setResponse(response);
+ socketioResponse.setData(gson.toJson(sipSetting));
+ return socketioResponse;
+ }
+
+ public static SocketioResponse fromRamInformation(String response, RamInformation ramInformation){
+ SocketioResponse socketioResponse = new SocketioResponse();
+ socketioResponse.setResponse(response);
+ socketioResponse.setData(gson.toJson(ramInformation));
+ return socketioResponse;
+ }
+
+ public static SocketioResponse fromCpuStatus(String response, int cpuTemperature, Map cpuUsage){
+ SocketioResponse socketioResponse = new SocketioResponse();
+ socketioResponse.setResponse(response);
+ JsonObject jo = new JsonObject();
+ jo.addProperty("cpuTemperature", cpuTemperature);
+ jo.addProperty("cpuUsage", gson.toJson(cpuUsage));
+ socketioResponse.setData(jo.toString());
+ return socketioResponse;
+ }
+
+ public static SocketioResponse fromTxRxMap(String response, Map txmap, Map rxmap){
+ SocketioResponse socketioResponse = new SocketioResponse();
+ socketioResponse.setResponse(response);
+ JsonObject jo = new JsonObject();
+ jo.addProperty("txmap", gson.toJson(txmap));
+ jo.addProperty("rxmap", gson.toJson(rxmap));
+ socketioResponse.setData(jo.toString());
+ return socketioResponse;
+ }
+
+
+}
diff --git a/src/Webpage/SocketioServer.java b/src/Webpage/SocketioServer.java
new file mode 100644
index 0000000..3fadece
--- /dev/null
+++ b/src/Webpage/SocketioServer.java
@@ -0,0 +1,56 @@
+package Webpage;
+
+import com.corundumstudio.socketio.Configuration;
+import com.corundumstudio.socketio.SocketIONamespace;
+import com.corundumstudio.socketio.SocketIOServer;
+import lombok.NonNull;
+import lombok.Setter;
+import org.pmw.tinylog.Logger;
+
+import java.util.function.Function;
+
+public class SocketioServer {
+ private final SocketIOServer server;
+ private @Setter Function<@NonNull SocketioRequest, @NonNull SocketioResponse> onRequest;
+
+ /**
+ * Create Socket.io Server
+ * @param localip Local Ip address to bind.
if null or empty will default to 0.0.0.0
+ * @param listenport Local Port to bind.
if invalid, will default to 9092
+ */
+ public SocketioServer(String localip,int listenport){
+ if (localip==null || localip.isEmpty()) localip="0.0.0.0";
+ if (listenport<=0 || listenport>65535) listenport=9092;
+ Configuration config = new Configuration();
+ config.setHostname(localip);
+ config.setPort(listenport);
+
+ server = new SocketIOServer(config);
+ SocketIONamespace socketio = server.addNamespace("/socketio");
+ socketio.addConnectListener(client -> Logger.info("Client id={} remoteaddress={} Connected to /socketio: " , client.getSessionId(), client.getRemoteAddress()));
+ socketio.addDisconnectListener(client -> Logger.info("Client id={} remoteaddress={} Disconnected from /socketio: ", client.getSessionId(), client.getRemoteAddress()));
+ socketio.addEventListener("command", SocketioRequest.class, (client, data, ackRequest) -> {
+ Logger.info("Client id={} remoteaddress={} request: {}", client.getSessionId(), client.getRemoteAddress(), data);
+ if (onRequest!=null){
+ SocketioResponse response = onRequest.apply(data);
+ Logger.info("Client id={} remoteaddress={} response: {}", client.getSessionId(), client.getRemoteAddress(), response);
+ ackRequest.sendAckData(response);
+ }
+ });
+
+ }
+
+ /**
+ * Start the server
+ */
+ public void Start(){
+ if (server!=null) server.start();
+ }
+
+ /**
+ * Stop the server
+ */
+ public void Stop(){
+ if (server!=null) server.stop();
+ }
+}
diff --git a/src/code/common.java b/src/code/common.java
index 31b7d63..6885c6f 100644
--- a/src/code/common.java
+++ b/src/code/common.java
@@ -23,6 +23,9 @@ public class common {
public static final Path gpioPath = Paths.get("/sys/class/gpio") ;
public static final Path gpioExportPath = Paths.get("/sys/class/gpio/export");
public static final Path gpioUnexportPath = Paths.get("/sys/class/gpio/unexport");
+ public static final double KB_threshold = 1024.0;
+ public static final double MB_threshold = 1024.0 * 1024.0;
+ public static final double GB_threshold = 1024.0 * 1024.0 * 1024.0;
public static String GetProperties_StringValue(Properties prop, String key, String defaultavalue){
if (prop!=null){
@@ -108,6 +111,19 @@ public class common {
return prop;
}
+ public static boolean SaveProperties(String directory, String filename, Properties prop){
+ try {
+ File file = new File(directory,filename);
+ file.createNewFile();
+ prop.store(Files.newOutputStream(file.toPath()),"");
+ Logger.info("Saved properties file: {}",filename);
+ return true;
+ } catch (Exception e) {
+ Logger.error("Failed to save properties file: {}",filename);
+ }
+ return false;
+ }
+
/**
* Check if String is not null and have value
* @param value string to check
diff --git a/src/peers/sip/core/useragent/UserAgent.java b/src/peers/sip/core/useragent/UserAgent.java
index 8e178d6..46125ce 100644
--- a/src/peers/sip/core/useragent/UserAgent.java
+++ b/src/peers/sip/core/useragent/UserAgent.java
@@ -26,7 +26,6 @@ import java.util.List;
import lombok.Getter;
import lombok.Setter;
-import org.pmw.tinylog.Logger;
import peers.Config;
import peers.XmlConfig;
@@ -125,16 +124,7 @@ public class UserAgent {
cseqCounter = 1;
- String buf = "starting user agent [" +
- "myAddress: " +
- config.getLocalInetAddress().getHostAddress() + ", " +
- "sipPort: " +
- config.getSipPort() + ", " +
- "userpart: " +
- config.getUserPart() + ", " +
- "domain: " +
- config.getDomain() + "]";
- Logger.info(buf);
+
//transaction user
diff --git a/src/peers/sip/transport/MessageReceiver.java b/src/peers/sip/transport/MessageReceiver.java
index 0c1dbcf..b7365b0 100644
--- a/src/peers/sip/transport/MessageReceiver.java
+++ b/src/peers/sip/transport/MessageReceiver.java
@@ -26,6 +26,7 @@ import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
+import lombok.Setter;
import org.pmw.tinylog.Logger;
import peers.Config;
@@ -47,10 +48,11 @@ public abstract class MessageReceiver implements Runnable {
private boolean isListening;
//private UAS uas;
+ @Setter
private SipServerTransportUser sipServerTransportUser;
- private TransactionManager transactionManager;
- private TransportManager transportManager;
- private Config config;
+ private final TransactionManager transactionManager;
+ private final TransportManager transportManager;
+ private final Config config;
public MessageReceiver(int port, TransactionManager transactionManager,
@@ -83,10 +85,7 @@ public abstract class MessageReceiver implements Runnable {
} catch (UnsupportedEncodingException e) {
Logger.error("unsupported encoding", e);
}
- if (RFC3261.DEFAULT_SIP_VERSION.equals(beginning)) {
- return false;
- }
- return true;
+ return !RFC3261.DEFAULT_SIP_VERSION.equals(beginning);
}
protected void processMessage(byte[] message, InetAddress sourceIp,
@@ -115,10 +114,7 @@ public abstract class MessageReceiver implements Runnable {
}
return;
}
- StringBuffer direction = new StringBuffer();
- direction.append("RECEIVED from ").append(sourceIp.getHostAddress());
- direction.append("/").append(sourcePort);
- Logger.info(new String(message),direction.toString());
+
SipMessage sipMessage = null;
try {
sipMessage = transportManager.sipParser.parse(
@@ -158,7 +154,7 @@ public abstract class MessageReceiver implements Runnable {
SipHeaderParamName rportName = new SipHeaderParamName(
RFC3261.PARAM_RPORT);
String rport = topVia.getParam(rportName);
- if (rport != null && "".equals(rport)) {
+ if (rport != null && rport.isEmpty()) {
topVia.removeParam(rportName);
topVia.addParam(rportName, String.valueOf(sourcePort));
}
@@ -193,13 +189,4 @@ public abstract class MessageReceiver implements Runnable {
return isListening;
}
- public void setSipServerTransportUser(
- SipServerTransportUser sipServerTransportUser) {
- this.sipServerTransportUser = sipServerTransportUser;
- }
-
-// public void setUas(UAS uas) {
-// this.uas = uas;
-// }
-
}
diff --git a/src/peers/sip/transport/TransportManager.java b/src/peers/sip/transport/TransportManager.java
index 7d302d1..811d839 100644
--- a/src/peers/sip/transport/TransportManager.java
+++ b/src/peers/sip/transport/TransportManager.java
@@ -329,7 +329,6 @@ public class TransportManager {
}
datagramSocket.setSoTimeout(SOCKET_TIMEOUT);
datagramSockets.put(conn, datagramSocket);
- Logger.info("added datagram socket " + conn);
}
socket = datagramSocket;
messageSender = new UdpMessageSender(conn.getRemoteInetAddress(),
@@ -409,7 +408,6 @@ public class TransportManager {
}
sipPort = datagramSocket.getLocalPort();
datagramSockets.put(sipTransportConnection, datagramSocket);
- Logger.info("added datagram socket " + sipTransportConnection);
}
messageReceiver = new UdpMessageReceiver(datagramSocket,
transactionManager, this, config);
@@ -420,8 +418,7 @@ public class TransportManager {
//messageReceiver = new TcpMessageReceiver(port);
}
messageReceivers.put(sipTransportConnection, messageReceiver);
- Logger.info("added " + sipTransportConnection + ": " + messageReceiver
- + " to message receivers");
+
return messageReceiver;
}
diff --git a/src/peers/sip/transport/UdpMessageSender.java b/src/peers/sip/transport/UdpMessageSender.java
index 4e65fcb..e65e137 100644
--- a/src/peers/sip/transport/UdpMessageSender.java
+++ b/src/peers/sip/transport/UdpMessageSender.java
@@ -44,15 +44,11 @@ public class UdpMessageSender extends MessageSender {
@Override
public synchronized void sendMessage(SipMessage sipMessage) {
- Logger.debug("UdpMessageSender.sendMessage");
- if (sipMessage == null) {
+ if (sipMessage == null) {
return;
}
byte[] buf = sipMessage.toString().getBytes();
sendBytes(buf);
- String direction = "SENT to " + inetAddress.getHostAddress() +
- "/" + port;
- Logger.info(new String(buf), direction);
}
@Override