/**
   * Sets the values of the properties of a specific <tt>ColibriConferenceIQ</tt> to the values of
   * the respective properties of this instance. Thus, the specified <tt>iq</tt> may be thought of
   * as a description of this instance.
   *
   * <p><b>Note</b>: The copying of the values is deep i.e. the <tt>Contents</tt>s of this instance
   * are described in the specified <tt>iq</tt>.
   *
   * @param iq the <tt>ColibriConferenceIQ</tt> to set the values of the properties of this instance
   *     on
   */
  public void describeDeep(ColibriConferenceIQ iq) {
    describeShallow(iq);

    if (isRecording()) {
      ColibriConferenceIQ.Recording recordingIQ =
          new ColibriConferenceIQ.Recording(State.ON.toString());
      recordingIQ.setDirectory(getRecordingDirectory());
      iq.setRecording(recordingIQ);
    }
    for (Content content : getContents()) {
      ColibriConferenceIQ.Content contentIQ = iq.getOrCreateContent(content.getName());

      for (Channel channel : content.getChannels()) {
        if (channel instanceof SctpConnection) {
          ColibriConferenceIQ.SctpConnection sctpConnectionIQ =
              new ColibriConferenceIQ.SctpConnection();

          channel.describe(sctpConnectionIQ);
          contentIQ.addSctpConnection(sctpConnectionIQ);
        } else {
          ColibriConferenceIQ.Channel channelIQ = new ColibriConferenceIQ.Channel();

          channel.describe(channelIQ);
          contentIQ.addChannel(channelIQ);
        }
      }
    }
  }
Пример #2
0
  /**
   * Processes channels allocation response from the JVB and stores info about new channels in
   * {@link #conferenceState}.
   *
   * @param allocateResponse the Colibri IQ that describes JVB response to allocate request.
   */
  public void processChannelAllocResp(ColibriConferenceIQ allocateResponse) {
    String conferenceResponseID = allocateResponse.getID();
    String colibriID = conferenceState.getID();

    if (colibriID == null) conferenceState.setID(conferenceResponseID);
    else if (!colibriID.equals(conferenceResponseID))
      throw new IllegalStateException("conference.id");

    /*
     * XXX We must remember the JID of the Jitsi Videobridge because
     * (1) we do not want to re-discover it in every method
     * invocation on this Call instance and (2) we want to use one
     * and the same for all CallPeers within this Call instance.
     */
    conferenceState.setFrom(allocateResponse.getFrom());

    for (ColibriConferenceIQ.Content contentResponse : allocateResponse.getContents()) {
      String contentName = contentResponse.getName();
      ColibriConferenceIQ.Content content = conferenceState.getOrCreateContent(contentName);

      // FIXME: we do not check if allocated channel does not clash
      // with any existing one
      for (ColibriConferenceIQ.Channel channelResponse : contentResponse.getChannels()) {
        content.addChannel(channelResponse);
      }
      for (ColibriConferenceIQ.SctpConnection sctpConnResponse :
          contentResponse.getSctpConnections()) {
        content.addSctpConnection(sctpConnResponse);
      }
    }

    for (ColibriConferenceIQ.ChannelBundle bundle : allocateResponse.getChannelBundles()) {
      conferenceState.addChannelBundle(bundle);
    }
  }
Пример #3
0
  /**
   * Utility method for extracting info about channels allocated from JVB response. FIXME: this
   * might not work as expected when channels for multiple peers with single query were allocated.
   *
   * @param conferenceResponse JVB response to allocate channels request.
   * @param peerContents list of peer media contents that has to be matched with allocated channels.
   * @return the Colibri IQ that describes allocated channels.
   */
  public static ColibriConferenceIQ getResponseContents(
      ColibriConferenceIQ conferenceResponse, List<ContentPacketExtension> peerContents) {
    ColibriConferenceIQ conferenceResult = new ColibriConferenceIQ();

    conferenceResult.setFrom(conferenceResponse.getFrom());
    conferenceResult.setID(conferenceResponse.getID());

    // FIXME: we support single bundle for all channels
    String bundleId = null;
    for (ContentPacketExtension content : peerContents) {
      MediaType mediaType = JingleUtils.getMediaType(content);

      ColibriConferenceIQ.Content contentResponse =
          conferenceResponse.getContent(mediaType.toString());

      if (contentResponse != null) {
        String contentName = contentResponse.getName();
        ColibriConferenceIQ.Content contentResult = new ColibriConferenceIQ.Content(contentName);

        conferenceResult.addContent(contentResult);

        for (ColibriConferenceIQ.Channel channelResponse : contentResponse.getChannels()) {
          contentResult.addChannel(channelResponse);

          bundleId = readChannelBundle(channelResponse, bundleId);
        }

        for (ColibriConferenceIQ.SctpConnection sctpConnResponse :
            contentResponse.getSctpConnections()) {
          contentResult.addSctpConnection(sctpConnResponse);

          bundleId = readChannelBundle(sctpConnResponse, bundleId);
        }
      }
    }

    // Copy only peer's bundle(JVB returns all bundles)
    if (bundleId != null) {
      for (ColibriConferenceIQ.ChannelBundle bundle : conferenceResponse.getChannelBundles()) {
        if (bundleId.equals(bundle.getId())) {
          conferenceResult.addChannelBundle(bundle);
          break;
        }
      }
    }

    return conferenceResult;
  }
  /**
   * Adds the channel-bundles of this <tt>Conference</tt> as
   * <tt>ColibriConferenceIQ.ChannelBundle</tt> instances in <tt>iq</tt>.
   *
   * @param iq the <tt>ColibriConferenceIQ</tt> in which to describe.
   */
  void describeChannelBundles(ColibriConferenceIQ iq) {
    synchronized (transportManagers) {
      for (Map.Entry<String, IceUdpTransportManager> entry : transportManagers.entrySet()) {
        ColibriConferenceIQ.ChannelBundle responseBundleIQ =
            new ColibriConferenceIQ.ChannelBundle(entry.getKey());

        entry.getValue().describe(responseBundleIQ);
        iq.addChannelBundle(responseBundleIQ);
      }
    }
  }
  /**
   * Notifies this instance that a specific <tt>ColibriConferenceIQ</tt> has been received.
   *
   * @param conferenceIQ the <tt>ColibriConferenceIQ</tt> which has been received
   */
  private void processColibriConferenceIQ(ColibriConferenceIQ conferenceIQ) {
    /*
     * The application is not a Jitsi Videobridge server, it is a client.
     * Consequently, the specified ColibriConferenceIQ is sent to it in
     * relation to the part of the application's functionality which makes
     * requests to a Jitsi Videobridge server i.e. CallJabberImpl.
     *
     * Additionally, the method processColibriConferenceIQ is presently tasked
     * with processing ColibriConferenceIQ requests only. They are SET IQs
     * sent by the Jitsi Videobridge server to notify the application about
     * updates in the states of (colibri) conferences organized by the
     * application.
     */
    if (IQ.Type.SET.equals(conferenceIQ.getType()) && conferenceIQ.getID() != null) {
      OperationSetBasicTelephony<?> basicTelephony =
          protocolProvider.getOperationSet(OperationSetBasicTelephony.class);

      if (basicTelephony != null) {
        Iterator<? extends Call> i = basicTelephony.getActiveCalls();

        while (i.hasNext()) {
          Call call = i.next();

          if (call instanceof CallJabberImpl) {
            CallJabberImpl callJabberImpl = (CallJabberImpl) call;
            MediaAwareCallConference conference = callJabberImpl.getConference();

            if ((conference != null) && conference.isJitsiVideobridge()) {
              /*
               * TODO We may want to disallow rogue CallJabberImpl
               * instances which may throw an exception to prevent
               * the conferenceIQ from reaching the CallJabberImpl
               * instance which it was meant for.
               */
              if (callJabberImpl.processColibriConferenceIQ(conferenceIQ)) break;
            }
          }
        }
      }
    }
  }
 /**
  * Sets the values of the properties of a specific <tt>ColibriConferenceIQ</tt> to the values of
  * the respective properties of this instance. Thus, the specified <tt>iq</tt> may be thought of
  * as a description of this instance.
  *
  * <p><b>Note</b>: The copying of the values is shallow i.e. the <tt>Content</tt>s of this
  * instance are not described in the specified <tt>iq</tt>.
  *
  * @param iq the <tt>ColibriConferenceIQ</tt> to set the values of the properties of this instance
  *     on
  */
 public void describeShallow(ColibriConferenceIQ iq) {
   iq.setID(getID());
   iq.setName(getName());
 }
Пример #7
0
  private void handleColibriIq(ColibriConferenceIQ colibriIQ) {
    ColibriConferenceIQ.Recording recording = colibriIQ.getRecording();
    String from = colibriIQ.getFrom();
    JitsiMeetConference conference = getConferenceForMucJid(colibriIQ.getFrom());
    if (conference == null) {
      logger.debug("Room not found for JID: " + from);
      return;
    }

    JitsiMeetRecording recordingHandler = conference.getRecording();
    if (recordingHandler == null) {
      logger.error("JitsiMeetRecording is null for iq: " + colibriIQ.toXML());

      // Internal server error
      smackXmpp
          .getXmppConnection()
          .sendPacket(
              IQ.createErrorResponse(
                  colibriIQ, new XMPPError(XMPPError.Condition.interna_server_error)));
      return;
    }

    State recordingState =
        recordingHandler.modifyRecordingState(
            colibriIQ.getFrom(),
            recording.getToken(),
            recording.getState(),
            recording.getDirectory(),
            colibriIQ.getTo());

    ColibriConferenceIQ response = new ColibriConferenceIQ();

    response.setType(IQ.Type.RESULT);
    response.setPacketID(colibriIQ.getPacketID());
    response.setTo(colibriIQ.getFrom());
    response.setFrom(colibriIQ.getTo());
    response.setName(colibriIQ.getName());

    response.setRecording(new ColibriConferenceIQ.Recording(recordingState));

    smackXmpp.getXmppConnection().sendPacket(response);
  }