Ejemplo n.º 1
0
  /**
   * handles the INVITED state.
   *
   * @param response the response
   * @param clientTransaction the client transaction
   * @throws SipException SIP stack related error
   */
  private void handleCallParticipantInvited(Response response, ClientTransaction clientTransaction)
      throws ParseException, SipException, InvalidArgumentException {
    FromHeader fromHeader = (FromHeader) response.getHeader(FromHeader.NAME);

    String displayName = fromHeader.getAddress().getDisplayName();

    int statusCode = response.getStatusCode();

    Logger.println(
        "handleCallParticipantInvited "
            + cp
            + " status "
            + statusCode
            + " "
            + response.getReasonPhrase());
    Logger.println("handleCallParticipantInvited , displayname " + displayName);

    CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);

    if (sipCallId.equals(callIdHeader.getCallId())
        && displayName.equals(cp.getDisplayName())
        && (statusCode == Response.OK || statusCode == Response.SESSION_PROGRESS)
        && ((CSeqHeader) response.getHeader(CSeqHeader.NAME)).getMethod().equals(Request.INVITE)) {
      if (statusCode == Response.SESSION_PROGRESS) {
        /*
         * For some calls, we never get an OK.  Instead we just get
         * SESSION_PROGRESS.  In order to handle these calls, we treat
         * SESSION_PROGRESS as OK.  If an OK arrives later, we'll
         * send an ACK.  This flag allows us to enable or
         * disable this workaround for each call.
         *
         * The problem with always treating SESSION_PROGRESS as OK
         * is that in a conference everybody will hear the ringing sound
         * which the remote call sends until the call is actually answered.
         * This can be avoided if joinConfirmation is specified.
         * The other problem is that if we treat SESSION_PROGRESS
         * as though the call has been answered, then we'll start
         * playing the treatment before a person really answers to
         * hear the treatment.
         */

        if (cp.getHandleSessionProgress() == false) {
          Logger.writeFile("Call " + cp + " Ignoring SESSION_PROGRESS");
          return;
        }

        Logger.writeFile("Call " + cp + " Treating SESSION_PROGRESS as OK");
      }

      if (response.getRawContent() == null) {
        Logger.error("Call " + cp + " no SDP in OK Response!");
        cancelRequest("SIP error!  no SDP in OK Response!");
        return;
      }

      this.clientTransaction = clientTransaction;

      if (statusCode == Response.OK) {
        gotOk = true;
        Logger.writeFile("Call " + cp + " Got OK, call answered\n" + response);
      }

      ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);

      /*
       * We got an OK response.
       *
       * send an ACK back to the CallParticipant
       */

      if (statusCode == Response.OK) {
        sipUtil.sendAck(clientTransaction);
        ackSent = true;
      }

      if (callAnswered) {
        Logger.writeFile("Call " + cp + " done processing OK");
        return;
      }

      /*
       * Remember the IP and port of where to send data to
       * the CallParticipant.
       */

      sdpBody = new String(response.getRawContent());

      SdpInfo sdpInfo;

      try {
        sdpInfo = sipUtil.getSdpInfo(sdpBody, false);

      } catch (ParseException e) {

        Logger.error("Call " + cp + " Invalid SDP in OK Response! " + e.getMessage());
        cancelRequest("SIP error!  Invalid SDP in OK Response!");
        return;
      }

      MediaInfo mediaInfo = sdpInfo.getMediaInfo();
      InetSocketAddress isa =
          new InetSocketAddress(sdpInfo.getRemoteHost(), sdpInfo.getRemotePort());
      InetSocketAddress rtcpAddress = sdpInfo.getRtcpAddress();
      setEndpointAddress(
          isa,
          mediaInfo.getPayload(),
          sdpInfo.getTransmitMediaInfo().getPayload(),
          sdpInfo.getTelephoneEventPayload(),
          rtcpAddress);

      /*
       * The CallParticipant has answered.
       * If join confirmation is required, we remain in the
       * INVITED state.  We set the callAnswered flag so that
       * if the join confirmation times out we know to
       * send a BYE rather than a CANCEL.
       */

      callAnswered = true;

      if (cp.getJoinConfirmationTimeout() == 0) {
        setState(CallState.ANSWERED);
      }

      /*
       * Start treatment if any and wait for it to finish.
       * When the treatment finishes, notification will
       * be delivered to our parent which will indicate
       * we're ready for the conference.
       *
       * If there's no treatment to be played, we're ready now
       * unless we're waiting for join confirmation..
       */
      initializeCallAnsweredTreatment();

      if (callAnsweredTreatment != null) {
        startCallAnsweredTreatment();
      } else {

        if (cp.getJoinConfirmationTimeout() == 0) {
          setState(CallState.ESTABLISHED);
        }
      }

    } else {
      Logger.writeFile("Call " + cp + " Ignoring response: " + response.getReasonPhrase());

      if (Logger.logLevel >= Logger.LOG_SIP) {
        Logger.println("Call " + cp + " Response: " + response);
      }
    }
  }