You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SIPmodel.java 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package model;
  7. import gov.nist.javax.sip.DialogTimeoutEvent;
  8. import gov.nist.javax.sip.SipListenerExt;
  9. import gui.Hauptfenster;
  10. import java.net.InetAddress;
  11. import java.text.ParseException;
  12. import java.util.*;
  13. import java.util.logging.Level;
  14. import java.util.logging.Logger;
  15. import javax.sip.DialogTerminatedEvent;
  16. import javax.sip.IOExceptionEvent;
  17. import javax.sip.InvalidArgumentException;
  18. import javax.sip.ListeningPoint;
  19. import javax.sip.RequestEvent;
  20. import javax.sip.ResponseEvent;
  21. import javax.sip.SipException;
  22. import javax.sip.SipFactory;
  23. import javax.sip.SipProvider;
  24. import javax.sip.SipStack;
  25. import javax.sip.TimeoutEvent;
  26. import javax.sip.TransactionTerminatedEvent;
  27. import javax.sip.address.*;
  28. import javax.sip.header.*;
  29. import javax.sip.message.*;
  30. import logger.OhmLogger;
  31. /**
  32. *
  33. * @author Jan komplettes Model für SIPmodel evtl. Vererbung und für jeden SIP
  34. * Response/Request eigene Klasse oder Interface da es langsam unübersichtlich
  35. * wird :( ACK schicken muss noch ergänzt werden BYE muss noch ergänzt werden.
  36. */
  37. public class SIPmodel implements SipListenerExt
  38. {
  39. Hauptfenster view; //später entfernen wegen Zugriff
  40. public static final Logger lg = OhmLogger.getLogger();
  41. public SipFactory sipFactory; // Used to access the SIP API.
  42. public SipStack sipStack; // The SIP stack.
  43. public SipProvider sipProvider; // Used to send SIP messages.
  44. public MessageFactory messageFactory; // Used to create SIP message factory.
  45. public HeaderFactory headerFactory; // Used to create SIP headers.
  46. public AddressFactory addressFactory; // Used to create SIP URIs.
  47. public ListeningPoint listeningPoint; // SIP listening IP address/port.
  48. public Properties properties; // Other properties.
  49. private String[][] codecs; //unterstütze Codecs[RTP-Parameter][CodecBezeichnung]
  50. private int myPort = 5060;
  51. private String myName = "129";
  52. public String protocolTyp = "UDP";
  53. public String myIPAddress;
  54. public String proxyAddress;
  55. public CallIdHeader callID;
  56. Boolean invite; //Bool für SDP falls ich anrufe
  57. //Hilfsvariablen wenn ich angerufen werde. evtl. noch optimieren
  58. RequestEvent evtWerdeAngerufen;
  59. Boolean werdeAngerufen;
  60. private int countWerdeAngerufen;
  61. public long cSequenz = 1;
  62. private String proxyTag;
  63. private String myTag = String.valueOf(new Random().nextInt());
  64. private int branch = Integer.valueOf(hashCode());
  65. public Address contactAddress;
  66. public ContactHeader contactHeader;
  67. public SIPmodel(Hauptfenster view) //Konstruktor für eigene Daten
  68. {
  69. this.view = view;
  70. invite = true;
  71. proxyAddress = "";
  72. countWerdeAngerufen = 0;
  73. evtWerdeAngerufen = null;
  74. werdeAngerufen = false;
  75. codecs = new String[4][2]; // Alle unterstützen Codecs eintragen
  76. codecs[0][0] = "0";
  77. codecs[0][1] = "PCMU/8000";
  78. codecs[1][0] = "4";
  79. codecs[1][1] = "G723/8000";
  80. codecs[2][0] = "8";
  81. codecs[2][1] = "PCMA/8000";
  82. codecs[3][0] = "18";
  83. codecs[3][1] = "G729/8000";
  84. try
  85. {
  86. //wird an sich erstmal nicht gebraucht aber später sinnvoll um eigene Daten zu initialisieren
  87. String abc = InetAddress.getLocalHost().getHostAddress();
  88. this.myIPAddress = InetAddress.getLocalHost().getHostAddress();
  89. this.sipFactory = SipFactory.getInstance();
  90. this.sipFactory.setPathName("gov.nist");
  91. this.properties = new Properties();
  92. this.properties.setProperty("javax.sip.STACK_NAME", "stack");
  93. this.sipStack = this.sipFactory.createSipStack(this.properties);
  94. this.messageFactory = this.sipFactory.createMessageFactory();
  95. this.headerFactory = this.sipFactory.createHeaderFactory();
  96. this.addressFactory = this.sipFactory.createAddressFactory();
  97. this.listeningPoint = this.sipStack.createListeningPoint(this.myIPAddress, this.myPort, this.protocolTyp);
  98. this.sipProvider = this.sipStack.createSipProvider(this.listeningPoint);
  99. this.sipProvider.addSipListener(this);
  100. //this.contactAddress = this.addressFactory.createAddress("sip:129@" + this.myIPAddress + ":" + this.myPort); //+ ":" + this.myPort
  101. this.contactAddress = this.addressFactory.createAddress("sip:" + myName + "@" + this.myIPAddress + ":" + this.myPort);
  102. this.contactHeader = this.headerFactory.createContactHeader(contactAddress);
  103. }
  104. catch (Exception e)
  105. {
  106. System.out.println("Fehler bei Initialisierung eigener Addresse");
  107. System.exit(-1);
  108. }
  109. }
  110. public int hashCode()
  111. {
  112. int temp = Integer.valueOf(myTag)* (new Random(100)).nextInt();
  113. return temp;
  114. }
  115. public void sendRegister(String serverIP, int serverPort) throws ParseException, InvalidArgumentException, SipException
  116. {
  117. proxyAddress = serverIP + ":" + serverPort;
  118. SIPRegister register = new SIPRegister(proxyAddress, myTag, myIPAddress, myPort, branch, addressFactory, headerFactory, messageFactory, contactHeader, sipProvider.getNewCallId());
  119. this.sipProvider.sendRequest(register.getRequest());
  120. lg.info("Erfolgreiches Senden der Registrierung");
  121. }
  122. public void sendInvitation(String sipaddresse, String proxyaddresse,
  123. int serverPort) throws SipException
  124. { //ServerPort wird nicht verwendet?
  125. invite = true;
  126. callID = this.sipProvider.getNewCallId();
  127. SIPSessionDescription sdp = new SIPSessionDescription(myName, myIPAddress, evtWerdeAngerufen, true);
  128. SIPInvite sipinvite = new SIPInvite(sipaddresse, proxyaddresse, myIPAddress, myPort, myTag, branch, callID, cSequenz, addressFactory, sdp.getSessionDescription(), headerFactory, messageFactory, contactHeader);
  129. this.sipProvider.sendRequest(sipinvite.getInviterequest());
  130. lg.info("Erfolgreiches Senden der Invitation");
  131. }
  132. @Override
  133. public void processRequest(RequestEvent requestEvent)
  134. {
  135. lg.info("Bekomme Anfrage");
  136. if ((Request.OPTIONS).equals(requestEvent.getRequest().getMethod())) //Options Anfrage von Server nach erfolgreicher Registrierung
  137. {
  138. lg.info("Option Request von Server, erstellen 200 OK zu Server");
  139. try
  140. {
  141. SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
  142. this.sipProvider.sendResponse(tempOk.getResponse());
  143. view.getTxtArea().append("Server Option Request erfolgreich beantwortet\n");
  144. lg.info("Erfolgreiches senden des 200Ok-Headers");
  145. }
  146. catch (SipException ex)
  147. {
  148. lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
  149. }
  150. }
  151. //Aktive Kommunikation
  152. else if ((Request.INVITE).equals(requestEvent.getRequest().getMethod())) // Invite von anderem Benutzer
  153. {
  154. try
  155. {
  156. this.sipProvider.sendResponse(create180Ringing(requestEvent));
  157. view.getTxtArea().append("Ringing geschickt\n");
  158. }
  159. catch (Exception ex)//Exceptions evtl. genauer definieren
  160. {
  161. lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
  162. }
  163. countWerdeAngerufen++; //bessere Lösung muss her!!, was schickt andere User oder Proxy bei nicht erreichen
  164. FromHeader abc = (FromHeader) requestEvent.getRequest().getHeader("From");
  165. evtWerdeAngerufen = requestEvent;
  166. System.out.println(countWerdeAngerufen);
  167. if (countWerdeAngerufen < 7)
  168. {
  169. werdeAngerufen = true;
  170. lg.info("Hab Invitation bekommen");
  171. view.getTxtArea().append("Werde von " + abc.getAddress() + " angerufen\n");
  172. }
  173. else
  174. {
  175. werdeAngerufen = false;
  176. lg.info("Leider waren Sie nicht erreichbar");
  177. view.getTxtArea().append("Sie waren nicht erreichbar\n");
  178. countWerdeAngerufen = 0;
  179. }
  180. }
  181. else if ((Request.ACK).equals(requestEvent.getRequest().getMethod()))
  182. {
  183. }
  184. else if ((Request.CANCEL).equals(requestEvent.getRequest().getMethod()))
  185. {
  186. view.getTxtArea().append("Anruf wurde gecancelt");
  187. try
  188. {
  189. //Cancel Request -> Response 200 Ok + Response 487 Request Terminated
  190. //200 Ok
  191. werdeAngerufen = false;
  192. evtWerdeAngerufen = null; // sicher ist sicher
  193. SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
  194. this.sipProvider.sendResponse(tempOk.getResponse());
  195. view.getTxtArea().append("Anrufender canceld Anfrage\n");
  196. lg.info("Erfolgreiches senden des 200 OkHeaders auf CancelAnfrage");
  197. //487 Request Terminated
  198. }
  199. catch (SipException ex)
  200. {
  201. Logger.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
  202. }
  203. }
  204. else if ((Request.BYE).equals(requestEvent.getRequest().getMethod()))
  205. {
  206. try
  207. {
  208. SIP200Ok tempOk = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
  209. this.sipProvider.sendResponse(tempOk.getResponse());
  210. }
  211. catch (Exception ex)
  212. {
  213. }
  214. }
  215. }
  216. @Override
  217. public void processResponse(ResponseEvent responseEvent)
  218. {
  219. System.out.println("---Response---");
  220. //System.out.println(responseEvent.getResponse());
  221. if (responseEvent.getResponse().getStatusCode() == Response.UNAUTHORIZED)
  222. {
  223. try
  224. {
  225. Address addresstob = this.addressFactory.createAddress("sip:" + myName + "@" + proxyAddress);
  226. ToHeader temp = (ToHeader) responseEvent.getResponse().getHeader("To");
  227. ToHeader to = this.headerFactory.createToHeader(addresstob, temp.getTag()); // Integer.toString(myTag) address + myTag
  228. URI requestURI = addresstob.getURI();
  229. CallIdHeader callId = (CallIdHeader) responseEvent.getResponse().getHeader("Call-ID");
  230. FromHeader from = this.headerFactory.createFromHeader(addresstob, this.myTag); //this.contactAddress
  231. WWWAuthenticateHeader wwwauth = (WWWAuthenticateHeader) responseEvent.getResponse().getHeader("WWW-Authenticate");
  232. //wird bei AuthorizationHeader wirklich alles benötigt? war glaub nur mal Test -> testen!!
  233. AuthorizationHeader auth = this.headerFactory.createAuthorizationHeader("Digest");//was kommt in den string
  234. auth.setRealm(wwwauth.getRealm());
  235. auth.setNonce(wwwauth.getNonce());
  236. //Address addresstest = this.addressFactory.createAddress("sip:" + myName + "@192.168.100.11"); //vielleicht passwort setzen "sip:"+myName+":\"\"@192.168.100.11"
  237. Address addresstest = this.addressFactory.createAddress("sip:" + myName + "@" + proxyAddress);
  238. auth.setURI(addresstest.getURI());
  239. auth.setUsername(myName);
  240. ArrayList via = new ArrayList(); //Via needs a List as input
  241. ViaHeader viaheader = this.headerFactory.createViaHeader(this.myIPAddress, this.myPort, "UDP", String.valueOf(branch + 2));// String.valueOf(hashCode())string branch
  242. via.add(viaheader);
  243. CSeqHeader cSeq = this.headerFactory.createCSeqHeader(2L, "REGISTER");
  244. MaxForwardsHeader maxForwards = this.headerFactory.createMaxForwardsHeader(70);
  245. AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE");
  246. ExpiresHeader expire = this.headerFactory.createExpiresHeader(3600); //int value
  247. //Zusätzliche Register Header nach Unauthorzied
  248. //Create Request Header
  249. Request request = this.messageFactory.createRequest(requestURI, "REGISTER", callId, cSeq, from, to, via, maxForwards);
  250. request.addHeader(contactHeader);
  251. request.addHeader(allow);
  252. request.addHeader(expire);
  253. request.addHeader(auth);
  254. this.sipProvider.sendRequest(request);
  255. view.getTxtArea().append("Erfolgreich registriert\n");
  256. }
  257. catch (ParseException | SipException | InvalidArgumentException ex)
  258. {
  259. lg.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
  260. }
  261. }
  262. else if (responseEvent.getResponse().getStatusCode() == Response.OK)
  263. {
  264. lg.info("Erfolgreichen Response (200 OK) bekommen");
  265. }
  266. else if (responseEvent.getResponse().getStatusCode() == Response.RINGING)
  267. {
  268. ToHeader temp = (ToHeader) responseEvent.getResponse().getHeader("To");
  269. proxyTag = temp.getTag();
  270. }
  271. }
  272. public Response create180Ringing(RequestEvent requestEvent) throws ParseException, SipException
  273. {
  274. Response responsering = this.messageFactory.createResponse(180, requestEvent.getRequest());
  275. responsering.addHeader((ViaHeader) requestEvent.getRequest().getHeader("Via"));
  276. responsering.addHeader((FromHeader) requestEvent.getRequest().getHeader("From"));
  277. AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE");
  278. //Bei Ringing muss persönlicher Tag ergänzt werden
  279. ToHeader temptoring = (ToHeader) requestEvent.getRequest().getHeader("To");
  280. proxyTag = temptoring.getTag();
  281. temptoring.setTag(this.myTag);
  282. responsering.addHeader(temptoring);
  283. cSequenz = ((CSeqHeader) requestEvent.getRequest().getHeader("Cseq")).getSeqNumber();
  284. responsering.addHeader((CSeqHeader) requestEvent.getRequest().getHeader("Cseq"));
  285. responsering.addHeader(contactHeader);
  286. responsering.addHeader(allow);
  287. AllowEventsHeader allowevent = this.headerFactory.createAllowEventsHeader("talk,hold,refer,call-info");// für was gebraucht
  288. responsering.addHeader(allowevent);
  289. return responsering;
  290. }
  291. public SIPmodel()
  292. {
  293. }
  294. public void annehmen() //Fehlende Bedingung
  295. {
  296. RequestEvent requestEvent;
  297. if ((requestEvent = evtWerdeAngerufen) != null && werdeAngerufen == true)
  298. {
  299. countWerdeAngerufen = 0;
  300. try
  301. {
  302. //Werte für weitere Kommunikation abspeichern
  303. callID = (CallIdHeader) requestEvent.getRequest().getHeader("Call-ID");
  304. CSeqHeader tempCs = (CSeqHeader) requestEvent.getRequest().getHeader("Cseq");
  305. cSequenz = tempCs.getSeqNumber();
  306. FromHeader tempFrom = (FromHeader) requestEvent.getRequest().getHeader("From");
  307. proxyTag = tempFrom.getTag();
  308. //Trying Header erzeugen und abschicken
  309. SIP100Trying tempTrying = new SIP100Trying(messageFactory, requestEvent, headerFactory);
  310. this.sipProvider.sendResponse(tempTrying.getTryResponse());
  311. view.getTxtArea().append("Trying geschickt\n");
  312. lg.info("Trying ist raus");
  313. //Ringing Message to Server (Responste Ringing)From tag: proxyTag, To Tag, persönlicher Tag
  314. SIP180Ringing tempRinging = new SIP180Ringing(requestEvent, myTag, proxyTag, contactHeader, headerFactory);
  315. sipProvider.sendResponse(tempRinging.getResponseRing());
  316. view.getTxtArea().append("Ringing geschickt\n");
  317. //Jetzt kommt 200 Ok SIP Header + SDP (SIP/SDP)
  318. //Sdp Header erstellen nächster Schritt
  319. invite = false;
  320. SIP200Ok respcall = new SIP200Ok(messageFactory, requestEvent, contactHeader, headerFactory);
  321. SIPSessionDescription sdp = new SIPSessionDescription(myName, myIPAddress, requestEvent, false);
  322. respcall.addSDP(sdp.getSessionDescription(), myTag);
  323. System.out.println(respcall.getResponse());
  324. this.sipProvider.sendResponse(respcall.getResponse());
  325. view.getTxtArea().append("Telefonat beginnt\n");
  326. evtWerdeAngerufen = null;
  327. }
  328. catch (SipException ex)
  329. {
  330. Logger.getLogger(SIPmodel.class.getName()).log(Level.SEVERE, null, ex);
  331. }
  332. }
  333. else
  334. {
  335. view.getTxtArea().append("Zur Zeit gibt es keinen Anruf\n");
  336. }
  337. }
  338. public void byecall(String calluser) throws ParseException, InvalidArgumentException, SipException
  339. {
  340. invite = false;
  341. Address addressLine = this.addressFactory.createAddress("sip:" + calluser + "@" + proxyAddress);
  342. URI requestURI = addressLine.getURI();
  343. Address addressfrom = this.addressFactory.createAddress("sip:" + myName + "@" + myIPAddress);
  344. FromHeader from = this.headerFactory.createFromHeader(addressfrom, String.valueOf(this.myTag));
  345. Address addressTo = this.addressFactory.createAddress("sip:" + myName + "@" + proxyAddress);
  346. ToHeader to = this.headerFactory.createToHeader(addressTo, proxyTag); // Ergänzung TAG!!
  347. ArrayList via = new ArrayList(); //Via needs a List as input
  348. ViaHeader viaheader = this.headerFactory.createViaHeader(this.myIPAddress, this.myPort, "UDP", String.valueOf(branch));
  349. via.add(viaheader);
  350. cSequenz++;
  351. CSeqHeader cSeq = this.headerFactory.createCSeqHeader(cSequenz, "BYE");
  352. MaxForwardsHeader maxForwards = this.headerFactory.createMaxForwardsHeader(70);
  353. AllowHeader allow = this.headerFactory.createAllowHeader("NOTIFY,INVITE,ACK,CANCEL,BYE,REFER,INFO,OPTIONS,MESSAGE");
  354. ExpiresHeader expire = this.headerFactory.createExpiresHeader(3600); //int value
  355. Request request = this.messageFactory.createRequest(requestURI, "BYE", callID, cSeq, from, to, via, maxForwards);
  356. request.addHeader(contactHeader);
  357. request.addHeader(allow);
  358. request.addHeader(expire);
  359. this.sipProvider.sendRequest(request);
  360. invite = false;
  361. lg.info("Erfolgreiches Senden des BYE Headers");
  362. }
  363. //Get Methoden falls man mal die Parameter braucht
  364. public String getmyName()
  365. {
  366. return myName;
  367. }
  368. public Integer getMyPort()
  369. {
  370. return myPort;
  371. }
  372. public String getMyIPAdress()
  373. {
  374. return myIPAddress;
  375. }
  376. // Herausfinden bei welchen Events die unteren Funktionen aufgerufen werden -> evtl brauchbar
  377. @Override
  378. public void processTimeout(TimeoutEvent timeoutEvent)
  379. {
  380. //view.getTxtArea().append("processTimeout\n");
  381. }
  382. @Override
  383. public void processIOException(IOExceptionEvent exceptionEvent)
  384. {
  385. //view.getTxtArea().append("processIOException\n");
  386. }
  387. @Override
  388. public void processTransactionTerminated(
  389. TransactionTerminatedEvent transactionTerminatedEvent)
  390. {
  391. //view.getTxtArea().append("processTransactionTerminated\n");
  392. }
  393. @Override
  394. public void processDialogTerminated(
  395. DialogTerminatedEvent dialogTerminatedEvent)
  396. {
  397. //view.getTxtArea().append("processDialogTerminated\n");
  398. }
  399. @Override
  400. public void processDialogTimeout(DialogTimeoutEvent timeoutEvent)
  401. {
  402. //view.getTxtArea().append("processDialogTerminated\n");
  403. }
  404. /**
  405. * @param myPort the myPort to set
  406. */
  407. public void setMyPort(int myPort)
  408. {
  409. this.myPort = myPort;
  410. }
  411. /**
  412. * @return the myName
  413. */
  414. public String getMyName()
  415. {
  416. return myName;
  417. }
  418. /**
  419. * @return the proxyTag
  420. */
  421. public String getProxyTag()
  422. {
  423. return proxyTag;
  424. }
  425. /**
  426. * @param proxyTag the proxyTag to set
  427. */
  428. public void setProxyTag(String proxyTag)
  429. {
  430. this.proxyTag = proxyTag;
  431. }
  432. /**
  433. * @return the myTag
  434. */
  435. public String getMyTag()
  436. {
  437. return myTag;
  438. }
  439. /**
  440. * @param myTag the myTag to set
  441. */
  442. public void setMyTag(String myTag)
  443. {
  444. this.myTag = myTag;
  445. }
  446. /**
  447. * @return the branch
  448. */
  449. public int getBranch()
  450. {
  451. return branch;
  452. }
  453. }