new features 04/12/2024

This commit is contained in:
2024-12-04 15:01:24 +07:00
parent a5eb4e9157
commit 33cfd5d363
24 changed files with 947 additions and 135 deletions

View File

@@ -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<String, Integer> cpuUsage = new HashMap<>();
private static NetworkTransmitReceiveInfo[] previousNetworkInfo;
private static final Map<String, String> networkTX = new HashMap<>();
private static final Map<String, String> 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;ii<previousCpuInfo.length;ii++){
cpuUsage.put(cpuinfo[ii].name, cpuinfo[ii].cpu_usage(previousCpuInfo[ii]));
}
previousCpuInfo = cpuinfo;
}
}
NetworkTransmitReceiveInfo[] ntri = SystemInformation.getNetworkTransmitReceiveInfo();
if (ntri.length>0){
if (previousNetworkInfo==null || !Objects.equals(previousNetworkInfo.length, ntri.length)){
previousNetworkInfo = ntri;
} else {
for(int ii=0;ii<previousNetworkInfo.length;ii++){
double txspeed = ntri[ii].TxSpeed(previousNetworkInfo[ii], "B");
String txspeedstr;
if (txspeed < KB_threshold){
txspeedstr = String.format("%.0f B/s", txspeed);
} else if (txspeed < MB_threshold){
txspeedstr = String.format("%.1f KB/s", ntri[ii].TxSpeed(previousNetworkInfo[ii], "KB"));
} else if (txspeed < GB_threshold){
txspeedstr = String.format("%.1f MB/s", ntri[ii].TxSpeed(previousNetworkInfo[ii], "MB"));
} else {
txspeedstr = String.format("%.1f GB/s", ntri[ii].TxSpeed(previousNetworkInfo[ii], "GB"));
}
double rxspeed = ntri[ii].RxSpeed(previousNetworkInfo[ii], "B");
String rxspeedstr;
if (rxspeed < KB_threshold){
rxspeedstr = String.format("%.0f B/s", rxspeed);
} else if (rxspeed < MB_threshold){
rxspeedstr = String.format("%.1f KB/s", ntri[ii].RxSpeed(previousNetworkInfo[ii], "KB"));
} else if (rxspeed < GB_threshold){
rxspeedstr = String.format("%.1f MB/s", ntri[ii].RxSpeed(previousNetworkInfo[ii], "MB"));
} else {
rxspeedstr = String.format("%.1f GB/s", ntri[ii].RxSpeed(previousNetworkInfo[ii], "GB"));
}
networkTX.put(ntri[ii].name, txspeedstr);
networkRX.put(ntri[ii].name, rxspeedstr);
}
previousNetworkInfo = ntri;
}
}
}
};
system_monitoring_timer = new Timer();
system_monitoring_timer.scheduleAtFixedRate(tt, 1000, 5000);
}
}

8
src/SBC/CpuInfo.java Normal file
View File

@@ -0,0 +1,8 @@
package SBC;
public class CpuInfo {
public int processorCount;
public String revision;
public String serial;
public String model;
}

View File

@@ -0,0 +1,88 @@
package SBC;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import static code.common.ValidString;
public class NetworkTransmitReceiveInfo {
public String name;
public long bytesReceived;
public long packetsReceived;
public long errorsReceived;
public long droppedReceived;
public long fifoReceived;
public long frameReceived;
public long compressedReceived;
public long multicastReceived;
public long bytesTransmitted;
public long packetsTransmitted;
public long errorsTransmitted;
public long droppedTransmitted;
public long fifoTransmitted;
public long collsTransmitted;
public long carrierTransmitted;
public long compressedTransmitted;
public long timetick;
/**
* Calculate the download speed
* @param prev Previous NetworkTransmitReceiveInfo
* @param unit Speed unit (KB, MB, GB)
* @return Download speed in {unit}/second
*/
public double RxSpeed(NetworkTransmitReceiveInfo prev, String unit){
if (prev!=null){
if (Objects.equals(prev.name, name)){
long timeDiff = timetick - prev.timetick;
if (timeDiff>0){
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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<NetworkTransmitReceiveInfo> 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<ProcessorStatus> 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;
}
}

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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<String,Integer> 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<String,String> txmap, Map<String,String> 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;
}
}

View File

@@ -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.<br/>if null or empty will default to 0.0.0.0
* @param listenport Local Port to bind.<br/>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();
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
// }
}

View File

@@ -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;
}

View File

@@ -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