src/plugins/rayo/src/java/com/sun/voip/server/CallMigrator.java
/*
     * Migrate a call.  Set up the new call, join the conference and
     * terminate the original call.
     */
Migrate a call.  Set up the new call, join the conference and
terminate the original call.
Migrate a call . Set up the new call join the conference and terminate the original call .
public void run() {
	String callId = cp.getCallId();  
	CallHandler callHandler = CallHandler.findMigratingCall(callId);
	if (callHandler != null) {
	    /*
	     * Call migration is in progess.
	     * Cancel previous migration request.
	     */
	     callHandler.cancelRequest("new migration requested");
	}
	CallHandler previousCall = CallHandler.findCall(callId);
	if (previousCall == null) {
	    if (cp.getConferenceId() == null) {
	        Logger.println("Call migrator can't find call Id " + callId);
		return;
	    }
	    /*
	     * Treat it like a new call
	     */
	    migrateWithNoPreviousCall(requestHandler, cp);
	    return;
	}
if (false) {
	if (previousCall.isCallEstablished() == false) {
	    Logger.println(
		"Call migrator can't migrate call which is not established");
	    return;
	}
}
	CallParticipant previousCp = previousCall.getCallParticipant();
	String previousEndTreatment = previousCp.getCallEndTreatment();
        String previousLeaveTreatment = previousCp.getConferenceLeaveTreatment();
	previousCp.setCallEndTreatment(null);
	previousCp.setConferenceLeaveTreatment(null);
	cp.setMuted(previousCp.isMuted());	
	Logger.println("Call migrating " + previousCp + " preserving mute "
	    + previousCp.isMuted());
	if (cp.getConferenceId() == null) {
	    cp.setConferenceId(previousCp.getConferenceId());
	}
	if (cp.getName() == null) {
	    cp.setName(previousCp.getName());
	}
	/*
	 * SecondPartyNumber is the new number to call.
	 * If it starts with "Id-", it's a callId of
	 * a call already in progress.  Otherwise, it's a phone number to call.
	 */
	String secondParty = cp.getSecondPartyNumber();
	if (secondParty.indexOf("Id-") == 0) {
	    callHandler = CallHandler.findCall(secondParty.substring(3));
	    if (callHandler == null) {
		Logger.println("Can't find existing call to " + secondParty);
		return;
	    }
	    cp = callHandler.getCallParticipant();
	    cp.setCallId(previousCp.getCallId());
	} else {
	    /*
	     * Invite the secondParty if call is not already setup.
	     * After the party answers terminate the previous call.
	     */
	    cp.setPhoneNumber(cp.getSecondPartyNumber());
	    cp.setConferenceJoinTreatment(null);
	    /*
	     * Use the request handler from the previous call (if there
	     * is one) so that status changes will be sent to the same socket
	     * as the previous call.  This will make the migration seemless.
	     */
	    CallEventListener previousCallEventListener = (CallEventListener) previousCall.getRequestHandler();
	    if (previousCallEventListener != null) {
		requestHandler = previousCallEventListener;
	    }
	    /*
	     * Previous call is migrating.  It will probably be
	     * common for someone to hangup their cell phone before
	     * answering the new call.  In this case we need to
	     * suppress status from the previous call.
	     * However, if the previous call ends and then migration fails,
	     * we need to send call ending status back.
	     */
	    previousCall.suppressStatus = true;
	    OutgoingCallHandler newCall =
		new OutgoingCallHandler(requestHandler, cp);
	    previousCall.getMember().migrating();
	    synchronized(this) {
	        newCall.suppressStatus = true;
	        newCall.start();		
	        /*
	         * Wait for call to be established
	         */
	        if (newCall.waitForCallToBeEstablished() == false) {
		    String reason = newCall.getReasonCallEnded();
		    Logger.println("Migration failed: " + reason);
		    previousCp.setConferenceLeaveTreatment(previousLeaveTreatment);
		    previousCp.setCallEndTreatment(previousEndTreatment);
		    CallEvent callEvent = new CallEvent(CallEvent.STATE_CHANGED);
		    callEvent.setCallState(new CallState(CallState.ENDED));
		    callEvent.setInfo("Migration failed: " + reason);
		    newCall.suppressStatus = false;
		    newCall.sendCallEventNotification(callEvent);
		    previousCall.suppressStatus = false;
		    if (!previousCall.isCallEstablished()) {
	 	        previousCall.sendCallEventNotification(callEvent);
		    }
	            return;
	        }
	        newCall.suppressStatus = false;
	    }
	    if (previousCall.isCallEstablished() == true) {
		Logger.println("migrate mix descriptors for " + previousCall);
	        newCall.getMember().migrate(previousCall.getMember());
	    } else {
		Logger.println("migrate:  previous call is not established "
		    + previousCall);
	    }
	}
	Logger.println("Call " + previousCp
	    + " migrated to " + cp.getPhoneNumber());
	previousCall.suppressStatus = false;
	cp.setMigrateCall(false);	
	/*
	 * If the previous call ended early, we need to re-add
	 * it as a call status listener so that it will get the MIGRATED status
	 */
	if (!previousCall.isCallEstablished()) {
	    previousCall.addCallEventListener(previousCall.getRequestHandler());
	}
	CallEvent callEvent = new CallEvent(CallEvent.MIGRATED);
	callEvent.setInfo(previousCp + " migrated to " + cp);
	previousCall.sendCallEventNotification(callEvent);
	previousCall.suppressStatus = true;
	/*
	 * Suppress conference leave treatment.  No other calls should
	 * know that this call migrated.
	 */
	previousCp.setCallEndTreatment(null);
	previousCp.setConferenceLeaveTreatment(null);
	previousCall.cancelRequest("Call " + previousCp
	    + " migrated to " + cp.getPhoneNumber());
    }
public void run ( ) { String callId = cp . getCallId ( ) ; CallHandler callHandler = CallHandler . findMigratingCall ( callId ) ; if ( callHandler != null ) { /*
	     * Call migration is in progess.
	     * Cancel previous migration request.
	     */ callHandler . cancelRequest ( "new migration requested" ) ; } CallHandler previousCall = CallHandler . findCall ( callId ) ; if ( previousCall == null ) { if ( cp . getConferenceId ( ) == null ) { Logger . println ( "Call migrator can't find call Id " + callId ) ; return ; } /*
	     * Treat it like a new call
	     */ migrateWithNoPreviousCall ( requestHandler , cp ) ; return ; } if ( false ) { if ( previousCall . isCallEstablished ( ) == false ) { Logger . println ( "Call migrator can't migrate call which is not established" ) ; return ; } } CallParticipant previousCp = previousCall . getCallParticipant ( ) ; String previousEndTreatment = previousCp . getCallEndTreatment ( ) ; String previousLeaveTreatment = previousCp . getConferenceLeaveTreatment ( ) ; previousCp . setCallEndTreatment ( null ) ; previousCp . setConferenceLeaveTreatment ( null ) ; cp . setMuted ( previousCp . isMuted ( ) ) ; Logger . println ( "Call migrating " + previousCp + " preserving mute " + previousCp . isMuted ( ) ) ; if ( cp . getConferenceId ( ) == null ) { cp . setConferenceId ( previousCp . getConferenceId ( ) ) ; } if ( cp . getName ( ) == null ) { cp . setName ( previousCp . getName ( ) ) ; } /*
	 * SecondPartyNumber is the new number to call.
	 * If it starts with "Id-", it's a callId of
	 * a call already in progress.  Otherwise, it's a phone number to call.
	 */ String secondParty = cp . getSecondPartyNumber ( ) ; if ( secondParty . indexOf ( "Id-" ) == 0 ) { callHandler = CallHandler . findCall ( secondParty . substring ( 3 ) ) ; if ( callHandler == null ) { Logger . println ( "Can't find existing call to " + secondParty ) ; return ; } cp = callHandler . getCallParticipant ( ) ; cp . setCallId ( previousCp . getCallId ( ) ) ; } else { /*
	     * Invite the secondParty if call is not already setup.
	     * After the party answers terminate the previous call.
	     */ cp . setPhoneNumber ( cp . getSecondPartyNumber ( ) ) ; cp . setConferenceJoinTreatment ( null ) ; /*
	     * Use the request handler from the previous call (if there
	     * is one) so that status changes will be sent to the same socket
	     * as the previous call.  This will make the migration seemless.
	     */ CallEventListener previousCallEventListener = ( CallEventListener ) previousCall . getRequestHandler ( ) ; if ( previousCallEventListener != null ) { requestHandler = previousCallEventListener ; } /*
	     * Previous call is migrating.  It will probably be
	     * common for someone to hangup their cell phone before
	     * answering the new call.  In this case we need to
	     * suppress status from the previous call.
	     * However, if the previous call ends and then migration fails,
	     * we need to send call ending status back.
	     */ previousCall . suppressStatus = true ; OutgoingCallHandler newCall = new OutgoingCallHandler ( requestHandler , cp ) ; previousCall . getMember ( ) . migrating ( ) ; synchronized ( this ) { newCall . suppressStatus = true ; newCall . start ( ) ; /*
	         * Wait for call to be established
	         */ if ( newCall . waitForCallToBeEstablished ( ) == false ) { String reason = newCall . getReasonCallEnded ( ) ; Logger . println ( "Migration failed: " + reason ) ; previousCp . setConferenceLeaveTreatment ( previousLeaveTreatment ) ; previousCp . setCallEndTreatment ( previousEndTreatment ) ; CallEvent callEvent = new CallEvent ( CallEvent . STATE_CHANGED ) ; callEvent . setCallState ( new CallState ( CallState . ENDED ) ) ; callEvent . setInfo ( "Migration failed: " + reason ) ; newCall . suppressStatus = false ; newCall . sendCallEventNotification ( callEvent ) ; previousCall . suppressStatus = false ; if ( ! previousCall . isCallEstablished ( ) ) { previousCall . sendCallEventNotification ( callEvent ) ; } return ; } newCall . suppressStatus = false ; } if ( previousCall . isCallEstablished ( ) == true ) { Logger . println ( "migrate mix descriptors for " + previousCall ) ; newCall . getMember ( ) . migrate ( previousCall . getMember ( ) ) ; } else { Logger . println ( "migrate:  previous call is not established " + previousCall ) ; } } Logger . println ( "Call " + previousCp + " migrated to " + cp . getPhoneNumber ( ) ) ; previousCall . suppressStatus = false ; cp . setMigrateCall ( false ) ; /*
	 * If the previous call ended early, we need to re-add
	 * it as a call status listener so that it will get the MIGRATED status
	 */ if ( ! previousCall . isCallEstablished ( ) ) { previousCall . addCallEventListener ( previousCall . getRequestHandler ( ) ) ; } CallEvent callEvent = new CallEvent ( CallEvent . MIGRATED ) ; callEvent . setInfo ( previousCp + " migrated to " + cp ) ; previousCall . sendCallEventNotification ( callEvent ) ; previousCall . suppressStatus = true ; /*
	 * Suppress conference leave treatment.  No other calls should
	 * know that this call migrated.
	 */ previousCp . setCallEndTreatment ( null ) ; previousCp . setConferenceLeaveTreatment ( null ) ; previousCall . cancelRequest ( "Call " + previousCp + " migrated to " + cp . getPhoneNumber ( ) ) ; }
Migrate a call.
Migrate a call .
// call to migrate // preserve mute //Logger.logLevel = logLevel; // call new party //Logger.logLevel = logLevel; // call is no longer migrating