diff --git a/Properties/config.properties b/Properties/config.properties index f008b5a..3e48dfd 100644 --- a/Properties/config.properties +++ b/Properties/config.properties @@ -1,7 +1,7 @@ WebUsername=admin WebPassword=admin WebListenPort = 8080 -SipServer=rdkartono.ddns.me +SipServer=192.168.10.2 SipPort=5060 SipUsername=101 SipPassword=password101 \ No newline at end of file diff --git a/src/Audio/BassSoundManager.java b/src/Audio/BassSoundManager.java index 35f8be5..643e2b5 100644 --- a/src/Audio/BassSoundManager.java +++ b/src/Audio/BassSoundManager.java @@ -153,6 +153,7 @@ public class BassSoundManager extends AbstractSoundManager { int rs; Pointer buf = new Memory(read_size); while(true) { + if (recordhandle==0) break; if (BASS.BASS_ChannelIsActive(recordhandle)!=Bass.BASS_ACTIVE_PLAYING) break; rs = BASS.BASS_ChannelGetData(recordhandle, buf, read_size); if (rs<0) { @@ -165,7 +166,7 @@ public class BassSoundManager extends AbstractSoundManager { if (bsml!=null) bsml.ReadToRTP(rs, result); return result; } else { - // nol + // nol, tunggu bentar try { Thread.sleep(2); } catch (InterruptedException e) { diff --git a/src/Main.java b/src/Main.java index 9daab4e..ef2b873 100644 --- a/src/Main.java +++ b/src/Main.java @@ -41,275 +41,23 @@ public class Main { private static NetworkTransmitReceiveInfo[] previousNetworkInfo; private static final Map networkTX = new HashMap<>(); private static final Map networkRX = new HashMap<>(); + private static Properties config; public static void main(String[] args) { common.ExtractProperties(currentDir,"config.properties", false); - Properties config = common.LoadProperties(currentDir,"config.properties"); + config = common.LoadProperties(currentDir,"config.properties"); // Timer Section timer = new Timer(); // SIP Section - client = new jSIPClient(config); - // event dari sisi Bass Sound Manager - client.SetBassSoundManagerEvent(new BassSoundManagerEvent() { - @Override - public void SoundChannelOpened() { - - } - - @Override - public void SoundChannelClosed() { - - } - - @Override - public void OutputChannelPCMData(int length, byte[] pcmdata) { - - } - - @Override - public void InputChannelPCMData(int length, byte[] pcmdata) { - - } - - @Override - public void DeviceFailure(boolean onOutput, String msg) { - - } - - @Override - public void BufferingInformation(boolean onOutput, String msg) { - - } - - @Override - public void ChannelLevel(boolean onOutput, int level) { - - } - }); - // event dari sisi protocol SIP - client.SetJavaSipEvent(new javaSipEvents() { - @Override - public void Registering(SIP_Request req) { - Logger.info("Registering to SIP Server, Request: {}",req); - Buzzer_Off(); - callLight_Registering(); - SipStatus = "Registering"; - } - - @Override - public void RegisterSuccesful(SIP_Response resp) { - Logger.info("Registered to SIP Server, Response: {}",resp); - Buzzer_Off(); - callLight_Idle(); - SipStatus = "Idle"; - - } - - @Override - public void RegisterFailed(SIP_Response resp) { - Logger.info("Failed to register to SIP Server, Response: {}",resp); - Buzzer_Off(); - SipStatus = "Register Failed"; - - } - - @Override - public void IncomingCall(SIP_Request req, SIP_Response resp) { - Logger.info("Incoming Call, Request: {}, Response: {}",req,resp); - callLight_IncomingCall(); - Buzzer_IncomingCall(); - incomingRequest = req; - incomingResponse = resp; - oncallRequest = null; - oncallResponse = null; - SipStatus = "Incoming Call from "+req.CallID; - //client.AcceptIncomingCall(req); - } - - @Override - public void RemoteHangUp(SIP_Request req) { - Logger.info("Remote Hangup, Request: {}",req); - callLight_Idle(); - Buzzer_Off(); - - client.HangUp(); - SipStatus = "Remote Hangup from "+req.CallID; - incomingRequest = null; - incomingResponse = null; - oncallRequest = null; - oncallResponse = null; - - } - - @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); - oncallResponse = resp; - SipStatus = "Communication with "+resp.CallID; - } - }); - client.Connect(); - + SIPClient_Section(); // 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 || incomingResponse!=null){ - resp = new SocketioResponse("success", "Reject Incoming Call from "+incomingRequest.CallID); - hangupCall(); - } else if (oncallRequest!=null || oncallResponse!=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": - int extension = ParseInt(req.getData(),-1) ; - if (extension>0){ - if (Call(""+extension)){ - resp = new SocketioResponse("success", "Call to "+extension+" is successful"); - } else { - resp = new SocketioResponse("error", "Call to "+extension+" is failed"); - } - } else resp = new SocketioResponse("error", "Invalid Extension"); - break; - case "getDiskInfo": - resp = new SocketioResponse("error", "Not Implemented"); - break; - default: - resp = new SocketioResponse("error", "Invalid Request"); - break; - } - return resp; - }); + WebServer_Section(); // 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"); - //pickupCall(); - Call("100"); - }); - callButton.setOnShortPress(vv->{ - Logger.info("Call Button Short Pressed"); - pickupCall(); - }); - } else Logger.error("Failed to initialize Call Button"); - hangupButton = new GpioInput(NanopiDuo2.Pin14.gpionumber, true); - if (hangupButton.isInitialized()){ - hangupButton.setOnShortPress(vv->{ - Logger.info("Hangup Button Short Pressed"); - hangupCall(); - }); - hangupButton.setOnLongPress(vv->{ - Logger.info("Hangup Button Long Pressed"); - hangupCall(); - }); - } else Logger.error("Failed to initialize Hangup Button"); - - // belum ada pinout nya di PCB demo (04/12/2024) - pilotLight = new GpioOutput(NanopiDuo2.Pin16.gpionumber, true); - if (pilotLight.isInitialized()){ - timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - if (pilotLight!=null && pilotLight.isInitialized()) pilotLight.BlinkON(100); - } - }, 0, 1000); - } - - 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); + GPIO_Section(); // Start System monitoring init_system_monitoring(); @@ -330,19 +78,293 @@ public class Main { })); } + private static void SIPClient_Section(){ + // initialize pakai thread, biar cepat + new Thread(()->{ + client = new jSIPClient(config); + // event dari sisi Bass Sound Manager + client.SetBassSoundManagerEvent(new BassSoundManagerEvent() { + @Override + public void SoundChannelOpened() { + + } + + @Override + public void SoundChannelClosed() { + + } + + @Override + public void OutputChannelPCMData(int length, byte[] pcmdata) { + + } + + @Override + public void InputChannelPCMData(int length, byte[] pcmdata) { + + } + + @Override + public void DeviceFailure(boolean onOutput, String msg) { + + } + + @Override + public void BufferingInformation(boolean onOutput, String msg) { + + } + + @Override + public void ChannelLevel(boolean onOutput, int level) { + + } + }); + // event dari sisi protocol SIP + client.SetJavaSipEvent(new javaSipEvents() { + @Override + public void Registering(SIP_Request req) { + Logger.info("Registering to SIP Server, Request: {}",req); + Buzzer_Off(); + callLight_Registering(); + SipStatus = "Registering"; + } + + @Override + public void RegisterSuccesful(SIP_Response resp) { + Logger.info("Registered to SIP Server, Response: {}",resp); + Buzzer_Off(); + callLight_Idle(); + SipStatus = "Idle"; + + } + + @Override + public void RegisterFailed(SIP_Response resp) { + Logger.info("Failed to register to SIP Server, Response: {}",resp); + Buzzer_Off(); + SipStatus = "Register Failed"; + + } + + @Override + public void IncomingCall(SIP_Request req, SIP_Response resp) { + Logger.info("Incoming Call, Request: {}, Response: {}",req,resp); + callLight_IncomingCall(); + Buzzer_IncomingCall(); + incomingRequest = req; + incomingResponse = resp; + oncallRequest = null; + oncallResponse = null; + SipStatus = "Incoming Call from "+req.CallID; + //client.AcceptIncomingCall(req); + } + + @Override + public void RemoteHangUp(SIP_Request req) { + Logger.info("Remote Hangup, Request: {}",req); + callLight_Idle(); + Buzzer_Off(); + + client.HangUp(); + SipStatus = "Remote Hangup from "+req.CallID; + incomingRequest = null; + incomingResponse = null; + oncallRequest = null; + oncallResponse = null; + + } + + @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) { + oncallResponse = resp; + Logger.info("Callee Pickup, Response: {}",oncallResponse); + SipStatus = "Communication with "+oncallResponse.CallID; + } + }); + client.Connect(); + }).start(); + + } + + private static void WebServer_Section(){ + // initialize pakai thread, biar cepat + new Thread(()->{ + 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": + hangupCall(); + resp = new SocketioResponse("success", "Hangup Call"); + 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": + int extension = ParseInt(req.getData(),-1) ; + if (extension>0){ + if (Call(""+extension)){ + resp = new SocketioResponse("success", "Call to "+extension+" is successful"); + } else { + resp = new SocketioResponse("error", "Call to "+extension+" is failed"); + } + } else resp = new SocketioResponse("error", "Invalid Extension"); + break; + case "getDiskInfo": + resp = new SocketioResponse("error", "Not Implemented"); + break; + default: + resp = new SocketioResponse("error", "Invalid Request"); + break; + } + return resp; + }); + }).start(); + + } + + /** + * GPIO Section + * talk button = pin12 + * hangup button = pin14 + * Call light = pin 22 + * Network light = pin 20 + * Pilot light = pin 16 + * Buzzer = pin 18 + */ + private static void GPIO_Section(){ + // initialize pakai thread, biar cepat + new Thread(()->{ + callButton = new GpioInput(NanopiDuo2.Pin12.gpionumber, true); + if (callButton.isInitialized()){ + callButton.setOnLongPress(vv->{ + Logger.info("Call Button Long Pressed"); + //pickupCall(); + Call("100"); + }); + callButton.setOnShortPress(vv->{ + Logger.info("Call Button Short Pressed"); + pickupCall(); + }); + } else Logger.error("Failed to initialize Call Button"); + hangupButton = new GpioInput(NanopiDuo2.Pin14.gpionumber, true); + if (hangupButton.isInitialized()){ + hangupButton.setOnShortPress(vv->{ + Logger.info("Hangup Button Short Pressed"); + hangupCall(); + }); + hangupButton.setOnLongPress(vv->{ + Logger.info("Hangup Button Long Pressed"); + hangupCall(); + }); + } else Logger.error("Failed to initialize Hangup Button"); + + + pilotLight = new GpioOutput(NanopiDuo2.Pin16.gpionumber, true); + if (pilotLight.isInitialized()){ + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + if (pilotLight!=null && pilotLight.isInitialized()) pilotLight.BlinkON(100); + } + }, 0, 1000); + } + + networkLight = new GpioOutput(NanopiDuo2.Pin20.gpionumber, true); + callLight = new GpioOutput(NanopiDuo2.Pin22.gpionumber, true); + + + Buzzer = new GpioOutput(NanopiDuo2.Pin18.gpionumber, true); + }).start(); + + } + /** * Hangup call */ private static void hangupCall() { - if (oncallRequest!=null || oncallResponse!=null){ - client.HangUp(); - oncallResponse = null; - oncallRequest = null; - } else if (incomingRequest!=null || incomingResponse!=null){ + if (incomingRequest!=null || incomingResponse!=null){ client.RejectIncomingCall(incomingRequest); - incomingRequest = null; - incomingResponse = null; + } else { + client.HangUp(); } + incomingResponse = null; + incomingRequest = null; + oncallResponse = null; + oncallRequest = null; callLight_Idle(); Buzzer_Off(); SipStatus = "Idle"; @@ -392,6 +414,7 @@ public class Main { File ff = new File(currentDir, filename); if (ff.isFile()){ String callnumber = MessageFormat.format("sip:{0}@{1}", extension, client.getServerAddress()); + if (client.StreamFile(callnumber, ff.getAbsolutePath())){ Logger.info("Stream to {} is successful",callnumber); try{ @@ -519,6 +542,7 @@ public class Main { private static void init_system_monitoring(){ TimerTask tt = new TimerTask() { + @SuppressWarnings("IfStatementWithIdenticalBranches") @Override public void run() { cpuTemperature = SystemInformation.getCPUTemperature(); diff --git a/src/SBC/GpioInput.java b/src/SBC/GpioInput.java index 9225bf7..3ade32f 100644 --- a/src/SBC/GpioInput.java +++ b/src/SBC/GpioInput.java @@ -6,13 +6,11 @@ import org.pmw.tinylog.Logger; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import static code.common.*; -@SuppressWarnings("unused") @Getter public class GpioInput { private boolean initialized = false; diff --git a/src/SBC/GpioOutput.java b/src/SBC/GpioOutput.java index e94e9fa..a2c7227 100644 --- a/src/SBC/GpioOutput.java +++ b/src/SBC/GpioOutput.java @@ -8,7 +8,7 @@ import java.nio.file.Path; import static code.common.*; -@SuppressWarnings({"unused", "UnusedReturnValue"}) +@SuppressWarnings({"unused","UnusedReturnValue"}) @Getter public class GpioOutput { private boolean initialized = false; diff --git a/src/SIP/jSIPClient.java b/src/SIP/jSIPClient.java index 2f69c23..0509de6 100644 --- a/src/SIP/jSIPClient.java +++ b/src/SIP/jSIPClient.java @@ -379,6 +379,7 @@ public class jSIPClient { DialogManager dialogManager = user_agent.getDialogManager(); Dialog dialog = dialogManager.getDialog(callId); user_agent.acceptCall(req, dialog); + sip_request = req; }); }