TerminatingAdhocGroupChatSession.java :  » UnTagged » android-rcs-ims-stack » com » orangelabs » rcs » core » ims » service » im » chat » Android Open Source

Android Open Source » UnTagged » android rcs ims stack 
android rcs ims stack » com » orangelabs » rcs » core » ims » service » im » chat » TerminatingAdhocGroupChatSession.java
/*******************************************************************************
 * Software Name : RCS IMS Stack
 * Version : 2.0
 * 
 * Copyright  2010 France Telecom S.A.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.orangelabs.rcs.core.ims.service.im.chat;

import java.io.IOException;
import java.util.Vector;

import javax.sip.header.SubjectHeader;

import com.orangelabs.rcs.core.ims.network.sip.SipManager;
import com.orangelabs.rcs.core.ims.network.sip.SipMessageFactory;
import com.orangelabs.rcs.core.ims.network.sip.SipUtils;
import com.orangelabs.rcs.core.ims.protocol.msrp.MsrpEventListener;
import com.orangelabs.rcs.core.ims.protocol.msrp.MsrpSession;
import com.orangelabs.rcs.core.ims.protocol.sdp.MediaAttribute;
import com.orangelabs.rcs.core.ims.protocol.sdp.MediaDescription;
import com.orangelabs.rcs.core.ims.protocol.sdp.SdpParser;
import com.orangelabs.rcs.core.ims.protocol.sdp.SdpUtils;
import com.orangelabs.rcs.core.ims.protocol.sip.SipRequest;
import com.orangelabs.rcs.core.ims.protocol.sip.SipResponse;
import com.orangelabs.rcs.core.ims.protocol.sip.SipTransactionContext;
import com.orangelabs.rcs.core.ims.service.ImsService;
import com.orangelabs.rcs.core.ims.service.ImsServiceSession;
import com.orangelabs.rcs.core.ims.service.im.InstantMessageError;
import com.orangelabs.rcs.core.ims.service.im.InstantMessageSession;
import com.orangelabs.rcs.utils.logger.Logger;

/**
 * Terminating ad-hoc group chat session
 * 
 * @author jexa7410
 */
public class TerminatingAdhocGroupChatSession extends InstantMessageSession implements MsrpEventListener {
  /**
     * The logger
     */
    private Logger logger = Logger.getLogger(this.getClass().getName());

    /**
     * Constructor
     * 
   * @param parent IMS service
   * @param invite Initial INVITE request
   */
  public TerminatingAdhocGroupChatSession(ImsService parent, SipRequest invite) {
    super(parent, SipUtils.getAssertedIdentity(invite),
        ((SubjectHeader)invite.getHeader(SubjectHeader.NAME)).getSubject());

    // Create dialog path
    createTerminatingDialogPath(invite);
  }

  /**
   * Background processing
   */
  public void run() {
    try {
        if (logger.isActivated()) {
          logger.info("Initiate a new ad-hoc group chat session as terminating");
        }
          
        // Send a 180 Ringing
      send180Ringing(getDialogPath().getInvite(), getDialogPath().getLocalTag());
      
      // Wait invitation answer
        int answer = waitInvitationAnswer();
      if (answer == ImsServiceSession.INVITATION_REJECTED) {
        if (logger.isActivated()) {
          logger.debug("Session has been rejected by user");
        }
        
          // Remove the current session
          getImsService().removeSession(this);

          // Notify listener
            if (getListener() != null) {
              getListener().handleSessionAborted();
            }
        return;
      } else
      if (answer == ImsServiceSession.INVITATION_NOT_ANSWERED) {
        if (logger.isActivated()) {
          logger.debug("Session has been rejected on timeout");
        }

        // Ringing period timeout
        send603Decline(getDialogPath().getInvite(), getDialogPath().getLocalTag());
        
          // Remove the current session
          getImsService().removeSession(this);

          // Notify listener
            if (getListener() != null) {
              getListener().handleSessionAborted();
            }
        return;
      }
      
        // Extract the SDP part
      byte[] remoteSdp = null;
        String content = getDialogPath().getInvite().getContent();
        String boundary = "--" + getDialogPath().getInvite().getBoundaryContentType();
        int index  = 0;
        while(index != -1) {
          int begin = content.indexOf(boundary, index);
          int end = content.indexOf(boundary, begin+boundary.length());
          if ((begin != -1) && (end != -1)) {
            String part = content.substring(begin+boundary.length(), end);
            if (part.indexOf("application/sdp") != -1) {
                // SDP
                String contentPart = part.substring(part.indexOf("v=")); // TODO: to be changed
              remoteSdp = contentPart.getBytes();
            } else
            if (part.indexOf("application/resource-lists+xml") != -1) {
              // Resource list: nothing done here
            }
          }
          index = end; 
        }

          // Parse the remote SDP part
          SdpParser parser = new SdpParser(remoteSdp);
        Vector<MediaDescription> media = parser.getMediaDescriptions();
      MediaDescription desc = media.elementAt(0);
      MediaAttribute attr1 = desc.getMediaAttribute("path");
            String remotePath = attr1.getValue();
        String remoteHost = SdpUtils.extractRemoteHost(parser.sessionDescription.connectionInfo);
        int remotePort = desc.port;
      
            // Extract the "setup" parameter
            String remoteSetup = "passive";
      MediaAttribute attr4 = desc.getMediaAttribute("setup");
      if (attr4 != null) {
        remoteSetup = attr4.getValue();
      }
            if (logger.isActivated()){
        logger.debug("Remote setup attribute is " + remoteSetup);
      }
            
        // Set setup mode
            String localSetup = "passive";
            if (remoteSetup.equals("active")) {
              // Passive mode: the terminal should wait a media connection
          localSetup = "passive";
            } else 
            if (remoteSetup.equals("passive")) {
              // Active mode: the terminal should initiate a media connection
          localSetup = "active";
            } else {
              // The terminal is active by default
          localSetup = "active";
            }
            if (logger.isActivated()){
        logger.debug("Local setup attribute is " + localSetup);
      }

      // Build SDP part
        String ntpTime = SipUtils.constructNTPtime(System.currentTimeMillis());
        String sdp =
          "v=0" + SipUtils.CRLF +
              "o=- " + ntpTime + " " + ntpTime + " IN IP4 " + getDialogPath().getSipStack().getLocalIpAddress() + SipUtils.CRLF +
              "s=-" + SipUtils.CRLF +
        "c=IN IP4 " + getDialogPath().getSipStack().getLocalIpAddress() + SipUtils.CRLF +
              "t=0 0" + SipUtils.CRLF +      
              "m=message " + getMsrpMgr().getLocalMsrpPort() + " TCP/MSRP *" + SipUtils.CRLF +
              "a=connection:new" + SipUtils.CRLF +
              "a=setup:" + localSetup + SipUtils.CRLF +
              "a=accept-types:message/cpim" + SipUtils.CRLF +
              "a=path:" + getMsrpMgr().getLocalMsrpPath() + SipUtils.CRLF +
          "a=sendrecv" + SipUtils.CRLF;

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

          // Test if the session should be interrupted
      if (isInterrupted()) {
        if (logger.isActivated()) {
          logger.debug("Session has been interrupted: end of processing");
        }
        return;
      }
          
        // Create the MSRP server session, setting the soTimeout on the socket to false
            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();
            } catch (IOException e) {
              if (logger.isActivated()) {
                    logger.error("Can't create the MSRP server session", e);
                  }
            }    
            }
          };
          thread.start();
            }
            
            // Send a 200 OK response
          if (logger.isActivated()) {
            logger.info("Send 200 OK");
          }
            SipResponse resp = SipMessageFactory.create200OkInviteResponse(getDialogPath(), sdp);

          // Set feature tags
          String[] tags = {SipUtils.FEATURE_OMA_IM};
          SipUtils.setFeatureTags(getDialogPath().getInvite(), tags);

          // Send the response
            SipTransactionContext ctx = getImsService().getImsModule().getSipManager().sendSipMessageAndWait(resp);
        
          // The signalisation is established
          getDialogPath().sigEstablished();

            // Wait response
            ctx.waitResponse(SipManager.TIMEOUT);
            
            // 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, setting the soTimeout on the socket to false
                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();
                }

                // Notify listener
              if (getListener() != null) {
                getListener().handleSessionStarted();
              }
            } else {
            if (logger.isActivated()) {
                logger.debug("No ACK received for INVITE");
              }

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

          // Unexpected error
      handleError(new InstantMessageError(InstantMessageError.UNEXPECTED_EXCEPTION,
          e.getMessage()));
    }    
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.