patch 06/12/2024

This commit is contained in:
2024-12-06 13:18:09 +07:00
parent 6a54013eda
commit a4ede5b1f3
6 changed files with 293 additions and 269 deletions

View File

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

View File

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

View File

@@ -41,275 +41,23 @@ public class Main {
private static NetworkTransmitReceiveInfo[] previousNetworkInfo;
private static final Map<String, String> networkTX = new HashMap<>();
private static final Map<String, String> 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();

View File

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

View File

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

View File

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