code: protected EventObject waitResponse(long timeout) {
      synchronized (responseBlock) {
        LinkedList<EventObject> events = transaction.getEvents();
        if (events.isEmpty()) {
          try {
            LOG.trace("about to block, waiting");
            responseBlock.waitForEvent(timeout);
            LOG.trace("we've come out of the block");
          } catch (Exception ex) {
            setException(ex);
            setErrorMessage("Exception: " + ex.getClass().getName() + ": " + ex.getMessage());
            setReturnCode(SipSession.EXCEPTION_ENCOUNTERED);
            return null;
          }
        }
  
        LOG.trace("either we got the response, or timed out");
  
        if (events.isEmpty()) {
          setReturnCode(SipSession.TIMEOUT_OCCURRED);
          setErrorMessage("The maximum amount of time to wait for a response message has elapsed.");
          return null;
        }
  
        return (EventObject) events.removeFirst();
      }
    }
docs: The waitResponse() method waits for a response for a previously sent subscription request
  message (SUBSCRIBE, REFER, ...).
  
  <p>
  This method blocks until one of the following occurs: 1) A javax.sip.ResponseEvent is received.
  This is the object returned by this method. 2) A javax.sip.TimeoutEvent is received. This is
  the object returned by this method. 3) The wait timeout period specified by the parameter to
  this method expires. Null is returned in this case. 4) An error occurs. Null is returned in
  this case.
  
  @param timeout The maximum amount of time to wait, in milliseconds. Use a value of 0 to wait
  indefinitely.
  @return A javax.sip.ResponseEvent, javax.sip.TimeoutEvent, or null in the case of wait
  parameter timeout or error. If null, call getReturnCode() and/or getErrorMessage() and,
  if applicable, getException() for further diagnostics.