JingleUtil.java

  1. /**
  2.  *
  3.  * Copyright 2017 Paul Schaub
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.jingle;

  18. import org.jivesoftware.smack.SmackException;
  19. import org.jivesoftware.smack.SmackException.NoResponseException;
  20. import org.jivesoftware.smack.XMPPConnection;
  21. import org.jivesoftware.smack.XMPPException;
  22. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  23. import org.jivesoftware.smack.packet.IQ;
  24. import org.jivesoftware.smack.packet.StanzaError;

  25. import org.jivesoftware.smackx.jingle.element.Jingle;
  26. import org.jivesoftware.smackx.jingle.element.JingleAction;
  27. import org.jivesoftware.smackx.jingle.element.JingleContent;
  28. import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
  29. import org.jivesoftware.smackx.jingle.element.JingleContentTransport;
  30. import org.jivesoftware.smackx.jingle.element.JingleError;
  31. import org.jivesoftware.smackx.jingle.element.JingleReason;

  32. import org.jxmpp.jid.FullJid;

  33. /**
  34.  * Util to quickly create and send jingle stanzas.
  35.  */
  36. public class JingleUtil {

  37.     private final XMPPConnection connection;

  38.     public JingleUtil(XMPPConnection connection) {
  39.         this.connection = connection;
  40.     }

  41.     public Jingle createSessionInitiate(FullJid recipient,
  42.                                         String sessionId,
  43.                                         JingleContent.Creator contentCreator,
  44.                                         String contentName,
  45.                                         JingleContent.Senders contentSenders,
  46.                                         JingleContentDescription description,
  47.                                         JingleContentTransport transport) {

  48.         Jingle.Builder jb = Jingle.builder(connection);
  49.         jb.setAction(JingleAction.session_initiate)
  50.                 .setSessionId(sessionId)
  51.                 .setInitiator(connection.getUser());

  52.         JingleContent.Builder cb = JingleContent.getBuilder();
  53.         cb.setCreator(contentCreator)
  54.                 .setName(contentName)
  55.                 .setSenders(contentSenders)
  56.                 .setDescription(description)
  57.                 .setTransport(transport);

  58.         Jingle jingle = jb.addJingleContent(cb.build()).build();
  59.         jingle.setFrom(connection.getUser());
  60.         jingle.setTo(recipient);

  61.         return jingle;
  62.     }

  63.     public Jingle createSessionInitiateFileOffer(FullJid recipient,
  64.                                                  String sessionId,
  65.                                                  JingleContent.Creator contentCreator,
  66.                                                  String contentName,
  67.                                                  JingleContentDescription description,
  68.                                                  JingleContentTransport transport) {
  69.         return createSessionInitiate(recipient, sessionId, contentCreator, contentName,
  70.                 JingleContent.Senders.initiator, description, transport);
  71.     }

  72.     public IQ sendSessionInitiateFileOffer(FullJid recipient,
  73.                                            String sessionId,
  74.                                            JingleContent.Creator contentCreator,
  75.                                            String contentName,
  76.                                            JingleContentDescription description,
  77.                                            JingleContentTransport transport)
  78.             throws SmackException.NotConnectedException, InterruptedException,
  79.             XMPPException.XMPPErrorException, SmackException.NoResponseException {

  80.         Jingle jingle = createSessionInitiateFileOffer(recipient, sessionId, contentCreator, contentName, description, transport);
  81.         return connection.sendIqRequestAndWaitForResponse(jingle);
  82.     }

  83.     public IQ sendSessionInitiate(FullJid recipient,
  84.                                   String sessionId,
  85.                                   JingleContent.Creator contentCreator,
  86.                                   String contentName,
  87.                                   JingleContent.Senders contentSenders,
  88.                                   JingleContentDescription description,
  89.                                   JingleContentTransport transport)
  90.             throws SmackException.NotConnectedException, InterruptedException, NoResponseException, XMPPErrorException {

  91.         Jingle jingle = createSessionInitiate(recipient, sessionId, contentCreator, contentName, contentSenders,
  92.                 description, transport);

  93.         return connection.sendIqRequestAndWaitForResponse(jingle);
  94.     }

  95.     public Jingle createSessionAccept(FullJid recipient,
  96.                                       String sessionId,
  97.                                       JingleContent.Creator contentCreator,
  98.                                       String contentName,
  99.                                       JingleContent.Senders contentSenders,
  100.                                       JingleContentDescription description,
  101.                                       JingleContentTransport transport) {

  102.         Jingle.Builder jb = Jingle.builder(connection);
  103.         jb.setResponder(connection.getUser())
  104.                 .setAction(JingleAction.session_accept)
  105.                 .setSessionId(sessionId);

  106.         JingleContent.Builder cb = JingleContent.getBuilder();
  107.         cb.setCreator(contentCreator)
  108.                 .setName(contentName)
  109.                 .setSenders(contentSenders)
  110.                 .setDescription(description)
  111.                 .setTransport(transport);

  112.         Jingle jingle = jb.addJingleContent(cb.build()).build();
  113.         jingle.setTo(recipient);
  114.         jingle.setFrom(connection.getUser());

  115.         return jingle;
  116.     }

  117.     public IQ sendSessionAccept(FullJid recipient,
  118.                                 String sessionId,
  119.                                 JingleContent.Creator contentCreator,
  120.                                 String contentName,
  121.                                 JingleContent.Senders contentSenders,
  122.                                 JingleContentDescription description,
  123.                                 JingleContentTransport transport)
  124.             throws SmackException.NotConnectedException, InterruptedException, NoResponseException, XMPPErrorException {

  125.         Jingle jingle = createSessionAccept(recipient, sessionId, contentCreator, contentName, contentSenders,
  126.                 description, transport);

  127.         return connection.sendIqRequestAndWaitForResponse(jingle);
  128.     }

  129.     public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason reason) {
  130.         Jingle.Builder jb = Jingle.builder(connection);
  131.         jb.setAction(JingleAction.session_terminate)
  132.                 .setSessionId(sessionId)
  133.                 .setReason(reason);

  134.         Jingle jingle = jb.build();
  135.         jingle.setFrom(connection.getUser());
  136.         jingle.setTo(recipient);

  137.         return jingle;
  138.     }

  139.     public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason.Reason reason) {
  140.         return createSessionTerminate(recipient, sessionId, new JingleReason(reason));
  141.     }

  142.     public Jingle createSessionTerminateDecline(FullJid recipient, String sessionId) {
  143.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.decline);
  144.     }

  145.     public IQ sendSessionTerminateDecline(FullJid recipient, String sessionId)
  146.             throws SmackException.NotConnectedException, InterruptedException,
  147.             XMPPException.XMPPErrorException, SmackException.NoResponseException {

  148.         Jingle jingle = createSessionTerminateDecline(recipient, sessionId);
  149.         return connection.sendIqRequestAndWaitForResponse(jingle);
  150.     }

  151.     public Jingle createSessionTerminateSuccess(FullJid recipient, String sessionId) {
  152.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.success);
  153.     }

  154.     public IQ sendSessionTerminateSuccess(FullJid recipient, String sessionId)
  155.             throws InterruptedException, XMPPException.XMPPErrorException,
  156.             SmackException.NotConnectedException, SmackException.NoResponseException {

  157.         Jingle jingle = createSessionTerminateSuccess(recipient, sessionId);
  158.         return connection.sendIqRequestAndWaitForResponse(jingle);
  159.     }

  160.     public Jingle createSessionTerminateBusy(FullJid recipient, String sessionId) {
  161.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.busy);
  162.     }

  163.     public IQ sendSessionTerminateBusy(FullJid recipient, String sessionId)
  164.             throws InterruptedException, XMPPException.XMPPErrorException,
  165.             SmackException.NotConnectedException, SmackException.NoResponseException {

  166.         Jingle jingle = createSessionTerminateBusy(recipient, sessionId);
  167.         return connection.sendIqRequestAndWaitForResponse(jingle);
  168.     }

  169.     public Jingle createSessionTerminateAlternativeSession(FullJid recipient, String sessionId, String altSessionId) {
  170.         return createSessionTerminate(recipient, sessionId, JingleReason.AlternativeSession(altSessionId));
  171.     }

  172.     public IQ sendSessionTerminateAlternativeSession(FullJid recipient, String sessionId, String altSessionId)
  173.             throws InterruptedException, XMPPException.XMPPErrorException,
  174.             SmackException.NotConnectedException, SmackException.NoResponseException {

  175.         Jingle jingle = createSessionTerminateAlternativeSession(recipient, sessionId, altSessionId);
  176.         return connection.sendIqRequestAndWaitForResponse(jingle);
  177.     }

  178.     public Jingle createSessionTerminateCancel(FullJid recipient, String sessionId) {
  179.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.cancel);
  180.     }

  181.     public IQ sendSessionTerminateCancel(FullJid recipient,
  182.                                   String sessionId)
  183.             throws InterruptedException, XMPPException.XMPPErrorException,
  184.             SmackException.NotConnectedException, SmackException.NoResponseException {

  185.         Jingle jingle = createSessionTerminateCancel(recipient, sessionId);
  186.         return connection.sendIqRequestAndWaitForResponse(jingle);
  187.     }

  188.     public Jingle createSessionTerminateContentCancel(FullJid recipient, String sessionId,
  189.                                                       JingleContent.Creator contentCreator, String contentName) {
  190.         Jingle.Builder jb = Jingle.builder(connection);
  191.         jb.setAction(JingleAction.session_terminate)
  192.                 .setSessionId(sessionId);

  193.         JingleContent.Builder cb = JingleContent.getBuilder();
  194.         cb.setCreator(contentCreator).setName(contentName);

  195.         Jingle jingle = jb.addJingleContent(cb.build()).build();
  196.         jingle.setFrom(connection.getUser());
  197.         jingle.setTo(recipient);

  198.         return jingle;
  199.     }

  200.     public IQ sendSessionTerminateContentCancel(FullJid recipient, String sessionId,
  201.                                   JingleContent.Creator contentCreator, String contentName)
  202.             throws SmackException.NotConnectedException, InterruptedException,
  203.             XMPPException.XMPPErrorException, SmackException.NoResponseException {
  204.         Jingle jingle = createSessionTerminateContentCancel(recipient, sessionId, contentCreator, contentName);
  205.         return connection.sendIqRequestAndWaitForResponse(jingle);
  206.     }

  207.     public Jingle createSessionTerminateUnsupportedTransports(FullJid recipient, String sessionId) {
  208.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.unsupported_transports);
  209.     }

  210.     public IQ sendSessionTerminateUnsupportedTransports(FullJid recipient, String sessionId)
  211.             throws InterruptedException, XMPPException.XMPPErrorException,
  212.             SmackException.NotConnectedException, SmackException.NoResponseException {
  213.         Jingle jingle = createSessionTerminateUnsupportedTransports(recipient, sessionId);
  214.         return connection.sendIqRequestAndWaitForResponse(jingle);
  215.     }

  216.     public Jingle createSessionTerminateFailedTransport(FullJid recipient, String sessionId) {
  217.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.failed_transport);
  218.     }

  219.     public IQ sendSessionTerminateFailedTransport(FullJid recipient, String sessionId)
  220.             throws InterruptedException, XMPPException.XMPPErrorException,
  221.             SmackException.NotConnectedException, SmackException.NoResponseException {
  222.         Jingle jingle = createSessionTerminateFailedTransport(recipient, sessionId);
  223.         return connection.sendIqRequestAndWaitForResponse(jingle);
  224.     }

  225.     public Jingle createSessionTerminateUnsupportedApplications(FullJid recipient, String sessionId) {
  226.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.unsupported_applications);
  227.     }

  228.     public IQ sendSessionTerminateUnsupportedApplications(FullJid recipient, String sessionId)
  229.             throws InterruptedException, XMPPException.XMPPErrorException,
  230.             SmackException.NotConnectedException, SmackException.NoResponseException {
  231.         Jingle jingle = createSessionTerminateUnsupportedApplications(recipient, sessionId);
  232.         return connection.sendIqRequestAndWaitForResponse(jingle);
  233.     }

  234.     public Jingle createSessionTerminateFailedApplication(FullJid recipient, String sessionId) {
  235.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.failed_application);
  236.     }

  237.     public IQ sendSessionTerminateFailedApplication(FullJid recipient, String sessionId)
  238.             throws InterruptedException, XMPPException.XMPPErrorException,
  239.             SmackException.NotConnectedException, SmackException.NoResponseException {
  240.         Jingle jingle = createSessionTerminateFailedApplication(recipient, sessionId);
  241.         return connection.sendIqRequestAndWaitForResponse(jingle);
  242.     }

  243.     public Jingle createSessionTerminateIncompatibleParameters(FullJid recipient, String sessionId) {
  244.         return createSessionTerminate(recipient, sessionId, JingleReason.Reason.incompatible_parameters);
  245.     }

  246.     public IQ sendSessionTerminateIncompatibleParameters(FullJid recipient, String sessionId)
  247.             throws InterruptedException, XMPPException.XMPPErrorException,
  248.             SmackException.NotConnectedException, SmackException.NoResponseException {
  249.         Jingle jingle = createSessionTerminateIncompatibleParameters(recipient, sessionId);
  250.         return connection.sendIqRequestAndWaitForResponse(jingle);
  251.     }

  252.     public IQ sendContentRejectFileNotAvailable(FullJid recipient, String sessionId, JingleContentDescription description) {
  253.         return null; //TODO Later
  254.     }

  255.     public Jingle createSessionPing(FullJid recipient, String sessionId) {
  256.         Jingle.Builder jb = Jingle.builder(connection);
  257.         jb.setSessionId(sessionId)
  258.                 .setAction(JingleAction.session_info);

  259.         Jingle jingle = jb.build();
  260.         jingle.setFrom(connection.getUser());
  261.         jingle.setTo(recipient);

  262.         return jingle;
  263.     }

  264.     public IQ sendSessionPing(FullJid recipient, String sessionId)
  265.             throws SmackException.NotConnectedException, InterruptedException,
  266.             XMPPException.XMPPErrorException, SmackException.NoResponseException {
  267.         Jingle jingle = createSessionPing(recipient, sessionId);
  268.         return connection.sendIqRequestAndWaitForResponse(jingle);
  269.     }

  270.     public IQ createAck(Jingle jingle) {
  271.         return IQ.createResultIQ(jingle);
  272.     }

  273.     public void sendAck(Jingle jingle) throws SmackException.NotConnectedException, InterruptedException {
  274.         connection.sendStanza(createAck(jingle));
  275.     }

  276.     public Jingle createTransportReplace(FullJid recipient, FullJid initiator, String sessionId,
  277.                                          JingleContent.Creator contentCreator, String contentName,
  278.                                          JingleContentTransport transport) {
  279.         Jingle.Builder jb = Jingle.builder(connection);
  280.         jb.setInitiator(initiator)
  281.                 .setSessionId(sessionId)
  282.                 .setAction(JingleAction.transport_replace);

  283.         JingleContent.Builder cb = JingleContent.getBuilder();
  284.         cb.setName(contentName).setCreator(contentCreator).setTransport(transport);
  285.         Jingle jingle = jb.addJingleContent(cb.build()).build();

  286.         jingle.setTo(recipient);
  287.         jingle.setFrom(connection.getUser());

  288.         return jingle;
  289.     }

  290.     public IQ sendTransportReplace(FullJid recipient, FullJid initiator, String sessionId,
  291.                                    JingleContent.Creator contentCreator, String contentName,
  292.                                    JingleContentTransport transport)
  293.             throws SmackException.NotConnectedException, InterruptedException,
  294.             XMPPException.XMPPErrorException, SmackException.NoResponseException {
  295.         Jingle jingle = createTransportReplace(recipient, initiator, sessionId, contentCreator, contentName, transport);
  296.         return connection.sendIqRequestAndWaitForResponse(jingle);
  297.     }

  298.     public Jingle createTransportAccept(FullJid recipient, FullJid initiator, String sessionId,
  299.                                         JingleContent.Creator contentCreator, String contentName,
  300.                                         JingleContentTransport transport) {
  301.         Jingle.Builder jb = Jingle.builder(connection);
  302.         jb.setAction(JingleAction.transport_accept)
  303.                 .setInitiator(initiator)
  304.                 .setSessionId(sessionId);

  305.         JingleContent.Builder cb = JingleContent.getBuilder();
  306.         cb.setCreator(contentCreator).setName(contentName).setTransport(transport);

  307.         Jingle jingle = jb.addJingleContent(cb.build()).build();
  308.         jingle.setTo(recipient);
  309.         jingle.setFrom(connection.getUser());

  310.         return jingle;
  311.     }

  312.     public IQ sendTransportAccept(FullJid recipient, FullJid initiator, String sessionId,
  313.                                   JingleContent.Creator contentCreator, String contentName,
  314.                                   JingleContentTransport transport)
  315.             throws SmackException.NotConnectedException, InterruptedException,
  316.             XMPPException.XMPPErrorException, SmackException.NoResponseException {
  317.         Jingle jingle = createTransportAccept(recipient, initiator, sessionId, contentCreator, contentName, transport);
  318.         return connection.sendIqRequestAndWaitForResponse(jingle);
  319.     }

  320.     public Jingle createTransportReject(FullJid recipient, FullJid initiator, String sessionId,
  321.                                         JingleContent.Creator contentCreator, String contentName,
  322.                                         JingleContentTransport transport) {
  323.         Jingle.Builder jb = Jingle.builder(connection);
  324.         jb.setAction(JingleAction.transport_reject)
  325.                 .setInitiator(initiator)
  326.                 .setSessionId(sessionId);

  327.         JingleContent.Builder cb = JingleContent.getBuilder();
  328.         cb.setCreator(contentCreator).setName(contentName).setTransport(transport);

  329.         Jingle jingle = jb.addJingleContent(cb.build()).build();
  330.         jingle.setTo(recipient);
  331.         jingle.setFrom(connection.getUser());

  332.         return jingle;
  333.     }

  334.     public IQ sendTransportReject(FullJid recipient, FullJid initiator, String sessionId,
  335.                                   JingleContent.Creator contentCreator, String contentName,
  336.                                   JingleContentTransport transport)
  337.             throws SmackException.NotConnectedException, InterruptedException,
  338.             XMPPException.XMPPErrorException, SmackException.NoResponseException {
  339.         Jingle jingle = createTransportReject(recipient, initiator, sessionId, contentCreator, contentName, transport);
  340.         return connection.sendIqRequestAndWaitForResponse(jingle);
  341.     }

  342.     /*
  343.      * ####################################################################################################
  344.      */

  345.     public IQ createErrorUnknownSession(Jingle request) {
  346.         StanzaError error = StanzaError.getBuilder()
  347.                         .setCondition(StanzaError.Condition.item_not_found)
  348.                         .addExtension(JingleError.UNKNOWN_SESSION)
  349.                         .build();
  350.         return IQ.createErrorResponse(request, error);
  351.     }

  352.     public void sendErrorUnknownSession(Jingle request)
  353.             throws SmackException.NotConnectedException, InterruptedException {
  354.         connection.sendStanza(createErrorUnknownSession(request));
  355.     }

  356.     public IQ createErrorUnknownInitiator(Jingle request) {
  357.         return IQ.createErrorResponse(request, StanzaError.Condition.service_unavailable);
  358.     }

  359.     public void sendErrorUnknownInitiator(Jingle request)
  360.             throws SmackException.NotConnectedException, InterruptedException {
  361.         connection.sendStanza(createErrorUnknownInitiator(request));
  362.     }

  363.     public IQ createErrorUnsupportedInfo(Jingle request) {
  364.         StanzaError error = StanzaError.getBuilder()
  365.                         .setCondition(StanzaError.Condition.feature_not_implemented)
  366.                         .addExtension(JingleError.UNSUPPORTED_INFO)
  367.                         .build();
  368.         return IQ.createErrorResponse(request, error);
  369.     }

  370.     public void sendErrorUnsupportedInfo(Jingle request)
  371.             throws SmackException.NotConnectedException, InterruptedException {
  372.         connection.sendStanza(createErrorUnsupportedInfo(request));
  373.     }

  374.     public IQ createErrorTieBreak(Jingle request) {
  375.         StanzaError error = StanzaError.getBuilder()
  376.                         .setCondition(StanzaError.Condition.conflict)
  377.                         .addExtension(JingleError.TIE_BREAK)
  378.                         .build();
  379.         return IQ.createErrorResponse(request, error);
  380.     }

  381.     public void sendErrorTieBreak(Jingle request)
  382.             throws SmackException.NotConnectedException, InterruptedException {
  383.         connection.sendStanza(createErrorTieBreak(request));
  384.     }

  385.     public IQ createErrorOutOfOrder(Jingle request) {
  386.         StanzaError error = StanzaError.getBuilder()
  387.                         .setCondition(StanzaError.Condition.unexpected_request)
  388.                         .addExtension(JingleError.OUT_OF_ORDER)
  389.                         .build();
  390.         return IQ.createErrorResponse(request, error);
  391.     }

  392.     public void sendErrorOutOfOrder(Jingle request)
  393.             throws SmackException.NotConnectedException, InterruptedException {
  394.         connection.sendStanza(createErrorOutOfOrder(request));
  395.     }

  396.     public IQ createErrorMalformedRequest(Jingle request) {
  397.         return IQ.createErrorResponse(request, StanzaError.Condition.bad_request);
  398.     }

  399.     public void sendErrorMalformedRequest(Jingle request)
  400.             throws SmackException.NotConnectedException, InterruptedException {
  401.         connection.sendStanza(createErrorMalformedRequest(request));
  402.     }
  403. }