/** 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); }
/** 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); }
/** * 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); }
private void sendInviteOK() { try { if (inviteTid.getState() != TransactionState.COMPLETED) { System.out.println("shootme: Dialog state before 486: " + inviteTid.getDialog().getState()); inviteTid.sendResponse(okResponse); System.out.println("shootme: Dialog state after 486: " + inviteTid.getDialog().getState()); } } catch (SipException ex) { ex.printStackTrace(); } catch (InvalidArgumentException ex) { ex.printStackTrace(); } }
/* * Begin Third-Party Call Control. */ public void initiateCall() throws IOException { try { try { busyTreatment = new TreatmentManager("busy.au", 0); } catch (IOException e) { Logger.println("Invalid busy treatment: " + e.getMessage()); } Logger.writeFile("Call " + cp + ": Begin SIP third party call"); setState(CallState.INVITED); InetSocketAddress isa = callHandler.getReceiveAddress(); if (isa == null) { throw new IOException("can't get receiver socket!"); } // send INVITE to the CallParticipant clientTransaction = sipUtil.sendInvite(cp, isa); if (clientTransaction == null) { Logger.error("Error placing call: " + cp); setState(CallState.ENDED, "Reason='Error placing call'"); throw new IOException("Error placing call: " + cp); } CallIdHeader callIdHeader = (CallIdHeader) clientTransaction.getRequest().getHeader(CallIdHeader.NAME); sipCallId = callIdHeader.getCallId(); sipServerCallback = SipServer.getSipServerCallback(); sipServerCallback.addSipListener(sipCallId, this); } catch (java.text.ParseException e) { Logger.println("Call " + cp + " Error placing call " + cp + ": " + e.getMessage()); setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'"); throw new IOException("Error placing call " + cp + " " + e.getMessage()); } catch (InvalidArgumentException e) { Logger.println("Call " + cp + " Error placing call " + cp + ": " + e.getMessage()); setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'"); throw new IOException("Error placing call " + cp + " " + e.getMessage()); } catch (SipException e) { Logger.println("Call " + cp + " Error placing call " + cp + ": " + e.getMessage()); setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'"); throw new IOException("Error placing call " + cp + " " + e.getMessage()); } }
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; } }
/** * handles a BYE request * * @param request the request * @param transId the transaction Id * @throws TransactionDoesNotExistException when the transaction record does not exist. */ private void handleBye(Request request, ServerTransaction st) { try { CallIdHeader callIdHeader = (CallIdHeader) request.getHeader("Call-Id"); String sipCallId = callIdHeader.getCallId(); if (sipCallId.equals(this.sipCallId)) { receivedBye = true; try { Logger.writeFile("Call " + cp + " has hung up."); // sipUtil.sendOK(clientTransaction, st, cp); sipUtil.sendOK(request, st); } catch (Exception e) { /* * We sometimes get a null ServerTransaction */ } cancelRequest("hung up"); sipServerCallback.removeSipListener(sipCallId); } else { /* * this should not happen since the message has been * delegated to this sip agent. */ throw new TransactionDoesNotExistException( cp + "BYE request received did not " + "match either party: " + request); } } catch (TransactionDoesNotExistException e) { Logger.error("Call " + cp + " Transaction not found " + e.getMessage()); } catch (SipException e) { Logger.exception("Call " + cp + " SIP Stack error", e); cancelRequest("handleBye: SIP Stack error " + e.getMessage()); } catch (Exception e) { Logger.exception("Call " + cp + " Unknown error ", e); cancelRequest("handleBye: SIP Stack error " + e.getMessage()); } }
public synchronized void processResponse(ResponseEvent responseReceivedEvent) { try { Response response = (Response) responseReceivedEvent.getResponse(); ClientTransaction clientTransaction = responseReceivedEvent.getClientTransaction(); int statusCode = response.getStatusCode(); FromHeader fromHeader = (FromHeader) response.getHeader(FromHeader.NAME); String displayName = fromHeader.getAddress().getDisplayName(); if (Logger.logLevel >= Logger.LOG_SIP) { Logger.println( "Response: statusCode " + statusCode + " state " + getCallState() + " fromHeader " + displayName + " call participant " + cp.getName()); } if (reasonCallTerminated != null) { /* * Ignore OK and Request Terminated. * XXX what's the symbol for 487? */ if (statusCode != Response.OK && statusCode != 487) { if (Logger.logLevel >= Logger.LOG_SIP) { Logger.println("Call " + cp + ": request cancelled, ignoring response"); } } CallIdHeader callIdHeader = (CallIdHeader) response.getHeader("Call-Id"); String sipCallId = callIdHeader.getCallId(); sipServerCallback.removeSipListener(sipCallId); return; } /* * Some type of global failure that prevents the * CallParticipant from being contacted, report failure. */ if (forceGatewayError) { statusCode = 500; forceGatewayError = false; } if (statusCode >= 500 && getState() == CallState.INVITED) { Logger.error( "Call " + cp + " gateway error: " + statusCode + " " + response.getReasonPhrase()); cancelRequest("gateway error: " + statusCode + " " + response.getReasonPhrase()); return; } else if (statusCode == Response.PROXY_AUTHENTICATION_REQUIRED || statusCode == Response.UNAUTHORIZED) { if (cp.getProxyCredentials() != null) { try { SipServer.handleChallenge(response, clientTransaction, cp.getProxyCredentials()) .sendRequest(); } catch (Exception e) { Logger.println("Proxy authentification failed " + e); } } return; } else if (statusCode >= 400) { // if we get a busy or an unknown error, play busy. Logger.println("Call " + cp + " got status code :" + statusCode); cp.setCallEndTreatment(null); cp.setConferenceJoinTreatment(null); cp.setConferenceLeaveTreatment(null); /* * play busy treatment, but deallocate any resources * held up by ringBack first, if any. */ // stopCallAnsweredTreatment(); if (statusCode == Response.BUSY_HERE) { try { if (busyTreatment != null) { addTreatment(busyTreatment); // busyTreatment.waitForTreatment(); } else { Logger.println("Unable to play busy treatment!!!"); } } catch (Exception e) { Logger.error("can't start busy treatment!" + sdpBody); } CallEvent callEvent = new CallEvent(CallEvent.BUSY_HERE); callEvent.setInfo(response.getReasonPhrase()); sendCallEventNotification(callEvent); } // sipUtil.sendBye(clientTransaction); cancelRequest(response.getReasonPhrase()); return; } /* state machine */ switch (getState()) { /* * CallParticipant picked up, send treatment if any, * and wait for it to finish. */ case CallState.INVITED: if (rejectCall) { Logger.error( "Call " + cp + " gateway error: " + statusCode + " " + response.getReasonPhrase()); cancelRequest("gateway error: " + statusCode + " " + response.getReasonPhrase()); return; } handleCallParticipantInvited(response, clientTransaction); break; /* * Call established, the ACK needs to be resent. * According to Ranga, this is done by the NIST SIP Stack. */ case CallState.ESTABLISHED: if (statusCode == Response.OK) { gotOk = true; Logger.writeFile("Call " + cp + " Got OK, ESTABLISHED"); if (ackSent == false) { sipUtil.sendAck(clientTransaction); ackSent = true; } } break; case CallState.ENDED: break; // ignore the response default: Logger.error("Process Response bad state " + getState() + "\n" + response); } } catch (SipException e) { Logger.exception("Call " + cp + " SIP Stack error ", e); cancelRequest("processResponse: SIP Stack error " + e.getMessage()); } catch (Exception e) { Logger.exception("processResponse: " + cp, e); cancelRequest("processResponse: SIP Stack error " + e.getMessage()); } }
/** 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; }