From cbb42b3041930eb7867925bf742998230531011d Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 30 Jul 2019 13:37:54 +0200 Subject: [PATCH] . --- src/controller/commands/CommandAnnehmen.java | 19 ++ src/controller/commands/CommandBeenden.java | 39 ++- src/gui/Hauptfenster.form | 2 +- src/gui/Hauptfenster.java | 17 +- src/model/Audioaufnahme.java | 132 ++++++++++ src/model/Audioausgabe.java | 95 +++++++ src/model/SIPRinging.java | 107 ++++++++ src/model/SIPmodel.java | 245 ++++++++++++------- 8 files changed, 545 insertions(+), 111 deletions(-) create mode 100644 src/model/Audioaufnahme.java create mode 100644 src/model/Audioausgabe.java create mode 100644 src/model/SIPRinging.java diff --git a/src/controller/commands/CommandAnnehmen.java b/src/controller/commands/CommandAnnehmen.java index c52ac00..0fcf013 100644 --- a/src/controller/commands/CommandAnnehmen.java +++ b/src/controller/commands/CommandAnnehmen.java @@ -24,6 +24,12 @@ public class CommandAnnehmen implements CommandInterface private static final Logger lginvite = OhmLogger.getLogger(); private SIPmodel model; private Hauptfenster view; + + //private InputStream istream; + + //Socket s; + + public CommandAnnehmen(SIPmodel model, Hauptfenster view) { this.model = model; @@ -35,6 +41,19 @@ public class CommandAnnehmen implements CommandInterface { { model.annehmen(); + try + { + //s = new Socket(model.getMyIPAdress(),model.getMyPort()); + view.getTxtArea().append("Socket geöffnet"); + + //istream = s.getInputStream(); + //System.out.println(istream); + } + catch(Exception ex) + { + + } + } } @Override diff --git a/src/controller/commands/CommandBeenden.java b/src/controller/commands/CommandBeenden.java index b1aeb64..815a2ce 100644 --- a/src/controller/commands/CommandBeenden.java +++ b/src/controller/commands/CommandBeenden.java @@ -3,7 +3,6 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ - package controller.commands; import controller.CommandInterface; @@ -14,41 +13,41 @@ import model.SIPmodel; /** * - * @author Jan - * Muss noch komplett implementiert werden - * -> Bye bei laufendem Gespräch - * -> Cancel bei laufender Anfrage, sollte beides recht schnell gehen wenn ihr Lust habt. + * @author Jan Muss noch komplett implementiert werden -> Bye bei laufendem + * Gespräch -> Cancel bei laufender Anfrage, sollte beides recht schnell gehen + * wenn ihr Lust habt. * */ public class CommandBeenden implements CommandInterface -{ - private static final Logger lginvite = OhmLogger.getLogger(); +{ + private static final Logger lginvite = OhmLogger.getLogger(); private SIPmodel model; private Hauptfenster view; + public CommandBeenden(SIPmodel model, Hauptfenster view) { this.model = model; - this.view = view; + this.view = view; } - + @Override - public void execute() - {/* + public void execute() + { + + view.getTxtArea().append("Anruf beenden\n"); try - { - view.getTxtArea().append("Anruf beenden\n"); - model.cancelcall(); - } - catch (ParseException|InvalidArgumentException|SdpException|SipException ex) { - view.getTxtArea().append("Einladung fehlgeschlagen\n"); - lginvite.getLogger(CommandBeenden.class.getName()).log(Level.SEVERE, null, ex); - }*/ + model.byecall(view.getTxtcallUser().getText()); + } + catch (Exception e) + { + } } + @Override public void undo() { - + } @Override diff --git a/src/gui/Hauptfenster.form b/src/gui/Hauptfenster.form index 578b956..bd41860 100644 --- a/src/gui/Hauptfenster.form +++ b/src/gui/Hauptfenster.form @@ -127,7 +127,7 @@ - + diff --git a/src/gui/Hauptfenster.java b/src/gui/Hauptfenster.java index e4eeb08..250d146 100644 --- a/src/gui/Hauptfenster.java +++ b/src/gui/Hauptfenster.java @@ -11,6 +11,13 @@ package gui; */ public class Hauptfenster extends javax.swing.JFrame { + /** + * @return the txtcallUser + */ + public javax.swing.JTextField getTxtcallUser() + { + return txtcallUser; + } /** * @return the btnannehmen */ @@ -100,7 +107,7 @@ public class Hauptfenster extends javax.swing.JFrame jPanel2 = new javax.swing.JPanel(); lblmyIP = new javax.swing.JLabel(); txtServerIP = new javax.swing.JTextField(); - txtcallIP = new javax.swing.JTextField(); + txtcallUser = new javax.swing.JTextField(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); @@ -150,8 +157,8 @@ public class Hauptfenster extends javax.swing.JFrame txtServerIP.setText("xxx.xxx.xxx.xxx"); jPanel2.add(txtServerIP); - txtcallIP.setText("name"); - jPanel2.add(txtcallIP); + txtcallUser.setText("name"); + jPanel2.add(txtcallUser); jPanel3.add(jPanel2); @@ -226,7 +233,7 @@ public class Hauptfenster extends javax.swing.JFrame private javax.swing.JLabel lblmyIP; private javax.swing.JTextArea txtArea; private javax.swing.JTextField txtServerIP; - private javax.swing.JTextField txtcallIP; + private javax.swing.JTextField txtcallUser; // End of variables declaration//GEN-END:variables /** @@ -258,6 +265,6 @@ public class Hauptfenster extends javax.swing.JFrame */ public javax.swing.JTextField getTxtcallIP() { - return txtcallIP; + return txtcallUser; } } diff --git a/src/model/Audioaufnahme.java b/src/model/Audioaufnahme.java new file mode 100644 index 0000000..4f4da2c --- /dev/null +++ b/src/model/Audioaufnahme.java @@ -0,0 +1,132 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package model; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.ExecutorService; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * + * @author Jan + */ +public class Audioaufnahme implements Runnable +{ + AudioFormat format; + TargetDataLine mic; + AudioInputStream audioInput; + //AudioOutputStream audioOutput; + SourceDataLine sourceData; + private ExecutorService audioausgabe; + ByteArrayOutputStream out; + + public Audioaufnahme() + { + float sampleRate = 48000; + int sampleSizeInBits = 16; + int channels = 1; + boolean signed = true; + boolean bigEndian = true; + try + { + format = new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian); + mic = AudioSystem.getTargetDataLine(format); + DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); + mic = (TargetDataLine) AudioSystem.getLine(info); + } + catch (Exception e) + { + System.out.println("Fehler bei dem Audioformat des Mikrophones"); + Logger.getLogger(Audioaufnahme.class.getName()).log(Level.SEVERE, null, e); + } + } + + public void startaufnahme() + { + out = new ByteArrayOutputStream(); + try + { + mic.open(format); + int numBytesRead; + int CHUNCK_SIZE = 1024; + byte[] data = new byte[mic.getBufferSize() / 5]; + mic.start(); + int bytesRead = 0; + + try + { + while (bytesRead < 1000000) + { + numBytesRead = mic.read(data, 0, CHUNCK_SIZE); + bytesRead = bytesRead + numBytesRead; + out.write(data, 0, numBytesRead); + } + + } + catch (Exception e) + { + e.printStackTrace(); + } + mic.close(); + } + catch (LineUnavailableException ex) + { + Logger.getLogger(Audioaufnahme.class.getName()).log(Level.SEVERE, null, ex); + } + } + public void playAudio() + { + try + { + byte audioData[] = out.toByteArray(); + InputStream byteArrayInputStream = new ByteArrayInputStream( + audioData); + audioInput = new AudioInputStream(byteArrayInputStream, format, audioData.length / format.getFrameSize()); + DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format); + sourceData = (SourceDataLine) AudioSystem.getLine(dataLineInfo); + sourceData.open(format); + sourceData.start(); + int cnt = 0; + byte tempBuffer[] = new byte[1000000]; + try + { + while ((cnt = audioInput.read(tempBuffer, 0, tempBuffer.length)) != -1) + { + if (cnt > 0) + { + sourceData.write(tempBuffer, 0, cnt); + } + } + } + catch (IOException e) + { + e.printStackTrace(); + } + sourceData.drain(); + sourceData.close(); + } + catch (Exception e) + { + + } + } + + @Override + public void run() + { + } +} diff --git a/src/model/Audioausgabe.java b/src/model/Audioausgabe.java new file mode 100644 index 0000000..492f952 --- /dev/null +++ b/src/model/Audioausgabe.java @@ -0,0 +1,95 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package model; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.DataLine; +import javax.sound.sampled.SourceDataLine; +import javax.sound.sampled.TargetDataLine; + +/** + * + * @author Jan + */ +public class Audioausgabe implements Runnable +{ + AudioFormat format; + AudioInputStream audioInput; + SourceDataLine sourceData; + private ExecutorService audioausgabe; + ByteArrayOutputStream output; + + public Audioausgabe() + { + audioausgabe = Executors.newSingleThreadExecutor(); + float sampleRate = 48000; + int sampleSizeInBits = 16; + int channels = 1; + boolean signed = true; + boolean bigEndian = true; + try + { + format = new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian); + DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); + } + catch (Exception e) + { + System.out.println("Fehler bei dem Audioformat des Mikrophones"); + Logger.getLogger(Audioausgabe.class.getName()).log(Level.SEVERE, null, e); + } + } + public void playAudio() + { + try + { + byte audioData[] = output.toByteArray(); + InputStream byteArrayInputStream = new ByteArrayInputStream( + audioData); + audioInput = new AudioInputStream(byteArrayInputStream, format, audioData.length / format.getFrameSize()); + DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format); + sourceData = (SourceDataLine) AudioSystem.getLine(dataLineInfo); + sourceData.open(format); + sourceData.start(); + int cnt = 0; + byte tempBuffer[] = new byte[1000000]; + try + { + while ((cnt = audioInput.read(tempBuffer, 0, tempBuffer.length)) != -1) + { + if (cnt > 0) + { + sourceData.write(tempBuffer, 0, cnt); + } + } + } + catch (IOException e) + { + e.printStackTrace(); + } + sourceData.drain(); + sourceData.close(); + } + catch (Exception e) + { + + } + } + + @Override + public void run() + { + } +} diff --git a/src/model/SIPRinging.java b/src/model/SIPRinging.java new file mode 100644 index 0000000..6668d9c --- /dev/null +++ b/src/model/SIPRinging.java @@ -0,0 +1,107 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package model; + +import static java.lang.Thread.sleep; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.sip.RequestEvent; +import javax.sip.SipException; +import javax.sip.header.AllowEventsHeader; +import javax.sip.header.AllowHeader; +import javax.sip.header.CSeqHeader; +import javax.sip.header.FromHeader; +import javax.sip.header.ToHeader; +import javax.sip.header.ViaHeader; +import javax.sip.message.Response; + +/** + * + * @author Jan + */ +public class SIPRinging implements Runnable +{ + private RequestEvent evtubergabe; + private ExecutorService threadring; + private boolean run; + private Response responsering; + //private SubmissionPublisher publisherZahl; + + public SIPRinging(RequestEvent evtubergabe) + { + this.evtubergabe = evtubergabe; + threadring = Executors.newSingleThreadExecutor(); + try + { + responsering = this.messageFactory.createResponse(180, evtubergabe.getRequest()); + } + catch (Exception ex) + { + lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public void start() + { + run = true; + threadring.submit(this); + } + + public void stop() + { + run = false; + } + + public void createRingingHeader() + { + try + { + responsering.addHeader((ViaHeader) evtubergabe.getRequest().getHeader("Via")); + responsering.addHeader((FromHeader) evtubergabe.getRequest().getHeader("From")); + AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE"); + //Bei Ringing muss persönlicher Tag ergänzt werden + ToHeader temptoring = (ToHeader) evtubergabe.getRequest().getHeader("To"); + proxyTag = temptoring.getTag(); + temptoring.setTag(String.valueOf(this.myTag)); + responsering.addHeader(temptoring); + cSequenz = ((CSeqHeader) evtubergabe.getRequest().getHeader("Cseq")).getSeqNumber(); + responsering.addHeader((CSeqHeader) evtubergabe.getRequest().getHeader("Cseq")); + responsering.addHeader(contactHeader); + responsering.addHeader(allow); + AllowEventsHeader allowevent = this.headerFactory.createAllowEventsHeader("talk,hold,refer,call-info");// für was gebraucht + responsering.addHeader(allowevent); + } + catch (Exception ex) + { + lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex); + } + } + + @Override + public void run() + { + while (run) + { + try + { + this.sipProvider.sendResponse(responsering); + } + catch (SipException ex) + { + Logger.getLogger(SIPRinging.class.getName()).log(Level.SEVERE, null, ex); + } + try + { + sleep(1000); + } + catch (Exception e) + { + } + } + } +} diff --git a/src/model/SIPmodel.java b/src/model/SIPmodel.java index b080e42..4622287 100644 --- a/src/model/SIPmodel.java +++ b/src/model/SIPmodel.java @@ -42,23 +42,24 @@ import logger.OhmLogger; public class SIPmodel implements SipListenerExt { Hauptfenster view; //später entfernen wegen Zugriff - private static final Logger lg = OhmLogger.getLogger(); - SipFactory sipFactory; // Used to access the SIP API. - SipStack sipStack; // The SIP stack. - SipProvider sipProvider; // Used to send SIP messages. - MessageFactory messageFactory; // Used to create SIP message factory. - HeaderFactory headerFactory; // Used to create SIP headers. - AddressFactory addressFactory; // Used to create SIP URIs. - ListeningPoint listeningPoint; // SIP listening IP address/port. - Properties properties; // Other properties. + public static final Logger lg = OhmLogger.getLogger(); + public SipFactory sipFactory; // Used to access the SIP API. + public SipStack sipStack; // The SIP stack. + public SipProvider sipProvider; // Used to send SIP messages. + public MessageFactory messageFactory; // Used to create SIP message factory. + public HeaderFactory headerFactory; // Used to create SIP headers. + public AddressFactory addressFactory; // Used to create SIP URIs. + public ListeningPoint listeningPoint; // SIP listening IP address/port. + public Properties properties; // Other properties. - private int counter = 10; + private String[][] codecs; //unterstütze Codecs[RTP-Parameter][CodecBezeichnung] - private int myPort = 5060; - private String myName = "129"; - private String protocolTyp = "UDP"; - private String myIPAddress; - private String proxyAddress; + public int myPort = 5060; + public String myName = "129"; + public String protocolTyp = "UDP"; + public String myIPAddress; + public String proxyAddress; + public CallIdHeader callID; Boolean invite; //Bool für SDP falls ich anrufe @@ -67,10 +68,12 @@ public class SIPmodel implements SipListenerExt Boolean werdeAngerufen; private int countWerdeAngerufen; - int tag = (new Random()).nextInt(); - private int branch = hashCode(); - Address contactAddress; - private ContactHeader contactHeader; + public long cSequenz = 1; + public String proxyTag; + public int myTag = (new Random()).nextInt(); + public int branch = hashCode(); + public Address contactAddress; + public ContactHeader contactHeader; public SIPmodel(Hauptfenster view) //Konstruktor für eigene Daten { @@ -81,14 +84,21 @@ public class SIPmodel implements SipListenerExt countWerdeAngerufen = 0; evtWerdeAngerufen = null; werdeAngerufen = false; + codecs = new String[4][2]; // Alle unterstützen Codecs eintragen + codecs[0][0] = "0"; + codecs[0][1] = "PCMU/8000"; + codecs[1][0] = "4"; + codecs[1][1] = "G723/8000"; + codecs[2][0] = "8"; + codecs[2][1] = "PCMA/8000"; + codecs[3][0] = "18"; + codecs[3][1] = "G729/8000"; try { //wird an sich erstmal nicht gebraucht aber später sinnvoll um eigene Daten zu initialisieren String abc = InetAddress.getLocalHost().getHostAddress(); - this.myIPAddress = InetAddress.getLocalHost().getHostAddress(); - this.sipFactory = SipFactory.getInstance(); this.sipFactory.setPathName("gov.nist"); this.properties = new Properties(); @@ -103,19 +113,17 @@ public class SIPmodel implements SipListenerExt //this.contactAddress = this.addressFactory.createAddress("sip:129@" + this.myIPAddress + ":" + this.myPort); //+ ":" + this.myPort this.contactAddress = this.addressFactory.createAddress("sip:" + myName + "@" + this.myIPAddress + ":" + this.myPort); this.contactHeader = this.headerFactory.createContactHeader(contactAddress); - } catch (Exception e) { System.out.println("Fehler bei Initialisierung eigener Addresse"); System.exit(-1); } - } public int hashCode() { - int temp = tag * (new Random(100)).nextInt(); + int temp = myTag * (new Random(100)).nextInt(); return temp; } @@ -124,10 +132,10 @@ public class SIPmodel implements SipListenerExt lg.info("Vorbereiten des Registrierungs Headers"); proxyAddress = serverIP + ":" + serverPort; Address addressto = this.addressFactory.createAddress("sip:" + proxyAddress); //evtl. mit Port: sip:192.168.100.11:5060 - ToHeader to = this.headerFactory.createToHeader(addressto, null); // Integer.toString(tag) address + tag + ToHeader to = this.headerFactory.createToHeader(addressto, null); // Integer.toString(myTag) address + myTag URI requestURI = addressto.getURI(); CallIdHeader callId = this.sipProvider.getNewCallId(); - FromHeader from = this.headerFactory.createFromHeader(addressto, String.valueOf(this.tag)); //this.contactAddress + FromHeader from = this.headerFactory.createFromHeader(addressto, String.valueOf(this.myTag)); //this.contactAddress ArrayList via = new ArrayList(); //Via needs a List as input ViaHeader viaheader = this.headerFactory.createViaHeader(this.myIPAddress, this.myPort, "UDP", String.valueOf(branch)); via.add(viaheader); @@ -148,26 +156,26 @@ public class SIPmodel implements SipListenerExt { invite = true; Address addressto = this.addressFactory.createAddress("sip:" + sipaddresse + "@" + proxyaddresse); - ToHeader to = this.headerFactory.createToHeader(addressto, null); // Integer.toString(tag) address + tag + ToHeader to = this.headerFactory.createToHeader(addressto, null); // Integer.toString(myTag) address + myTag URI requestURI = addressto.getURI(); - CallIdHeader callId = this.sipProvider.getNewCallId(); - FromHeader from = this.headerFactory.createFromHeader(addressto, String.valueOf(this.tag)); //this.contactAddress + callID = this.sipProvider.getNewCallId(); + FromHeader from = this.headerFactory.createFromHeader(addressto, String.valueOf(this.myTag)); //this.contactAddress ArrayList via = new ArrayList(); //Via needs a List as input ViaHeader viaheader = this.headerFactory.createViaHeader(this.myIPAddress, this.myPort, "UDP", String.valueOf(branch)); via.add(viaheader); - CSeqHeader cSeq = this.headerFactory.createCSeqHeader(1L, "INVITE"); + + CSeqHeader cSeq = this.headerFactory.createCSeqHeader(cSequenz, "INVITE"); + MaxForwardsHeader maxForwards = this.headerFactory.createMaxForwardsHeader(70); AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE"); ExpiresHeader expire = this.headerFactory.createExpiresHeader(3600); //int value - Request request = this.messageFactory.createRequest(requestURI, "INVITE", callId, cSeq, from, to, via, maxForwards); + Request request = this.messageFactory.createRequest(requestURI, "INVITE", callID, cSeq, from, to, via, maxForwards); request.addHeader(contactHeader); request.addHeader(allow); request.addHeader(expire); - ContentTypeHeader content = headerFactory.createContentTypeHeader("application", "sdp"); request.addHeader(content); - - request.setContent(createSDPHeader(), content); + request.setContent(createSDPHeader(null), content); this.sipProvider.sendRequest(request); lg.info("Erfolgreiches Senden der Invitation"); @@ -185,25 +193,6 @@ public class SIPmodel implements SipListenerExt this.sipProvider.sendResponse(create200Ok(requestEvent)); view.getTxtArea().append("Server Option Request erfolgreich beantwortet\n"); lg.info("Erfolgreiches senden des Headers"); - /* - Response response = this.messageFactory.createResponse(200, requestEvent.getRequest()); - response.addHeader((ViaHeader) requestEvent.getRequest().getHeader("Via")); - response.addHeader((FromHeader) requestEvent.getRequest().getHeader("From")); - response.addHeader((ToHeader) requestEvent.getRequest().getHeader("To")); - response.addHeader((CallIdHeader) requestEvent.getRequest().getHeader("Call-ID")); - response.addHeader((CSeqHeader) requestEvent.getRequest().getHeader("Cseq")); - //Kontakt Header - response.addHeader(contactHeader); - //Accept Header für application/sdp - AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE"); - AllowEventsHeader allowevents = this.headerFactory.createAllowEventsHeader("talk,hold,refer,call-info"); - response.addHeader((CallIdHeader) requestEvent.getRequest().getHeader("Call-ID")); - response.addHeader(allow); - response.addHeader(allowevents); - this.sipProvider.sendResponse(response); - view.getTxtArea().append("Server Option Request erfolgreich beantwortet\n"); - lg.info("Erfolgreiches senden des Headers"); - */ } catch (ParseException | SipException ex) { @@ -213,8 +202,18 @@ public class SIPmodel implements SipListenerExt //Aktive Kommunikation else if ((Request.INVITE).equals(requestEvent.getRequest().getMethod())) // Invite von anderem Benutzer { + try + { + this.sipProvider.sendResponse(create180Ringing(requestEvent)); + view.getTxtArea().append("Ringing geschickt\n"); + } + catch (Exception ex)//Exceptions evtl. genauer definieren + { + lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex); + } countWerdeAngerufen++; //bessere Lösung muss her!!, was schickt andere User oder Proxy bei nicht erreichen FromHeader abc = (FromHeader) requestEvent.getRequest().getHeader("From"); + evtWerdeAngerufen = requestEvent; System.out.println(countWerdeAngerufen); if (countWerdeAngerufen < 7) @@ -238,6 +237,7 @@ public class SIPmodel implements SipListenerExt } else if ((Request.CANCEL).equals(requestEvent.getRequest().getMethod())) { + view.getTxtArea().append("Anruf wurde gecancelt"); try { //Cancel Request -> Response 200 Ok + Response 487 Request Terminated @@ -257,9 +257,15 @@ public class SIPmodel implements SipListenerExt } else if ((Request.BYE).equals(requestEvent.getRequest().getMethod())) { + try + { + this.sipProvider.sendResponse(create200Ok(requestEvent)); + } + catch (Exception ex) + { + } } - } @Override @@ -270,20 +276,15 @@ public class SIPmodel implements SipListenerExt if (responseEvent.getResponse().getStatusCode() == Response.UNAUTHORIZED) { - try { - //Address addresstob = this.addressFactory.createAddress("sip:129@192.168.100.11"); //"sip:Jan@192.168.100.11" Address addresstob = this.addressFactory.createAddress("sip:" + myName + "@" + proxyAddress); ToHeader temp = (ToHeader) responseEvent.getResponse().getHeader("To"); - ToHeader to = this.headerFactory.createToHeader(addresstob, temp.getTag()); // Integer.toString(tag) address + tag + ToHeader to = this.headerFactory.createToHeader(addresstob, temp.getTag()); // Integer.toString(myTag) address + myTag URI requestURI = addresstob.getURI(); CallIdHeader callId = (CallIdHeader) responseEvent.getResponse().getHeader("Call-ID"); - FromHeader from = this.headerFactory.createFromHeader(addresstob, String.valueOf(this.tag)); //this.contactAddress - - //set Authorization header evtl. user Name benutzen den es gibt - //wird WWWAuthenticateHeader überhaupt benötigt??? + FromHeader from = this.headerFactory.createFromHeader(addresstob, String.valueOf(this.myTag)); //this.contactAddress WWWAuthenticateHeader wwwauth = (WWWAuthenticateHeader) responseEvent.getResponse().getHeader("WWW-Authenticate"); //wird bei AuthorizationHeader wirklich alles benötigt? war glaub nur mal Test -> testen!! @@ -324,6 +325,12 @@ public class SIPmodel implements SipListenerExt { lg.info("Erfolgreichen Response (200 OK) bekommen"); } + else if (responseEvent.getResponse().getStatusCode() == Response.RINGING) + { + ToHeader temp = (ToHeader) responseEvent.getResponse().getHeader("To"); + proxyTag = temp.getTag(); + + } } @@ -344,14 +351,33 @@ public class SIPmodel implements SipListenerExt return response; } - public SessionDescription createSDPHeader() throws SdpException + public Response create180Ringing(RequestEvent requestEvent) throws ParseException, SipException + { + + Response responsering = this.messageFactory.createResponse(180, requestEvent.getRequest()); + responsering.addHeader((ViaHeader) requestEvent.getRequest().getHeader("Via")); + responsering.addHeader((FromHeader) requestEvent.getRequest().getHeader("From")); + AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE"); + //Bei Ringing muss persönlicher Tag ergänzt werden + ToHeader temptoring = (ToHeader) requestEvent.getRequest().getHeader("To"); + proxyTag = temptoring.getTag(); + temptoring.setTag(String.valueOf(this.myTag)); + responsering.addHeader(temptoring); + cSequenz = ((CSeqHeader) requestEvent.getRequest().getHeader("Cseq")).getSeqNumber(); + responsering.addHeader((CSeqHeader) requestEvent.getRequest().getHeader("Cseq")); + responsering.addHeader(contactHeader); + responsering.addHeader(allow); + AllowEventsHeader allowevent = this.headerFactory.createAllowEventsHeader("talk,hold,refer,call-info");// für was gebraucht + responsering.addHeader(allowevent); + return responsering; + } + + public SIPmodel() + { + } + + public SessionDescription createSDPHeader(ArrayList reqSDP) throws SdpException { - /* - String contentparam = "v=0\r\n" + "o=129 1202 1202" + " IN IP4 192.168.100.247\r\n" + "s=SIP Call\r\n" - + "c=192.168.100.247\r\n" + "t=0 0\r\n" + "m=audio 6022 RTP/AVP 0 4 18\r\n" - + "a=rtpmap:0 PCMU/8000\r\n" + "a=rtpmap:4 G723/8000\r\n" + "a=rtpmap:18 G729A/8000\r\n" + - "a=ptime:20\r\n"; - */ SdpFactory sdpFactory = SdpFactory.getInstance(); SessionDescription sessionDescription = sdpFactory.createSessionDescription(); sessionDescription.setOrigin(sdpFactory.createOrigin(myName, 8000, 8000, "IN", "IP4", myIPAddress)); @@ -360,27 +386,37 @@ public class SIPmodel implements SipListenerExt //Media Body Vector mediavec = new Vector(); + String cods[] = new String[codecs.length]; + System.out.println("System out: " + codecs.length); + + for (int i = 0; i < cods.length; i++)//Übertragung der RTP-Values in neues Array + { + cods[i] = codecs[i][0]; + } + + mediavec.add(sdpFactory.createMediaDescription("audio", 6022, 1, "RTP/AVP", cods)); //(Übertragungstyp, Port, anzahl der Ports, Verbindungstyp,..) + mediavec.add(sdpFactory.createAttribute("sendrecv", null)); if (invite = true) { - String sdpformat[] = + for (int i = 0; i == codecs[0].length; i++) { - "0", "4", "8", "18", - }; - mediavec.add(sdpFactory.createMediaDescription("audio", 6022, 1, "RTP/AVP", sdpformat)); //(Übertragungstyp, Port, anzahl der Ports, Verbindungstyp,..) - //Media Attribute - mediavec.add(sdpFactory.createAttribute("sendrecv", null)); - mediavec.add(sdpFactory.createAttribute("rtpmap", "0 PCMU/8000")); - mediavec.add(sdpFactory.createAttribute("rtpmap", "4 G723/8000")); - mediavec.add(sdpFactory.createAttribute("rtpmap", "8 PCMA/8000")); - mediavec.add(sdpFactory.createAttribute("rtpmap", "18 G729/8000")); - mediavec.add(sdpFactory.createAttribute("ptime", "20")); + System.out.println("Codecs: " + codecs[i][0] + " " + codecs[i][1]); + mediavec.add(sdpFactory.createAttribute("rtpmap", codecs[i][0] + " " + codecs[i][1])); + } } else//Vergleich von eigenen Codecs mit Codecs der anruft -> Rückgabe entsprechend wählen { - + boolean temp = true; //evtl noch was besseres da so erster Codec nicht bester verwendet wird + for (int i = 0; i == codecs[0].length; i++) + { + if (codecs[i][1].equals(reqSDP) && temp == true) + { + mediavec.add(sdpFactory.createAttribute("rtpmap", "8 G711a/8000")); + temp = false; + } + } } sessionDescription.setAttributes(mediavec); - return sessionDescription; } @@ -393,6 +429,7 @@ public class SIPmodel implements SipListenerExt try { + callID = (CallIdHeader) requestEvent.getRequest().getHeader("Call-ID"); //Trying Message to Server (Response Trying) Response responsetry = this.messageFactory.createResponse(100, requestEvent.getRequest()); responsetry.addHeader((ViaHeader) requestEvent.getRequest().getHeader("Via")); @@ -401,6 +438,8 @@ public class SIPmodel implements SipListenerExt responsetry.addHeader((CallIdHeader) requestEvent.getRequest().getHeader("Call-ID")); responsetry.addHeader((CSeqHeader) requestEvent.getRequest().getHeader("Cseq")); + CSeqHeader tempcs = (CSeqHeader) requestEvent.getRequest().getHeader("Cseq"); + tempcs.getSeqNumber(); SupportedHeader supp = this.headerFactory.createSupportedHeader("replace,path,timer"); //nachschauen AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE"); @@ -416,7 +455,7 @@ public class SIPmodel implements SipListenerExt responsering.addHeader((FromHeader) requestEvent.getRequest().getHeader("From")); ToHeader temptoring = (ToHeader) requestEvent.getRequest().getHeader("To"); - String tempTag = String.valueOf(this.tag + Math.random()); + String tempTag = String.valueOf(this.myTag + Math.random()); temptoring.setTag(tempTag); //evtl. besseren Tag responsering.addHeader(temptoring); @@ -433,7 +472,6 @@ public class SIPmodel implements SipListenerExt //Jetzt kommt 200 Ok SIP Header + SDP (SIP/SDP) //Sdp Header erstellen nächster Schritt invite = false; - System.out.println(requestEvent.getDialog()); Response okandSDP = this.messageFactory.createResponse(Response.OK, requestEvent.getRequest()); //okandSDP.addHeader((ViaHeader) requestEvent.getRequest().getHeader("Via")); okandSDP.addHeader((FromHeader) requestEvent.getRequest().getHeader("From")); @@ -447,7 +485,18 @@ public class SIPmodel implements SipListenerExt okandSDP.addHeader(allowevent); ContentTypeHeader content = headerFactory.createContentTypeHeader("application", "sdp"); okandSDP.addHeader(content); - okandSDP.setContent(createSDPHeader(), content); + + String[] reqbody = (requestEvent.getRequest()).toString().split("\\s|" + System.getProperty("line.seperator"));//Req. Body in Zeilen aufteilen + ArrayList reqSDP = new ArrayList<>(); + for (String req : reqbody)//jeden String durchgehen und nach Codecs suchen die unterstützt werden + { + if (req.startsWith("a=rtpmap")) + { + reqSDP.add(req.replace("a=rtpmap:", "")); + System.out.println(reqSDP); + } + } + okandSDP.setContent(createSDPHeader(reqSDP), content); this.sipProvider.sendResponse(okandSDP); view.getTxtArea().append("Telefonat beginnt\n"); @@ -466,9 +515,35 @@ public class SIPmodel implements SipListenerExt } - public void cancelcall() + public void byecall(String calluser) throws ParseException, InvalidArgumentException, SipException { + invite = false; + Address addressLine = this.addressFactory.createAddress("sip:" + calluser + "@" + proxyAddress); + URI requestURI = addressLine.getURI(); + Address addressfrom = this.addressFactory.createAddress("sip:" + myName + "@" + myIPAddress); + FromHeader from = this.headerFactory.createFromHeader(addressfrom, String.valueOf(this.myTag)); + + Address addressTo = this.addressFactory.createAddress("sip:" + myName + "@" + proxyAddress); + ToHeader to = this.headerFactory.createToHeader(addressTo, proxyTag); // Ergänzung TAG!! + + ArrayList via = new ArrayList(); //Via needs a List as input + ViaHeader viaheader = this.headerFactory.createViaHeader(this.myIPAddress, this.myPort, "UDP", String.valueOf(branch)); + via.add(viaheader); + + cSequenz++; + CSeqHeader cSeq = this.headerFactory.createCSeqHeader(cSequenz, "BYE"); + MaxForwardsHeader maxForwards = this.headerFactory.createMaxForwardsHeader(70); + AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE"); + ExpiresHeader expire = this.headerFactory.createExpiresHeader(3600); //int value + Request request = this.messageFactory.createRequest(requestURI, "BYE", callID, cSeq, from, to, via, maxForwards); + request.addHeader(contactHeader); + request.addHeader(allow); + request.addHeader(expire); + this.sipProvider.sendRequest(request); + invite = false; + + lg.info("Erfolgreiches Senden des BYE Headers"); } //Get Methoden falls man mal die Parameter braucht