Пример #1
0
  /**
   * Returns a list containing all <tt>crypto</tt> sub-elements.
   *
   * @return a {@link List} containing all our <tt>crypto</tt> sub-elements.
   */
  @Override
  public List<? extends PacketExtension> getChildExtensions() {
    List<PacketExtension> ret = new ArrayList<PacketExtension>();

    ret.addAll(super.getChildExtensions());
    return ret;
  }
    /**
     * Adds a <tt>payload-type</tt> element defined by XEP-0167: Jingle RTP Sessions to this
     * <tt>channel</tt>.
     *
     * @param payloadType the <tt>payload-type</tt> element to be added to this <tt>channel</tt>
     * @return <tt>true</tt> if the list of <tt>payload-type</tt> elements associated with this
     *     <tt>channel</tt> has been modified as part of the method call; otherwise, <tt>false</tt>
     * @throws NullPointerException if the specified <tt>payloadType</tt> is <tt>null</tt>
     */
    public boolean addPayloadType(PayloadTypePacketExtension payloadType) {
      if (payloadType == null) throw new NullPointerException("payloadType");

      // Make sure that the COLIBRI namespace is used.
      payloadType.setNamespace(null);
      for (ParameterPacketExtension p : payloadType.getParameters()) p.setNamespace(null);

      return payloadTypes.contains(payloadType) ? false : payloadTypes.add(payloadType);
    }
Пример #3
0
  /**
   * Process candidates received.
   *
   * @param sessionInitIQ The {@link SessionIQ} that created the session we are handling here
   */
  public void processCandidates(SessionIQ sessionInitIQ) {
    Collection<PacketExtension> extensions = sessionInitIQ.getExtensions();
    List<GTalkCandidatePacketExtension> candidates = new ArrayList<GTalkCandidatePacketExtension>();

    for (PacketExtension ext : extensions) {
      if (ext.getElementName().equalsIgnoreCase(GTalkCandidatePacketExtension.ELEMENT_NAME)) {
        GTalkCandidatePacketExtension cand = (GTalkCandidatePacketExtension) ext;
        candidates.add(cand);
      }
    }

    try {
      getMediaHandler().processCandidates(candidates);
    } catch (OperationFailedException ofe) {
      logger.warn("Failed to process an incoming candidates", ofe);

      // send an error response
      String reasonText = "Error: " + ofe.getMessage();
      SessionIQ errResp =
          GTalkPacketFactory.createSessionTerminate(
              sessionInitIQ.getTo(),
              sessionInitIQ.getFrom(),
              sessionInitIQ.getID(),
              Reason.GENERAL_ERROR,
              reasonText);

      getMediaHandler().getTransportManager().close();
      setState(CallPeerState.FAILED, reasonText);
      getProtocolProvider().getConnection().sendPacket(errResp);
      return;
    }

    // HACK for FreeSwitch that send accept message before sending
    // candidates
    if (sessAcceptedWithNoCands != null) {
      if (isInitiator()) {
        try {
          answer();
        } catch (OperationFailedException e) {
          logger.info("Failed to answer call (FreeSwitch hack)");
        }
      } else {
        final SessionIQ sess = sessAcceptedWithNoCands;
        sessAcceptedWithNoCands = null;

        // run in another thread to not block smack receive thread and
        // possibly delay others candidates messages.
        new Thread() {
          @Override
          public void run() {
            processSessionAccept(sess);
          }
        }.start();
      }
      sessAcceptedWithNoCands = null;
    }
  }
    @Override
    protected boolean hasContent() {
      List<PayloadTypePacketExtension> payloadTypes = getPayloadTypes();
      boolean hasPayloadTypes = !payloadTypes.isEmpty();
      List<SourcePacketExtension> sources = getSources();
      boolean hasSources = !sources.isEmpty();
      int[] ssrcs = getSSRCs();
      boolean hasSSRCs = (ssrcs.length != 0);

      return hasPayloadTypes || hasSources || hasSSRCs;
    }
  /**
   * Creates an instance of this operation set.
   *
   * @param provider a reference to the <tt>ProtocolProviderServiceImpl</tt> that created us and
   *     that we'll use for retrieving the underlying aim connection.
   */
  OperationSetBasicInstantMessagingJabberImpl(ProtocolProviderServiceJabberImpl provider) {
    this.jabberProvider = provider;

    packetFilters.add(new GroupMessagePacketFilter());
    packetFilters.add(new PacketTypeFilter(org.jivesoftware.smack.packet.Message.class));

    provider.addRegistrationStateChangeListener(new RegistrationStateListener());

    ProviderManager man = ProviderManager.getInstance();
    MessageCorrectionExtensionProvider extProvider = new MessageCorrectionExtensionProvider();
    man.addExtensionProvider(
        MessageCorrectionExtension.ELEMENT_NAME, MessageCorrectionExtension.NAMESPACE, extProvider);
  }
Пример #6
0
 /**
  * Removes a specific <tt>UserCapsNodeListener</tt> from the list of
  * <tt>UserCapsNodeListener</tt>s interested in events notifying about changes in the list of user
  * caps nodes of this <tt>EntityCapsManager</tt>.
  *
  * @param listener the <tt>UserCapsNodeListener</tt> which is no longer interested in events
  *     notifying about changes in the list of user caps nodes of this <tt>EntityCapsManager</tt>
  */
 public void removeUserCapsNodeListener(UserCapsNodeListener listener) {
   if (listener != null) {
     synchronized (userCapsNodeListeners) {
       userCapsNodeListeners.remove(listener);
     }
   }
 }
Пример #7
0
  /**
   * Remove records telling what entity caps node a contact has.
   *
   * @param contact the contact
   */
  public void removeContactCapsNode(Contact contact) {
    Caps caps = null;
    String lastRemovedJid = null;

    Iterator<String> iter = userCaps.keySet().iterator();
    while (iter.hasNext()) {
      String jid = iter.next();

      if (StringUtils.parseBareAddress(jid).equals(contact.getAddress())) {
        caps = userCaps.get(jid);
        lastRemovedJid = jid;
        iter.remove();
      }
    }

    // fire only for the last one, at the end the event out
    // of the protocol will be one and for the contact
    if (caps != null) {
      UserCapsNodeListener[] listeners;
      synchronized (userCapsNodeListeners) {
        listeners = userCapsNodeListeners.toArray(NO_USER_CAPS_NODE_LISTENERS);
      }
      if (listeners.length != 0) {
        String nodeVer = caps.getNodeVer();

        for (UserCapsNodeListener listener : listeners)
          listener.userCapsNodeRemoved(lastRemovedJid, nodeVer, false);
      }
    }
  }
    /**
     * Appends the XML <tt>String</tt> representation of this <tt>Content</tt> to a specific
     * <tt>StringBuilder</tt>.
     *
     * @param xml the <tt>StringBuilder</tt> to which the XML <tt>String</tt> representation of this
     *     <tt>Content</tt> is to be appended
     */
    public void toXML(StringBuilder xml) {
      xml.append('<').append(ELEMENT_NAME);
      xml.append(' ').append(NAME_ATTR_NAME).append("='").append(getName()).append('\'');

      List<Channel> channels = getChannels();
      List<SctpConnection> connections = getSctpConnections();

      if (channels.size() == 0 && connections.size() == 0) {
        xml.append(" />");
      } else {
        xml.append('>');
        for (Channel channel : channels) channel.toXML(xml);
        for (SctpConnection conn : connections) conn.toXML(xml);
        xml.append("</").append(ELEMENT_NAME).append('>');
      }
    }
Пример #9
0
  /**
   * Add a record telling what entity caps node a user has.
   *
   * @param user the user (Full JID)
   * @param node the node (of the caps packet extension)
   * @param hash the hashing algorithm used to calculate <tt>ver</tt>
   * @param ver the version (of the caps packet extension)
   * @param ext the ext (of the caps packet extension)
   * @param online indicates if the user is online
   */
  private void addUserCapsNode(
      String user, String node, String hash, String ver, String ext, boolean online) {
    if ((user != null) && (node != null) && (hash != null) && (ver != null)) {
      Caps caps = userCaps.get(user);

      if ((caps == null)
          || !caps.node.equals(node)
          || !caps.hash.equals(hash)
          || !caps.ver.equals(ver)) {
        caps = new Caps(node, hash, ver, ext);

        userCaps.put(user, caps);
      } else return;

      // Fire userCapsNodeAdded.
      UserCapsNodeListener[] listeners;

      synchronized (userCapsNodeListeners) {
        listeners = userCapsNodeListeners.toArray(NO_USER_CAPS_NODE_LISTENERS);
      }
      if (listeners.length != 0) {
        String nodeVer = caps.getNodeVer();

        for (UserCapsNodeListener listener : listeners)
          listener.userCapsNodeAdded(user, nodeVer, online);
      }
    }
  }
  /**
   * Returns an XML <tt>String</tt> representation of this <tt>IQ</tt>.
   *
   * @return an XML <tt>String</tt> representation of this <tt>IQ</tt>
   */
  @Override
  public String getChildElementXML() {
    StringBuilder xml = new StringBuilder();

    xml.append('<').append(ELEMENT_NAME);
    xml.append(" xmlns='").append(NAMESPACE).append('\'');

    String id = getID();

    if (id != null) xml.append(' ').append(ID_ATTR_NAME).append("='").append(id).append('\'');

    List<Content> contents = getContents();

    if (contents.size() == 0) {
      xml.append(" />");
    } else {
      xml.append('>');
      for (Content content : contents) content.toXML(xml);
      xml.append("</").append(ELEMENT_NAME).append('>');
    }
    return xml.toString();
  }
Пример #11
0
  /**
   * Remove a record telling what entity caps node a user has.
   *
   * @param user the user (Full JID)
   */
  public void removeUserCapsNode(String user) {
    Caps caps = userCaps.remove(user);

    // Fire userCapsNodeRemoved.
    if (caps != null) {
      UserCapsNodeListener[] listeners;

      synchronized (userCapsNodeListeners) {
        listeners = userCapsNodeListeners.toArray(NO_USER_CAPS_NODE_LISTENERS);
      }
      if (listeners.length != 0) {
        String nodeVer = caps.getNodeVer();

        for (UserCapsNodeListener listener : listeners)
          listener.userCapsNodeRemoved(user, nodeVer, false);
      }
    }
  }
Пример #12
0
  static {
    // DATE_FORMATS
    DateFormat fmt;

    // XEP-0091
    DATE_FORMATS.add(DelayInformation.XEP_0091_UTC_FORMAT);
    fmt = new SimpleDateFormat("yyyyMd'T'HH:mm:ss'Z'");
    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    DATE_FORMATS.add(fmt);

    // XEP-0082
    fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    DATE_FORMATS.add(fmt);
    fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    DATE_FORMATS.add(fmt);
    DATE_FORMATS.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"));
    DATE_FORMATS.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
  }
    /**
     * Adds a <tt>SourcePacketExtension</tt> to the list of sources of this channel.
     *
     * @param source the <tt>SourcePacketExtension</tt> to add to the list of sources of this
     *     channel
     * @return <tt>true</tt> if the list of sources of this channel changed as a result of the
     *     execution of the method; otherwise, <tt>false</tt>
     */
    public synchronized boolean addSource(SourcePacketExtension source) {
      if (source == null) throw new NullPointerException("source");

      return sources.contains(source) ? false : sources.add(source);
    }
    /**
     * Handles incoming messages and dispatches whatever events are necessary.
     *
     * @param packet the packet that we need to handle (if it is a message).
     */
    public void processPacket(Packet packet) {
      if (!(packet instanceof org.jivesoftware.smack.packet.Message)) return;

      org.jivesoftware.smack.packet.Message msg = (org.jivesoftware.smack.packet.Message) packet;

      boolean isForwardedSentMessage = false;
      if (msg.getBody() == null) {

        CarbonPacketExtension carbonExt =
            (CarbonPacketExtension) msg.getExtension(CarbonPacketExtension.NAMESPACE);
        if (carbonExt == null) return;

        isForwardedSentMessage =
            (carbonExt.getElementName() == CarbonPacketExtension.SENT_ELEMENT_NAME);
        List<ForwardedPacketExtension> extensions =
            carbonExt.getChildExtensionsOfType(ForwardedPacketExtension.class);
        if (extensions.isEmpty()) return;
        ForwardedPacketExtension forwardedExt = extensions.get(0);
        msg = forwardedExt.getMessage();
        if (msg == null || msg.getBody() == null) return;
      }

      Object multiChatExtension = msg.getExtension("x", "http://jabber.org/protocol/muc#user");

      // its not for us
      if (multiChatExtension != null) return;

      String userFullId = isForwardedSentMessage ? msg.getTo() : msg.getFrom();

      String userBareID = StringUtils.parseBareAddress(userFullId);

      boolean isPrivateMessaging = false;
      ChatRoom privateContactRoom = null;
      OperationSetMultiUserChatJabberImpl mucOpSet =
          (OperationSetMultiUserChatJabberImpl)
              jabberProvider.getOperationSet(OperationSetMultiUserChat.class);
      if (mucOpSet != null) privateContactRoom = mucOpSet.getChatRoom(userBareID);

      if (privateContactRoom != null) {
        isPrivateMessaging = true;
      }

      if (logger.isDebugEnabled()) {
        if (logger.isDebugEnabled())
          logger.debug("Received from " + userBareID + " the message " + msg.toXML());
      }

      Message newMessage = createMessage(msg.getBody(), DEFAULT_MIME_TYPE, msg.getPacketID());

      // check if the message is available in xhtml
      PacketExtension ext = msg.getExtension("http://jabber.org/protocol/xhtml-im");

      if (ext != null) {
        XHTMLExtension xhtmlExt = (XHTMLExtension) ext;

        // parse all bodies
        Iterator<String> bodies = xhtmlExt.getBodies();
        StringBuffer messageBuff = new StringBuffer();
        while (bodies.hasNext()) {
          String body = bodies.next();
          messageBuff.append(body);
        }

        if (messageBuff.length() > 0) {
          // we remove body tags around message cause their
          // end body tag is breaking
          // the visualization as html in the UI
          String receivedMessage =
              messageBuff
                  .toString()
                  // removes body start tag
                  .replaceAll("\\<[bB][oO][dD][yY].*?>", "")
                  // removes body end tag
                  .replaceAll("\\</[bB][oO][dD][yY].*?>", "");

          // for some reason &apos; is not rendered correctly
          // from our ui, lets use its equivalent. Other
          // similar chars(< > & ") seem ok.
          receivedMessage = receivedMessage.replaceAll("&apos;", "&#39;");

          newMessage = createMessage(receivedMessage, HTML_MIME_TYPE, msg.getPacketID());
        }
      }

      PacketExtension correctionExtension = msg.getExtension(MessageCorrectionExtension.NAMESPACE);
      String correctedMessageUID = null;
      if (correctionExtension != null) {
        correctedMessageUID =
            ((MessageCorrectionExtension) correctionExtension).getCorrectedMessageUID();
      }

      Contact sourceContact =
          opSetPersPresence.findContactByID((isPrivateMessaging ? userFullId : userBareID));
      if (msg.getType() == org.jivesoftware.smack.packet.Message.Type.error) {
        // error which is multichat and we don't know about the contact
        // is a muc message error which is missing muc extension
        // and is coming from the room, when we try to send message to
        // room which was deleted or offline on the server
        if (isPrivateMessaging && sourceContact == null) {
          if (privateContactRoom != null) {
            XMPPError error = packet.getError();
            int errorResultCode = ChatRoomMessageDeliveryFailedEvent.UNKNOWN_ERROR;

            if (error != null && error.getCode() == 403) {
              errorResultCode = ChatRoomMessageDeliveryFailedEvent.FORBIDDEN;
            }

            String errorReason = error.getMessage();

            ChatRoomMessageDeliveryFailedEvent evt =
                new ChatRoomMessageDeliveryFailedEvent(
                    privateContactRoom, null, errorResultCode, errorReason, new Date(), newMessage);
            ((ChatRoomJabberImpl) privateContactRoom).fireMessageEvent(evt);
          }

          return;
        }

        if (logger.isInfoEnabled()) logger.info("Message error received from " + userBareID);

        int errorResultCode = MessageDeliveryFailedEvent.UNKNOWN_ERROR;
        if (packet.getError() != null) {
          int errorCode = packet.getError().getCode();

          if (errorCode == 503) {
            org.jivesoftware.smackx.packet.MessageEvent msgEvent =
                (org.jivesoftware.smackx.packet.MessageEvent)
                    packet.getExtension("x", "jabber:x:event");
            if (msgEvent != null && msgEvent.isOffline()) {
              errorResultCode = MessageDeliveryFailedEvent.OFFLINE_MESSAGES_NOT_SUPPORTED;
            }
          }
        }

        if (sourceContact == null) {
          sourceContact = opSetPersPresence.createVolatileContact(userFullId, isPrivateMessaging);
        }

        MessageDeliveryFailedEvent ev =
            new MessageDeliveryFailedEvent(
                newMessage, sourceContact, correctedMessageUID, errorResultCode);

        // ev = messageDeliveryFailedTransform(ev);

        if (ev != null) fireMessageEvent(ev);
        return;
      }
      putJidForAddress(userFullId, msg.getThread());

      // In the second condition we filter all group chat messages,
      // because they are managed by the multi user chat operation set.
      if (sourceContact == null) {
        if (logger.isDebugEnabled())
          logger.debug("received a message from an unknown contact: " + userBareID);
        // create the volatile contact
        sourceContact = opSetPersPresence.createVolatileContact(userFullId, isPrivateMessaging);
      }

      Date timestamp = new Date();
      // Check for XEP-0091 timestamp (deprecated)
      PacketExtension delay = msg.getExtension("x", "jabber:x:delay");
      if (delay != null && delay instanceof DelayInformation) {
        timestamp = ((DelayInformation) delay).getStamp();
      }
      // check for XEP-0203 timestamp
      delay = msg.getExtension("delay", "urn:xmpp:delay");
      if (delay != null && delay instanceof DelayInfo) {
        timestamp = ((DelayInfo) delay).getStamp();
      }

      ContactResource resource = ((ContactJabberImpl) sourceContact).getResourceFromJid(userFullId);

      EventObject msgEvt = null;
      if (!isForwardedSentMessage)
        msgEvt =
            new MessageReceivedEvent(
                newMessage,
                sourceContact,
                resource,
                timestamp,
                correctedMessageUID,
                isPrivateMessaging,
                privateContactRoom);
      else msgEvt = new MessageDeliveredEvent(newMessage, sourceContact, timestamp);
      // msgReceivedEvt = messageReceivedTransform(msgReceivedEvt);
      if (msgEvt != null) fireMessageEvent(msgEvt);
    }
    /**
     * Adds a specific <tt>Channel</tt> to the list of <tt>Channel</tt>s included into this
     * <tt>Content</tt>.
     *
     * @param channel the <tt>Channel</tt> to be included into this <tt>Content</tt>
     * @return <tt>true</tt> if the list of <tt>Channel</tt>s included into this <tt>Content</tt>
     *     was modified as a result of the execution of the method; otherwise, <tt>false</tt>
     * @throws NullPointerException if the specified <tt>channel</tt> is <tt>null</tt>
     */
    public boolean addChannel(Channel channel) {
      if (channel == null) throw new NullPointerException("channel");

      return channels.contains(channel) ? false : channels.add(channel);
    }
Пример #16
0
 /**
  * Adds a new <tt>crypto</tt> element to this encryption element.
  *
  * @param crypto the new <tt>crypto</tt> element to add.
  */
 public void addCrypto(CryptoPacketExtension crypto) {
   if (!cryptoList.contains(crypto)) {
     cryptoList.add(crypto);
   }
 }
    /**
     * Adds a specific <tt>SctpConnection</tt> to the list of <tt>SctpConnection</tt>s included into
     * this <tt>Content</tt>.
     *
     * @param conn the <tt>SctpConnection</tt> to be included into this <tt>Content</tt>
     * @return <tt>true</tt> if the list of <tt>SctpConnection</tt>s included into this
     *     <tt>Content</tt> was modified as a result of the execution of the method; otherwise,
     *     <tt>false</tt>
     * @throws NullPointerException if the specified <tt>conn</tt> is <tt>null</tt>
     */
    public boolean addSctpConnection(SctpConnection conn) {
      if (conn == null) throw new NullPointerException("Sctp connection");

      return !sctpConnections.contains(conn) && sctpConnections.add(conn);
    }
  /**
   * Adds a specific {@link Content} instance to the list of <tt>Content</tt> instances included
   * into this <tt>conference</tt> IQ.
   *
   * @param content the <tt>Content</tt> instance to be added to this list of <tt>Content</tt>
   *     instances included into this <tt>conference</tt> IQ
   * @return <tt>true</tt> if the list of <tt>Content</tt> instances included into this
   *     <tt>conference</tt> IQ has been modified as a result of the method call; otherwise,
   *     <tt>false</tt>
   * @throws NullPointerException if the specified <tt>content</tt> is <tt>null</tt>
   */
  public boolean addContent(Content content) {
    if (content == null) throw new NullPointerException("content");

    return contents.contains(content) ? false : contents.add(content);
  }
 /**
  * Removes a <tt>SourcePacketExtension</tt> from the list of sources of this channel.
  *
  * @param source the <tt>SourcePacketExtension</tt> to remove from the list of sources of this
  *     channel
  * @return <tt>true</tt> if the list of sources of this channel changed as a result of the
  *     execution of the method; otherwise, <tt>false</tt>
  */
 public synchronized boolean removeSource(SourcePacketExtension source) {
   return sources.remove(source);
 }
 /**
  * Removes a <tt>payload-type</tt> element defined by XEP-0167: Jingle RTP Sessions from this
  * <tt>channel</tt>.
  *
  * @param payloadType the <tt>payload-type</tt> element to be removed from this <tt>channel</tt>
  * @return <tt>true</tt> if the list of <tt>payload-type</tt> elements associated with this
  *     <tt>channel</tt> has been modified as part of the method call; otherwise, <tt>false</tt>
  */
 public boolean removePayloadType(PayloadTypePacketExtension payloadType) {
   return payloadTypes.remove(payloadType);
 }
Пример #21
0
 /**
  * Adds a specific <tt>UserCapsNodeListener</tt> to the list of <tt>UserCapsNodeListener</tt>s
  * interested in events notifying about changes in the list of user caps nodes of this
  * <tt>EntityCapsManager</tt>.
  *
  * @param listener the <tt>UserCapsNodeListener</tt> which is interested in events notifying about
  *     changes in the list of user caps nodes of this <tt>EntityCapsManager</tt>
  */
 public void addUserCapsNodeListener(UserCapsNodeListener listener) {
   if (listener == null) throw new NullPointerException("listener");
   synchronized (userCapsNodeListeners) {
     if (!userCapsNodeListeners.contains(listener)) userCapsNodeListeners.add(listener);
   }
 }
 /**
  * Removes a specific <tt>Channel</tt> from the list of <tt>Channel</tt>s included into this
  * <tt>Content</tt>.
  *
  * @param channel the <tt>Channel</tt> to be excluded from this <tt>Content</tt>
  * @return <tt>true</tt> if the list of <tt>Channel</tt>s included into this <tt>Content</tt>
  *     was modified as a result of the execution of the method; otherwise, <tt>false</tt>
  */
 public boolean removeChannel(Channel channel) {
   return channels.remove(channel);
 }
 /**
  * Removes a specific {@link Content} instance from the list of <tt>Content</tt> instances
  * included into this <tt>conference</tt> IQ.
  *
  * @param content the <tt>Content</tt> instance to be removed from the list of <tt>Content</tt>
  *     instances included into this <tt>conference</tt> IQ
  * @return <tt>true</tt> if the list of <tt>Content</tt> instances included into this
  *     <tt>conference</tt> IQ has been modified as a result of the method call; otherwise,
  *     <tt>false</tt>
  */
 public boolean removeContent(Content content) {
   return contents.remove(content);
 }