/** * Handle default error * * @param resp Error response */ public void handleDefaultError(SipResponse resp) { // Default handle handleError( new ImsSessionBasedServiceError( ImsSessionBasedServiceError.SESSION_INITIATION_FAILED, resp.getStatusCode() + " " + resp.getReasonPhrase())); }
/** * Handle 404 Session Not Found * * @param resp 404 response */ public void handle404SessionNotFound(SipResponse resp) { // Rejoin session has failed, we update the database with status terminated by remote RichMessaging.getInstance().addChatSessionTerminationByRemote(this); // Notify listener handleError(new ChatError(ChatError.SESSION_NOT_FOUND, resp.getReasonPhrase())); }
/** * Handle 407 Proxy Authentication Required * * @param resp 407 response */ public void handle407Authentication(SipResponse resp) { try { if (logger.isActivated()) { logger.info("407 response received"); } // Set the remote tag getDialogPath().setRemoteTag(resp.getToTag()); // Update the authentication agent getAuthenticationAgent().readProxyAuthenticateHeader(resp); // Increment the Cseq number of the dialog path getDialogPath().incrementCseq(); // Create a second INVITE request with the right token if (logger.isActivated()) { logger.info("Send second INVITE"); } SipRequest invite = SipMessageFactory.createInvite( getDialogPath(), InstantMessagingService.FT_FEATURE_TAGS, getDialogPath().getLocalContent()); // Reset initial request in the dialog path getDialogPath().setInvite(invite); // Set the Proxy-Authorization header getAuthenticationAgent().setProxyAuthorizationHeader(invite); // Send INVITE request sendInvite(invite); } catch (Exception e) { if (logger.isActivated()) { logger.error("Session initiation has failed", e); } // Unexpected error handleError(new FileSharingError(FileSharingError.UNEXPECTED_EXCEPTION, e.getMessage())); } }
/** * Handle 407 Proxy Authentication Required * * @param resp 407 response */ public void handle407Authentication(SipResponse resp) { try { if (logger.isActivated()) { logger.info("407 response received"); } // Set the remote tag getDialogPath().setRemoteTag(resp.getToTag()); // Update the authentication agent getAuthenticationAgent().readProxyAuthenticateHeader(resp); // Increment the Cseq number of the dialog path getDialogPath().incrementCseq(); // Create the invite request SipRequest invite = createInvite(); // Reset initial request in the dialog path getDialogPath().setInvite(invite); // Set the Proxy-Authorization header getAuthenticationAgent().setProxyAuthorizationHeader(invite); // Send INVITE request sendInvite(invite); } catch (Exception e) { if (logger.isActivated()) { logger.error("Session initiation has failed", e); } // Unexpected error handleError(new ImsServiceError(ImsServiceError.UNEXPECTED_EXCEPTION, e.getMessage())); } }
/** * 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())); } }
/** * Handle 603 Decline * * @param resp 603 response */ public void handle603Declined(SipResponse resp) { handleError( new ImsSessionBasedServiceError( ImsSessionBasedServiceError.SESSION_INITIATION_DECLINED, resp.getStatusCode() + " " + resp.getReasonPhrase())); }
/** * Handle 487 Cancel * * @param resp 487 response */ public void handle487Cancel(SipResponse resp) { handleError( new ImsSessionBasedServiceError( ImsSessionBasedServiceError.SESSION_INITIATION_CANCELLED, resp.getStatusCode() + " " + resp.getReasonPhrase())); }
/** * 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 signaling 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()); Capabilities capabilities = CapabilityUtils.extractCapabilities(resp); if (capabilities != null && this instanceof GroupChatSession) { ((GroupChatSession) this).setMsrpFtSupport(capabilities.isFileTransferSupported()); } // Set the remote SIP instance ID ContactHeader remoteContactHeader = (ContactHeader) resp.getHeader(ContactHeader.NAME); if (remoteContactHeader != null) { getDialogPath() .setRemoteSipInstance(remoteContactHeader.getParameter(SipUtils.SIP_INSTANCE_PARAM)); } // Prepare Media Session prepareMediaSession(); // Send ACK request if (logger.isActivated()) { logger.info("Send ACK"); } getImsService().getImsModule().getSipManager().sendSipAck(getDialogPath()); // The session is established getDialogPath().sessionEstablished(); // Start Media Session startMediaSession(); // Notify listeners for (int i = 0; i < getListeners().size(); i++) { getListeners().get(i).handleSessionStarted(); } // Start session timer if (getSessionTimerManager().isSessionTimerActivated(resp)) { getSessionTimerManager() .start(resp.getSessionTimerRefresher(), resp.getSessionTimerExpire()); } } catch (Exception e) { // Unexpected error if (logger.isActivated()) { logger.error("Session initiation has failed", e); } handleError(new ImsServiceError(ImsServiceError.UNEXPECTED_EXCEPTION, e.getMessage())); } }