diff --git a/Properties/config.properties b/Properties/config.properties
new file mode 100644
index 0000000..e581083
--- /dev/null
+++ b/Properties/config.properties
@@ -0,0 +1,6 @@
+WebUsername=admin
+WebPassword=admin
+WebListenPort = 8080
+SipServer=100.64.0.3
+SipUsername=100
+SipPassword=12345678
\ No newline at end of file
diff --git a/SIPIntercom.iml b/SIPIntercom.iml
index dc9b352..7208ba6 100644
--- a/SIPIntercom.iml
+++ b/SIPIntercom.iml
@@ -5,6 +5,8 @@
+
+
diff --git a/src/Main.java b/src/Main.java
index fb8d8f5..0e913d7 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -1,21 +1,18 @@
+import Webpage.WebServer;
+import code.common;
import org.pmw.tinylog.Logger;
import java.io.File;
import java.text.MessageFormat;
+import static code.common.currentDir;
public class Main {
- private static String serverAddress="100.64.0.3";
- private static String Username="user1";
- private static String Password="12345678";
private static jSIPClient client;
- private static String currentDir;
+ private static WebServer webserver;
public static void main(String[] args) {
- currentDir = System.getProperty("user.dir");
- GetArguments(args);
- Logger.info("Server Address: "+serverAddress);
- Logger.info("Username: "+Username);
- Logger.info("Password: "+Password);
+ common.ExtractProperties(currentDir,"config.properties", false);
+ // SIP Section
client = new jSIPClient();
client.SetJavaSipEvent(new javaSipEvents() {
@Override
@@ -56,11 +53,22 @@ public class Main {
}
});
ReconnectSIP();
+
+
+ // Web Server Section
+ webserver = new WebServer();
+ webserver.Start();
+
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ Logger.info("Shutting down SIPIntercom");
+ if (client!=null) client.Disconnect();
+ if (webserver!=null) webserver.Stop();
+ }));
}
@SuppressWarnings("unused")
private static void CallTest(String extension){
- String callnumber = MessageFormat.format("sip:{0}@{1}", extension, serverAddress);
+ String callnumber = MessageFormat.format("sip:{0}@{1}", extension, client.getServerAddress());
if (client.Call(callnumber)){
Logger.info("Call to {} is successful",callnumber);
try{
@@ -78,7 +86,7 @@ public class Main {
private static void StreamTest(String extension, String filename){
File ff = new File(currentDir, filename);
if (ff.isFile()){
- String callnumber = MessageFormat.format("sip:{0}@{1}", extension, serverAddress);
+ String callnumber = MessageFormat.format("sip:{0}@{1}", extension, client.getServerAddress());
if (client.StreamFile(callnumber, ff.getAbsolutePath())){
Logger.info("Stream to {} is successful",callnumber);
try{
@@ -94,7 +102,7 @@ public class Main {
}
private static void ReconnectSIP(){
- if (client.Connect(serverAddress, Username, Password,"0.0.0.0")){
+ if (client.Connect()){
Logger.info("Connected to SIP Server");
}
else{
@@ -107,19 +115,5 @@ public class Main {
}
}
- private static void GetArguments(String[] args) {
- if (args != null){
- for(String a : args){
- if (a.startsWith("--serverip=")){
- serverAddress=a.substring(11);
- }
- else if (a.startsWith("--username=")){
- Username=a.substring(11);
- }
- else if (a.startsWith("--password=")){
- Password=a.substring(11);
- }
- }
- }
- }
+
}
\ No newline at end of file
diff --git a/src/Webpage/WebServer.java b/src/Webpage/WebServer.java
new file mode 100644
index 0000000..b9606c5
--- /dev/null
+++ b/src/Webpage/WebServer.java
@@ -0,0 +1,77 @@
+package Webpage;
+
+import code.common;
+import io.javalin.Javalin;
+import io.javalin.http.staticfiles.Location;
+
+import java.util.Objects;
+import java.util.Properties;
+
+import static code.common.*;
+
+public class WebServer {
+ private final Javalin app;
+ private final int listenport;
+ private final String webusername;
+ private final String webpassword;
+ public WebServer() {
+ Properties prop = common.LoadProperties(currentDir,"config.properties");
+ listenport = GetProperties_IntValue(prop,"WebListenPort", 8080);
+ webusername = GetProperties_StringValue(prop,"WebUsername", "admin");
+ webpassword = GetProperties_StringValue(prop,"WebPassword", "admin");
+
+ app = Javalin.create(config -> config.addStaticFiles("/public", Location.CLASSPATH)).start(listenport);
+ app.get("/", ctx ->{
+ if (Objects.equals(ctx.sessionAttribute("username"), webusername)){
+ ctx.redirect("/index.html");
+ } else {
+ ctx.sessionAttribute("username", null);
+ ctx.redirect("/login.html");
+ }
+ });
+ app.get("/logout", ctx -> {
+ ctx.sessionAttribute("username", null);
+ ctx.redirect("/login.html");
+ });
+ app.get("/setting", ctx -> {
+ if (Objects.equals(ctx.sessionAttribute("username"), webusername)){
+ //TODO Setting Page
+ ctx.result("Setting Page");
+ } else {
+ ctx.redirect("/login.html");
+ }
+ });
+ app.post("/login", ctx -> {
+ String username = ctx.formParam("username");
+ String password = ctx.formParam("password");
+ if (Objects.equals(username, webusername) && Objects.equals(password, webpassword)){
+ ctx.sessionAttribute("username", username);
+ ctx.redirect("/index.html");
+ } else {
+ ctx.redirect("/login.html");
+ }
+ });
+ app.post("/setting", ctx -> {
+ if (Objects.equals(ctx.sessionAttribute("username"), webusername)){
+ //TODO Setting Page
+ ctx.result("Setting Page");
+ } else {
+ ctx.redirect("/login.html");
+ }
+ });
+ }
+
+ /**
+ * Start the web server
+ */
+ public void Start(){
+ if (app!=null) app.start(listenport);
+ }
+
+ /**
+ * Stop the web server
+ */
+ public void Stop(){
+ if (app!=null) app.stop();
+ }
+}
diff --git a/src/code/common.java b/src/code/common.java
new file mode 100644
index 0000000..44e9ec0
--- /dev/null
+++ b/src/code/common.java
@@ -0,0 +1,143 @@
+package code;
+
+import com.google.gson.Gson;
+import com.sun.jna.Native;
+import org.pmw.tinylog.Logger;
+import peers.sip.syntaxencoding.SipHeaderFieldName;
+import peers.sip.syntaxencoding.SipHeaderFieldValue;
+import peers.sip.syntaxencoding.SipHeaders;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class common {
+ public static String currentDir = System.getProperty("user.dir");
+ public static Gson gson = new Gson();
+
+ public static String GetProperties_StringValue(Properties prop, String key, String defaultavalue){
+ if (prop!=null){
+ if (ValidString(key)){
+ return prop.getProperty(key,defaultavalue);
+ }
+ }
+ return defaultavalue;
+ }
+
+ public static int GetProperties_IntValue(Properties prop, String key, int defaultavalue){
+ if (prop!=null){
+ if (ValidString(key)){
+ return ParseInt(prop.getProperty(key),defaultavalue);
+ }
+ }
+ return defaultavalue;
+ }
+
+
+
+ /**
+ * Parse integer from string
+ * @param value string to parse
+ * @param defaultvalue default value if parsing failed
+ * @return parsed integer
+ */
+ public static int ParseInt(String value, int defaultvalue){
+ try {
+ return Integer.parseInt(value);
+ } catch (Exception e) {
+ return defaultvalue;
+ }
+ }
+
+ /**
+ * Extract properties file from resource path
+ * @param directory destination directory
+ * @param filename destination filename
+ * @param overwrite overwrite if file already exists
+ */
+ public static void ExtractProperties(String directory, String filename, boolean overwrite){
+ try{
+ File dest = new File(directory,filename);
+ if (dest.isFile() && !overwrite){
+ Logger.info("Properties file already exists: {}",filename);
+ return;
+ }
+ File source = Native.extractFromResourcePath(filename);
+ if (source==null){
+ Logger.error("Failed to extract properties file: {}",filename);
+ return;
+ }
+ if (source.renameTo(dest))
+ Logger.info("Extracted properties file: {}",filename);
+ else Logger.error("Failed to rename properties file: {}",filename);
+ } catch (Exception e) {
+ Logger.error("Failed to extract properties file: {}",filename);
+ }
+ }
+
+ /**
+ * Load properties file from directory
+ * @param directory destination directory
+ * @param filename destination filename
+ * @return properties object
+ */
+ @SuppressWarnings("IOStreamConstructor")
+ public static Properties LoadProperties(String directory, String filename){
+ Properties prop = new Properties();
+ try {
+ File file = new File(directory,filename);
+ if (file.isFile()){
+ InputStream is = new FileInputStream(file);
+ prop.load(is);
+ is.close();
+ Logger.info("Loaded properties file: {}",filename);
+ } else Logger.info("Properties file not found: {}",filename);
+
+ } catch (Exception e) {
+ Logger.error("Failed to load properties file: {}",filename);
+ }
+ return prop;
+ }
+
+ /**
+ * Check if String is not null and have value
+ * @param value string to check
+ * @return true if string is not null and have value
+ */
+ public static boolean ValidString(String value){
+ if (value!=null){
+ return !value.isEmpty();
+ }
+ return false;
+ }
+
+ /**
+ * Check if port number is valid
+ * @param value port number to check
+ * @return true if port number is valid
+ */
+ public static boolean ValidPortNumber(int value){
+ return value>0 && value<65536;
+ }
+
+ /**
+ * Get SIP header value from SIP headers
+ * @param head SIP headers
+ * @param headername header name
+ * @param defaultvalue default value if header not found
+ * @return header value
+ */
+ public static String GetSIPHeaderValue(SipHeaders head, String headername, String defaultvalue) {
+ if (head!=null) {
+ SipHeaderFieldName _fn = new SipHeaderFieldName(headername);
+ if (head.contains(_fn)) {
+ SipHeaderFieldValue _fv = head.get(_fn);
+ if (_fv!=null) {
+ return _fv.getValue();
+ }
+ }
+ }
+ return defaultvalue;
+ }
+}
diff --git a/src/common.java b/src/common.java
deleted file mode 100644
index 6f00c9b..0000000
--- a/src/common.java
+++ /dev/null
@@ -1,30 +0,0 @@
-import peers.sip.syntaxencoding.SipHeaderFieldName;
-import peers.sip.syntaxencoding.SipHeaderFieldValue;
-import peers.sip.syntaxencoding.SipHeaders;
-
-public class common {
-
- public static boolean ValidString(String value){
- if (value!=null){
- return !value.isEmpty();
- }
- return false;
- }
-
- public static boolean ValidPortNumber(int value){
- return value>0 && value<65536;
- }
-
- public static String GetSIPHeaderValue(SipHeaders head, String headername) {
- if (head!=null) {
- SipHeaderFieldName _fn = new SipHeaderFieldName(headername);
- if (head.contains(_fn)) {
- SipHeaderFieldValue _fv = head.get(_fn);
- if (_fv!=null) {
- return _fv.getValue();
- }
- }
- }
- return null;
- }
-}
diff --git a/src/jSIPClient.java b/src/jSIPClient.java
index b108e84..39ad526 100644
--- a/src/jSIPClient.java
+++ b/src/jSIPClient.java
@@ -1,12 +1,11 @@
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.MessageFormat;
+import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -14,10 +13,8 @@ import Audio.BassFileReader;
import Audio.BassFileReaderListener;
import Audio.BassSoundManager;
import Audio.BassSoundManagerListener;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import code.common;
import com.google.gson.JsonIOException;
-import com.google.gson.JsonSyntaxException;
import lombok.Getter;
import org.pmw.tinylog.Logger;
@@ -35,13 +32,12 @@ import peers.sip.transactionuser.DialogManager;
import peers.sip.transport.SipRequest;
import peers.sip.transport.SipResponse;
+import static code.common.*;
+
@SuppressWarnings({"unused", "UnusedReturnValue"})
public class jSIPClient {
public jSIPClient() {
- gs = new GsonBuilder()
- .setPrettyPrinting()
- .create();
runningfolder = new File("").getAbsolutePath();
load_config();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
@@ -51,11 +47,14 @@ public class jSIPClient {
Disconnect();
}));
}
+
+ @Getter private String serverAddress;
+ @Getter private String Username;
+ @Getter private String Password;
public CustomConfig cc = new CustomConfig();
private EventManager em;
- private final Gson gs;
private final String runningfolder;
@@ -67,23 +66,18 @@ public class jSIPClient {
/**
- * Connect to SIP Server
- * @param serverip SIP Server IP
- * @param username Username to register
- * @param password Password to register
- * @param localip use if need to specify which Network Adapter to use
+ * Connect to SIP Server
* @return true if parameter completed
*/
- public boolean Connect(String serverip, String username, String password, String localip) {
+ public boolean Connect() {
Disconnect();
if (cc==null) {
System.out.println("Creating Custom Config");
cc = new CustomConfig();
} else System.out.println("Custom Config already created");
- if (common.ValidString(serverip)) cc.setDomain(serverip);
- if (common.ValidString(username)) cc.setUserPart(username);
- if (common.ValidString(password)) cc.setPassword(password);
- if (common.ValidString(localip)) cc.SetLocalInetAddress(localip);
+ cc.setDomain(serverAddress);
+ cc.setUserPart(Username);
+ cc.setPassword(Password);
em = new EventManager(cc);
return false;
@@ -537,7 +531,7 @@ public class jSIPClient {
@Override
public void error(SipResponse sipResponse) {
- raise_log_event("sip error, response="+gs.toJson(sipResponse));
+ raise_log_event("sip error, response="+common.gson.toJson(sipResponse));
}
@@ -555,10 +549,10 @@ public class jSIPClient {
req = source;
if (req!=null) {
SipHeaders head = source.getSipHeaders();
- this.To = common.GetSIPHeaderValue(head,"To");
- this.From = common.GetSIPHeaderValue(head, "From");
- this.CallID = common.GetSIPHeaderValue(head, "Call-ID");
- this.Contact = common.GetSIPHeaderValue(head, "Contact");
+ this.To = common.GetSIPHeaderValue(head,"To", null);
+ this.From = common.GetSIPHeaderValue(head, "From", null);
+ this.CallID = common.GetSIPHeaderValue(head, "Call-ID", null);
+ this.Contact = common.GetSIPHeaderValue(head, "Contact", null);
}
}
@@ -578,12 +572,12 @@ public class jSIPClient {
this.statusCode = source.getStatusCode();
this.reasonPhrase = source.getReasonPhrase();
SipHeaders head = source.getSipHeaders();
- this.To = common.GetSIPHeaderValue(head, "To");
- this.From = common.GetSIPHeaderValue(head, "From");
- this.CallID = common.GetSIPHeaderValue(head, "Call-ID");
- this.Contact = common.GetSIPHeaderValue(head, "Contact");
- this.Server = common.GetSIPHeaderValue(head, "Server");
- this.Date = common.GetSIPHeaderValue(head, "Date");
+ this.To = common.GetSIPHeaderValue(head, "To", null);
+ this.From = common.GetSIPHeaderValue(head, "From", null);
+ this.CallID = common.GetSIPHeaderValue(head, "Call-ID", null);
+ this.Contact = common.GetSIPHeaderValue(head, "Contact", null);
+ this.Server = common.GetSIPHeaderValue(head, "Server", null);
+ this.Date = common.GetSIPHeaderValue(head, "Date", null);
}
}
private @Getter final SipResponse resp;
@@ -974,25 +968,21 @@ public class jSIPClient {
private void save_config() {
if (cc!=null) {
try {
- gs.toJson(cc, new FileWriter(new File(runningfolder,"Config.json")));
+ common.gson.toJson(cc, new FileWriter(new File(runningfolder,"Config.json")));
raise_log_event("Config.json saved");
} catch (JsonIOException | IOException e) {
raise_log_event("save_config failed, exception = "+e.getMessage());
}
}
}
-
- /**
- * Dipanggil saat initialization
- */
- private void load_config() {
- try {
- CustomConfig xx = gs.fromJson(new FileReader(new File(runningfolder,"Config.json")), CustomConfig.class);
- raise_log_event("Config.json loaded");
- cc = xx;
- } catch (JsonSyntaxException | JsonIOException | FileNotFoundException e) {
- raise_log_event("load_config failed, exception = "+e.getMessage());
- }
-
+
+ private void load_config(){
+ Properties prop = LoadProperties(currentDir,"config.properties");
+ serverAddress = GetProperties_StringValue(prop,"SipServer","100.64.0.3");
+ Username = GetProperties_StringValue(prop,"SipUsername","user1");
+ Password = GetProperties_StringValue(prop,"SipPassword","12345678");
+ Logger.info("SipServer: "+serverAddress);
+ Logger.info("SipUsername: "+Username);
+ Logger.info("SipPassword: "+Password);
}
}
diff --git a/src/peers/sip/core/useragent/handlers/RegisterHandler.java b/src/peers/sip/core/useragent/handlers/RegisterHandler.java
index be67137..4c0e93f 100644
--- a/src/peers/sip/core/useragent/handlers/RegisterHandler.java
+++ b/src/peers/sip/core/useragent/handlers/RegisterHandler.java
@@ -72,7 +72,7 @@ public class RegisterHandler extends MethodHandler
super(userAgent, transactionManager, transportManager);
}
- //TODO factorize common code here and in invitehandler
+ //TODO factorize code.common code here and in invitehandler
public synchronized ClientTransaction preProcessRegister(SipRequest sipRequest)
throws SipUriSyntaxException {
registered = false;