/** * Acknowledge a IQ packet. * * @param iq * The IQ to acknowledge */ public IQ createAck(IQ iq) { IQ result = null; if (iq != null) { // Don't acknowledge ACKs, errors... if (iq.getType().equals(IQ.Type.set)) { IQ ack = IQ.createResultIQ(iq); // No! Don't send it. Let it flow to the normal way IQ results get processed and sent. // getConnection().sendStanza(ack); result = ack; } } return result; }
/** * Receive a session-initiate packet. * @param jingle * @param description * @return the iq */ private IQ receiveSessionInitiateAction(Jingle jingle, JingleDescription description) { IQ response = null; List<PayloadType> offeredPayloads = new ArrayList<PayloadType>(); offeredPayloads = description.getAudioPayloadTypesList(); bestCommonAudioPt = calculateBestCommonAudioPt(offeredPayloads); synchronized (remoteAudioPts) { remoteAudioPts.addAll(offeredPayloads); } // If there are suitable/matching payload types then accept this content. if (bestCommonAudioPt != null) { // Let thre transport negotiators sort-out connectivity and content-accept instead. //response = createAudioPayloadTypesOffer(); setNegotiatorState(JingleNegotiatorState.PENDING); } else { // Don't really know what to send here. XEP-166 is not clear. setNegotiatorState(JingleNegotiatorState.FAILED); } return response; }
/** * Open request with a block size that exceeds the maximum block size should be replied with an * resource-constraint error. * * @throws Exception should not happen */ @Test public void shouldRejectRequestWithTooBigBlockSize() throws Exception { byteStreamManager.setMaximumBlockSize(1024); // run the listener with the initiation packet initiationListener.handleIQRequest(initBytestream); // wait because packet is processed in an extra thread Thread.sleep(200); // capture reply to the In-Band Bytestream open request ArgumentCaptor<IQ> argument = ArgumentCaptor.forClass(IQ.class); verify(connection).sendStanza(argument.capture()); // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.error, argument.getValue().getType()); assertEquals(XMPPError.Condition.resource_constraint, argument.getValue().getError().getCondition()); }
@Test public void shouldReturnSession() throws Exception { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); IQ success = IBBPacketUtils.createResultIQ(targetJID, initiatorJID); protocol.addResponse(success, Verification.correspondingSenderReceiver, Verification.requestTypeSET); // start In-Band Bytestream InBandBytestreamSession session = byteStreamManager.establishSession(targetJID); assertNotNull(session); assertNotNull(session.getInputStream()); assertNotNull(session.getOutputStream()); protocol.verifyAll(); }
@Override public IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type) { final String key = XmppStringUtils.generateKey(element, namespace); switch (type) { case set: synchronized (setIqRequestHandler) { return setIqRequestHandler.remove(key); } case get: synchronized (getIqRequestHandler) { return getIqRequestHandler.remove(key); } default: throw new IllegalArgumentException("Only IQ type of 'get' and 'set' allowed"); } }
/** * @param jingle * @param jingleTransport * @return the iq * @throws SmackException */ private IQ receiveSessionInitiateAction(Jingle jingle) throws XMPPException, SmackException { IQ response = null; // Parse the Jingle and get any proposed transport candidates //addRemoteCandidates(obtainCandidatesList(jin)); // Start offering candidates sendTransportCandidatesOffer(); // All these candidates will be checked asyncronously. Wait for some // time and check if we have a valid candidate to use... delayedCheckBestCandidate(session, jingle); // Set the next state setNegotiatorState(JingleNegotiatorState.PENDING); return response; }
/** * Constructor. * * @param connection the XMPP connection * @param byteStreamRequest the In-Band Bytestream open request for this session * @param remoteJID JID of the remote peer */ protected InBandBytestreamSession(XMPPConnection connection, Open byteStreamRequest, String remoteJID) { this.connection = connection; this.byteStreamRequest = byteStreamRequest; this.remoteJID = remoteJID; // initialize streams dependent to the uses stanza type switch (byteStreamRequest.getStanza()) { case IQ: this.inputStream = new IQIBBInputStream(); this.outputStream = new IQIBBOutputStream(); break; case MESSAGE: this.inputStream = new MessageIBBInputStream(); this.outputStream = new MessageIBBOutputStream(); break; } }
@Override protected synchronized void writeToXML(DataPacketExtension data) throws IOException { // create IQ stanza containing data packet IQ iq = new Data(data); iq.setTo(remoteJID); try { connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); } catch (Exception e) { // close session unless it is already closed if (!this.isClosed) { InBandBytestreamSession.this.close(); // Sadly we are unable to use the IOException(Throwable) constructor because this // constructor is only supported from Android API 9 on. IOException ioException = new IOException(); ioException.initCause(e); throw ioException; } } }
/** * If no listeners are registered for incoming In-Band Bytestream requests, all request should * be rejected with an error. * * @throws Exception should not happen */ @Test public void shouldRespondWithError() throws Exception { // run the listener with the initiation packet initiationListener.handleIQRequest(initBytestream); // wait because packet is processed in an extra thread Thread.sleep(200); // capture reply to the In-Band Bytestream open request ArgumentCaptor<IQ> argument = ArgumentCaptor.forClass(IQ.class); verify(connection).sendStanza(argument.capture()); // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.error, argument.getValue().getType()); assertEquals(XMPPError.Condition.not_acceptable, argument.getValue().getError().getCondition()); }
/** * Creates a new account using the specified username, password and account attributes. * The attributes Map must contain only String name/value pairs and must also have values * for all required attributes. * * @param username the username. * @param password the password. * @param attributes the account attributes. * @throws XMPPErrorException if an error occurs creating the account. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException * @see #getAccountAttributes() */ public void createAccount(String username, String password, Map<String, String> attributes) throws NoResponseException, XMPPErrorException, NotConnectedException { if (!connection().isSecureConnection() && !allowSensitiveOperationOverInsecureConnection) { // TODO throw exception in newer Smack versions LOGGER.warning("Creating account over insecure connection. " + "This will throw an exception in future versions of Smack if AccountManager.sensitiveOperationOverInsecureConnection(true) is not set"); } attributes.put("username", username); attributes.put("password", password); Registration reg = new Registration(attributes); reg.setType(IQ.Type.set); reg.setTo(connection().getServiceName()); createPacketCollectorAndSend(reg).nextResultOrThrow(); }
/** * Get the version of the server and make sure that all the required data is present * * Note: This test expects the server to answer an iq:version packet. */ public void testGetServerVersion() { Version version = new Version(); version.setType(IQ.Type.get); version.setTo(getServiceName()); // Create a packet collector to listen for a response. PacketCollector collector = getConnection(0).createPacketCollector(new PacketIDFilter(version.getStanzaId())); getConnection(0).sendStanza(version); // Wait up to 5 seconds for a result. IQ result = (IQ)collector.nextResult(5000); // Close the collector collector.cancel(); assertNotNull("No result from the server", result); assertEquals("Incorrect result type", IQ.Type.result, result.getType()); assertNotNull("No name specified in the result", ((Version)result).getName()); assertNotNull("No version specified in the result", ((Version)result).getVersion()); }
/** * This method is invoked if a request to close the In-Band Bytestream has been received. * * @param closeRequest the close request from the remote peer * @throws NotConnectedException */ protected void closeByPeer(Close closeRequest) throws NotConnectedException { /* * close streams without flushing them, because stream is already considered closed on the * remote peers side */ this.inputStream.closeInternal(); this.inputStream.cleanup(); this.outputStream.closeInternal(false); // acknowledge close request IQ confirmClose = IQ.createResultIQ(closeRequest); this.connection.sendStanza(confirmClose); }
/** * Asks the workgroup for it's Chat Settings. * * @return key specify a key to retrieve only that settings. Otherwise for all settings, key should be null. * @throws NoResponseException * @throws XMPPErrorException if an error occurs while getting information from the server. * @throws NotConnectedException */ private ChatSettings getChatSettings(String key, int type) throws NoResponseException, XMPPErrorException, NotConnectedException { ChatSettings request = new ChatSettings(); if (key != null) { request.setKey(key); } if (type != -1) { request.setType(type); } request.setType(IQ.Type.get); request.setTo(workgroupJID); ChatSettings response = (ChatSettings) connection.createPacketCollectorAndSend(request).nextResultOrThrow(); return response; }
/** * Process the ACK of our list of codecs (our offer). */ private Jingle receiveResult(IQ iq) throws XMPPException { Jingle response = null; // if (!remoteAudioPts.isEmpty()) { // // Calculate the best common codec // bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); // // // and send an accept if we havee an agreement... // if (bestCommonAudioPt != null) { // response = createAcceptMessage(); // } else { // throw new JingleException(JingleError.NO_COMMON_PAYLOAD); // } // } return response; }
/** * Sets the name associated with this entry. * * @param name the name. * @throws NotConnectedException * @throws XMPPErrorException * @throws NoResponseException */ public synchronized void setName(String name) throws NotConnectedException, NoResponseException, XMPPErrorException { // Do nothing if the name hasn't changed. if (name != null && name.equals(this.name)) { return; } RosterPacket packet = new RosterPacket(); packet.setType(IQ.Type.set); // Create a new roster item with the current RosterEntry and the *new* name. Note that we can't set the name of // RosterEntry right away, as otherwise the updated event wont get fired, because equalsDeep would return true. packet.addRosterItem(toRosterItem(this, name)); connection().createPacketCollectorAndSend(packet).nextResultOrThrow(); // We have received a result response to the IQ set, the name was successfully changed this.name = name; }
/** * Test successive calls to the output stream flush() method. * * @throws Exception should not happen */ @Test public void shouldSendNothingOnSuccessiveCallsToFlush() throws Exception { byte[] controlData = new byte[blockSize * 3]; InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream, initiatorJID); // set acknowledgments for the data packets IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID); protocol.addResponse(resultIQ, incrementingSequence); protocol.addResponse(resultIQ, incrementingSequence); protocol.addResponse(resultIQ, incrementingSequence); OutputStream outputStream = session.getOutputStream(); outputStream.write(controlData); outputStream.flush(); outputStream.flush(); outputStream.flush(); protocol.verifyAll(); }
/** * Test the output stream flush() method. * * @throws Exception should not happen */ @Test public void shouldSendThirtyDataPackets() throws Exception { byte[] controlData = new byte[blockSize * 3]; InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream, initiatorJID); // set acknowledgments for the data packets IQ resultIQ = IBBPacketUtils.createResultIQ(initiatorJID, targetJID); for (int i = 0; i < controlData.length; i++) { protocol.addResponse(resultIQ, incrementingSequence); } OutputStream outputStream = session.getOutputStream(); for (byte b : controlData) { outputStream.write(b); outputStream.flush(); } protocol.verifyAll(); }
public IQ processJingle(JingleSession session, Jingle jingle, JingleActionEnum action) throws SmackException { IQ response = null; switch (action) { case SESSION_INITIATE: response = receiveSessionInitiateAction(session, jingle); break; case SESSION_TERMINATE: response = receiveSessionTerminateAction(session, jingle); break; default: // Anything other than session-initiate is an error. response = session.createJingleError(jingle, JingleError.MALFORMED_STANZA); break; } return response; }
/** * Invoking {@link InBandBytestreamManager#establishSession(String)} should * throw an exception if the given target does not support in-band * bytestream. * @throws SmackException * @throws XMPPException */ @Test public void shouldFailIfTargetDoesNotSupportIBB() throws SmackException, XMPPException { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); try { XMPPError xmppError = new XMPPError( XMPPError.Condition.feature_not_implemented); IQ errorIQ = IBBPacketUtils.createErrorIQ(targetJID, initiatorJID, xmppError); protocol.addResponse(errorIQ); // start In-Band Bytestream byteStreamManager.establishSession(targetJID); fail("exception should be thrown"); } catch (XMPPErrorException e) { assertEquals(XMPPError.Condition.feature_not_implemented, e.getXMPPError().getCondition()); } }
@Test public void shouldUseConfiguredStanzaType() throws SmackException { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setStanza(StanzaType.MESSAGE); protocol.addResponse(null, new Verification<Open, IQ>() { public void verify(Open request, IQ response) { assertEquals(StanzaType.MESSAGE, request.getStanza()); } }); try { // start In-Band Bytestream byteStreamManager.establishSession(targetJID); } catch (XMPPException e) { protocol.verifyAll(); } }
@Override public SampleResult perform(JMeterXMPPSampler sampler, SampleResult res) throws Exception { long counter = 0; for (Packet packet : incomingPackets) { incomingPackets.remove(packet); SampleResult subRes = new SampleResult(); subRes.setSuccessful(true); subRes.setResponseCode("200"); subRes.setResponseMessage("OK"); subRes.setSampleLabel(packet.getClass().getSimpleName().isEmpty() ? packet.getClass().getName() : packet.getClass().getSimpleName()); subRes.setResponseData(packet.toXML().toString().getBytes()); if ((packet instanceof Presence) && (((Presence) packet).getType() == Presence.Type.error)) { subRes.setSuccessful(false); subRes.setResponseCode("500"); subRes.setResponseMessage(packet.getError().toString()); } else if ((packet instanceof Message) && (((Message) packet).getType() == Message.Type.error)) { subRes.setSuccessful(false); subRes.setResponseCode("500"); subRes.setResponseMessage(packet.getError().toString()); } else if ((packet instanceof IQ) && (((IQ) packet).getType() == IQ.Type.error)) { subRes.setSuccessful(false); subRes.setResponseCode("500"); subRes.setResponseMessage(packet.getError().toString()); } res.addSubResult(subRes); counter++; } res.setResponseData(("Received packets: " + counter).getBytes()); return counter > 0 ? res : null; }
@Override public SampleResult perform(JMeterXMPPSampler sampler, SampleResult res) throws Exception { String entID = sampler.getPropertyAsString(ENTITY_ID); res.setSamplerData("Entity ID: " + entID); ServiceDiscoveryManager discoMgr = ServiceDiscoveryManager.getInstanceFor(sampler.getXMPPConnection()); IQ info; if (Type.valueOf(sampler.getPropertyAsString(TYPE)) == Type.info) { info = discoMgr.discoverInfo(entID); } else { info = discoMgr.discoverItems(entID); } res.setResponseData(info.toXML().toString().getBytes()); return res; }
private void sendRoomQuery(String jid) { DiscoverItems disco = new DiscoverItems(); disco.setType(IQ.Type.GET); disco.setTo(jid); disco.setNode(QUERY_ROOMS); conn.sendPacket(disco); }
/** * 注册用户 * @param xmppConnection * @param userName * @param password * @return 1、注册成功 0、服务器没有返回结果2、这个账号已经存在3、注册失败 */ public static int regist(XMPPConnection xmppConnection, String userName, String password) { Registration registration = new Registration(); registration.setType(IQ.Type.SET); registration.setTo(xmppConnection.getServiceName()); registration.setUsername(userName); registration.setPassword(password); // 这边addAttribute不能为空,否则出错。所以做个标志是android手机创建的吧!!!!! registration.addAttribute("android", "fhr"); PacketFilter filter = new AndFilter(new PacketIDFilter(registration.getPacketID()), new PacketTypeFilter(IQ.class)); PacketCollector collector = xmppConnection.createPacketCollector(filter); xmppConnection.sendPacket(registration); IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results停止请求results(是否成功的结果) collector.cancel(); if (result == null) { Log.e("regist", "No response from server."); return 0; } else if (result.getType() == IQ.Type.RESULT) { Log.v("regist", "regist success."); return 1; } else { if (result.getError().toString().equalsIgnoreCase("conflict(409)")) { Log.e("regist", "IQ.Type.ERROR: " + result.getError().toString()); return 2; } else { Log.e("regist", "IQ.Type.ERROR: " + result.getError().toString()); return 3; } } }
/** * Constructor. * * @param data data stanza(/packet) extension containing the encoded data */ public Data(DataPacketExtension data) { super(DataPacketExtension.ELEMENT, DataPacketExtension.NAMESPACE); if (data == null) { throw new IllegalArgumentException("Data must not be null"); } this.dataPacketExtension = data; setType(IQ.Type.set); }
private void changeRole(Collection<String> nicknames, MUCRole role) throws NoResponseException, XMPPErrorException, NotConnectedException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.set); for (String nickname : nicknames) { // Set the new role. MUCItem item = new MUCItem(role, nickname); iq.addItem(item); } connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); }
@Override public IQ parseIQ(XmlPullParser parser) throws Exception { NotificationIQ notification = new NotificationIQ(); for (boolean done = false; !done;) { int eventType = parser.next(); if (eventType == 2) { if ("id".equals(parser.getName())) { notification.setId(parser.nextText()); } if ("apiKey".equals(parser.getName())) { notification.setApiKey(parser.nextText()); } if ("title".equals(parser.getName())) { notification.setTitle(parser.nextText()); } if ("message".equals(parser.getName())) { notification.setMessage(parser.nextText()); } if ("uri".equals(parser.getName())) { notification.setUri(parser.nextText()); } } else if (eventType == 3 && "notification".equals(parser.getName())) { done = true; } } return notification; }
/** * @param jingle * @return the iq */ private IQ receiveSessionAcceptAction(Jingle jingle) { IQ response = null; LOGGER.fine("Transport stabilished"); //triggerTransportEstablished(getAcceptedLocalCandidate(), getBestRemoteCandidate()); //setNegotiatorState(JingleNegotiatorState.SUCCEEDED); return response; }
private HttpOverXmppReq parseReq(String string) throws Exception { HttpOverXmppReqProvider provider = new HttpOverXmppReqProvider(); XmlPullParser parser = PacketParserUtils.getParserFor(string); IQ iq = provider.parse(parser); assertTrue(iq instanceof HttpOverXmppReq); HttpOverXmppReq castedIq = (HttpOverXmppReq) iq; return castedIq; }
@Test public void areRespAttributesWothoutMessageCorrectlyParsed() throws Exception { String string = "<resp xmlns='urn:xmpp:http' version='1.1' statusCode='200'/>"; HttpOverXmppRespProvider provider = new HttpOverXmppRespProvider(); XmlPullParser parser = PacketParserUtils.getParserFor(string); IQ iq = provider.parse(parser); assertTrue(iq instanceof HttpOverXmppResp); HttpOverXmppResp resp = (HttpOverXmppResp) iq; assertEquals(resp.getVersion(), "1.1"); assertEquals(resp.getStatusCode(), 200); assertNull(resp.getStatusMessage()); }
private HttpOverXmppResp parseAbstractBody(String string, String tag) throws Exception { HttpOverXmppRespProvider provider = new HttpOverXmppRespProvider(); XmlPullParser parser = PacketParserUtils.getParserFor(string, tag); IQ iq = provider.parse(parser); assertTrue(iq instanceof HttpOverXmppResp); return (HttpOverXmppResp) iq; }
public InputStream createIncomingStream(final StreamInitiation initiation) throws SmackException, XMPPErrorException { // This could be either an xep47 ibb 'open' iq or an xep65 streamhost iq IQ initationSet = initiateIncomingStream(connection, initiation); StreamNegotiator streamNegotiator = determineNegotiator(initationSet); try { return streamNegotiator.negotiateIncomingStream(initationSet); } catch (InterruptedException e) { // TODO remove this try/catch once merged into 4.2's master branch throw new IllegalStateException(e); } }
/** * Terminates the session with a custom reason. * * @throws XMPPException * @throws NotConnectedException */ public void terminate(String reason) throws XMPPException, NotConnectedException { if (isClosed()) return; LOGGER.fine("Terminate " + reason); Jingle jout = new Jingle(JingleActionEnum.SESSION_TERMINATE); jout.setType(IQ.Type.set); sendStanza(jout); triggerSessionClosed(reason); }
/** * Tries to parse and return either a Message, IQ or Presence stanza. * * connection is optional and is used to return feature-not-implemented errors for unknown IQ stanzas. * * @param parser * @return a stanza(/packet) which is either a Message, IQ or Presence. * @throws XmlPullParserException * @throws SmackException * @throws IOException */ public static Stanza parseStanza(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException { ParserUtils.assertAtStartTag(parser); final String name = parser.getName(); switch (name) { case Message.ELEMENT: return parseMessage(parser); case IQ.IQ_ELEMENT: return parseIQ(parser); case Presence.ELEMENT: return parsePresence(parser); default: throw new IllegalArgumentException("Can only parse message, iq or presence, not " + name); } }
/** * A jmf description has been accepted. In this case, we must save the * accepted payload type and notify any listener... * * @param jin * The input packet * @return a Jingle packet * @throws JingleException */ private IQ receiveSessionAcceptAction(Jingle jingle, JingleDescription description) throws JingleException { IQ response = null; PayloadType.Audio agreedCommonAudioPt; List<PayloadType> offeredPayloads = new ArrayList<PayloadType>(); if (bestCommonAudioPt == null) { // Update the best common audio PT bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); //response = createAcceptMessage(); } offeredPayloads = description.getAudioPayloadTypesList(); if (!offeredPayloads.isEmpty()) { if (offeredPayloads.size() == 1) { agreedCommonAudioPt = (PayloadType.Audio) offeredPayloads.get(0); if (bestCommonAudioPt != null) { // If the accepted PT matches the best payload // everything is fine if (!agreedCommonAudioPt.equals(bestCommonAudioPt)) { throw new JingleException(JingleError.NEGOTIATION_ERROR); } } } else if (offeredPayloads.size() > 1) { throw new JingleException(JingleError.MALFORMED_STANZA); } } return response; }
NotifyServicePacket(String workgroup, String roomName) { super("offer-confirmation", "http://jabber.org/protocol/workgroup"); this.setTo(workgroup); this.setType(IQ.Type.result); this.roomName = roomName; }
/** * If the data stanza(/packet) contains invalid Base64 encoding an 'bad-request' error should be * returned. See XEP-0047 Section 2.2. * * @throws Exception should not happen */ @Test public void shouldReplyWithErrorIfDataIsInvalid() throws Exception { // verify reply to invalid data packet is an error protocol.addResponse(null, Verification.requestTypeERROR, new Verification<IQ, IQ>() { public void verify(IQ request, IQ response) { assertEquals(XMPPError.Condition.bad_request, request.getError().getCondition()); } }); // get IBB sessions data packet listener InBandBytestreamSession session = new InBandBytestreamSession(connection, initBytestream, initiatorJID); InputStream inputStream = session.getInputStream(); StanzaListener listener = Whitebox.getInternalState(inputStream, StanzaListener.class); // build data packets DataPacketExtension dpe = new DataPacketExtension(sessionID, 0, "AA=BB"); Data data = new Data(dpe); // notify listener listener.processPacket(data); protocol.verifyAll(); }