Compare commits

...

2 Commits

Author SHA1 Message Date
362ece1bd2 new features 04/12/2024 2024-12-04 15:02:26 +07:00
33cfd5d363 new features 04/12/2024 2024-12-04 15:01:24 +07:00
72 changed files with 59598 additions and 135 deletions

52
.idea/artifacts/SIPIntercom_jar.xml generated Normal file
View File

@@ -0,0 +1,52 @@
<component name="ArtifactManager">
<artifact type="jar" name="SIPIntercom:jar">
<output-path>$PROJECT_DIR$/out/artifacts/SIPIntercom_jar</output-path>
<root id="archive" name="SIPIntercom.jar">
<element id="module-output" name="SIPIntercom" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog/1.3.6/tinylog-1.3.6.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/javalin/javalin/4.6.8/javalin-4.6.8.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-server/9.4.51.v20230217/jetty-server-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-http/9.4.51.v20230217/jetty-http-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util/9.4.51.v20230217/jetty-util-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-io/9.4.51.v20230217/jetty-io-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-webapp/9.4.51.v20230217/jetty-webapp-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-xml/9.4.51.v20230217/jetty-xml-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-servlet/9.4.51.v20230217/jetty-servlet-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-security/9.4.51.v20230217/jetty-security-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util-ajax/9.4.51.v20230217/jetty-util-ajax-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-server/9.4.51.v20230217/websocket-server-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-common/9.4.51.v20230217/websocket-common-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-api/9.4.51.v20230217/websocket-api-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-client/9.4.51.v20230217/websocket-client-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-client/9.4.51.v20230217/jetty-client-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-servlet/9.4.51.v20230217/websocket-servlet-9.4.51.v20230217.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.5.32/kotlin-stdlib-jdk8-1.5.32.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.5.32/kotlin-stdlib-1.5.32.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.5.32/kotlin-stdlib-common-1.5.32.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.5.32/kotlin-stdlib-jdk7-1.5.32.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/corundumstudio/socketio/netty-socketio/2.0.12/netty-socketio-2.0.12.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-buffer/4.1.114.Final/netty-buffer-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-common/4.1.114.Final/netty-common-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport/4.1.114.Final/netty-transport-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-resolver/4.1.114.Final/netty-resolver-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-handler/4.1.114.Final/netty-handler-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-native-unix-common/4.1.114.Final/netty-transport-native-unix-common-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-codec-http/4.1.114.Final/netty-codec-http-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-codec/4.1.114.Final/netty-codec-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/2.0.16/slf4j-api-2.0.16.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.18.1/jackson-core-2.18.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.18.1/jackson-databind-2.18.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.18.1/jackson-annotations-2.18.1.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-native-epoll/4.1.114.Final/netty-transport-native-epoll-4.1.114.Final-linux-x86_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-classes-epoll/4.1.114.Final/netty-transport-classes-epoll-4.1.114.Final.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/io/netty/netty-transport-native-epoll/4.1.114.Final/netty-transport-native-epoll-4.1.114.Final-linux-aarch_64.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.36/lombok-1.18.36.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.jar" path-in-jar="/" />
</root>
</artifact>
</component>

14
.idea/deployment.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData" serverName="192.168.10.35" remoteFilesAllowedToDisappearOnAutoupload="false">
<serverData>
<paths name="192.168.10.35">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>

View File

@@ -0,0 +1,25 @@
<component name="libraryTable">
<library name="corundumstudio.socketio.netty" type="repository">
<properties maven-id="com.corundumstudio.socketio:netty-socketio:2.0.12" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/corundumstudio/socketio/netty-socketio/2.0.12/netty-socketio-2.0.12.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-buffer/4.1.114.Final/netty-buffer-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-common/4.1.114.Final/netty-common-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-transport/4.1.114.Final/netty-transport-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-resolver/4.1.114.Final/netty-resolver-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-handler/4.1.114.Final/netty-handler-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-transport-native-unix-common/4.1.114.Final/netty-transport-native-unix-common-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-codec-http/4.1.114.Final/netty-codec-http-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-codec/4.1.114.Final/netty-codec-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/2.0.16/slf4j-api-2.0.16.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.18.1/jackson-core-2.18.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.18.1/jackson-databind-2.18.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.18.1/jackson-annotations-2.18.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-transport-native-epoll/4.1.114.Final/netty-transport-native-epoll-4.1.114.Final-linux-x86_64.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-transport-classes-epoll/4.1.114.Final/netty-transport-classes-epoll-4.1.114.Final.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/netty/netty-transport-native-epoll/4.1.114.Final/netty-transport-native-epoll-4.1.114.Final-linux-aarch_64.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

14
.idea/webServers.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebServers">
<option name="servers">
<webServer id="610211eb-605e-4cac-85d6-11044ffa9537" name="192.168.10.35">
<fileTransfer rootFolder="/home/pi" accessType="SFTP" host="192.168.10.35" port="22" sshConfigId="0f3a4fce-ffbb-4b34-8d8e-21a84edbfd18" sshConfig="pi@192.168.10.35:22 password">
<advancedOptions>
<advancedOptions dataProtectionLevel="Private" keepAliveTimeout="0" passiveMode="true" shareSSLContext="true" />
</advancedOptions>
</fileTransfer>
</webServer>
</option>
</component>
</project>

View File

@@ -1,6 +1,7 @@
WebUsername=admin
WebPassword=admin
WebListenPort = 8080
SipServer=100.64.0.3
SipUsername=100
SipPassword=12345678
SipServer=rdkartono.ddns.me
SipPort=5060
SipUsername=101
SipPassword=password101

View File

@@ -15,5 +15,6 @@
<orderEntry type="library" name="google.code.gson" level="project" />
<orderEntry type="library" name="projectlombok.lombok" level="project" />
<orderEntry type="library" name="tinylog" level="project" />
<orderEntry type="library" name="corundumstudio.socketio.netty" level="project" />
</component>
</module>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
@font-face {
font-family: 'Font Awesome 5 Brands';
src: url(../../assets/fonts/Font%20Awesome%205%20Brands-9f495c22369544f2a6865c9d60b59dee.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%205%20Brands-ea242bb20f9fe7db35296896fae9867f.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
}

View File

@@ -0,0 +1,8 @@
@font-face {
font-family: 'Font Awesome 5 Duotone';
src: url(../../assets/fonts/Font%20Awesome%205%20Duotone-941715f4aecfe6f923ad4d98b8e09408.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%205%20Duotone-0609b5442e186979b732d3eecf885c57.ttf) format('truetype');
font-weight: 900;
font-style: normal;
font-display: block;
}

View File

@@ -0,0 +1,26 @@
@font-face {
font-family: 'Font Awesome 5 Pro';
src: url(../../assets/fonts/Font%20Awesome%205%20Pro-813a01e49b4431cc33412a84ca94d347.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%205%20Pro-87a1b179a40953ca88a6205650aa32c9.ttf) format('truetype');
font-weight: 300;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'Font Awesome 5 Pro';
src: url(../../assets/fonts/Font%20Awesome%205%20Pro-82e3029674e5d3395e37aea7b40ecc63.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%205%20Pro-8a781dd91fd45555bafe112b5008c208.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'Font Awesome 5 Pro';
src: url(../../assets/fonts/Font%20Awesome%205%20Pro-e17c2daa07b98413686eaeccf1f5e65a.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%205%20Pro-3724e0236c1ca473e4d73f7065e5de28.ttf) format('truetype');
font-weight: 900;
font-style: normal;
font-display: block;
}

View File

@@ -0,0 +1,8 @@
@font-face {
font-family: 'Font Awesome 6 Brands';
src: url(../../assets/fonts/Font%20Awesome%206%20Brands-9f495c22369544f2a6865c9d60b59dee.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%206%20Brands-ea242bb20f9fe7db35296896fae9867f.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
}

View File

@@ -0,0 +1,8 @@
@font-face {
font-family: 'Font Awesome 6 Duotone';
src: url(../../assets/fonts/Font%20Awesome%206%20Duotone-941715f4aecfe6f923ad4d98b8e09408.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%206%20Duotone-0609b5442e186979b732d3eecf885c57.ttf) format('truetype');
font-weight: 900;
font-style: normal;
font-display: block;
}

View File

@@ -0,0 +1,35 @@
@font-face {
font-family: 'Font Awesome 6 Pro';
src: url(../../assets/fonts/Font%20Awesome%206%20Pro-61d823b3361d879c119cf056e85d3dbf.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%206%20Pro-4eda3069f6f64ce115228a4726aef19f.ttf) format('truetype');
font-weight: 100;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'Font Awesome 6 Pro';
src: url(../../assets/fonts/Font%20Awesome%206%20Pro-813a01e49b4431cc33412a84ca94d347.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%206%20Pro-87a1b179a40953ca88a6205650aa32c9.ttf) format('truetype');
font-weight: 300;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'Font Awesome 6 Pro';
src: url(../../assets/fonts/Font%20Awesome%206%20Pro-82e3029674e5d3395e37aea7b40ecc63.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%206%20Pro-8a781dd91fd45555bafe112b5008c208.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'Font Awesome 6 Pro';
src: url(../../assets/fonts/Font%20Awesome%206%20Pro-e17c2daa07b98413686eaeccf1f5e65a.woff2) format('woff2'),
url(../../assets/fonts/Font%20Awesome%206%20Pro-3724e0236c1ca473e4d73f7065e5de28.ttf) format('truetype');
font-weight: 900;
font-style: normal;
font-display: block;
}

View File

@@ -0,0 +1,37 @@
@font-face {
font-family: 'FontAwesome';
src: url(../../assets/fonts/FontAwesome-e17c2daa07b98413686eaeccf1f5e65a.woff2) format('woff2'),
url(../../assets/fonts/FontAwesome-3724e0236c1ca473e4d73f7065e5de28.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'FontAwesome';
src: url(../../assets/fonts/FontAwesome-9f495c22369544f2a6865c9d60b59dee.woff2) format('woff2'),
url(../../assets/fonts/FontAwesome-ea242bb20f9fe7db35296896fae9867f.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
}
@font-face {
font-family: 'FontAwesome';
src: url(../../assets/fonts/FontAwesome-82e3029674e5d3395e37aea7b40ecc63.woff2) format('woff2'),
url(../../assets/fonts/FontAwesome-8a781dd91fd45555bafe112b5008c208.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
unicode-range: u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc;
}
@font-face {
font-family: 'FontAwesome';
src: url(../../assets/fonts/FontAwesome-817c19ff4bd5fc55e3922afce45e4117.woff2) format('woff2'),
url(../../assets/fonts/FontAwesome-01b9ff0cac2f6363c217c19d5787b037.ttf) format('truetype');
font-weight: 400;
font-style: normal;
font-display: block;
unicode-range: u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a;
}

View File

@@ -0,0 +1,57 @@
.bs-icon {
--bs-icon-size: .75rem;
display: flex;
flex-shrink: 0;
justify-content: center;
align-items: center;
font-size: var(--bs-icon-size);
width: calc(var(--bs-icon-size) * 2);
height: calc(var(--bs-icon-size) * 2);
color: var(--bs-primary);
}
.bs-icon-xs {
--bs-icon-size: 1rem;
width: calc(var(--bs-icon-size) * 1.5);
height: calc(var(--bs-icon-size) * 1.5);
}
.bs-icon-sm {
--bs-icon-size: 1rem;
}
.bs-icon-md {
--bs-icon-size: 1.5rem;
}
.bs-icon-lg {
--bs-icon-size: 2rem;
}
.bs-icon-xl {
--bs-icon-size: 2.5rem;
}
.bs-icon.bs-icon-primary {
color: var(--bs-white);
background: var(--bs-primary);
}
.bs-icon.bs-icon-primary-light {
color: var(--bs-primary);
background: rgba(var(--bs-primary-rgb), .2);
}
.bs-icon.bs-icon-semi-white {
color: var(--bs-primary);
background: rgba(255, 255, 255, .5);
}
.bs-icon.bs-icon-rounded {
border-radius: .5rem;
}
.bs-icon.bs-icon-circle {
border-radius: 50%;
}

28905
WebContentt/public/assets/css/all.min.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
function indexload(){
console.log("Index loaded");
}
function settingload(){
console.log("Setting loaded");
}
function loginload(){
console.log("Login loaded");
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>SIPIntercom</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Brands.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Duotone.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Pro.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Brands.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Duotone.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/all.min.css">
<link rel="stylesheet" href="assets/css/Navbar-Centered-Brand-icons.css">
</head>
<body onload="indexload()">
<nav class="navbar navbar-expand-md bg-body py-3">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="#"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>SIP Intercom</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-4"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-4">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="#">Overview</a></li>
<li class="nav-item"><a class="nav-link" href="setting.html">Setting</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
</div>
<div class="d-none d-md-block"><button class="btn btn-light me-2" type="button">Log Off</button></div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col">
<p>SIP Status</p>
</div>
<div class="col">
<p id="sipStatus">No Status</p>
</div>
</div>
<div class="row">
<div class="col">
<p>CPU Status</p>
</div>
<div class="col">
<p id="cpuStatus">No Status</p>
</div>
</div>
<div class="row">
<div class="col">
<p>RAM Status</p>
</div>
<div class="col">
<p id="ramStatus">No Status</p>
</div>
</div>
<div class="row">
<div class="col">
<p>Storage Status</p>
</div>
<div class="col">
<p id="storageStatus">No Status</p>
</div>
</div>
<div class="row">
<div class="col">
<p>Network Status</p>
</div>
<div class="col">
<p id="networkStatus">No Status</p>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col">
<p>Dial To</p>
</div>
<div class="col"><input type="text" id="dialNumber" name="dialNumber"></div>
<div class="col"><button class="btn btn-primary btn-lg" id="dialButton" type="button">Dial</button></div>
</div>
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/jquery-3.7.1.js"></script>
<script src="assets/js/socket.io.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>

View File

@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>SIPIntercom</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Brands.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Duotone.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Pro.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Brands.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Duotone.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/all.min.css">
<link rel="stylesheet" href="assets/css/Navbar-Centered-Brand-icons.css">
</head>
<body onload="loginload()">
<section class="position-relative py-4 py-xl-5">
<div class="container">
<div class="row mb-5">
<div class="col-md-8 col-xl-6 text-center mx-auto">
<h2>Log in</h2>
<p class="w-lg-50">SIP Intercom</p>
</div>
</div>
<div class="row d-flex justify-content-center">
<div class="col-md-6 col-xl-4">
<div class="card mb-5">
<div class="card-body d-flex flex-column align-items-center">
<div class="bs-icon-xl bs-icon-circle bs-icon-primary bs-icon my-4"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-person">
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664z"></path>
</svg></div>
<form class="text-center" method="post">
<div class="mb-3"><input class="form-control" type="email" name="username" placeholder="Username"></div>
<div class="mb-3"><input class="form-control" type="password" name="password" placeholder="Password"></div>
<div class="mb-3"><button class="btn btn-primary d-block w-100" type="submit">Login</button></div>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/jquery-3.7.1.js"></script>
<script src="assets/js/socket.io.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>

View File

@@ -0,0 +1,90 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>SIPIntercom</title>
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Brands.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Duotone.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%205%20Pro.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Brands.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Duotone.css">
<link rel="stylesheet" href="assets/css/Font%20Awesome%206%20Pro.css">
<link rel="stylesheet" href="assets/css/FontAwesome.css">
<link rel="stylesheet" href="assets/css/all.min.css">
<link rel="stylesheet" href="assets/css/Navbar-Centered-Brand-icons.css">
</head>
<body onload="settingload()">
<nav class="navbar navbar-expand-md bg-body py-3">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="#"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>SIP Intercom</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-4"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-4">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link" href="index.html">Overview</a></li>
<li class="nav-item"><a class="nav-link active" href="#">Setting</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
</div>
<div class="d-none d-md-block"><button class="btn btn-light me-2" type="button">Log Off</button></div>
</div>
</nav>
<div class="container">
<form>
<div class="col">
<div class="row">
<div class="col"><label class="col-form-label">Login Username</label></div>
<div class="col"><input class="form-control" type="text" id="webUsername" name="webUsername" placeholder="Login Username"></div>
</div>
<div class="row">
<div class="col"><label class="col-form-label">Login Password</label></div>
<div class="col"><input class="form-control" type="text" id="webPassword" name="webPassword" placeholder="Login Password"></div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col"><button class="btn btn-primary btn-lg" type="button">Save&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 0 512 512" width="1em" height="1em" fill="currentColor">
<!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<path d="M48 96V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V170.5c0-4.2-1.7-8.3-4.7-11.3l33.9-33.9c12 12 18.7 28.3 18.7 45.3V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H309.5c17 0 33.3 6.7 45.3 18.7l74.5 74.5-33.9 33.9L320.8 84.7c-.3-.3-.5-.5-.8-.8V184c0 13.3-10.7 24-24 24H104c-13.3 0-24-10.7-24-24V80H64c-8.8 0-16 7.2-16 16zm80-16v80H272V80H128zm32 240a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z"></path>
</svg></button></div>
</div>
</div>
</form>
</div>
<div class="container">
<form>
<div class="row">
<div class="col"><label class="col-form-label">SIP Server</label></div>
<div class="col"><input class="form-control" type="text" id="sipServer" name="sipServer" placeholder="SIP Server"></div>
</div>
<div class="row">
<div class="col"><label class="col-form-label">SIP Port</label></div>
<div class="col"><input class="form-control" type="text" id="sipPort" name="sipPort" placeholder="SIP Portnumber"></div>
</div>
<div class="row">
<div class="col"><label class="col-form-label">SIP Username</label></div>
<div class="col"><input class="form-control" type="text" id="sipUsername" name="sipUsername" placeholder="SIP Username"></div>
</div>
<div class="row">
<div class="col"><label class="col-form-label">SIP Password</label></div>
<div class="col"><input class="form-control" type="text" id="sipPassword" name="sipPassword" placeholder="SIP Password"></div>
</div>
<div class="row">
<div class="col"><button class="btn btn-primary btn-lg" type="button">Save&nbsp;&nbsp;<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 0 512 512" width="1em" height="1em" fill="currentColor">
<!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. -->
<path d="M48 96V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V170.5c0-4.2-1.7-8.3-4.7-11.3l33.9-33.9c12 12 18.7 28.3 18.7 45.3V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H309.5c17 0 33.3 6.7 45.3 18.7l74.5 74.5-33.9 33.9L320.8 84.7c-.3-.3-.5-.5-.8-.8V184c0 13.3-10.7 24-24 24H104c-13.3 0-24-10.7-24-24V80H64c-8.8 0-16 7.2-16 16zm80-16v80H272V80H128zm32 240a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z"></path>
</svg></button></div>
</div>
</form>
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/jquery-3.7.1.js"></script>
<script src="assets/js/socket.io.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Main

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