/** Tests sending a request from a ClientTransaction. */ public void testSendRequest() { try { Request invite = createTiInviteRequest(null, null, null); RequestEvent receivedRequestEvent = null; ClientTransaction tran = null; try { tran = tiSipProvider.getNewClientTransaction(invite); eventCollector.collectRequestEvent(riSipProvider); tran.sendRequest(); waitForMessage(); receivedRequestEvent = eventCollector.extractCollectedRequestEvent(); assertNotNull("The sent request was not received by the RI!", receivedRequestEvent); assertNotNull( "The sent request was not received by the RI!", receivedRequestEvent.getRequest()); } catch (TransactionUnavailableException exc) { throw new TiUnexpectedError( "A TransactionUnavailableException was thrown while trying to " + "create a new client transaction", exc); } catch (SipException exc) { exc.printStackTrace(); fail("The SipException was thrown while trying to send the request."); } catch (TooManyListenersException exc) { throw new TckInternalError( "A TooManyListenersException was thrown while trying " + "to add a SipListener to an RI SipProvider", exc); } } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); }
/** Sends a single invite request and checks whether it arrives normally at the other end. */ public void testSendRequest() { try { // create an empty invite request. Request invite = createTiInviteRequest(null, null, null); Request receivedRequest = null; try { // Send using TI and collect using RI eventCollector.collectRequestEvent(riSipProvider); waitForMessage(); tiSipProvider.sendRequest(invite); waitForMessage(); RequestEvent receivedRequestEvent = eventCollector.extractCollectedRequestEvent(); assertNotNull("The sent request was not received at the other end!", receivedRequestEvent); assertNotNull( "The sent request was not received at the other end!", receivedRequestEvent.getRequest()); } catch (TooManyListenersException ex) { throw new TckInternalError( "The following exception was thrown while trying to add " + "a SipListener to an RI SipProvider", ex); } catch (SipException ex) { ex.printStackTrace(); fail("A SipException exception was thrown while " + "trying to send a request."); } } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); }
/** * Creates an invite request using the Tested Implementation and then tests creating a cancel for * the same invite request. */ public void testCreateCancel() { try { Request invite = createTiInviteRequest(null, null, null); ClientTransaction tran = null; try { tran = tiSipProvider.getNewClientTransaction(invite); } catch (TransactionUnavailableException exc) { throw new TiUnexpectedError( "A TransactionUnavailableException was thrown while trying to " + "create a new client transaction", exc); } Request cancel = null; try { cancel = tran.createCancel(); } catch (SipException ex) { ex.printStackTrace(); fail("Failed to create cancel request!"); } assertEquals( "The created request did not have a CANCEL method.", cancel.getMethod(), Request.CANCEL); assertEquals( "Request-URIs of the original and the cancel request do not match", cancel.getRequestURI(), invite.getRequestURI()); assertEquals( "Call-IDs of the original and the cancel request do not match", cancel.getHeader(CallIdHeader.NAME), invite.getHeader(CallIdHeader.NAME)); assertEquals( "ToHeaders of the original and the cancel request do not match", cancel.getHeader(ToHeader.NAME), invite.getHeader(ToHeader.NAME)); assertTrue( "The CSeqHeader's sequence number of the original and " + "the cancel request do not match", ((CSeqHeader) cancel.getHeader(CSeqHeader.NAME)).getSequenceNumber() == ((CSeqHeader) invite.getHeader(CSeqHeader.NAME)).getSequenceNumber()); assertEquals( "The CSeqHeader's method of the cancel request was not CANCEL", ((CSeqHeader) cancel.getHeader(CSeqHeader.NAME)).getMethod(), Request.CANCEL); assertTrue( "There was no ViaHeader in the cancel request", cancel.getHeaders(ViaHeader.NAME).hasNext()); Iterator cancelVias = cancel.getHeaders(ViaHeader.NAME); ViaHeader cancelVia = ((ViaHeader) cancelVias.next()); ViaHeader inviteVia = ((ViaHeader) invite.getHeaders(ViaHeader.NAME).next()); assertEquals( "ViaHeaders of the original and the cancel request do not match!", cancelVia, inviteVia); assertFalse("Cancel request had more than one ViaHeader.", cancelVias.hasNext()); } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); }
public void unregister() throws IOException { if (!isRegistered) { return; } cancelPendingRegistrations(); isRegistered = false; if (this.registerRequest == null) { Log.info("Couldn't find the initial register request"); throw new IOException("Couldn't find the initial register request"); } Request unregisterRequest = (Request) registerRequest.clone(); try { unregisterRequest.getExpires().setExpires(0); CSeqHeader cSeqHeader = (CSeqHeader) unregisterRequest.getHeader(CSeqHeader.NAME); // [issue 1] - increment registration cseq number // reported by - Roberto Tealdi <*****@*****.**> cSeqHeader.setSequenceNumber(cSeqHeader.getSequenceNumber() + 1); } catch (InvalidArgumentException e) { Log.info("Unable to set Expires Header " + e.getMessage()); return; } ClientTransaction unregisterTransaction = null; try { unregisterTransaction = sipProvider.getNewClientTransaction(unregisterRequest); } catch (TransactionUnavailableException e) { throw new IOException("Unable to create a unregister transaction " + e.getMessage()); } try { unregisterTransaction.sendRequest(); } catch (SipException e) { Log.info("Faied to send unregister request " + e.getMessage()); return; } }
/** Tests creating of ACK requests. */ public void testCreateAck() { try { // 1. Create and send the original request Request invite = createTiInviteRequest(null, null, null); RequestEvent receivedRequestEvent = null; ClientTransaction tran = null; try { tran = tiSipProvider.getNewClientTransaction(invite); eventCollector.collectRequestEvent(riSipProvider); tran.sendRequest(); waitForMessage(); receivedRequestEvent = eventCollector.extractCollectedRequestEvent(); if (receivedRequestEvent == null || receivedRequestEvent.getRequest() == null) throw new TiUnexpectedError("The sent request was not received by the RI!"); } catch (TooManyListenersException ex) { throw new TckInternalError( "A TooManyListenersException was thrown while trying to add " + "a SipListener to an RI SipProvider.", ex); } catch (SipException ex) { throw new TiUnexpectedError("The TI failed to send the request!", ex); } Request receivedRequest = receivedRequestEvent.getRequest(); // 2. Create and send the response Response ok = null; try { ok = riMessageFactory.createResponse(Response.OK, receivedRequest); } catch (ParseException ex) { throw new TckInternalError("Failed to create an OK response!", ex); } // Send the response using the RI and collect using TI try { eventCollector.collectResponseEvent(tiSipProvider); } catch (TooManyListenersException ex) { throw new TiUnexpectedError("Error while trying to add riSipProvider"); } try { riSipProvider.sendResponse(ok); } catch (SipException ex) { throw new TckInternalError("Could not send back the response", ex); } waitForMessage(); ResponseEvent responseEvent = eventCollector.extractCollectedResponseEvent(); // 3. Now let's create the ack if (responseEvent == null || responseEvent.getResponse() == null) throw new TiUnexpectedError("The TI failed to receive the response!"); if (responseEvent.getClientTransaction() != tran) throw new TiUnexpectedError( "The TI has associated a new ClientTransaction to a response " + "instead of using existing one!"); Request ack = null; try { ack = tran.createAck(); } catch (SipException ex) { ex.printStackTrace(); fail("A SipException was thrown while creating an ack request"); } assertNotNull("ClientTransaction.createAck returned null!", ack); assertEquals( "The created request did not have a CANCEL method.", ack.getMethod(), Request.ACK); assertEquals( "Request-URIs of the original and the ack request do not match", ack.getRequestURI(), invite.getRequestURI()); assertEquals( "Call-IDs of the original and the ack request do not match", ack.getHeader(CallIdHeader.NAME), invite.getHeader(CallIdHeader.NAME)); assertEquals( "ToHeaders of the original and the ack request do not match", ack.getHeader(ToHeader.NAME), invite.getHeader(ToHeader.NAME)); assertTrue( "The CSeqHeader's sequence number of the original and " + "the ack request do not match", ((CSeqHeader) ack.getHeader(CSeqHeader.NAME)).getSequenceNumber() == ((CSeqHeader) invite.getHeader(CSeqHeader.NAME)).getSequenceNumber()); assertEquals( "The CSeqHeader's method of the ack request was not ACK", ((CSeqHeader) ack.getHeader(CSeqHeader.NAME)).getMethod(), Request.ACK); } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); }
/** * Sends a request from the RI, generates a response at the TI side, sends it back and checks * whether it arrives at the RI. */ public void testSendResponse() { try { // 1. Create and send the original request Request invite = createRiInviteRequest(null, null, null); RequestEvent receivedRequestEvent = null; try { // Send using RI and collect using TI eventCollector.collectRequestEvent(tiSipProvider); riSipProvider.sendRequest(invite); waitForMessage(); receivedRequestEvent = eventCollector.extractCollectedRequestEvent(); if (receivedRequestEvent == null || receivedRequestEvent.getRequest() == null) throw new TiUnexpectedError("The sent request was not received by the RI!"); } catch (TooManyListenersException ex) { throw new TiUnexpectedError( "A TooManyListenersException was thrown while trying to add " + "a SipListener to a TI SipProvider.", ex); } catch (SipException ex) { throw new TckInternalError("The RI failed to send the request!", ex); } Request receivedRequest = receivedRequestEvent.getRequest(); // 2. Create and send the response // Create an ok response. We are not testing the message factory so let's // not leave it a chance to mess something up and specify the response // as completely as possible. List via = new LinkedList(); via.add(receivedRequest.getHeader(ViaHeader.NAME)); Response ok = null; try { ok = tiMessageFactory.createResponse( Response.OK, (CallIdHeader) receivedRequest.getHeader(CallIdHeader.NAME), (CSeqHeader) receivedRequest.getHeader(CSeqHeader.NAME), (FromHeader) receivedRequest.getHeader(FromHeader.NAME), (ToHeader) receivedRequest.getHeader(ToHeader.NAME), via, (MaxForwardsHeader) receivedRequest.getHeader(MaxForwardsHeader.NAME)); addStatus(receivedRequest, ok); } catch (ParseException ex) { throw new TiUnexpectedError("Failed to create an OK response!", ex); } // Send the response using the TI and collect using RI try { eventCollector.collectResponseEvent(riSipProvider); } catch (TooManyListenersException ex) { throw new TckInternalError("Error while trying to add riSipProvider"); } try { tiSipProvider.sendResponse(ok); } catch (SipException ex) { ex.printStackTrace(); fail("A SipException occurred while trying to send an ok response."); } waitForMessage(); ResponseEvent responseEvent = eventCollector.extractCollectedResponseEvent(); assertNotNull("The sent response was not received by the RI!", responseEvent); assertNotNull("The sent response was not received by the RI!", responseEvent.getResponse()); } catch (Throwable exc) { exc.printStackTrace(); fail(exc.getClass().getName() + ": " + exc.getMessage()); } assertTrue(new Exception().getStackTrace()[0].toString(), true); }
@Override public void run() { try { logger.logEntry(); // From FromHeader fromHeader = null; try { // this keep alive task only makes sense in case we have // a registrar so we deliberately use our AOR and do not // use the getOurSipAddress() method. fromHeader = provider .getHeaderFactory() .createFromHeader( provider.getRegistrarConnection().getAddressOfRecord(), SipMessageFactory.generateLocalTag()); } catch (ParseException ex) { // this should never happen so let's just log and bail. logger.error("Failed to generate a from header for " + "our register request.", ex); return; } // Call ID Header CallIdHeader callIdHeader = provider.getDefaultJainSipProvider().getNewCallId(); // CSeq Header CSeqHeader cSeqHeader = null; try { cSeqHeader = provider.getHeaderFactory().createCSeqHeader(getNextCSeqValue(), Request.OPTIONS); } catch (ParseException ex) { // Should never happen logger.error("Corrupt Sip Stack", ex); return; } catch (InvalidArgumentException ex) { // Should never happen logger.error("The application is corrupt", ex); return; } // To Header ToHeader toHeader = null; try { // this request isn't really going anywhere so we put our // own address in the To Header. toHeader = provider.getHeaderFactory().createToHeader(fromHeader.getAddress(), null); } catch (ParseException ex) { logger.error("Could not create a To header for address:" + fromHeader.getAddress(), ex); return; } // MaxForwardsHeader MaxForwardsHeader maxForwardsHeader = provider.getMaxForwardsHeader(); // Request Request request = null; try { // create a host-only uri for the request uri header. String domain = ((SipURI) toHeader.getAddress().getURI()).getHost(); // request URI SipURI requestURI = provider.getAddressFactory().createSipURI(null, domain); // Via Headers ArrayList<ViaHeader> viaHeaders = provider.getLocalViaHeaders(requestURI); request = provider .getMessageFactory() .createRequest( requestURI, Request.OPTIONS, callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwardsHeader); if (logger.isDebugEnabled()) logger.debug("Created OPTIONS request " + request); } catch (ParseException ex) { logger.error("Could not create an OPTIONS request!", ex); return; } Iterator<String> supportedMethods = provider.getSupportedMethods().iterator(); // add to the allows header all methods that we support while (supportedMethods.hasNext()) { String method = supportedMethods.next(); // don't support REGISTERs if (method.equals(Request.REGISTER)) continue; request.addHeader(provider.getHeaderFactory().createAllowHeader(method)); } Iterator<String> events = provider.getKnownEventsList().iterator(); synchronized (provider.getKnownEventsList()) { while (events.hasNext()) { String event = events.next(); request.addHeader(provider.getHeaderFactory().createAllowEventsHeader(event)); } } // Transaction ClientTransaction optionsTrans = null; try { optionsTrans = provider.getDefaultJainSipProvider().getNewClientTransaction(request); } catch (TransactionUnavailableException ex) { logger.error("Could not create options transaction!\n", ex); return; } try { optionsTrans.sendRequest(); if (logger.isDebugEnabled()) logger.debug("sent request= " + request); } catch (SipException ex) { logger.error("Could not send out the options request!", ex); if (ex.getCause() instanceof IOException) { // IOException problem with network disconnect(); } return; } } catch (Exception ex) { logger.error("Cannot send OPTIONS keep alive", ex); } }
/** * Process a request from a distant contact * * @param requestEvent the <tt>RequestEvent</tt> containing the newly received request. * @return <tt>true</tt> if the specified event has been handled by this processor and shouldn't * be offered to other processors registered for the same method; <tt>false</tt>, otherwise */ @Override public boolean processRequest(RequestEvent requestEvent) { synchronized (messageProcessors) { for (SipMessageProcessor listener : messageProcessors) if (!listener.processMessage(requestEvent)) return true; } // get the content String content = null; Request req = requestEvent.getRequest(); try { content = new String(req.getRawContent(), getCharset(req)); } catch (UnsupportedEncodingException ex) { if (logger.isDebugEnabled()) logger.debug("failed to convert the message charset"); content = new String(requestEvent.getRequest().getRawContent()); } // who sent this request ? FromHeader fromHeader = (FromHeader) requestEvent.getRequest().getHeader(FromHeader.NAME); if (fromHeader == null) { logger.error("received a request without a from header"); return false; } Contact from = opSetPersPresence.resolveContactID(fromHeader.getAddress().getURI().toString()); ContentTypeHeader ctheader = (ContentTypeHeader) req.getHeader(ContentTypeHeader.NAME); String ctype = null; String cencoding = null; if (ctheader == null) { ctype = DEFAULT_MIME_TYPE; } else { ctype = ctheader.getContentType() + "/" + ctheader.getContentSubType(); cencoding = ctheader.getParameter("charset"); } if (cencoding == null) cencoding = DEFAULT_MIME_ENCODING; Message newMessage = createMessage(content, ctype, cencoding, null); if (from == null) { if (logger.isDebugEnabled()) logger.debug( "received a message from an unknown contact: " + fromHeader.getAddress().getURI().toString()); // create the volatile contact from = opSetPersPresence.createVolatileContact(fromHeader.getAddress().getURI().toString()); } // answer ok try { Response ok = sipProvider.getMessageFactory().createResponse(Response.OK, requestEvent.getRequest()); SipStackSharing.getOrCreateServerTransaction(requestEvent).sendResponse(ok); } catch (ParseException exc) { logger.error("failed to build the response", exc); } catch (SipException exc) { logger.error("failed to send the response : " + exc.getMessage(), exc); } catch (InvalidArgumentException exc) { if (logger.isDebugEnabled()) logger.debug("Invalid argument for createResponse : " + exc.getMessage(), exc); } // fire an event MessageReceivedEvent msgReceivedEvt = new MessageReceivedEvent(newMessage, from, System.currentTimeMillis()); fireMessageEvent(msgReceivedEvt); return true; }