Compare commits

...

2 Commits

Author SHA1 Message Date
142c400273 patches 20/11/2024 2024-11-20 11:32:50 +07:00
26579a8acf patches 20/11/2024 2024-11-20 11:30:44 +07:00
8 changed files with 293 additions and 118 deletions

View File

@@ -0,0 +1,6 @@
WebUsername=admin
WebPassword=admin
WebListenPort = 8080
SipServer=100.64.0.3
SipUsername=100
SipPassword=12345678

View File

@@ -5,6 +5,8 @@
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/libs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Properties" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/WebContentt" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

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

View File

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

143
src/code/common.java Normal file
View File

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

View File

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

View File

@@ -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(() -> {
@@ -52,10 +48,13 @@ public class jSIPClient {
}));
}
@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;
@@ -68,22 +67,17 @@ 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
* @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,7 +968,7 @@ 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());
@@ -982,17 +976,13 @@ public class jSIPClient {
}
}
/**
* 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);
}
}

View File

@@ -25,6 +25,8 @@ import java.util.Hashtable;
import java.util.Timer;
import java.util.TimerTask;
import lombok.Getter;
import lombok.Setter;
import org.pmw.tinylog.Logger;
import peers.Config;
@@ -54,6 +56,7 @@ public class RegisterHandler extends MethodHandler
public static final int REFRESH_MARGIN = 10; // seconds
@Setter
private InitialRequestManager initialRequestManager;
private Timer timer;
@@ -64,6 +67,7 @@ public class RegisterHandler extends MethodHandler
//FIXME should be on a profile based context
private boolean unregisterInvoked;
@Getter
private boolean registered;
public RegisterHandler(UserAgent userAgent,
@@ -72,7 +76,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;
@@ -132,7 +136,7 @@ public class RegisterHandler extends MethodHandler
public void errResponseReceived(SipResponse sipResponse) {
String password = userAgent.getConfig().getPassword();
if (password != null && !"".equals(password.trim())) {
if (password != null && !password.trim().isEmpty()) {
int statusCode = sipResponse.getStatusCode();
if (statusCode == RFC3261.CODE_401_UNAUTHORIZED
|| statusCode ==
@@ -170,7 +174,7 @@ public class RegisterHandler extends MethodHandler
}
}
String received = via.getParam(receivedName);
if (received != null && !"".equals(received.trim())) {
if (received != null && !received.trim().isEmpty()) {
if (viaValue.equals(received)) {
notifyListener(sipResponse);
} else { // received != via ip address
@@ -180,10 +184,7 @@ public class RegisterHandler extends MethodHandler
Config config = userAgent.getConfig();
config.setPublicInetAddress(receivedInetAddress);
userAgent.register();
} catch (UnknownHostException e) {
notifyListener(sipResponse);
Logger.error(e.getMessage(), e);
} catch (SipUriSyntaxException e) {
} catch (Exception e) {
notifyListener(sipResponse);
Logger.error(e.getMessage(), e);
}
@@ -237,7 +238,7 @@ public class RegisterHandler extends MethodHandler
// patch mobicents simple application
registered = true;
int delay = -1;
if (expires == null || "".equals(expires.trim())) {
if (expires == null || expires.trim().isEmpty()) {
delay = 3600;
}
if (!unregisterInvoked) {
@@ -246,7 +247,7 @@ public class RegisterHandler extends MethodHandler
}
timer = new Timer(getClass().getSimpleName()
+ " refresh timer");
timer.schedule(new RefreshTimerTask(), delay * 1000);
timer.schedule(new RefreshTimerTask(), delay * 1000L);
}
}
SipListener sipListener = userAgent.getSipListener();
@@ -266,10 +267,6 @@ public class RegisterHandler extends MethodHandler
//TODO alert user
}
public boolean isRegistered() {
return registered;
}
//////////////////////////////////////////////////////////
// TimerTask
//////////////////////////////////////////////////////////
@@ -286,8 +283,4 @@ public class RegisterHandler extends MethodHandler
}
}
public void setInitialRequestManager(InitialRequestManager initialRequestManager) {
this.initialRequestManager = initialRequestManager;
}
}