patches 20/11/2024
This commit is contained in:
170
src/Main.java
170
src/Main.java
@@ -25,8 +25,14 @@ public class Main {
|
|||||||
private static GpioOutput pilotLight;
|
private static GpioOutput pilotLight;
|
||||||
private static GpioOutput networkLight;
|
private static GpioOutput networkLight;
|
||||||
private static GpioOutput callLight;
|
private static GpioOutput callLight;
|
||||||
|
private static GpioOutput Buzzer;
|
||||||
private static Timer timer;
|
private static Timer timer;
|
||||||
private static TimerTask callLightTask;
|
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;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
common.ExtractProperties(currentDir,"config.properties", false);
|
common.ExtractProperties(currentDir,"config.properties", false);
|
||||||
@@ -40,6 +46,12 @@ public class Main {
|
|||||||
if (callLight!=null && callLight.isInitialized()) callLight.BlinkON(100);
|
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
|
// SIP Section
|
||||||
client = new jSIPClient(config);
|
client = new jSIPClient(config);
|
||||||
@@ -47,38 +59,47 @@ public class Main {
|
|||||||
@Override
|
@Override
|
||||||
public void Registering(SIP_Request req) {
|
public void Registering(SIP_Request req) {
|
||||||
Logger.info("Registering to SIP Server, Request: {}",req);
|
Logger.info("Registering to SIP Server, Request: {}",req);
|
||||||
|
Buzzer_Off();
|
||||||
// selama registering, blink dengan interval 500ms
|
callLight_Registering();
|
||||||
callLightTask.cancel();
|
|
||||||
timer.purge();
|
|
||||||
timer.scheduleAtFixedRate(callLightTask, 0, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void RegisterSuccesful(SIP_Response resp) {
|
public void RegisterSuccesful(SIP_Response resp) {
|
||||||
Logger.info("Registered to SIP Server, Response: {}",resp);
|
Logger.info("Registered to SIP Server, Response: {}",resp);
|
||||||
|
Buzzer_Off();
|
||||||
// setelah register berhasil, blink dengan interval 3000ms
|
callLight_Idle();
|
||||||
callLightTask.cancel();
|
|
||||||
timer.purge();
|
|
||||||
timer.scheduleAtFixedRate(callLightTask, 0, 3000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void RegisterFailed(SIP_Response resp) {
|
public void RegisterFailed(SIP_Response resp) {
|
||||||
Logger.info("Failed to register to SIP Server, Response: {}",resp);
|
Logger.info("Failed to register to SIP Server, Response: {}",resp);
|
||||||
|
Buzzer_Off();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void IncomingCall(SIP_Request req, SIP_Response resp) {
|
public void IncomingCall(SIP_Request req, SIP_Response resp) {
|
||||||
Logger.info("Incoming Call, Request: {}, Response: {}",req,resp);
|
Logger.info("Incoming Call, Request: {}, Response: {}",req,resp);
|
||||||
client.AcceptIncomingCall(req);
|
callLight_IncomingCall();
|
||||||
|
Buzzer_IncomingCall();
|
||||||
|
incomingRequest = req;
|
||||||
|
incomingResponse = resp;
|
||||||
|
oncallRequest = null;
|
||||||
|
oncallResponse = null;
|
||||||
|
//client.AcceptIncomingCall(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void RemoteHangUp(SIP_Request req) {
|
public void RemoteHangUp(SIP_Request req) {
|
||||||
Logger.info("Remote Hangup, Request: {}",req);
|
Logger.info("Remote Hangup, Request: {}",req);
|
||||||
|
callLight_Idle();
|
||||||
|
Buzzer_Off();
|
||||||
|
|
||||||
client.HangUp();
|
client.HangUp();
|
||||||
|
incomingRequest = null;
|
||||||
|
incomingResponse = null;
|
||||||
|
oncallRequest = null;
|
||||||
|
oncallResponse = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -99,8 +120,64 @@ public class Main {
|
|||||||
webserver.Start();
|
webserver.Start();
|
||||||
|
|
||||||
// GPIO Section
|
// GPIO Section
|
||||||
callButton = new GpioInput(NanopiDuo2.Pin12.gpionumber);
|
callButton = new GpioInput(NanopiDuo2.Pin12.gpionumber, true);
|
||||||
hangupButton = new GpioInput(NanopiDuo2.Pin14.gpionumber);
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
}
|
||||||
pilotLight = new GpioOutput(NanopiDuo2.Pin16.gpionumber, true);
|
pilotLight = new GpioOutput(NanopiDuo2.Pin16.gpionumber, true);
|
||||||
if (pilotLight.isInitialized()){
|
if (pilotLight.isInitialized()){
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
@@ -112,6 +189,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
networkLight = new GpioOutput(NanopiDuo2.Pin18.gpionumber, true);
|
networkLight = new GpioOutput(NanopiDuo2.Pin18.gpionumber, true);
|
||||||
callLight = new GpioOutput(NanopiDuo2.Pin20.gpionumber, true);
|
callLight = new GpioOutput(NanopiDuo2.Pin20.gpionumber, true);
|
||||||
|
Buzzer = new GpioOutput(NanopiDuo2.Pin22.gpionumber, true);
|
||||||
|
|
||||||
// Shutdown Hook
|
// Shutdown Hook
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
@@ -176,5 +254,71 @@ public class Main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registering state, call light is blinking with 500ms interval
|
||||||
|
*/
|
||||||
|
private static void callLight_Registering(){
|
||||||
|
if (callLightTask!=null) callLightTask.cancel();
|
||||||
|
if (timer!=null){
|
||||||
|
timer.purge();
|
||||||
|
timer.scheduleAtFixedRate(callLightTask, 0, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Idle state, call light is blinking with interval 3000ms
|
||||||
|
*/
|
||||||
|
private static void callLight_Idle(){
|
||||||
|
if (callLightTask!=null) callLightTask.cancel();
|
||||||
|
if (timer!=null){
|
||||||
|
timer.purge();
|
||||||
|
timer.scheduleAtFixedRate(callLightTask, 0, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming call, call light is blinking with 1000ms interval
|
||||||
|
*/
|
||||||
|
private static void callLight_IncomingCall(){
|
||||||
|
if (callLightTask!=null) callLightTask.cancel();
|
||||||
|
if (timer!=null){
|
||||||
|
timer.purge();
|
||||||
|
timer.scheduleAtFixedRate(callLightTask, 0, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On call, call light is on
|
||||||
|
*/
|
||||||
|
private static void callLight_OnCall(){
|
||||||
|
if (callLightTask!=null) callLightTask.cancel();
|
||||||
|
if (timer!=null) timer.purge();
|
||||||
|
callLight.SetValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming call, buzzer is beeping with 1000ms interval
|
||||||
|
*/
|
||||||
|
private static void Buzzer_IncomingCall(){
|
||||||
|
if (BuzzerTask!=null) BuzzerTask.cancel();
|
||||||
|
if (timer!=null){
|
||||||
|
timer.purge();
|
||||||
|
timer.scheduleAtFixedRate(BuzzerTask, 0, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On-call, buzzer is off
|
||||||
|
*/
|
||||||
|
private static void Buzzer_OnCall(){
|
||||||
|
if (BuzzerTask!=null) BuzzerTask.cancel();
|
||||||
|
if (timer!=null) timer.purge();
|
||||||
|
Buzzer.SetValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Buzzer_Off(){
|
||||||
|
if (BuzzerTask!=null) BuzzerTask.cancel();
|
||||||
|
if (timer!=null) timer.purge();
|
||||||
|
Buzzer.SetValue(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import org.pmw.tinylog.Logger;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import static code.common.*;
|
import static code.common.*;
|
||||||
@@ -16,24 +17,33 @@ import static code.common.*;
|
|||||||
public class GpioInput {
|
public class GpioInput {
|
||||||
private boolean initialized = false;
|
private boolean initialized = false;
|
||||||
private int gpionumber = 0;
|
private int gpionumber = 0;
|
||||||
private String lastvalue = "";
|
|
||||||
private Path valuePath;
|
private Path valuePath;
|
||||||
private Path directionPath;
|
private Path directionPath;
|
||||||
@Setter private Consumer<String> onChange;
|
private final AtomicInteger OnCounter = new AtomicInteger(0);
|
||||||
|
@Setter private Consumer<Void> onShortPress;
|
||||||
|
@Setter private Consumer<Void> onLongPress;
|
||||||
|
|
||||||
private void updateValue(String value){
|
// 10 x 10ms timer = 100ms
|
||||||
if (onChange!=null){
|
private final int shortPressTime = 10;
|
||||||
if (ValidString(value)){
|
// 200 x 10ms timer = 2000ms
|
||||||
onChange.accept(value);
|
private final int longPressTime = 200;
|
||||||
}
|
|
||||||
|
private void updateShortPressed(){
|
||||||
|
if (onShortPress!=null) onShortPress.accept(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLongPressed(){
|
||||||
|
if (onLongPress!=null) onLongPress.accept(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create GpioInput object
|
* Create GpioInput object
|
||||||
|
* Active Low = true : 0 = ON, 1 = OFF
|
||||||
|
* Active Low = false : 0 = OFF, 1 = ON
|
||||||
* @param gpionumber GPIO number
|
* @param gpionumber GPIO number
|
||||||
|
* @param activeLow Active Low
|
||||||
*/
|
*/
|
||||||
public GpioInput(int gpionumber){
|
public GpioInput(int gpionumber, final boolean activeLow){
|
||||||
if (gpionumber>0){
|
if (gpionumber>0){
|
||||||
if (HaveGPIO()){
|
if (HaveGPIO()){
|
||||||
if (WriteFile(gpioExportPath,gpionumber)){
|
if (WriteFile(gpioExportPath,gpionumber)){
|
||||||
@@ -49,9 +59,19 @@ public class GpioInput {
|
|||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
String value = ReadFile(valuePath);
|
String value = ReadFile(valuePath);
|
||||||
if (Objects.equals(lastvalue, value)) continue;
|
if (Objects.equals(value,activeLow?"0":"1")){
|
||||||
lastvalue = value;
|
OnCounter.incrementAndGet();
|
||||||
updateValue(value);
|
} else {
|
||||||
|
int vv = OnCounter.getAndSet(0);
|
||||||
|
if (vv>= shortPressTime){
|
||||||
|
if (vv < longPressTime){
|
||||||
|
updateShortPressed();
|
||||||
|
} else {
|
||||||
|
updateLongPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// di bawah shortPressTime, diabaikan
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
Logger.info("GPIO Input created: {}",gpionumber);
|
Logger.info("GPIO Input created: {}",gpionumber);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public class GpioOutput {
|
|||||||
this.activeHigh = activeHigh;
|
this.activeHigh = activeHigh;
|
||||||
this.gpionumber = gpionumber;
|
this.gpionumber = gpionumber;
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
SetValue(false);
|
||||||
Logger.info("GPIO Output created: {}",gpionumber);
|
Logger.info("GPIO Output created: {}",gpionumber);
|
||||||
} else Logger.info("Failed to set direction to in: {}",gpionumber);
|
} else Logger.info("Failed to set direction to in: {}",gpionumber);
|
||||||
} else Logger.info("Failed to export GPIO: {}",gpionumber);
|
} else Logger.info("Failed to export GPIO: {}",gpionumber);
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ public class jSIPClient {
|
|||||||
if (em!=null) {
|
if (em!=null) {
|
||||||
if (em.IsCreated()) {
|
if (em.IsCreated()) {
|
||||||
if (em.CallingInProgress()) {
|
if (em.CallingInProgress()) {
|
||||||
|
|
||||||
em.HangUp();
|
em.HangUp();
|
||||||
return true;
|
return true;
|
||||||
} else raise_log_event("HangUp failed, no call made");
|
} else raise_log_event("HangUp failed, no call made");
|
||||||
@@ -451,6 +452,7 @@ public class jSIPClient {
|
|||||||
return sip_request!=null;
|
return sip_request!=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hang-Up current call
|
* Hang-Up current call
|
||||||
*/
|
*/
|
||||||
@@ -458,6 +460,7 @@ public class jSIPClient {
|
|||||||
if (sip_request!=null) {
|
if (sip_request!=null) {
|
||||||
if (user_agent!=null) {
|
if (user_agent!=null) {
|
||||||
exec.submit(() -> {
|
exec.submit(() -> {
|
||||||
|
|
||||||
user_agent.terminate(sip_request);
|
user_agent.terminate(sip_request);
|
||||||
sip_request = null;
|
sip_request = null;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user