/** * Performs ANONYMOUS SASL authentication. If SASL authentication was successful * then resource binding and session establishment will be performed. This method will return * the full JID provided by the server while binding a resource to the connection.<p> * * The server will assign a full JID with a randomly generated resource and possibly with * no username. * * @throws SASLErrorException * @throws XMPPErrorException if an error occures while authenticating. * @throws SmackException if there was no response from the server. */ public void authenticateAnonymously() throws SASLErrorException, SmackException, XMPPErrorException { currentMechanism = (new SASLAnonymous()).instanceForAuthentication(connection); // Wait until SASL negotiation finishes synchronized (this) { currentMechanism.authenticate(null, null, null, ""); try { wait(connection.getPacketReplyTimeout()); } catch (InterruptedException e) { // Ignore } } maybeThrowException(); if (!authenticationSuccessful) { throw NoResponseException.newWith(connection); } }
/** * Send the given top level stream element and wait for a response. * * @param request the plain stream element to send. * @throws NoResponseException if no response was received. * @throws NotConnectedException if the connection is not connected. */ public void sendAndWaitForResponse(TopLevelStreamElement request) throws NoResponseException, NotConnectedException { assert (state == State.Initial); connectionLock.lock(); try { if (request != null) { if (request instanceof Stanza) { connection.sendStanza((Stanza) request); } else if (request instanceof PlainStreamElement){ connection.send((PlainStreamElement) request); } else { throw new IllegalStateException("Unsupported element type"); } state = State.RequestSent; } waitForConditionOrTimeout(); } finally { connectionLock.unlock(); } checkForResponse(); }
/** * Sets the agent's current status with the workgroup. The presence mode affects how offers * are routed to the agent. The possible presence modes with their meanings are as follows:<ul> * <p/> * <li>Presence.Mode.AVAILABLE -- (Default) the agent is available for more chats * (equivalent to Presence.Mode.CHAT). * <li>Presence.Mode.DO_NOT_DISTURB -- the agent is busy and should not be disturbed. * However, special case, or extreme urgency chats may still be offered to the agent. * <li>Presence.Mode.AWAY -- the agent is not available and should not * have a chat routed to them (equivalent to Presence.Mode.EXTENDED_AWAY).</ul> * * @param presenceMode the presence mode of the agent. * @param status sets the status message of the presence update. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException * @throws IllegalStateException if the agent is not online with the workgroup. */ public void setStatus(Presence.Mode presenceMode, String status) throws NoResponseException, XMPPErrorException, NotConnectedException { if (!online) { throw new IllegalStateException("Cannot set status when the agent is not online."); } if (presenceMode == null) { presenceMode = Presence.Mode.available; } this.presenceMode = presenceMode; Presence presence = new Presence(Presence.Type.available); presence.setMode(presenceMode); presence.setTo(this.getWorkgroupJID()); if (status != null) { presence.setStatus(status); } presence.addExtension(new MetaData(this.metaData)); PacketCollector collector = this.connection.createPacketCollectorAndSend(new AndFilter(new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence); collector.nextResultOrThrow(); }
/** * Changes the subject within the room. As a default, only users with a role of "moderator" * are allowed to change the subject in a room. Although some rooms may be configured to * allow a mere participant or even a visitor to change the subject. * * @param subject the new room's subject to set. * @throws XMPPErrorException if someone without appropriate privileges attempts to change the * room subject will throw an error with code 403 (i.e. Forbidden) * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ public void changeSubject(final String subject) throws NoResponseException, XMPPErrorException, NotConnectedException { Message message = createMessage(); message.setSubject(subject); // Wait for an error or confirmation message back from the server. StanzaFilter responseFilter = new AndFilter(fromRoomGroupchatFilter, new StanzaFilter() { @Override public boolean accept(Stanza packet) { Message msg = (Message) packet; return subject.equals(msg.getSubject()); } }); PacketCollector response = connection.createPacketCollectorAndSend(responseFilter, message); // Wait up to a certain number of seconds for a reply. response.nextResultOrThrow(); }
/** * Executes the <code>action</code> with the <code>form</code>. * The action could be any of the available actions. The form must * be the answer of the previous stage. It can be <tt>null</tt> if it is the first stage. * * @param action the action to execute. * @param form the form with the information. * @throws XMPPErrorException if there is a problem executing the command. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ private void executeAction(Action action, Form form) throws NoResponseException, XMPPErrorException, NotConnectedException { // TODO: Check that all the required fields of the form were filled, if // TODO: not throw the corresponding exeption. This will make a faster response, // TODO: since the request is stoped before it's sent. AdHocCommandData data = new AdHocCommandData(); data.setType(IQ.Type.set); data.setTo(getOwnerJID()); data.setNode(getNode()); data.setSessionID(sessionID); data.setAction(action); if (form != null) { data.setForm(form.getDataFormToSend()); } AdHocCommandData responseData = (AdHocCommandData) connection.createPacketCollectorAndSend( data).nextResultOrThrow(); this.sessionID = responseData.getSessionID(); super.setData(responseData); }
/** * Removes a conference from the bookmarks. * * @param jid the jid of the conference to be removed. * @throws XMPPErrorException thrown when there is a problem with the connection attempting to * retrieve the bookmarks or persist the bookmarks. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException * @throws IllegalArgumentException thrown when the conference being removed is a shared * conference */ public void removeBookmarkedConference(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException { retrieveBookmarks(); Iterator<BookmarkedConference> it = bookmarks.getBookmarkedConferences().iterator(); while(it.hasNext()) { BookmarkedConference conference = it.next(); if(conference.getJid().equalsIgnoreCase(jid)) { if(conference.isShared()) { throw new IllegalArgumentException("Conference is shared and can't be removed"); } it.remove(); privateDataManager.setPrivateData(bookmarks); return; } } }
/** * Creates a node with specified configuration. * * Note: This is the only way to create a collection node. * * @param name The name of the node, which must be unique within the * pubsub service * @param config The configuration for the node * @return The node that was created * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public Node createNode(String name, Form config) throws NoResponseException, XMPPErrorException, NotConnectedException { PubSub request = PubSub.createPubsubPacket(to, Type.set, new NodeExtension(PubSubElementType.CREATE, name), null); boolean isLeafNode = true; if (config != null) { request.addExtension(new FormNode(FormNodeType.CONFIGURE, config)); FormField nodeTypeField = config.getField(ConfigureNodeFields.node_type.getFieldName()); if (nodeTypeField != null) isLeafNode = nodeTypeField.getValues().get(0).equals(NodeType.leaf.toString()); } // Errors will cause exceptions in getReply, so it only returns // on success. sendPubsubPacket(con, request); Node newNode = isLeafNode ? new LeafNode(con, name) : new CollectionNode(con, name); newNode.setTo(to); nodeMap.put(newNode.getId(), newNode); return newNode; }
/** * Like {@link #create(String)}, but will return true if the room creation was acknowledged by * the service (with an 201 status code). It's up to the caller to decide, based on the return * value, if he needs to continue sending the room configuration. If false is returned, the room * already existed and the user is able to join right away, without sending a form. * * @param nickname the nickname to use. * @param password the password to use. * @param history the amount of discussion history to receive while joining a room. * @param timeout the amount of time to wait for a reply from the MUC service(in milliseconds). * @return true if the room creation was acknowledged by the service, false otherwise. * @throws XMPPErrorException if the room couldn't be created for some reason (e.g. 405 error if * the user is not allowed to create the room) * @throws NoResponseException if there was no response from the server. */ public synchronized boolean createOrJoin(String nickname, String password, DiscussionHistory history, long timeout) throws NoResponseException, XMPPErrorException, SmackException { if (joined) { throw new IllegalStateException("Creation failed - User already joined the room."); } Presence presence = enter(nickname, password, history, timeout); // Look for confirmation of room creation from the server MUCUser mucUser = MUCUser.from(presence); if (mucUser != null && mucUser.getStatus().contains(Status.ROOM_CREATED_201)) { // Room was created and the user has joined the room return true; } return false; }
/** * Shuts down the stanza(/packet) writer. Once this method has been called, no further * packets will be written to the server. */ void shutdown(boolean instant) { instantShutdown = instant; shutdownTimestamp = System.currentTimeMillis(); queue.shutdown(); try { shutdownDone.checkIfSuccessOrWait(); } catch (NoResponseException e) { LOGGER.log(Level.WARNING, "shutdownDone was not marked as successful by the writer thread", e); } }
/** * Returns the next available packet. The method call will block until a stanza(/packet) is available or * the <tt>timeout</tt> has elapsed. This method does also cancel the PacketCollector. * * @param timeout the amount of time to wait for the next stanza(/packet) (in milleseconds). * @return the next available packet. * @throws NoResponseException if there was no response from the server. * @throws XMPPErrorException in case an error response. */ public <P extends Stanza> P nextResultOrThrow(long timeout) throws NoResponseException, XMPPErrorException { P result = nextResult(timeout); cancel(); if (result == null) { throw NoResponseException.newWith(connection, this); } XMPPErrorException.ifHasErrorThenThrow(result); return result; }
/** * Performs SASL authentication of the specified user. If SASL authentication was successful * then resource binding and session establishment will be performed. This method will return * the full JID provided by the server while binding a resource to the connection.<p> * * The server may assign a full JID with a username or resource different than the requested * by this method. * * @param resource the desired resource. * @param cbh the CallbackHandler used to get information from the user * @throws IOException * @throws XMPPErrorException * @throws SASLErrorException * @throws SmackException */ public void authenticate(String resource, CallbackHandler cbh) throws IOException, XMPPErrorException, SASLErrorException, SmackException { SASLMechanism selectedMechanism = selectMechanism(); if (selectedMechanism != null) { currentMechanism = selectedMechanism; synchronized (this) { currentMechanism.authenticate(connection.getHost(), connection.getServiceName(), cbh); try { // Wait until SASL negotiation finishes wait(connection.getPacketReplyTimeout()); } catch (InterruptedException e) { // Ignore } } maybeThrowException(); if (!authenticationSuccessful) { throw NoResponseException.newWith(connection); } } else { throw new SmackException( "SASL Authentication failed. No known authentication mechanisims."); } }
/** * Check if this synchronization point is successful or wait the connections reply timeout. * @throws NoResponseException if there was no response marking the synchronization point as success or failed. * @throws E if there was a failure */ public void checkIfSuccessOrWaitOrThrow() throws NoResponseException, E { checkIfSuccessOrWait(); if (state == State.Failure) { throw failureException; } }
/** * Check for a response and throw a {@link NoResponseException} if there was none. * <p> * The exception is thrown, if state is one of 'Initial', 'NoResponse' or 'RequestSent' * </p> * @throws NoResponseException */ private void checkForResponse() throws NoResponseException { switch (state) { case Initial: case NoResponse: case RequestSent: throw NoResponseException.newWith(connection); default: // Do nothing break; } }
public Socket getSocket(int timeout) throws IOException, InterruptedException, TimeoutException, XMPPException, SmackException { Socket socket = null; // check if stream host is the local SOCKS5 proxy if (this.streamHost.getJID().equals(this.connection.get().getUser())) { Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy(); socket = socks5Server.getSocket(this.digest); if (socket == null) { throw new SmackException("target is not connected to SOCKS5 proxy"); } } else { socket = super.getSocket(timeout); try { activate(); } catch (XMPPException e1) { socket.close(); throw e1; } catch (NoResponseException e2) { socket.close(); throw e2; } } return socket; }
private void changeRole(String nickname, MUCRole role, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.set); // Set the new role. MUCItem item = new MUCItem(role, nickname, reason); iq.addItem(item); connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); }
/** * Save this vCard for the user connected by 'connection'. XMPPConnection should be authenticated * and not anonymous. * * @throws XMPPErrorException thrown if there was an issue setting the VCard in the server. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ public void saveVCard(VCard vcard) throws NoResponseException, XMPPErrorException, NotConnectedException { // XEP-54 § 3.2 "A user may publish or update his or her vCard by sending an IQ of type "set" with no 'to' address…" vcard.setTo(null); vcard.setType(IQ.Type.set); // Also make sure to generate a new stanza id (the given vcard could be a vcard result), in which case we don't // want to use the same stanza id again (although it wouldn't break if we did) vcard.setStanzaId(StanzaIdUtil.newStanzaId()); connection().createPacketCollectorAndSend(vcard).nextResultOrThrow(); }
/** * Pings the server. This method will return true if the server is reachable. It * is the equivalent of calling <code>ping</code> with the XMPP domain. * <p> * Unlike the {@link #ping(String)} case, this method will return true even if * {@link #isPingSupported(String)} is false. * * @param notifyListeners Notify the PingFailedListener in case of error if true * @param pingTimeout The time to wait for a reply in milliseconds * @return true if the user's server could be pinged. * @throws NotConnectedException */ public boolean pingMyServer(boolean notifyListeners, long pingTimeout) throws NotConnectedException { boolean res; try { res = ping(connection().getServiceName(), pingTimeout); } catch (NoResponseException e) { res = false; } if (!res && notifyListeners) { for (PingFailedListener l : pingFailedListeners) l.pingFailed(); } return res; }
/** * Asks the workgroup for it's Global Macros. * * @param global true to retrieve global macros, otherwise false for personal macros. * @return MacroGroup the root macro group. * @throws XMPPErrorException if an error occurs while getting information from the server. * @throws NoResponseException * @throws NotConnectedException */ public MacroGroup getMacros(boolean global) throws NoResponseException, XMPPErrorException, NotConnectedException { Macros request = new Macros(); request.setType(IQ.Type.get); request.setTo(workgroupJID); request.setPersonal(!global); Macros response = (Macros) connection.createPacketCollectorAndSend(request).nextResultOrThrow(); return response.getRootGroup(); }
public boolean hasMonitorPrivileges(XMPPConnection con) throws NoResponseException, XMPPErrorException, NotConnectedException { MonitorPacket request = new MonitorPacket(); request.setType(IQ.Type.get); request.setTo(workgroupJID); MonitorPacket response = (MonitorPacket) connection.createPacketCollectorAndSend(request).nextResultOrThrow(); return response.isMonitor(); }
public void makeRoomOwner(XMPPConnection con, String sessionID) throws NoResponseException, XMPPErrorException, NotConnectedException { MonitorPacket request = new MonitorPacket(); request.setType(IQ.Type.set); request.setTo(workgroupJID); request.setSessionID(sessionID); connection.createPacketCollectorAndSend(request).nextResultOrThrow(); }
/** * Returns true if the workgroup is available for receiving new requests. The workgroup will be * available only when agents are available for this workgroup. * * @return true if the workgroup is available for receiving new requests. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public boolean isAvailable() throws NoResponseException, XMPPErrorException, NotConnectedException { Presence directedPresence = new Presence(Presence.Type.available); directedPresence.setTo(workgroupJID); StanzaFilter typeFilter = new StanzaTypeFilter(Presence.class); StanzaFilter fromFilter = FromMatchesFilter.create(workgroupJID); PacketCollector collector = connection.createPacketCollectorAndSend(new AndFilter(fromFilter, typeFilter), directedPresence); Presence response = (Presence)collector.nextResultOrThrow(); return Presence.Type.available == response.getType(); }
/** * Check if the server support RTPBridge Service. * * @param connection * @return true if the server supports the RTPBridge service * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public static boolean serviceAvailable(XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException { if (!connection.isConnected()) { return false; } LOGGER.fine("Service listing"); ServiceDiscoveryManager disco = ServiceDiscoveryManager .getInstanceFor(connection); // DiscoverItems items = disco.discoverItems(connection.getServiceName()); // Iterator iter = items.getItems(); // while (iter.hasNext()) { // DiscoverItems.Item item = (DiscoverItems.Item) iter.next(); // if (item.getEntityID().startsWith("rtpbridge.")) { // return true; // } // } DiscoverInfo discoInfo = disco.discoverInfo(connection.getServiceName()); for (DiscoverInfo.Identity identity : discoInfo.getIdentities()) { if ((identity.getName() != null) && (identity.getName().startsWith("rtpbridge"))) { return true; } } return false; }
/** * Set or change the default list to listName. * * @param listName the list name to set as the default one. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public void setDefaultListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setDefaultName(listName); // Send the package to the server setRequest(request); }
/** * Creates an instant node, if supported. * * @return The node that was created * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public LeafNode createNode() throws NoResponseException, XMPPErrorException, NotConnectedException { PubSub reply = sendPubsubPacket(Type.set, new NodeExtension(PubSubElementType.CREATE), null); NodeExtension elem = reply.getExtension("create", PubSubNamespace.BASIC.getXmlns()); LeafNode newNode = new LeafNode(con, elem.getNode()); newNode.setTo(to); nodeMap.put(newNode.getId(), newNode); return newNode; }
/** * Client declines the use of active lists. * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public void declineActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setDeclineActiveList(true); // Send the package to the server setRequest(request); }
/** * Establishes an In-Band Bytestream with the given user using the given session ID and returns * the session to send/receive data to/from the user. * * @param targetJID the JID of the user an In-Band Bytestream should be established * @param sessionID the session ID for the In-Band Bytestream request * @return the session to send/receive data to/from the user * @throws XMPPErrorException if the user doesn't support or accept in-band bytestreams, or if the * user prefers smaller block sizes * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ public InBandBytestreamSession establishSession(String targetJID, String sessionID) throws NoResponseException, XMPPErrorException, NotConnectedException { Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza); byteStreamRequest.setTo(targetJID); // sending packet will throw exception on timeout or error reply connection.createPacketCollectorAndSend(byteStreamRequest).nextResultOrThrow(); InBandBytestreamSession inBandBytestreamSession = new InBandBytestreamSession( this.connection, byteStreamRequest, targetJID); this.sessions.put(sessionID, inBandBytestreamSession); return inBandBytestreamSession; }
@Test public void verifyForm() throws Exception { FileTransferNegotiator fileNeg = FileTransferNegotiator.getInstanceFor(connection); try { fileNeg.negotiateOutgoingTransfer("me", "streamid", "file", 1024, null, 10); } catch (NoResponseException e) { // Ignore } Stanza packet = connection.getSentPacket(); String xml = packet.toXML().toString(); assertTrue(xml.indexOf("var='stream-method' type='list-single'") != -1); }
/** * Changes the password of the currently logged-in account. This operation can only * be performed after a successful login operation has been completed. Not all servers * support changing passwords; an XMPPException will be thrown when that is the case. * * @throws IllegalStateException if not currently logged-in to the server. * @throws XMPPErrorException if an error occurs when changing the password. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException, NotConnectedException { if (!connection().isSecureConnection() && !allowSensitiveOperationOverInsecureConnection) { // TODO throw exception in newer Smack versions LOGGER.warning("Changing password over insecure connection. " + "This will throw an exception in future versions of Smack if AccountManager.sensitiveOperationOverInsecureConnection(true) is not set"); } Map<String, String> map = new HashMap<String, String>(); map.put("username",XmppStringUtils.parseLocalpart(connection().getUser())); map.put("password",newPassword); Registration reg = new Registration(map); reg.setType(IQ.Type.set); reg.setTo(connection().getServiceName()); createPacketCollectorAndSend(reg).nextResultOrThrow(); }
@Override public void sendStanzaWithResponseCallback(Stanza stanza, final StanzaFilter replyFilter, final StanzaListener callback, final ExceptionCallback exceptionCallback, long timeout) throws NotConnectedException { Objects.requireNonNull(stanza, "stanza must not be null"); // While Smack allows to add PacketListeners with a PacketFilter value of 'null', we // disallow it here in the async API as it makes no sense Objects.requireNonNull(replyFilter, "replyFilter must not be null"); Objects.requireNonNull(callback, "callback must not be null"); final StanzaListener packetListener = new StanzaListener() { @Override public void processPacket(Stanza packet) throws NotConnectedException { try { XMPPErrorException.ifHasErrorThenThrow(packet); callback.processPacket(packet); } catch (XMPPErrorException e) { if (exceptionCallback != null) { exceptionCallback.processException(e); } } finally { removeAsyncStanzaListener(this); } } }; removeCallbacksService.schedule(new Runnable() { @Override public void run() { boolean removed = removeAsyncStanzaListener(packetListener); // If the packetListener got removed, then it was never run and // we never received a response, inform the exception callback if (removed && exceptionCallback != null) { exceptionCallback.processException(NoResponseException.newWith(AbstractXMPPConnection.this, replyFilter)); } } }, timeout, TimeUnit.MILLISECONDS); addAsyncStanzaListener(packetListener, replyFilter); sendStanza(stanza); }
private PubSub sendPubsubPacket(Type type, ExtensionElement ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException { return sendPubsubPacket(con, to, type, Collections.singletonList(ext), ns); }
public OutputStream createOutgoingStream(String streamID, String initiator, String target) throws NoResponseException, XMPPErrorException, NotConnectedException { InBandBytestreamSession session = this.manager.establishSession(target, streamID); session.setCloseBothStreamsEnabled(true); return session.getOutputStream(); }
@Override public void cancel() throws NoResponseException, XMPPErrorException, NotConnectedException { executeAction(Action.cancel); }
@Override public void complete(Form form) throws NoResponseException, XMPPErrorException, NotConnectedException { executeAction(Action.complete, form); }
@Override public void execute() throws NoResponseException, XMPPErrorException, NotConnectedException { executeAction(Action.execute); }
@Override public void next(Form form) throws NoResponseException, XMPPErrorException, NotConnectedException { executeAction(Action.next, form); }
private <T extends Item> List<T> getItems(PubSub request) throws NoResponseException, XMPPErrorException, NotConnectedException { return getItems(request, null); }
abstract InputStream negotiateIncomingStream(Stanza streamInitiation) throws XMPPErrorException, InterruptedException, NoResponseException, SmackException;
/** * Create new user with the provided password. * * @param username * @param password * @return true if user created successfully, false otherwise * @throws NotConnectedException * @throws XMPPErrorException * @throws NoResponseException */ public void createAccount(String username, String password) throws NoResponseException, XMPPErrorException, NotConnectedException { AccountManager.sensitiveOperationOverInsecureConnectionDefault(true); AccountManager accountManager = AccountManager.getInstance(connection); if (accountManager.supportsAccountCreation()) { accountManager.createAccount(username, password); } }