/** * 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())); } }
/** 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())); } }