/* * 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 gov.nist.javax.sip.DialogTimeoutEvent; import gov.nist.javax.sip.SipListenerExt; import gui.Hauptfenster; import java.net.InetAddress; 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 { 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 String[][] codecs; //unterstütze Codecs[RTP-Parameter][CodecBezeichnung] private int myPort = 5060; private 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 //Hilfsvariablen wenn ich angerufen werde. evtl. noch optimieren RequestEvent evtWerdeAngerufen; Boolean werdeAngerufen; private int countWerdeAngerufen; public long cSequenz = 1; private String proxyTag; private String myTag = String.valueOf(new Random().nextInt()); private int branch = Integer.valueOf(hashCode()); public Address contactAddress; public ContactHeader contactHeader; public SIPmodel(Hauptfenster view) //Konstruktor für eigene Daten { this.view = view; invite = true; proxyAddress = ""; 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(); 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.myPort, this.protocolTyp); this.sipProvider = this.sipStack.createSipProvider(this.listeningPoint); this.sipProvider.addSipListener(this); //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 = Integer.valueOf(myTag)* (new Random(100)).nextInt(); return temp; } public void sendRegister(String serverIP, int serverPort) throws ParseException, InvalidArgumentException, SipException { proxyAddress = serverIP + ":" + serverPort; SIPRegister register = new SIPRegister(proxyAddress, myTag, myIPAddress, myPort, branch, addressFactory, headerFactory, messageFactory, contactHeader, sipProvider.getNewCallId()); this.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? invite = true; callID = this.sipProvider.getNewCallId(); SIPSessionDescription sdp = new SIPSessionDescription(myName, myIPAddress, evtWerdeAngerufen, true); SIPInvite sipinvite = new SIPInvite(sipaddresse, proxyaddresse, myIPAddress, myPort, myTag, branch, callID, cSequenz, addressFactory, sdp.getSessionDescription(), headerFactory, messageFactory, contactHeader); this.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 { 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) { werdeAngerufen = true; lg.info("Hab Invitation bekommen"); view.getTxtArea().append("Werde von " + abc.getAddress() + " angerufen\n"); } else { werdeAngerufen = false; lg.info("Leider waren Sie nicht erreichbar"); view.getTxtArea().append("Sie waren nicht erreichbar\n"); countWerdeAngerufen = 0; } } else if ((Request.ACK).equals(requestEvent.getRequest().getMethod())) { } else if ((Request.CANCEL).equals(requestEvent.getRequest().getMethod())) { view.getTxtArea().append("Anruf wurde gecancelt"); try { //Cancel Request -> Response 200 Ok + Response 487 Request Terminated //200 Ok werdeAngerufen = false; evtWerdeAngerufen = null; // sicher ist sicher SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory); this.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 (Exception ex) { } } } @Override public void processResponse(ResponseEvent responseEvent) { System.out.println("---Response---"); //System.out.println(responseEvent.getResponse()); if (responseEvent.getResponse().getStatusCode() == Response.UNAUTHORIZED) { try { 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(myTag) address + myTag URI requestURI = addresstob.getURI(); CallIdHeader callId = (CallIdHeader) responseEvent.getResponse().getHeader("Call-ID"); FromHeader from = this.headerFactory.createFromHeader(addresstob, 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!! AuthorizationHeader auth = this.headerFactory.createAuthorizationHeader("Digest");//was kommt in den string auth.setRealm(wwwauth.getRealm()); auth.setNonce(wwwauth.getNonce()); //Address addresstest = this.addressFactory.createAddress("sip:" + myName + "@192.168.100.11"); //vielleicht passwort setzen "sip:"+myName+":\"\"@192.168.100.11" Address addresstest = this.addressFactory.createAddress("sip:" + myName + "@" + proxyAddress); auth.setURI(addresstest.getURI()); auth.setUsername(myName); ArrayList via = new ArrayList(); //Via needs a List as input ViaHeader viaheader = this.headerFactory.createViaHeader(this.myIPAddress, this.myPort, "UDP", String.valueOf(branch + 2));// String.valueOf(hashCode())string branch via.add(viaheader); CSeqHeader cSeq = this.headerFactory.createCSeqHeader(2L, "REGISTER"); 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 //Zusätzliche Register Header nach Unauthorzied //Create Request Header Request request = this.messageFactory.createRequest(requestURI, "REGISTER", callId, cSeq, from, to, via, maxForwards); request.addHeader(contactHeader); request.addHeader(allow); request.addHeader(expire); request.addHeader(auth); this.sipProvider.sendRequest(request); view.getTxtArea().append("Erfolgreich registriert\n"); } catch (ParseException | SipException | InvalidArgumentException ex) { lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex); } } else if (responseEvent.getResponse().getStatusCode() == Response.OK) { 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 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(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 void annehmen() //Fehlende Bedingung { RequestEvent requestEvent; if ((requestEvent = evtWerdeAngerufen) != null && werdeAngerufen == true) { countWerdeAngerufen = 0; try { //Werte für weitere Kommunikation abspeichern callID = (CallIdHeader) requestEvent.getRequest().getHeader("Call-ID"); CSeqHeader tempCs = (CSeqHeader) requestEvent.getRequest().getHeader("Cseq"); cSequenz = tempCs.getSeqNumber(); FromHeader tempFrom = (FromHeader) requestEvent.getRequest().getHeader("From"); proxyTag = tempFrom.getTag(); //Trying Header erzeugen und abschicken SIP100Trying tempTrying = new SIP100Trying(messageFactory, requestEvent, headerFactory); this.sipProvider.sendResponse(tempTrying.getTryResponse()); view.getTxtArea().append("Trying geschickt\n"); lg.info("Trying ist raus"); //Ringing Message to Server (Responste Ringing)From tag: proxyTag, To Tag, persönlicher Tag SIP180Ringing tempRinging = new SIP180Ringing(requestEvent, myTag, proxyTag, contactHeader, headerFactory); sipProvider.sendResponse(tempRinging.getResponseRing()); view.getTxtArea().append("Ringing geschickt\n"); //Jetzt kommt 200 Ok SIP Header + SDP (SIP/SDP) //Sdp Header erstellen nächster Schritt invite = false; SIP200Ok respcall = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory); SIPSessionDescription sdp = new SIPSessionDescription(myName, myIPAddress, requestEvent, false); respcall.addSDP(sdp.getSessionDescription(), myTag); System.out.println(respcall.getResponse()); this.sipProvider.sendResponse(respcall.getResponse()); view.getTxtArea().append("Telefonat beginnt\n"); evtWerdeAngerufen = null; } catch (SipException ex) { Logger.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex); } } else { view.getTxtArea().append("Zur Zeit gibt es keinen Anruf\n"); } } 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 public String getmyName() { return myName; } public Integer getMyPort() { return myPort; } 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 myPort to set */ public void setMyPort(int myPort) { this.myPort = myPort; } /** * @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 int getBranch() { return branch; } }