patches 19/11/2024
This commit is contained in:
@@ -802,6 +802,15 @@ public interface Bass extends Library {
|
||||
// gak bisa
|
||||
int BASS_StreamCreate(int freq, int chans, int flags, int proc, Pointer user);
|
||||
|
||||
class Utils {
|
||||
public static int LOBYTE(int n) { return n&0xff; }
|
||||
public static int HIBYTE(int n) { return (n>>8)&0xff; }
|
||||
public static int LOWORD(int n) { return n&0xffff; }
|
||||
public static int HIWORD(int n) { return (n>>16)&0xffff; }
|
||||
public static int MAKEWORD(int a, int b) { return (a&0xff)|((b&0xff)<<8); }
|
||||
public static int MAKELONG(int a, int b) { return (a&0xffff)|(b<<16); }
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
default String GetBassError(String function, int err) {
|
||||
if (err==0)
|
||||
|
||||
@@ -12,7 +12,6 @@ import peers.media.SoundSource;
|
||||
* @author rdkartono
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
public class BassFileReader implements SoundSource {
|
||||
// Device = 0 --> no sound
|
||||
private final int bassdev = 0;
|
||||
@@ -29,7 +28,7 @@ public class BassFileReader implements SoundSource {
|
||||
// Mixer create flag BASS_STREAM_DECODE karena untuk ambil data aja, bukan playback
|
||||
private final int mixerflag = Bass.BASS_STREAM_DECODE;
|
||||
// Mixer_AddChannel flag BAS_STREAM_AUTOFREE , supaya kalau channel habis & selesai, channel free sendiri
|
||||
//private final int addchannelflag = BassLibrary.Constant.BASS_STREAM_AUTOFREE;
|
||||
//private final int addchannelflag = Bass.BASS_STREAM_AUTOFREE;
|
||||
private final int addchannelflag = 0;
|
||||
|
||||
// sekali baca data, 256 bytes
|
||||
@@ -43,10 +42,9 @@ public class BassFileReader implements SoundSource {
|
||||
// indicator if file opened, mixer created, and file plugged to mixer
|
||||
private boolean channeladded = false;
|
||||
|
||||
private final BassFileReaderListener listener; // belum kepake
|
||||
private BassFileReaderListener listener; // belum kepake
|
||||
private final Bass BASS = Bass.Instance;
|
||||
private final BassMix BASSMIX = BassMix.Instance;
|
||||
|
||||
public BassFileReader(final String filename, BassFileReaderListener listener) {
|
||||
this.filename = filename;
|
||||
this.listener = listener;
|
||||
@@ -127,10 +125,12 @@ public class BassFileReader implements SoundSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AddListener(BassFileReaderListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private void logger_error(String msg) {
|
||||
Logger.error(msg);
|
||||
|
||||
}
|
||||
|
||||
private void logger_info(String msg) {
|
||||
|
||||
265
src/Audio/BassSoundManager.java
Normal file
265
src/Audio/BassSoundManager.java
Normal file
@@ -0,0 +1,265 @@
|
||||
package Audio;
|
||||
|
||||
|
||||
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Pointer;
|
||||
import peers.media.AbstractSoundManager;
|
||||
|
||||
/**
|
||||
* Pengganti /AxisAudio/src/net/sourceforge/peers/javaxsound/JavaxSoundManager.java
|
||||
* karena terbatas codec nya
|
||||
* @author rdkartono
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings({"unused", "FieldCanBeLocal", "BusyWait", "ConditionalBreakInInfiniteLoop"})
|
||||
public class BassSoundManager extends AbstractSoundManager {
|
||||
private final Bass BASS = Bass.Instance;
|
||||
private BassSoundManagerListener bsml;
|
||||
private final int record_device, play_device;
|
||||
private final int init_freq = 48000;
|
||||
private final int samplingrate = 8000;
|
||||
private final int play_initflag = Bass.BASS_DEVICE_16BITS | Bass.BASS_DEVICE_MONO;
|
||||
private final int streamcreate_flag = 0;
|
||||
private final int recordstart_flag = 0;
|
||||
private final int read_size = 320;
|
||||
|
||||
private int streamhandle, recordhandle;
|
||||
|
||||
|
||||
public BassSoundManager(int outputdevice , int inputdevice, BassSoundManagerListener listener) {
|
||||
this.bsml = listener;
|
||||
this.record_device = inputdevice;
|
||||
this.play_device = outputdevice;
|
||||
}
|
||||
|
||||
public void AddListener(BassSoundManagerListener listener) {
|
||||
this.bsml = listener;
|
||||
}
|
||||
|
||||
public boolean IsInitialized() {
|
||||
return (streamhandle!=0) && (recordhandle!=0);
|
||||
}
|
||||
|
||||
public void setInputChannelVolume(int value) {
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
|
||||
if (!BASS.BASS_RecordSetInput(record_device, Bass.BASS_INPUT_ON, value/100.0f)) {
|
||||
// gagal
|
||||
logger_error("BASS_RecordSetInput error = "+BASS.GetBassError("BASS_RecordSetInput"));
|
||||
}
|
||||
}
|
||||
|
||||
public int getInputChannelVolume() {
|
||||
Bass.FloatValue vol = new Bass.FloatValue();
|
||||
int code = BASS.BASS_RecordGetInput(record_device, vol);
|
||||
if (code==-1) {
|
||||
logger_error("BASS_RecordGetInput error = "+BASS.GetBassError("BASS_RecordGetInput"));
|
||||
return 0;
|
||||
} else {
|
||||
int value = (int)(vol.value * 100);
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void setOutputChannelVolume(int value) {
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
if (!BASS.BASS_SetVolume(value/100.0f)) {
|
||||
logger_error("BASS_SetVolume error = "+BASS.GetBassError("BASS_SetVolume"));
|
||||
}
|
||||
}
|
||||
|
||||
public int getOutputChannelVolume() {
|
||||
float fl = BASS.BASS_GetVolume() ;
|
||||
if (fl==-1) {
|
||||
logger_error("BASS_GetVolume error = "+BASS.GetBassError("BASS_GetVolume"));
|
||||
return 0;
|
||||
} else {
|
||||
int value = (int)(fl * 100);
|
||||
if (value<0) value = 0;
|
||||
if (value>100) value = 100;
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readData() {
|
||||
if (recordhandle!=0) {
|
||||
int rs;
|
||||
Pointer buf = new Memory(read_size);
|
||||
while(true) {
|
||||
if (BASS.BASS_ChannelIsActive(recordhandle)!=Bass.BASS_ACTIVE_PLAYING) break;
|
||||
rs = BASS.BASS_ChannelGetData(recordhandle, buf, read_size);
|
||||
if (rs<0) {
|
||||
// ada error
|
||||
if (bsml!=null) bsml.log_error("readData BASS_ChannelGetData error = "+BASS.GetBassError("BASS_ChannelGetData"));
|
||||
return null;
|
||||
} else if (rs>0) {
|
||||
// ada hasil
|
||||
byte[] result = buf.getByteArray(0, rs);
|
||||
if (bsml!=null) bsml.ReadToRTP(rs, result);
|
||||
return result;
|
||||
} else {
|
||||
// nol
|
||||
try {
|
||||
Thread.sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (streamhandle!=0 || recordhandle!=0) close();
|
||||
|
||||
if (BASS.BASS_GetVersion()!=0) {
|
||||
BASS.BASS_Init(play_device, init_freq, play_initflag);
|
||||
BASS.BASS_RecordInit(record_device);
|
||||
|
||||
recordhandle = BASS.BASS_RecordStart(samplingrate, 1, recordstart_flag,null, null);
|
||||
if (recordhandle!=0) {
|
||||
BASS.BASS_ChannelSetSync(recordhandle, Bass.BASS_SYNC_DEV_FAIL, 0, devfail, null);
|
||||
BASS.BASS_ChannelSetSync(recordhandle, Bass.BASS_SYNC_STALL, 0, bufferinginformation, null);
|
||||
|
||||
if (BASS.BASS_ChannelStart(recordhandle)) {
|
||||
logger_info("InputChannel Started");
|
||||
} else logger_error("BASS_ChannelStart recordhandle error = "+BASS.GetBassError("BASS_ChannelStart"));
|
||||
} else logger_error("BASS_RecordStart error = "+BASS.GetBassError("BASS_RecordStart"));
|
||||
|
||||
|
||||
streamhandle = BASS.BASS_StreamCreate(samplingrate, 1, streamcreate_flag, Bass.STREAMPROC_PUSH, null);
|
||||
if (streamhandle!=0) {
|
||||
BASS.BASS_ChannelSetSync(streamhandle, Bass.BASS_SYNC_DEV_FAIL, 0, devfail, null);
|
||||
BASS.BASS_ChannelSetSync(streamhandle, Bass.BASS_SYNC_STALL, 0, bufferinginformation, null);
|
||||
|
||||
if (BASS.BASS_ChannelStart(streamhandle)) {
|
||||
logger_info("OutputChannel Started");
|
||||
} else logger_error("BASS_ChannelStart streamhandle error = "+BASS.GetBassError("BASS_ChannelStart"));
|
||||
} else logger_error("BASS_StreamCreate error = "+BASS.GetBassError("BASS_StreamCreate"));
|
||||
|
||||
if (IsInitialized()) {
|
||||
logger_info("init complete");
|
||||
|
||||
new Thread(() -> {
|
||||
int inputvalue;
|
||||
int outputvalue;
|
||||
|
||||
while(IsInitialized()) {
|
||||
inputvalue = BASS.BASS_ChannelGetLevel(recordhandle);
|
||||
outputvalue = BASS.BASS_ChannelGetLevel(streamhandle);
|
||||
if (inputvalue>=0) {
|
||||
inputvalue = (int) ((Bass.Utils.LOWORD(inputvalue) * 1.0f)/32768);
|
||||
if (bsml!=null) bsml.ChannelLevel(true, inputvalue);
|
||||
}
|
||||
if (outputvalue>=0) {
|
||||
outputvalue = (int) ((Bass.Utils.LOWORD(outputvalue) * 1.0f)/32768);
|
||||
if (bsml!=null) bsml.ChannelLevel(false, outputvalue);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
logger_info("ChannelLevel thread interrupted");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
if (bsml!=null) bsml.Opened();
|
||||
return;
|
||||
}
|
||||
|
||||
logger_info("init failed");
|
||||
close();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
boolean somethingclosed = false;
|
||||
if (streamhandle!=0) {
|
||||
BASS.BASS_StreamFree(streamhandle);
|
||||
streamhandle = 0;
|
||||
somethingclosed = true;
|
||||
}
|
||||
if (recordhandle!=0) {
|
||||
BASS.BASS_ChannelStop(recordhandle);
|
||||
recordhandle = 0;
|
||||
somethingclosed = true;
|
||||
}
|
||||
|
||||
if (somethingclosed) {
|
||||
if (bsml!=null) bsml.Closed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int writeData(byte[] buffer, int offset, int length) {
|
||||
if (streamhandle!=0) {
|
||||
Pointer buf = new Memory(length);
|
||||
buf.write(0, buffer, 0, length);
|
||||
int rs = BASS.BASS_StreamPutData(streamhandle, buf, length);
|
||||
if (rs==-1) {
|
||||
if (bsml!=null) bsml.log_error("writeData BASS_StreamPutData error = "+BASS.GetBassError("BASS_StreamPutData"));
|
||||
} else {
|
||||
|
||||
if (bsml!=null) bsml.WriteFromRTP(length, buffer);
|
||||
return length;
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void logger_error(String msg) {
|
||||
if (bsml!=null) bsml.log_error(msg);
|
||||
|
||||
}
|
||||
|
||||
private void logger_info(String msg) {
|
||||
if (bsml!=null) bsml.log_info(msg);
|
||||
|
||||
}
|
||||
|
||||
Bass.SYNCPROC devfail = new Bass.SYNCPROC() {
|
||||
|
||||
@Override
|
||||
public void SYNCPROC(int handle, int channel, int data, Pointer user) {
|
||||
if (channel==streamhandle) {
|
||||
if (bsml!=null) bsml.DeviceFailure("OutputChannel stops unexpectedly");
|
||||
} else if (channel==recordhandle) {
|
||||
if (bsml!=null) bsml.DeviceFailure("InputChannel stops unexpectedly");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Bass.SYNCPROC bufferinginformation = new Bass.SYNCPROC() {
|
||||
|
||||
@Override
|
||||
public void SYNCPROC(int handle, int channel, int data, Pointer user) {
|
||||
if (channel==streamhandle) {
|
||||
if (bsml!=null) bsml.BufferingInformation("OutputChannel "+ (data==0?"Stalled":"Resumed"));
|
||||
} else if (channel==recordhandle) {
|
||||
if (bsml!=null) bsml.BufferingInformation("InputChannel "+ (data==0?"Stalled":"Resumed"));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
18
src/Audio/BassSoundManagerListener.java
Normal file
18
src/Audio/BassSoundManagerListener.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package Audio;
|
||||
|
||||
/**
|
||||
* Java Event untuk BassSoundManager
|
||||
* @author rdkartono
|
||||
*
|
||||
*/
|
||||
public interface BassSoundManagerListener {
|
||||
public void Opened();
|
||||
public void Closed();
|
||||
public void WriteFromRTP(int length, byte[] pcmdata);
|
||||
public void ReadToRTP(int length, byte[] pcmdata);
|
||||
public void log_info(String msg);
|
||||
public void log_error(String msg);
|
||||
public void DeviceFailure(String msg);
|
||||
public void BufferingInformation(String msg);
|
||||
public void ChannelLevel(boolean is_input, int value);
|
||||
}
|
||||
@@ -1,6 +1,32 @@
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
System.out.println("Hello, World!");
|
||||
public class Main {
|
||||
private static String serverAddress="100.64.0.3";
|
||||
private static String Username="user1";
|
||||
private static String Password="12345678";
|
||||
|
||||
public static void main(String[] args) {
|
||||
GetArguments(args);
|
||||
Logger.info("Server Address: "+serverAddress);
|
||||
Logger.info("Username: "+Username);
|
||||
Logger.info("Password: "+Password);
|
||||
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/common.java
Normal file
30
src/common.java
Normal file
@@ -0,0 +1,30 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
998
src/jSIPClient.java
Normal file
998
src/jSIPClient.java
Normal file
@@ -0,0 +1,998 @@
|
||||
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.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import Audio.BassFileReader;
|
||||
import Audio.BassFileReaderListener;
|
||||
import Audio.BassSoundManager;
|
||||
import Audio.BassSoundManagerListener;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.pmw.tinylog.Logger;
|
||||
import peers.Config;
|
||||
import peers.media.MediaManager;
|
||||
import peers.media.MediaMode;
|
||||
import peers.sip.Utils;
|
||||
import peers.sip.core.useragent.SipListener;
|
||||
import peers.sip.core.useragent.UserAgent;
|
||||
import peers.sip.syntaxencoding.SipHeaders;
|
||||
import peers.sip.syntaxencoding.SipURI;
|
||||
import peers.sip.syntaxencoding.SipUriSyntaxException;
|
||||
import peers.sip.transactionuser.Dialog;
|
||||
import peers.sip.transactionuser.DialogManager;
|
||||
import peers.sip.transport.SipRequest;
|
||||
import peers.sip.transport.SipResponse;
|
||||
|
||||
@SuppressWarnings({"unused", "UnusedReturnValue"})
|
||||
public class jSIPClient {
|
||||
|
||||
public jSIPClient() {
|
||||
gs = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
runningfolder = new File("").getAbsolutePath();
|
||||
load_config();
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
raise_log_event("jSIPClient ShutdownHook called");
|
||||
save_config();
|
||||
HangUp();
|
||||
Disconnect();
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
public CustomConfig cc = new CustomConfig();
|
||||
private EventManager em;
|
||||
private final Gson gs;
|
||||
private final String runningfolder;
|
||||
|
||||
|
||||
|
||||
private javaSipEvents jse;
|
||||
private BassFileReaderListener bfrl;
|
||||
|
||||
private final ExecutorService exec = Executors.newSingleThreadExecutor();
|
||||
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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);
|
||||
em = new EventManager(cc);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetJavaSipEvent(javaSipEvents xx) {
|
||||
this.jse = xx;
|
||||
}
|
||||
|
||||
public void SetBassFileReaderListener(BassFileReaderListener xx) {
|
||||
this.bfrl = xx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Input Volume
|
||||
* @param value 0 - 100
|
||||
*/
|
||||
public void setInputVolume(int value) {
|
||||
if (em!=null) em.setInputVolume(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Input Volume
|
||||
* @return 0 - 100
|
||||
*/
|
||||
public int getInputVolume() {
|
||||
if (em!=null) {
|
||||
return em.getInputVolume();
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Output Volume
|
||||
* @param value 0 - 100
|
||||
*/
|
||||
public void setOutputVolume(int value) {
|
||||
if (em!=null) em.setOutputVolume(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Output Volum
|
||||
* @return 0 - 100
|
||||
*/
|
||||
public int getOutputVolume() {
|
||||
if (em!=null) {
|
||||
return em.getOutputVolume();
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from SIP Server
|
||||
*/
|
||||
public void Disconnect() {
|
||||
if (em!=null) {
|
||||
em.Close();
|
||||
em = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HangUp current call
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean HangUp() {
|
||||
if (em!=null) {
|
||||
if (em.IsCreated()) {
|
||||
if (em.CallingInProgress()) {
|
||||
em.HangUp();
|
||||
return true;
|
||||
} else raise_log_event("HangUp failed, no call made");
|
||||
} else raise_log_event("HangUp failed, EventManager not created");
|
||||
} else raise_log_event("HangUp failed, Connect first");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream an audiofile to somebody
|
||||
* @param target target to call
|
||||
* @param filename file to stream
|
||||
* @return true if can be streamed
|
||||
*/
|
||||
public boolean StreamFile(String target, String filename) {
|
||||
if (em!=null) {
|
||||
if (em.IsCreated()) {
|
||||
if (cc!=null) {
|
||||
cc.setMediaFile(filename);
|
||||
cc.setMediaMode(MediaMode.file);
|
||||
em.Call(target);
|
||||
em.AddListener(bfrl);
|
||||
return true;
|
||||
} else raise_log_event("StreamFile failed, Custom Config not created");
|
||||
} else raise_log_event("StreamFile failed, EventManager not created");
|
||||
} else raise_log_event("StreamFile failed, Connect first");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call somebody
|
||||
* @param target target to call
|
||||
* @return true if can be called
|
||||
*/
|
||||
public boolean Call(String target) {
|
||||
if (em!=null) {
|
||||
if (em.IsCreated()) {
|
||||
if (cc!=null) {
|
||||
cc.setMediaMode(MediaMode.captureAndPlayback);
|
||||
em.Call(target);
|
||||
return true;
|
||||
} else raise_log_event("Call failed, Custom Config not created");
|
||||
} else raise_log_event("Call failed, EventManager not created");
|
||||
} else raise_log_event("Call failed, Connect first");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept Incoming Call
|
||||
* @param req SIP_Request object
|
||||
* @return true if call can be accepted
|
||||
*/
|
||||
public boolean AcceptIncomingCall(SIP_Request req) {
|
||||
if (em!=null) {
|
||||
if (em.IsCreated()) {
|
||||
if (req!=null) {
|
||||
cc.setMediaMode(MediaMode.captureAndPlayback);
|
||||
em.AcceptCall(req.getReq());
|
||||
return true;
|
||||
} else raise_log_event("AcceptIncomingCall failed, SIP_Request is null");
|
||||
} else raise_log_event("AcceptIncomingCall failed, EventManager not created");
|
||||
} else raise_log_event("AcceptIncomingCall failed, Connect first");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send DTMF code
|
||||
* @param code code to send
|
||||
* @return true if can be send
|
||||
*/
|
||||
public boolean SendDTMF(final char code) {
|
||||
if (em!=null) {
|
||||
if (em.IsCreated()) {
|
||||
em.DTMF(code);
|
||||
return true;
|
||||
} else raise_log_event("SendDTMF failed, EventManager not created");
|
||||
} else raise_log_event("SendDTMF failed, Connect first");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject Incoming Call
|
||||
* @param req SIP_Request to reject
|
||||
* @return true if can be rejected
|
||||
*/
|
||||
public boolean RejectIncomingCall(SIP_Request req) {
|
||||
if (em!=null) {
|
||||
if (em.IsCreated()) {
|
||||
if (req!=null) {
|
||||
em.RejectCall(req.getReq());
|
||||
return true;
|
||||
} else raise_log_event("RejectIncomingCall failed, SIP_Request is null");
|
||||
} else raise_log_event("RejectIncomingCall failed, EventManager not created");
|
||||
} else raise_log_event("RejectIncomingCall failed, Connect first");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////// Class Implementation ////////////////////
|
||||
|
||||
public class EventManager implements SipListener{
|
||||
private UserAgent user_agent;
|
||||
private SipRequest sip_request;
|
||||
private boolean all_success;
|
||||
//JavaxSoundManager jsm;
|
||||
BassSoundManager jsm;
|
||||
|
||||
public EventManager(final CustomConfig xx) {
|
||||
all_success = false;
|
||||
//Logger lg = new FileLogger(null);
|
||||
Logger lg = null;
|
||||
// jsm = new JavaxSoundManager(false, lg, null);
|
||||
jsm = new BassSoundManager(1,0, new BassSoundManagerListener() {
|
||||
|
||||
@Override
|
||||
public void Opened() {
|
||||
raise_log_event("BassSoundManager Opened");
|
||||
raise_soundchannelopened_event();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Closed() {
|
||||
raise_log_event("BassSoundManager Closed");
|
||||
raise_soundchannelclosed_event();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log_info(String msg) {
|
||||
raise_log_event("BassSoundManager info : "+msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log_error(String msg) {
|
||||
raise_log_event("BassSoundManager error : "+msg);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void WriteFromRTP(int length, byte[] pcmdata) {
|
||||
// buat debugging aja, kalau dikeluarin, spamming log
|
||||
//raise_log_event("BassSoundmanager WriteFromRTP "+length+" bytes");
|
||||
raise_outputchannelpcmdata_event(length, pcmdata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ReadToRTP(int length, byte[] pcmdata) {
|
||||
// buat debugging aja, kalau dikeluarin, spamming log
|
||||
//raise_log_event("BassSoundManager ReadToRTP "+length+" bytes");
|
||||
raise_inputchannelpcmdata_event(length, pcmdata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DeviceFailure(String msg) {
|
||||
raise_log_event("BassSondManager DeviceFailure : "+msg);
|
||||
if (msg.contains("OutputChannel"))
|
||||
raise_outputchanneldevicefailure_event();
|
||||
else if (msg.contains("InputChannel"))
|
||||
raise_inputchanneldevicefailure_event();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BufferingInformation(String msg) {
|
||||
raise_log_event("BassSoundManager BufferingInformation : "+msg);
|
||||
if (msg.contains("OutputChannel"))
|
||||
raise_outputchannelbuffering_event(msg);
|
||||
else if (msg.contains("InputChannel"))
|
||||
raise_inputchannelbuffering_event(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ChannelLevel(boolean is_input, int value) {
|
||||
if (is_input)
|
||||
raise_inputchannellevel_event(value);
|
||||
else
|
||||
raise_outputchannellevel_event(value);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
user_agent = new UserAgent(this, xx, jsm);
|
||||
exec.submit(() -> {
|
||||
try {
|
||||
user_agent.register();
|
||||
all_success = true;
|
||||
} catch (SipUriSyntaxException e) {
|
||||
raise_log_event("EventManager register exception = "+e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
} catch (SocketException e) {
|
||||
raise_log_event("EventManager create exception = "+e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setInputVolume(int value) {
|
||||
if (jsm!=null) jsm.setInputChannelVolume(value);
|
||||
}
|
||||
|
||||
public int getInputVolume() {
|
||||
if (jsm!=null) {
|
||||
return jsm.getInputChannelVolume();
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
public void setOutputVolume(int value) {
|
||||
if (jsm!=null) jsm.setOutputChannelVolume(value);
|
||||
}
|
||||
|
||||
public int getOutputVolume() {
|
||||
if (jsm!=null) {
|
||||
return jsm.getOutputChannelVolume();
|
||||
} else return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if EventManager succesfully created
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean IsCreated() {
|
||||
return all_success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
* @param targetsip Target SIP
|
||||
*/
|
||||
public void Call(final String targetsip) {
|
||||
if (user_agent!=null) {
|
||||
exec.submit(() -> {
|
||||
sip_request = null;
|
||||
try {
|
||||
sip_request = user_agent.invite(targetsip, null);
|
||||
} catch (SipUriSyntaxException e) {
|
||||
raise_log_event("Call exception = "+e.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept Incoming Call
|
||||
* @param req SipRequest to accept
|
||||
*/
|
||||
public void AcceptCall(final SipRequest req) {
|
||||
if (user_agent!=null) {
|
||||
if (req!=null) {
|
||||
exec.submit(() -> {
|
||||
// source : https://github.com/ymartineau/peers/blob/master/peers-gui/src/main/java/net/sourceforge/peers/gui/EventManager.java
|
||||
String callId = Utils.getMessageCallId(req);
|
||||
DialogManager dialogManager = user_agent.getDialogManager();
|
||||
Dialog dialog = dialogManager.getDialog(callId);
|
||||
user_agent.acceptCall(req, dialog);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Listener for File Streaming
|
||||
* @param event BassFileReaderListener
|
||||
* @return true if can be added
|
||||
*/
|
||||
public boolean AddListener(BassFileReaderListener event) {
|
||||
if (user_agent!=null) {
|
||||
MediaManager mm = user_agent.getMediaManager();
|
||||
if (mm!=null) {
|
||||
BassFileReader bfr = mm.getFileReader();
|
||||
if (bfr!=null) {
|
||||
bfr.AddListener(event);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void DTMF(final char code) {
|
||||
if (user_agent!=null) {
|
||||
exec.submit(() -> {
|
||||
MediaManager mm = user_agent.getMediaManager();
|
||||
mm.sendDtmf(code);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject Incoming Call
|
||||
* @param req SipRequest to reject
|
||||
*/
|
||||
public void RejectCall(final SipRequest req) {
|
||||
if (user_agent!=null) {
|
||||
if (req!=null) {
|
||||
exec.submit(() -> user_agent.rejectCall(req));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Calling in Progress
|
||||
* @return true if in progress
|
||||
*/
|
||||
public boolean CallingInProgress() {
|
||||
return sip_request!=null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hang-Up current call
|
||||
*/
|
||||
public void HangUp() {
|
||||
if (sip_request!=null) {
|
||||
if (user_agent!=null) {
|
||||
exec.submit(() -> {
|
||||
user_agent.terminate(sip_request);
|
||||
sip_request = null;
|
||||
});
|
||||
|
||||
} else raise_log_event("HangUp failed, user_agent not available");
|
||||
} else raise_log_event("HangUp failed, sip_request not available");
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Connection to SIP Server
|
||||
*/
|
||||
public void Close() {
|
||||
if (user_agent!=null) {
|
||||
user_agent.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registering(SipRequest sipRequest) {
|
||||
SIP_Request req = new SIP_Request(sipRequest);
|
||||
raise_registering_event(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSuccessful(SipResponse sipResponse) {
|
||||
SIP_Response resp = new SIP_Response(sipResponse);
|
||||
raise_registersuccesfull_event(resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFailed(SipResponse sipResponse) {
|
||||
SIP_Response resp = new SIP_Response(sipResponse);
|
||||
raise_registerfailed_event(resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incomingCall(SipRequest sipRequest, SipResponse provResponse) {
|
||||
SIP_Request req = new SIP_Request(sipRequest);
|
||||
SIP_Response resp = new SIP_Response(provResponse);
|
||||
raise_incomingcall_event(req, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remoteHangup(SipRequest sipRequest) {
|
||||
SIP_Request req = new SIP_Request(sipRequest);
|
||||
raise_remotehangup_event(req);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ringing(SipResponse sipResponse) {
|
||||
SIP_Response resp = new SIP_Response(sipResponse);
|
||||
raise_ringing_event(resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calleePickup(SipResponse sipResponse) {
|
||||
SIP_Response resp = new SIP_Response(sipResponse);
|
||||
raise_calleepickup_event(resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(SipResponse sipResponse) {
|
||||
raise_log_event("sip error, response="+gs.toJson(sipResponse));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SIP_Request{
|
||||
private @Getter final SipRequest req;
|
||||
public String To;
|
||||
public String From;
|
||||
public String CallID;
|
||||
public String Contact;
|
||||
|
||||
|
||||
public SIP_Request(SipRequest source) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MessageFormat.format("To:{0}\n"
|
||||
+ "From:{1}\n"
|
||||
+ "Call-ID:{2}\n"
|
||||
+ "Contact:{3}", To, From, CallID, Contact);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SIP_Response{
|
||||
public SIP_Response(SipResponse source) {
|
||||
resp = source;
|
||||
if (resp!=null) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
private @Getter final SipResponse resp;
|
||||
|
||||
public int statusCode;
|
||||
public String reasonPhrase;
|
||||
public String From;
|
||||
public String To;
|
||||
public String CallID;
|
||||
public String Server;
|
||||
public String Contact;
|
||||
public String Date;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MessageFormat.format("To:{0}\n"
|
||||
+ "From:{1}\n"
|
||||
+ "Call-ID:{2}\n"
|
||||
+ "Contact:{3}\n"
|
||||
+ "Server:{4}\n"
|
||||
+ "Date:{5}\n"
|
||||
+ "StatusCode:{6}\n"
|
||||
+ "ReasonPhrase:{7}", To, From, CallID, Contact, Server, Date, statusCode, reasonPhrase);
|
||||
}
|
||||
}
|
||||
|
||||
public class CustomConfig implements Config{
|
||||
private InetAddress localIpAddress;
|
||||
private InetAddress publicIpAddress;
|
||||
private String registrar;
|
||||
private String username;
|
||||
private String password;
|
||||
private int sip_port;
|
||||
private int rtp_port;
|
||||
private transient MediaMode mm; // tidak disave dan load
|
||||
private SipURI outbondproxy;
|
||||
private transient boolean mediadebug; // tidak disave dan load
|
||||
private transient String mediafile; // tidak disave dan load
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create CustomConfig
|
||||
* @param registrar Server IP
|
||||
* @param username username
|
||||
* @param password password
|
||||
*/
|
||||
public CustomConfig(String registrar, String username, String password) {
|
||||
this.registrar = registrar;
|
||||
this.password = password;
|
||||
this.username = username;
|
||||
setLocalInetAddress(null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create CustomConfig
|
||||
* @param registrar Server IP
|
||||
* @param username username
|
||||
* @param password password
|
||||
* @param localip local ethernet to use to register. if not valid, will use default LocalHost
|
||||
*/
|
||||
public CustomConfig(String registrar, String username, String password, String localip) {
|
||||
this.registrar = registrar;
|
||||
this.password = password;
|
||||
this.username = username;
|
||||
SetLocalInetAddress(localip);
|
||||
|
||||
}
|
||||
|
||||
public CustomConfig() {
|
||||
this.registrar = "192.168.5.1";
|
||||
this.username = "1002";
|
||||
this.password = "1234";
|
||||
setLocalInetAddress(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Local IP Address
|
||||
*/
|
||||
@Override
|
||||
public InetAddress getLocalInetAddress() {
|
||||
return localIpAddress;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get public IP Address used
|
||||
*/
|
||||
@Override
|
||||
public InetAddress getPublicInetAddress() {
|
||||
return publicIpAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Username to use for registering with SIP Server
|
||||
*/
|
||||
@Override
|
||||
public String getUserPart() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SIP Server (registrar)
|
||||
*/
|
||||
@Override
|
||||
public String getDomain() {
|
||||
return registrar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Password
|
||||
*/
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Outbond Proxy used
|
||||
*/
|
||||
@Override
|
||||
public SipURI getOutboundProxy() {
|
||||
return outbondproxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SIP Port . default is 5060
|
||||
*/
|
||||
@Override
|
||||
public int getSipPort() {
|
||||
return sip_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current MediaMode
|
||||
*/
|
||||
@Override
|
||||
public MediaMode getMediaMode() {
|
||||
return mm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public boolean isMediaDebug() {
|
||||
return mediadebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MediaFile used
|
||||
*/
|
||||
@Override
|
||||
public String getMediaFile() {
|
||||
return mediafile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get RTP Port used
|
||||
*/
|
||||
@Override
|
||||
public int getRtpPort() {
|
||||
return rtp_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Local Network Interface to use with jSIPClient
|
||||
* useful when having multiple network interfaces in the machine
|
||||
*/
|
||||
@Override
|
||||
public void setLocalInetAddress(InetAddress inetAddress) {
|
||||
try {
|
||||
this.localIpAddress = inetAddress == null ? InetAddress.getLocalHost() : inetAddress;
|
||||
} catch (UnknownHostException e) {
|
||||
raise_log_event("setLocalInetAddress exception = "+e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Local Network Interface to use with jSIPClient
|
||||
* useful when having multiple network interfaces in the machine
|
||||
* @param ipaddress IP Address of the network interface to use in the machine
|
||||
*/
|
||||
public void SetLocalInetAddress(String ipaddress) {
|
||||
try {
|
||||
InetAddress xx = InetAddress.getByName(ipaddress);
|
||||
setLocalInetAddress(xx);
|
||||
} catch (UnknownHostException e) {
|
||||
raise_log_event("SetLocalInetAddress exception = "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Public InetAddress to use with JSIPClient
|
||||
* personal note : dont know if really necessary
|
||||
*/
|
||||
@Override
|
||||
public void setPublicInetAddress(InetAddress inetAddress) {
|
||||
publicIpAddress = inetAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Public IP Address to use with jSIPClient
|
||||
* Personal Note : dont know if really necessary
|
||||
* @param ipaddress IP Address in string
|
||||
*/
|
||||
public void SetPublicInetAddress(String ipaddress) {
|
||||
try {
|
||||
InetAddress xx = InetAddress.getByName(ipaddress);
|
||||
setPublicInetAddress(xx);
|
||||
} catch (UnknownHostException e) {
|
||||
raise_log_event("SetPublicInetAddress exception = "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Username to use for registering to SIP Server
|
||||
*/
|
||||
@Override
|
||||
public void setUserPart(String username) {
|
||||
this.username = username;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SIP Server (registrar) IP Address / Domain
|
||||
*/
|
||||
@Override
|
||||
public void setDomain(String domain) {
|
||||
registrar = domain;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Password to use for registering to SIP Server
|
||||
*/
|
||||
@Override
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void setOutboundProxy(SipURI outboundProxy) {
|
||||
outbondproxy = outboundProxy;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void setSipPort(int sipPort) {
|
||||
this.sip_port = common.ValidPortNumber(sipPort) ? sipPort : 5060;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void setMediaMode(MediaMode mediaMode) {
|
||||
mm = mediaMode;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void setMediaDebug(boolean mediaDebug) {
|
||||
mediadebug = mediaDebug;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void setMediaFile(String mediaFile) {
|
||||
mediafile = mediaFile;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void setRtpPort(int rtpPort) {
|
||||
rtp_port = common.ValidPortNumber(rtpPort) ? rtpPort : 49152 ;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Not used
|
||||
*/
|
||||
@Override
|
||||
public void save() {}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//////////// private functions ///////////////
|
||||
|
||||
|
||||
|
||||
private void raise_log_event(String msg) {
|
||||
Logger.info(msg);
|
||||
}
|
||||
|
||||
private void raise_registering_event(SIP_Request req) {
|
||||
if (jse!=null) jse.Registering(req);
|
||||
}
|
||||
|
||||
private void raise_registersuccesfull_event(SIP_Response resp) {
|
||||
if (jse!=null) jse.RegisterSuccesful(resp);
|
||||
}
|
||||
|
||||
private void raise_registerfailed_event(SIP_Response resp) {
|
||||
if (jse!=null) jse.RegisterFailed(resp);
|
||||
}
|
||||
|
||||
private void raise_incomingcall_event(SIP_Request req, SIP_Response resp) {
|
||||
if (jse!=null) jse.IncomingCall(req, resp);
|
||||
}
|
||||
|
||||
private void raise_remotehangup_event(SIP_Request req) {
|
||||
if (jse!=null) jse.RemoteHangUp(req);
|
||||
}
|
||||
|
||||
private void raise_ringing_event(SIP_Response resp) {
|
||||
if (jse!=null) jse.Ringing(resp);
|
||||
}
|
||||
|
||||
private void raise_calleepickup_event(SIP_Response resp) {
|
||||
if (jse!=null) jse.CalleePickup(resp);
|
||||
}
|
||||
|
||||
private void raise_inputchanneldevicefailure_event(){
|
||||
|
||||
//if (need_inputchanneldevicefailure_event) ba.raiseEventFromDifferentThread(Me, null, 0,event+"_inputchanneldevicefailure", false,null );
|
||||
}
|
||||
|
||||
private void raise_inputchannelbuffering_event(String msg) {
|
||||
//if (need_inputchannelbuffering_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_inputchannelbuffering", false, new Object[] {msg});
|
||||
}
|
||||
|
||||
private void raise_inputchannelpcmdata_event(int length, byte[] bb) {
|
||||
//if (need_inputchannelpcmdata_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_inputchannelpcmdata", false, new Object[] {length, bb});
|
||||
}
|
||||
|
||||
private void raise_outputchanneldevicefailure_event(){
|
||||
//if (need_outputchanneldevicefailure_event) ba.raiseEventFromDifferentThread(Me, null, 0,event+"_outputchanneldevicefailure", false,null );
|
||||
}
|
||||
|
||||
private void raise_outputchannelbuffering_event(String msg) {
|
||||
//if (need_outputchannelbuffering_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_outputchannelbuffering", false, new Object[] {msg});
|
||||
}
|
||||
|
||||
private void raise_outputchannelpcmdata_event(int length, byte[] bb) {
|
||||
//if (need_outputchannelpcmdata_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_outputchannelpcmdata", false, new Object[] {length, bb});
|
||||
}
|
||||
|
||||
private void raise_soundchannelclosed_event() {
|
||||
//if (need_soundchannelclosed_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_soundchannelclosed", false, null);
|
||||
}
|
||||
|
||||
private void raise_soundchannelopened_event() {
|
||||
//if (need_soundchannelopened_event) ba.raiseEventFromDifferentThread(Me, null, 0,event+"_soundchannelopened", false, null);
|
||||
}
|
||||
|
||||
private void raise_inputchannellevel_event(int value) {
|
||||
//if (need_inputchannellevel_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_inputchannellevel", false, new Object[] {value});
|
||||
}
|
||||
|
||||
private void raise_outputchannellevel_event(int value) {
|
||||
//if (need_outputchannellevel_event) ba.raiseEventFromDifferentThread(Me, null, 0, event+"_outputchannellevel", false, new Object[] {value});
|
||||
}
|
||||
|
||||
/**
|
||||
* Dipanggil saat ShutdownHook
|
||||
*/
|
||||
private void save_config() {
|
||||
if (cc!=null) {
|
||||
try {
|
||||
gs.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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
10
src/javaSipEvents.java
Normal file
10
src/javaSipEvents.java
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
public interface javaSipEvents {
|
||||
void Registering(jSIPClient.SIP_Request req);
|
||||
void RegisterSuccesful(jSIPClient.SIP_Response resp);
|
||||
void RegisterFailed(jSIPClient.SIP_Response resp);
|
||||
void IncomingCall(jSIPClient.SIP_Request req, jSIPClient.SIP_Response resp);
|
||||
void RemoteHangUp(jSIPClient.SIP_Request req);
|
||||
void Ringing(jSIPClient.SIP_Response resp);
|
||||
void CalleePickup(jSIPClient.SIP_Response resp);
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import java.net.SocketException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.pmw.tinylog.Logger;
|
||||
import peers.Config;
|
||||
|
||||
@@ -51,35 +53,47 @@ import peers.sip.transport.SipResponse;
|
||||
import peers.sip.transport.TransportManager;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@SuppressWarnings({"unused", "FieldMayBeFinal", "FieldCanBeLocal", "UnusedReturnValue"})
|
||||
public class UserAgent {
|
||||
|
||||
public final static String CONFIG_FILE = "conf" + File.separator + "peers.xml";
|
||||
public final static int RTP_DEFAULT_PORT = 8000;
|
||||
|
||||
@Getter
|
||||
private String peersHome;
|
||||
@Getter
|
||||
private Config config;
|
||||
|
||||
@Getter
|
||||
private List<String> peers;
|
||||
//private List<Dialog> dialogs;
|
||||
|
||||
//TODO factorize echo and captureRtpSender
|
||||
@Setter
|
||||
@Getter
|
||||
private Echo echo;
|
||||
|
||||
@Getter
|
||||
private UAC uac;
|
||||
@Getter
|
||||
private UAS uas;
|
||||
|
||||
private ChallengeManager challengeManager;
|
||||
|
||||
@Getter
|
||||
private DialogManager dialogManager;
|
||||
private TransactionManager transactionManager;
|
||||
@Getter
|
||||
private TransportManager transportManager;
|
||||
|
||||
private int cseqCounter;
|
||||
@Getter
|
||||
private SipListener sipListener;
|
||||
|
||||
private SDPManager sdpManager;
|
||||
@Getter
|
||||
private AbstractSoundManager soundManager;
|
||||
@Getter
|
||||
private MediaManager mediaManager;
|
||||
|
||||
public UserAgent(SipListener sipListener, String peersHome,
|
||||
@@ -94,8 +108,8 @@ public class UserAgent {
|
||||
this(sipListener, config, null, soundManager);
|
||||
}
|
||||
|
||||
private UserAgent(SipListener sipListener, Config config, String peersHome,
|
||||
AbstractSoundManager soundManager)
|
||||
public UserAgent(SipListener sipListener, Config config, String peersHome,
|
||||
AbstractSoundManager soundManager)
|
||||
throws SocketException {
|
||||
this.sipListener = sipListener;
|
||||
if (peersHome == null) {
|
||||
@@ -111,17 +125,16 @@ public class UserAgent {
|
||||
|
||||
cseqCounter = 1;
|
||||
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("starting user agent [");
|
||||
buf.append("myAddress: ");
|
||||
buf.append(config.getLocalInetAddress().getHostAddress()).append(", ");
|
||||
buf.append("sipPort: ");
|
||||
buf.append(config.getSipPort()).append(", ");
|
||||
buf.append("userpart: ");
|
||||
buf.append(config.getUserPart()).append(", ");
|
||||
buf.append("domain: ");
|
||||
buf.append(config.getDomain()).append("]");
|
||||
Logger.info(buf.toString());
|
||||
String buf = "starting user agent [" +
|
||||
"myAddress: " +
|
||||
config.getLocalInetAddress().getHostAddress() + ", " +
|
||||
"sipPort: " +
|
||||
config.getSipPort() + ", " +
|
||||
"userpart: " +
|
||||
config.getUserPart() + ", " +
|
||||
"domain: " +
|
||||
config.getDomain() + "]";
|
||||
Logger.info(buf);
|
||||
|
||||
//transaction user
|
||||
|
||||
@@ -204,7 +217,7 @@ public class UserAgent {
|
||||
inviteHandler.setChallengeManager(challengeManager);
|
||||
byeHandler.setChallengeManager(challengeManager);
|
||||
|
||||
peers = new ArrayList<String>();
|
||||
peers = new ArrayList<>();
|
||||
//dialogs = new ArrayList<Dialog>();
|
||||
|
||||
sdpManager = new SDPManager(this);
|
||||
@@ -252,7 +265,7 @@ public class UserAgent {
|
||||
* Gives the sipMessage if sipMessage is a SipRequest or
|
||||
* the SipRequest corresponding to the SipResponse
|
||||
* if sipMessage is a SipResponse
|
||||
* @param sipMessage
|
||||
* @param sipMessage SipMessage
|
||||
* @return null if sipMessage is neither a SipRequest neither a SipResponse
|
||||
*/
|
||||
public SipRequest getSipRequest(SipMessage sipMessage) {
|
||||
@@ -275,32 +288,10 @@ public class UserAgent {
|
||||
}
|
||||
}
|
||||
|
||||
// public List<Dialog> getDialogs() {
|
||||
// return dialogs;
|
||||
// }
|
||||
|
||||
public List<String> getPeers() {
|
||||
return peers;
|
||||
}
|
||||
|
||||
// public Dialog getDialog(String peer) {
|
||||
// for (Dialog dialog : dialogs) {
|
||||
// String remoteUri = dialog.getRemoteUri();
|
||||
// if (remoteUri != null) {
|
||||
// if (remoteUri.contains(peer)) {
|
||||
// return dialog;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public String generateCSeq(String method) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(cseqCounter++);
|
||||
buf.append(' ');
|
||||
buf.append(method);
|
||||
return buf.toString();
|
||||
return String.valueOf(cseqCounter++) +
|
||||
' ' +
|
||||
method;
|
||||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
@@ -308,18 +299,6 @@ public class UserAgent {
|
||||
.isRegistered();
|
||||
}
|
||||
|
||||
public UAS getUas() {
|
||||
return uas;
|
||||
}
|
||||
|
||||
public UAC getUac() {
|
||||
return uac;
|
||||
}
|
||||
|
||||
public DialogManager getDialogManager() {
|
||||
return dialogManager;
|
||||
}
|
||||
|
||||
public int getSipPort() {
|
||||
return transportManager.getSipPort();
|
||||
}
|
||||
@@ -348,35 +327,4 @@ public class UserAgent {
|
||||
return config.getOutboundProxy();
|
||||
}
|
||||
|
||||
public Echo getEcho() {
|
||||
return echo;
|
||||
}
|
||||
|
||||
public void setEcho(Echo echo) {
|
||||
this.echo = echo;
|
||||
}
|
||||
|
||||
public SipListener getSipListener() {
|
||||
return sipListener;
|
||||
}
|
||||
|
||||
public AbstractSoundManager getSoundManager() {
|
||||
return soundManager;
|
||||
}
|
||||
|
||||
public MediaManager getMediaManager() {
|
||||
return mediaManager;
|
||||
}
|
||||
|
||||
public Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public String getPeersHome() {
|
||||
return peersHome;
|
||||
}
|
||||
|
||||
public TransportManager getTransportManager() {
|
||||
return transportManager;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user