/**
   * Handle 200 0K response
   *
   * @param resp 200 OK response
   */
  public void handle200OK(SipResponse resp) {
    try {
      // 200 OK received
      if (logger.isActivated()) {
        logger.info("200 OK response received");
      }

      // The signalisation is established
      getDialogPath().sigEstablished();

      // Set the remote tag
      getDialogPath().setRemoteTag(resp.getToTag());

      // Set the target
      getDialogPath().setTarget(resp.getContactURI());

      // Set the route path with the Record-Route header
      Vector<String> newRoute = SipUtils.routeProcessing(resp, true);
      getDialogPath().setRoute(newRoute);

      // Set the remote SDP part
      getDialogPath().setRemoteContent(resp.getContent());

      // Parse the remote SDP part
      SdpParser parser = new SdpParser(getDialogPath().getRemoteContent().getBytes());
      Vector<MediaDescription> media = parser.getMediaDescriptions();
      MediaDescription mediaDesc = media.elementAt(0);
      MediaAttribute attr = mediaDesc.getMediaAttribute("path");
      String remoteMsrpPath = attr.getValue();
      String remoteHost = SdpUtils.extractRemoteHost(parser.sessionDescription.connectionInfo);
      int remotePort = mediaDesc.port;

      // Send ACK request
      if (logger.isActivated()) {
        logger.info("Send ACK");
      }
      getImsService().getImsModule().getSipManager().sendSipAck(getDialogPath());

      // The session is established
      getDialogPath().sessionEstablished();

      // Create the MSRP client session
      MsrpSession session =
          msrpMgr.createMsrpClientSession(remoteHost, remotePort, remoteMsrpPath, this);
      session.setFailureReportOption(false);
      session.setSuccessReportOption(true);

      // Open the MSRP session
      msrpMgr.openMsrpSession();

      // Start session timer
      if (getSessionTimerManager().isSessionTimerActivated(resp)) {
        getSessionTimerManager()
            .start(resp.getSessionTimerRefresher(), resp.getSessionTimerExpire());
      }

      // Notify listeners
      for (int i = 0; i < getListeners().size(); i++) {
        getListeners().get(i).handleSessionStarted();
      }

      // Start sending data chunks
      byte[] data = getContent().getData();
      InputStream stream;
      if (data == null) {
        // Load data from URL
        stream = FileFactory.getFactory().openFileInputStream(getContent().getUrl());
      } else {
        // Load data from memory
        stream = new ByteArrayInputStream(data);
      }
      msrpMgr.sendChunks(
          stream,
          ChatUtils.generateMessageId(),
          getContent().getEncoding(),
          getContent().getSize());
    } catch (Exception e) {
      if (logger.isActivated()) {
        logger.error("Session initiation has failed", e);
      }

      // Unexpected error
      handleError(new FileSharingError(FileSharingError.UNEXPECTED_EXCEPTION, e.getMessage()));
    }
  }
Esempio n. 2
0
  /** Background processing */
  public void run() {
    try {
      if (logger.isActivated()) {
        logger.info("Initiate a new 1-1 chat session as terminating");
      }

      // Send message delivery report if requested
      if ((ChatUtils.isImdnDeliveredRequested(getDialogPath().getInvite()))
          || (ChatUtils.isFileTransferOverHttp(getDialogPath().getInvite()))) {
        // Check notification disposition
        String msgId = ChatUtils.getMessageId(getDialogPath().getInvite());
        if (msgId != null) {
          // Send message delivery status via a SIP MESSAGE
          getImdnManager()
              .sendMessageDeliveryStatusImmediately(
                  getDialogPath().getRemoteParty(),
                  msgId,
                  ImdnDocument.DELIVERY_STATUS_DELIVERED,
                  SipUtils.getRemoteInstanceID(getDialogPath().getInvite()));
        }
      }

      // Check if Auto-accept (FT HTTP force auto-accept for the chat session)
      if (RcsSettings.getInstance().isChatAutoAccepted()
          || ChatUtils.getHttpFTInfo(getDialogPath().getInvite()) != null) {
        if (logger.isActivated()) {
          logger.info("Auto accept chat invitation");
        }
      } else {
        if (logger.isActivated()) {
          logger.info("Accept manually chat invitation");
        }

        // Send a 180 Ringing response
        send180Ringing(getDialogPath().getInvite(), getDialogPath().getLocalTag());

        // Wait invitation answer
        int answer = waitInvitationAnswer();
        if (answer == ImsServiceSession.INVITATION_REJECTED) {
          if (logger.isActivated()) {
            logger.info("Session has been rejected by user");
          }

          // Remove the current session
          getImsService().removeSession(this);

          // Notify listeners
          for (int i = 0; i < getListeners().size(); i++) {
            getListeners().get(i).handleSessionAborted(ImsServiceSession.TERMINATION_BY_USER);
          }
          return;
        } else if (answer == ImsServiceSession.INVITATION_NOT_ANSWERED) {
          if (logger.isActivated()) {
            logger.info("Session has been rejected on timeout");
          }

          // Ringing period timeout
          send486Busy(getDialogPath().getInvite(), getDialogPath().getLocalTag());

          // Remove the current session
          getImsService().removeSession(this);

          // Notify listeners
          for (int i = 0; i < getListeners().size(); i++) {
            getListeners().get(i).handleSessionAborted(ImsServiceSession.TERMINATION_BY_TIMEOUT);
          }
          return;
        } else if (answer == ImsServiceSession.INVITATION_CANCELED) {
          if (logger.isActivated()) {
            logger.info("Session has been canceled");
          }
          return;
        }
      }

      // Parse the remote SDP part
      String remoteSdp = getDialogPath().getInvite().getSdpContent();
      SdpParser parser = new SdpParser(remoteSdp.getBytes());
      Vector<MediaDescription> media = parser.getMediaDescriptions();
      MediaDescription mediaDesc = media.elementAt(0);
      MediaAttribute attr1 = mediaDesc.getMediaAttribute("path");
      String remotePath = attr1.getValue();
      String remoteHost = SdpUtils.extractRemoteHost(parser.sessionDescription, mediaDesc);
      int remotePort = mediaDesc.port;

      // Extract the "setup" parameter
      String remoteSetup = "passive";
      MediaAttribute attr2 = mediaDesc.getMediaAttribute("setup");
      if (attr2 != null) {
        remoteSetup = attr2.getValue();
      }
      if (logger.isActivated()) {
        logger.info("Remote setup attribute is " + remoteSetup);
      }

      // Set setup mode
      String localSetup = createSetupAnswer(remoteSetup);
      if (logger.isActivated()) {
        logger.debug("Local setup attribute is " + localSetup);
      }

      // Set local port
      int localMsrpPort;
      if (localSetup.equals("active")) {
        localMsrpPort = 9; // See RFC4145, Page 4
      } else {
        localMsrpPort = getMsrpMgr().getLocalMsrpPort();
      }

      // Build SDP part
      String ntpTime = SipUtils.constructNTPtime(System.currentTimeMillis());
      String ipAddress = getDialogPath().getSipStack().getLocalIpAddress();
      String sdp = null;
      if (isSecureProtocolMessage()) {
        sdp =
            "v=0"
                + SipUtils.CRLF
                + "o=- "
                + ntpTime
                + " "
                + ntpTime
                + " "
                + SdpUtils.formatAddressType(ipAddress)
                + SipUtils.CRLF
                + "s=-"
                + SipUtils.CRLF
                + "c="
                + SdpUtils.formatAddressType(ipAddress)
                + SipUtils.CRLF
                + "t=0 0"
                + SipUtils.CRLF
                + "m=message "
                + localMsrpPort
                + " "
                + getMsrpMgr().getLocalSocketProtocol()
                + " *"
                + SipUtils.CRLF
                + "a=accept-types:"
                + getAcceptTypes()
                + SipUtils.CRLF
                + "a=accept-wrapped-types:"
                + getWrappedTypes()
                + SipUtils.CRLF
                + "a=setup:"
                + localSetup
                + SipUtils.CRLF
                + "a=path:"
                + getMsrpMgr().getLocalMsrpPath()
                + SipUtils.CRLF
                + "a=fingerprint:"
                + KeyStoreManager.getFingerPrint()
                + SipUtils.CRLF
                + "a=sendrecv"
                + SipUtils.CRLF;
      } else {
        sdp =
            "v=0"
                + SipUtils.CRLF
                + "o=- "
                + ntpTime
                + " "
                + ntpTime
                + " "
                + SdpUtils.formatAddressType(ipAddress)
                + SipUtils.CRLF
                + "s=-"
                + SipUtils.CRLF
                + "c="
                + SdpUtils.formatAddressType(ipAddress)
                + SipUtils.CRLF
                + "t=0 0"
                + SipUtils.CRLF
                + "m=message "
                + localMsrpPort
                + " "
                + getMsrpMgr().getLocalSocketProtocol()
                + " *"
                + SipUtils.CRLF
                + "a=accept-types:"
                + getAcceptTypes()
                + SipUtils.CRLF
                + "a=accept-wrapped-types:"
                + getWrappedTypes()
                + SipUtils.CRLF
                + "a=setup:"
                + localSetup
                + SipUtils.CRLF
                + "a=path:"
                + getMsrpMgr().getLocalMsrpPath()
                + SipUtils.CRLF
                + "a=sendrecv"
                + SipUtils.CRLF;
      }

      // Set the local SDP part in the dialog path
      getDialogPath().setLocalContent(sdp);

      // Test if the session should be interrupted
      if (isInterrupted()) {
        if (logger.isActivated()) {
          logger.info("Session has been interrupted: end of processing");
        }
        return;
      }

      // Create the MSRP server session
      if (localSetup.equals("passive")) {
        // Passive mode: client wait a connection
        MsrpSession session = getMsrpMgr().createMsrpServerSession(remotePath, this);
        session.setFailureReportOption(false);
        session.setSuccessReportOption(false);

        // Open the connection
        Thread thread =
            new Thread() {
              public void run() {
                try {
                  // Open the MSRP session
                  getMsrpMgr().openMsrpSession();

                  // Send an empty packet
                  sendEmptyDataChunk();
                } catch (IOException e) {
                  if (logger.isActivated()) {
                    logger.error("Can't create the MSRP server session", e);
                  }
                }
              }
            };
        thread.start();
      }

      // Create a 200 OK response
      if (logger.isActivated()) {
        logger.info("Send 200 OK");
      }
      SipResponse resp = null;
      if (!RcsSettings.getInstance().isCPMSupported()) {
        resp = SipMessageFactory.create200OkInviteResponse(getDialogPath(), getFeatureTags(), sdp);
      } else {
        if (logger.isActivated()) {
          logger.info("TerminatingFOne2OneSession2  CPMS");
        }
        resp =
            SipMessageFactory.createCpm200OkInviteResponse(
                getDialogPath(), getCpimFeatureTags(), sdp);
      }

      if (RcsSettings.getInstance().isCPMSupported()) {
        if (logger.isActivated()) {
          logger.info("TerminatingFOne2OneSession3  CPMS");
        }
        if (getContributionID() != null) {
          resp.addHeader(ChatUtils.HEADER_CONTRIBUTION_ID, getContributionID());
        }
        if (getConversationID() != null) {
          resp.addHeader(ChatUtils.HEADER_CONVERSATION_ID, getConversationID());
        }
        if (getInReplyID() != null) {
          resp.addHeader(ChatUtils.HEADER_INREPLY_TO_CONTRIBUTION_ID, getInReplyID());
        }
      }

      // The signalisation is established
      getDialogPath().sigEstablished();

      // Send response
      SipTransactionContext ctx =
          getImsService().getImsModule().getSipManager().sendSipMessageAndWait(resp);

      // Analyze the received response
      if (ctx.isSipAck()) {
        // ACK received
        if (logger.isActivated()) {
          logger.info("ACK request received");
        }

        // The session is established
        getDialogPath().sessionEstablished();

        // Create the MSRP client session
        if (localSetup.equals("active")) {
          // Active mode: client should connect
          MsrpSession session =
              getMsrpMgr().createMsrpClientSession(remoteHost, remotePort, remotePath, this);
          session.setFailureReportOption(false);
          session.setSuccessReportOption(false);

          // Open the MSRP session
          getMsrpMgr().openMsrpSession();

          // Send an empty packet
          sendEmptyDataChunk();
        }

        // Notify listeners
        for (int i = 0; i < getListeners().size(); i++) {
          getListeners().get(i).handleSessionStarted();
        }

        if (logger.isActivated()) {
          logger.info(
              "ABC ACK request received Dialog expire time: "
                  + getDialogPath().getSessionExpireTime());
        }

        // Start session timer
        if (getSessionTimerManager().isSessionTimerActivated(resp)) {
          getSessionTimerManager()
              .start(SessionTimerManager.UAS_ROLE, getDialogPath().getSessionExpireTime());
        }

        // Start the activity manager
        getActivityManager().start();

      } else {
        if (logger.isActivated()) {
          logger.info("No ACK received for INVITE");
        }

        // No response received: timeout
        handleError(new ChatError(ChatError.SESSION_INITIATION_FAILED));
      }
    } catch (Exception e) {
      if (logger.isActivated()) {
        logger.error("Session initiation has failed", e);
      }

      // Unexpected error
      handleError(new ChatError(ChatError.UNEXPECTED_EXCEPTION, e.getMessage()));
    }
  }