private void initServiceDiscovery() { debug(TAG, "init service discovery"); // register connection features ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mConnection); if (!sdm.includesFeature(DISCO_FEATURE)) sdm.addFeature(DISCO_FEATURE); if (!sdm.includesFeature(DeliveryReceipt.NAMESPACE)) sdm.addFeature(DeliveryReceipt.NAMESPACE); sdm.addFeature(HttpFileUploadManager.NAMESPACE); DeliveryReceiptManager.getInstanceFor(mConnection).dontAutoAddDeliveryReceiptRequests(); DeliveryReceiptManager.getInstanceFor(mConnection).setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.disabled); }
private void processErrorMessage(Message m) { DeliveryReceipt deliveryReceipt = DeliveryReceipt.from(m); // delivery receipt error if (deliveryReceipt != null) { // mark indicated message as incoming and try again MessageUpdater.forMessage(getContext(), deliveryReceipt.getId(), true) .setStatus(Messages.STATUS_INCOMING, System.currentTimeMillis()) .commit(); // send receipt again sendReceipt(null, deliveryReceipt.getId(), m.getFrom()); } String id = m.getStanzaId(); if (id != null) { MessageUpdater.forMessage(getContext(), m.getStanzaId(), false) .setStatus(Messages.STATUS_NOTDELIVERED, System.currentTimeMillis()) .commit(); } }
@Override public void processStanza(Stanza p) { // NOTE: the packet is not the acknowledgement itself but the packet // that is acknowledged if (!(p instanceof Message)) { // we are only interested in acks for messages return; } Message m = (Message) p; LOGGER.config("for message: "+m); if (DeliveryReceipt.from(m) != null) { // this is an ack for a 'received' message (XEP-0184) send by // KonMessageListener, ignore return; } if (m.getBody() == null && m.getExtensions().size() == 1 && m.getExtension(ChatStateExtension.NAMESPACE) != null) { // this is an ack for a chat state notification (XEP-0085), ignore return; } mControl.onMessageSent(MessageIDs.to(m)); }
static void registerSmackProviders() { ProviderManager pm = ProviderManager.getInstance(); // add IQ handling pm.addIQProvider("query", "http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); // add delayed delivery notifications pm.addExtensionProvider("delay", "urn:xmpp:delay", new DelayInfoProvider()); pm.addExtensionProvider("x", "jabber:x:delay", new DelayInfoProvider()); // add carbons and forwarding pm.addExtensionProvider("forwarded", Forwarded.NAMESPACE, new Forwarded.Provider()); pm.addExtensionProvider("sent", Carbon.NAMESPACE, new Carbon.Provider()); pm.addExtensionProvider("received", Carbon.NAMESPACE, new Carbon.Provider()); // add delivery receipts pm.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider()); pm.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceiptRequest.Provider()); // add XMPP Ping (XEP-0199) pm.addIQProvider("ping", "urn:xmpp:ping", new PingProvider()); ServiceDiscoveryManager.setIdentityName(XMPP_IDENTITY_NAME); ServiceDiscoveryManager.setIdentityType(XMPP_IDENTITY_TYPE); }
private void sendReceipt(org.jivesoftware.smack.packet.Message msg) { debug(TAG, "sending XEP-0184 ack to " + msg.getFrom() + " id=" + msg.getPacketID()); org.jivesoftware.smack.packet.Message ack = new org.jivesoftware.smack.packet.Message( msg.getFrom().asBareJid(), msg.getType()); ack.addExtension(new DeliveryReceipt(msg.getStanzaId())); sendPacket(ack); }
@Override public void sendMessage(TxMessage message) { if(message.getDestination().getType().equals(Resource.Type.ROOM)){ Room room = getRoom(message.getDestination().getAddress()); if(room != null) { room.sendMessage(message); } }else{ XmppRxMessage origin = (XmppRxMessage)message.getRequest(); Chat chat = ChatManager.getInstanceFor(connection).getThreadChat(origin.getThread()); if(chat == null){ logger.trace("chat was null, creating a new chat instance"); chat = ChatManager.getInstanceFor(connection).createChat(message.getDestination().getAddress(),origin.getThread(),null); }else{ logger.trace("an existing chat was found for thread id {}", (origin.getThread())); } try { Message msg = MessageHelper.createXmppMessage(message); msg.addExtension(new DeliveryReceipt(origin.getId())); chat.sendMessage(msg); } catch (SmackException.NotConnectedException e) { logger.warn("Trying to send a message on XMPP binding while connection is closed",e); } } }
@Override public void processStanza(Stanza packet) { // stanzas coming here are always messages WakefulHashSet<Long> waitingReceipt = getWaitingReceiptList(); synchronized (waitingReceipt) { long now = System.currentTimeMillis(); DeliveryReceipt receipt = DeliveryReceipt.from((Message) packet); if (receipt != null) { // ack received for outgoing delivery receipt // mark message as confirmed MessageUpdater.forMessage(getContext(), mDatabaseId) .setStatus(Messages.STATUS_CONFIRMED) .commit(); } else { // we have a message awaiting ack from server MessageUpdater.forMessage(getContext(), mDatabaseId) .setStatus(Messages.STATUS_SENT, now) .setServerTimestamp(now) .notifyOutgoing(packet.getTo().asBareJid().toString()) // this will handle receipts that came before the message was acked by the server .appendWhere(SELECTION_SENT_EXCLUDE) .commit(); } // remove the packet from the waiting list // this will also release the wake lock waitingReceipt.remove(mDatabaseId); // we can now release the message center. Hopefully // there will be one hold and one matching release. release(); } }
private void sendReceipt(Uri msgUri, String msgId, Jid from) { DeliveryReceipt receipt = new DeliveryReceipt(msgId); org.jivesoftware.smack.packet.Message ack = new org.jivesoftware.smack.packet.Message(from, org.jivesoftware.smack.packet.Message.Type.chat); ack.addExtension(receipt); long storageId = 0; if (msgUri != null) { // will use this to mark this message as confirmed storageId = ContentUris.parseId(msgUri); } sendMessage(ack, storageId); }
private AckPredicate() { super(new StanzaFilter() { @Override public boolean accept(Stanza packet) { return (packet instanceof Message && (((Message) packet).getBody() != null || DeliveryReceipt.from((Message) packet) != null || DeliveryReceiptRequest.from(packet) != null)); } }, 5); }
private void processReceiptMessage(Message m, DeliveryReceipt receipt) { LOGGER.config("message: "+m); Date delayDate = getDelay(m); if (delayDate == null) delayDate = new Date(); String receiptID = receipt.getId(); if (receiptID == null || receiptID.isEmpty()) { LOGGER.warning("message has invalid receipt ID: "+receiptID); } else { mControl.onMessageReceived(MessageIDs.from(m, receiptID), delayDate); } // we ignore anything else that might be in this message }
static void registerSmackProviders() { ProviderManager pm = ProviderManager.getInstance(); // add IQ handling pm.addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider()); pm.addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider()); // add delayed delivery notifications pm.addExtensionProvider("delay","urn:xmpp:delay", new DelayInfoProvider()); pm.addExtensionProvider("x","jabber:x:delay", new DelayInfoProvider()); // add XEP-0092 Software Version pm.addIQProvider("query", Version.NAMESPACE, new Version.Provider()); // add carbons and forwarding pm.addExtensionProvider("forwarded", Forwarded.NAMESPACE, new Forwarded.Provider()); pm.addExtensionProvider("sent", Carbon.NAMESPACE, new Carbon.Provider()); pm.addExtensionProvider("received", Carbon.NAMESPACE, new Carbon.Provider()); // add delivery receipts pm.addExtensionProvider(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceipt.Provider()); pm.addExtensionProvider(DeliveryReceiptRequest.ELEMENT, DeliveryReceipt.NAMESPACE, new DeliveryReceiptRequest.Provider()); // add XMPP Ping (XEP-0199) pm.addIQProvider("ping","urn:xmpp:ping", new PingProvider()); ServiceDiscoveryManager.setDefaultIdentity(YAXIM_IDENTITY); // XEP-0115 Entity Capabilities pm.addExtensionProvider("c", "http://jabber.org/protocol/caps", new CapsExtensionProvider()); XmppStreamHandler.addExtensionProviders(); }
private void processChatMessage(Message m) { LOGGER.config("message: "+m); // note: thread and subject are null if message comes from the Kontalk // Android client MessageIDs ids = MessageIDs.from(m); Date delayDate = getDelay(m); // process possible chat state notification (XEP-0085) ExtensionElement csExt = m.getExtension(ChatStateExtension.NAMESPACE); ChatState chatState = null; if (csExt != null) { chatState = ((ChatStateExtension) csExt).getChatState(); mControl.onChatStateNotification(ids, Optional.ofNullable(delayDate), chatState); } // must be an incoming message // get content/text from body and/or encryption/url extension MessageContent content = ClientUtils.parseMessageContent(m, false); // make sure not to save a message without content if (content.isEmpty()) { if (chatState == null) { LOGGER.warning("can't find any content in message"); } else if (chatState == ChatState.active) { LOGGER.info("only active chat state"); } return; } // add message mControl.onNewInMessage(ids, Optional.ofNullable(delayDate), content); // send a 'received' for a receipt request (XEP-0184) DeliveryReceiptRequest request = DeliveryReceiptRequest.from(m); if (request != null && !ids.xmppID.isEmpty()) { Message received = new Message(m.getFrom(), Message.Type.chat); received.addExtension(new DeliveryReceipt(ids.xmppID)); mClient.sendPacket(received); } }
public void sendReceipt(String toJID, String id) { Log.d(TAG, "sending XEP-0184 ack to " + toJID + " id=" + id); final Message ack = new Message(toJID, Message.Type.normal); ack.addExtension(new DeliveryReceipt(id)); mXMPPConnection.sendPacket(ack); }