123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- /*
- * 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 controller.commands.CommandInvite;
- import gov.nist.javax.sip.DialogTimeoutEvent;
- import gov.nist.javax.sip.SipListenerExt;
- import gui.Hauptfenster;
- import java.net.InetAddress;
- import java.net.UnknownHostException;
- import java.security.SecureRandom;
- import java.text.ParseException;
- import java.util.*;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javax.sip.DialogTerminatedEvent;
- import javax.sip.IOExceptionEvent;
- import javax.sip.InvalidArgumentException;
- import javax.sip.ListeningPoint;
- import javax.sip.RequestEvent;
- import javax.sip.ResponseEvent;
- import javax.sip.SipException;
- import javax.sip.SipFactory;
- import javax.sip.SipProvider;
- import javax.sip.SipStack;
- import javax.sip.TimeoutEvent;
- import javax.sip.TransactionTerminatedEvent;
- import javax.sip.address.*;
- import javax.sip.header.*;
- import javax.sip.message.*;
- import logger.OhmLogger;
-
- /**
- *
- * @author Jan komplettes Model für SIPmodel evtl. Vererbung und für jeden SIP
- * Response/Request eigene Klasse oder Interface da es langsam unübersichtlich
- * wird :( ACK schicken muss noch ergänzt werden BYE muss noch ergänzt werden.
- */
- public class SIPmodel implements SipListenerExt {
- //Stringhilfen zum erzeugen von RandomString (Branch)
-
- private static final String TEST = "0123456789abcdefghijklmnopqrstuvwxyz";//für Random String
- private static final SecureRandom RANDOM = new SecureRandom(); //für Random String
- //Verbindungskonstanten
- private static final int MYSIPPORT = 5060;
- private static final int MYRTPPORT = 5004;
- private static final int MYRTCPPORT = 5005;
- private static final String PROTOCOLTYP = "UDP";
-
- Hauptfenster view; //später entfernen wegen Zugriff
- 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 AudioRinging audioRinging;
-
- //Hilfsbooleans
- private Boolean anrufer; //Hilfsvariable ob ich selbst anrufer bin
- private Boolean anrufAngenommen;
- private Boolean anrufCancel;
- private Boolean werdeAngerufen;
-
- //Variablen die im Laufe des Gespräches ermittelt werden
- //Eigene Daten
- private String myIPAddress;
- private String myName = "129";
- private String myTag;
- private Address contactAddress;
- private ContactHeader contactHeader;
- //ProxyServer
- public String proxyAddress;
- private int proxyRTPPort;
- private String proxyTag;
- //CallDaten
- private String branch;
- public CallIdHeader callID;
- private long cSequenz;
- private String RTPCodec;
-
- public SIPmodel(Hauptfenster view) //Konstruktor für eigene Daten
- {
- this.view = view;
- anrufer = false;
- anrufAngenommen = false;
- anrufCancel = false;
- proxyAddress = "";
- proxyTag = "";
- cSequenz = 1;
- werdeAngerufen = false;
-
- audioRinging = new AudioRinging();
- myTag = createString(8); //erzeugt Random Tag mit Länge 8
- branch = createString(18);//erzeugt Random branch mit Länge 18
- try {
- //wird an sich erstmal nicht gebraucht aber später sinnvoll um eigene Daten zu initialisieren
- this.myIPAddress = InetAddress.getLocalHost().getHostAddress();
- this.sipFactory = SipFactory.getInstance();
- this.sipFactory.setPathName("gov.nist");
- this.properties = new Properties();
- this.properties.setProperty("javax.sip.STACK_NAME", "stack");
- this.sipStack = this.sipFactory.createSipStack(this.properties);
- this.messageFactory = this.sipFactory.createMessageFactory();
- this.headerFactory = this.sipFactory.createHeaderFactory();
- this.addressFactory = this.sipFactory.createAddressFactory();
- this.listeningPoint = this.sipStack.createListeningPoint(this.myIPAddress, this.MYSIPPORT, this.PROTOCOLTYP);
- this.sipProvider = this.sipStack.createSipProvider(this.listeningPoint);
- this.sipProvider.addSipListener(this);
- this.contactAddress = this.addressFactory.createAddress("sip:" + this.myName + "@" + this.myIPAddress + ":" + this.MYSIPPORT);
- this.contactHeader = this.headerFactory.createContactHeader(contactAddress);
- } catch (Exception e) {
- System.out.println("Fehler bei Initialisierung eigener Addresse");
- System.exit(-1);
- }
- }
-
- private String createString(int anzahl) //Erzeugt Random String in bestimmter länge für branch und Tag
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < anzahl; i++) {
- sb.append(TEST.charAt(RANDOM.nextInt(TEST.length())));
- }
- return sb.toString();
- }
-
- public void sendRegister(String serverIP, int serverPort) throws ParseException, InvalidArgumentException, SipException {
- proxyAddress = serverIP + ":" + serverPort;
- SIPRegister register = new SIPRegister(proxyAddress, myTag, myIPAddress, MYSIPPORT, branch, addressFactory, headerFactory, messageFactory, contactHeader, sipProvider.getNewCallId());
- sipProvider.sendRequest(register.getRequest());
- lg.info("Erfolgreiches Senden der Registrierung");
- }
-
- public void sendInvitation(String sipaddresse, String proxyaddresse,
- int serverPort) throws SipException { //ServerPort wird nicht verwendet?
- resetCallParameter();
- anrufer = true;
- callID = sipProvider.getNewCallId();
- SIPSessionDescription sdp = new SIPSessionDescription(myName, myIPAddress, getMYRTPPORT(), null, anrufer);
- SIPInvite sipinvite = new SIPInvite(sipaddresse, proxyaddresse, myIPAddress, MYSIPPORT, myTag, branch, callID, cSequenz, addressFactory, sdp.getSessionDescription(), headerFactory, messageFactory, contactHeader);
- sipProvider.sendRequest(sipinvite.getInviterequest());
- lg.info("Erfolgreiches Senden der Invitation");
- }
-
- @Override
- public void processRequest(RequestEvent requestEvent) {
- lg.info("Bekomme Anfrage");
- if ((Request.OPTIONS).equals(requestEvent.getRequest().getMethod())) //Options Anfrage von Server nach erfolgreicher Registrierung
- {
- lg.info("Option Request von Server, erstellen 200 OK zu Server");
- try {
- SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
- this.sipProvider.sendResponse(tempOk.getResponse());
- view.getTxtArea().append("Server Option Request erfolgreich beantwortet\n");
- lg.info("Erfolgreiches senden des 200Ok-Headers");
- } catch (SipException ex) {
- lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
- }
- } //Aktive Kommunikation
- else if ((Request.INVITE).equals(requestEvent.getRequest().getMethod())) // Invite von anderem Benutzer
- {
- resetCallParameter();
- anrufer = false;
- //Falls Anruf ankommt, wichtige Variablen Zwischenspeichern (Branch, Cseq, CallID, proxyTag)
- branch = ((ViaHeader) requestEvent.getRequest().getHeader("Via")).getBranch();
- cSequenz = ((CSeqHeader) requestEvent.getRequest().getHeader("Cseq")).getSeqNumber();
- proxyTag = ((FromHeader) requestEvent.getRequest().getHeader("From")).getTag();
- callID = ((CallIdHeader) requestEvent.getRequest().getHeader("CallID"));
- //Standartabfolge sobald man angerufen wird
- try {
- //Trying Response erzeugen und abschicken
- SIP100Trying tempTrying = new SIP100Trying(messageFactory, requestEvent, headerFactory);
- sipProvider.sendResponse(tempTrying.getTryResponse());
- view.getTxtArea().append("Trying geschickt\n");
- lg.info("Trying ist raus");
-
- //Ringing Response erzeugen und abschicken noch Schleife mit "Anruf annehmen"
- SIP180Ringing tempRinging = new SIP180Ringing(requestEvent, myTag, contactHeader, headerFactory, messageFactory);
- Timer timer = new Timer();
-
- timer.scheduleAtFixedRate(new TimerTask() {
- int counter = 0;
-
- @Override
- public void run() {
- try {
- if (anrufAngenommen != true && counter % 4 == 0) //Falls man nicht abnimmt, klingeln + Ringing schicken
- {
- sipProvider.sendResponse(tempRinging.getResponseRing());
- audioRinging.startRinging();
- } else if (anrufAngenommen == true) //bei annehmen, klingeln aufhören, OK mit SDP schicken
- {
- audioRinging.endRinging();
- audioRinging.endRinging();
- SIP200Ok respcall = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
- SIPSessionDescription sdp = new SIPSessionDescription(myName, myIPAddress, getMYRTPPORT(), requestEvent, anrufer);
- respcall.addSDP(sdp.getSessionDescription(), myTag);
- sipProvider.sendResponse(respcall.getResponse());
- view.getTxtArea().append("Telefonat beginnt\n");
- timer.cancel();
- } else if (anrufCancel == true) {
- timer.cancel();
- }
- counter++;
- } catch (SipException ex) {
-
- }
- }
- }, 0, 1000);
- } catch (SipException ex) {
- lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
- }
- } else if ((Request.ACK).equals(requestEvent.getRequest().getMethod())) {
-
- } else if ((Request.CANCEL).equals(requestEvent.getRequest().getMethod())) {
- System.out.println("Anruf cancel");
- view.getTxtArea().append("Anruf wurde gecancelt");
- try {
- //Cancel Request -> Response 200 Ok + Response 487 Request Terminated
- //200 Ok
- anrufCancel = true;
- SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
- sipProvider.sendResponse(tempOk.getResponse());
- view.getTxtArea().append("Anrufender canceld Anfrage\n");
- lg.info("Erfolgreiches senden des 200 OkHeaders auf CancelAnfrage");
- //487 Request Terminated
- } catch (SipException ex) {
- Logger.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
- }
- } else if ((Request.BYE).equals(requestEvent.getRequest().getMethod())) {
- try {
- SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
- this.sipProvider.sendResponse(tempOk.getResponse());
- } catch (SipException ex) {
- Logger.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
-
- @Override
- public void processResponse(ResponseEvent responseEvent) {
- if (responseEvent.getResponse().getStatusCode() == Response.UNAUTHORIZED) {
- try {
- cSequenz += 1L;
- branch += 10;
- SIPUnauthReq req2 = new SIPUnauthReq(myName, proxyAddress, myTag, myIPAddress, branch, cSequenz, MYSIPPORT, contactHeader, addressFactory, headerFactory, responseEvent, messageFactory);
- sipProvider.sendRequest(req2.getUnauthReq());
- view.getTxtArea().append("Erfolgreich registriert\n");
- } catch (SipException ex) {
- lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
- }
- } else if (responseEvent.getResponse().getStatusCode() == Response.OK) {
- //Überprüfen ob Ok Header mit SDP ist
- if ((((ContentTypeHeader) responseEvent.getResponse().getHeader("Content-Type")).getContentSubType()).equals("sdp")) {
- lg.info("Erfolgreichen Response 200 OK mit SDP bekommen");
- getRTPParameters(responseEvent);
- // SIPACK ack = new SIPACK();
- // sipProvider.sendResponse(rspns);
- /*
- System.out.println("Starte RTP Session");
- //String[] s = null;
- SoundSenderDemo aDemo = null;
- // try {
- // aDemo = new SoundSenderDemo(true);
- // } catch (UnknownHostException | InterruptedException ex) {
- // Logger.getLogger(CommandInvite.class.getName()).log(Level.SEVERE, null, ex);
- // }
- try {
- aDemo.SendDemo(null);
- } catch (UnknownHostException | InterruptedException ex) {
- Logger.getLogger(CommandInvite.class.getName()).log(Level.SEVERE, null, ex);
- }
- System.out.println("Beende RTP Session");
- */
- } else {
- lg.info("Erfolgreichen Response (200 OK) bekommen");
- }
- } else if (responseEvent.getResponse().getStatusCode() == Response.RINGING) {
- ToHeader temp = (ToHeader) responseEvent.getResponse().getHeader("To");
- proxyTag = temp.getTag();
- }
-
- }
-
- public void byecall(String calluser) throws ParseException, InvalidArgumentException, SipException {
- cSequenz++;
- SIPBye tempBye = new SIPBye(calluser, proxyAddress, myName, myIPAddress, myTag, proxyTag, MYSIPPORT, branch, callID, cSequenz, messageFactory, contactHeader, addressFactory, headerFactory);
- sipProvider.sendRequest(tempBye.getByeRequest());
- lg.info("Erfolgreiches Senden des BYE Headers");
- }
-
- public void getRTPParameters(ResponseEvent responseEvent) {
- int identifier = 0;
- String[] reqbody = (responseEvent.getResponse()).toString().split("\\s|" + System.getProperty("line.seperator"));
- for (String req : reqbody) {
- if (identifier == 1) {
- proxyRTPPort = Integer.valueOf(req);
- identifier = 0;
- } else if (identifier == 2) {
- RTPCodec = req;
- identifier = 0;
- }
- if (req.startsWith("m=audio")) {
- identifier = 1;
- } else if (req.startsWith("a=rtpmap:")) {
- identifier = 2;
- }
- }
- }
-
- public void resetCallParameter() {
- anrufAngenommen = false;
- anrufer = false;
- }
-
- public void anrufAnnehmen() {
- anrufAngenommen = true;
- }
-
- //Get Methoden falls man mal die Parameter braucht
- public String getmyName() {
- return myName;
- }
-
- public Integer getMyPort() {
- return MYSIPPORT;
- }
-
- public String getMyIPAdress() {
- return myIPAddress;
- }
-
- // Herausfinden bei welchen Events die unteren Funktionen aufgerufen werden -> evtl brauchbar
- @Override
- public void processTimeout(TimeoutEvent timeoutEvent) {
- //view.getTxtArea().append("processTimeout\n");
- }
-
- @Override
- public void processIOException(IOExceptionEvent exceptionEvent) {
- //view.getTxtArea().append("processIOException\n");
- }
-
- @Override
- public void processTransactionTerminated(
- TransactionTerminatedEvent transactionTerminatedEvent) {
- //view.getTxtArea().append("processTransactionTerminated\n");
- }
-
- @Override
- public void processDialogTerminated(
- DialogTerminatedEvent dialogTerminatedEvent) {
- //view.getTxtArea().append("processDialogTerminated\n");
- }
-
- @Override
- public void processDialogTimeout(DialogTimeoutEvent timeoutEvent) {
- //view.getTxtArea().append("processDialogTerminated\n");
- }
-
- /**
- * @param myPort the MYSIPPORT to set
- */
- /**
- * @return the myName
- */
- public String getMyName() {
- return myName;
- }
-
- /**
- * @return the proxyTag
- */
- public String getProxyTag() {
- return proxyTag;
- }
-
- /**
- * @param proxyTag the proxyTag to set
- */
- public void setProxyTag(String proxyTag) {
- this.proxyTag = proxyTag;
- }
-
- /**
- * @return the myTag
- */
- public String getMyTag() {
- return myTag;
- }
-
- /**
- * @param myTag the myTag to set
- */
- public void setMyTag(String myTag) {
- this.myTag = myTag;
- }
-
- /**
- * @return the branch
- */
- public String getBranch() {
- return branch;
- }
-
- /**
- * @param proxyRTPPort the proxyRTPPort to set
- */
- public void setProxyRTPPort(int proxyRTPPort) {
- this.proxyRTPPort = proxyRTPPort;
- }
-
- /**
- * @param RTPCodec the RTPCodec to set
- */
- public void setRTPCodec(String RTPCodec) {
- this.RTPCodec = RTPCodec;
- }
-
- /**
- * @return the proxyRTPPort
- */
- public int getProxyRTPPort() {
- return proxyRTPPort;
- }
-
- /**
- * @return the RTPCodec
- */
- public String getRTPCodec() {
- return RTPCodec;
- }
-
- /**
- * @return the MYRTPPORT
- */
- public static int getMYRTPPORT() {
- return MYRTPPORT;
- }
-
- /**
- * @return the MYRTCPPORT
- */
- public static int getMYRTCPPORT() {
- return MYRTCPPORT;
- }
- }
|