/** * Ends the call with for this <tt>CallPeer</tt>. Depending on the state of the peer the method * would send a CANCEL, BYE, or BUSY_HERE message and set the new state to DISCONNECTED. * * @param failed indicates if the hangup is following to a call failure or simply a disconnect * @param reasonText the text, if any, to be set on the <tt>ReasonPacketExtension</tt> as the * value of its * @param reasonOtherExtension the <tt>PacketExtension</tt>, if any, to be set on the * <tt>ReasonPacketExtension</tt> as the value of its <tt>otherExtension</tt> property */ public void hangup(boolean failed, String reasonText, PacketExtension reasonOtherExtension) { // do nothing if the call is already ended if (CallPeerState.DISCONNECTED.equals(getState()) || CallPeerState.FAILED.equals(getState())) { if (logger.isDebugEnabled()) logger.debug("Ignoring a request to hangup a call peer " + "that is already DISCONNECTED"); return; } CallPeerState prevPeerState = getState(); getMediaHandler().getTransportManager().close(); if (failed) setState(CallPeerState.FAILED, reasonText); else setState(CallPeerState.DISCONNECTED, reasonText); SessionIQ responseIQ = null; if (prevPeerState.equals(CallPeerState.CONNECTED) || CallPeerState.isOnHold(prevPeerState)) { responseIQ = GTalkPacketFactory.createBye(getProtocolProvider().getOurJID(), peerJID, getSID()); responseIQ.setInitiator(isInitiator() ? getAddress() : getProtocolProvider().getOurJID()); } else if (CallPeerState.CONNECTING.equals(prevPeerState) || CallPeerState.CONNECTING_WITH_EARLY_MEDIA.equals(prevPeerState) || CallPeerState.ALERTING_REMOTE_SIDE.equals(prevPeerState)) { responseIQ = GTalkPacketFactory.createCancel(getProtocolProvider().getOurJID(), peerJID, getSID()); responseIQ.setInitiator(isInitiator() ? getAddress() : getProtocolProvider().getOurJID()); } else if (prevPeerState.equals(CallPeerState.INCOMING_CALL)) { responseIQ = GTalkPacketFactory.createBusy(getProtocolProvider().getOurJID(), peerJID, getSID()); responseIQ.setInitiator(isInitiator() ? getAddress() : getProtocolProvider().getOurJID()); } else if (prevPeerState.equals(CallPeerState.BUSY) || prevPeerState.equals(CallPeerState.FAILED)) { // For FAILED and BUSY we only need to update CALL_STATUS // as everything else has been done already. } else { logger.info("Could not determine call peer state!"); } if (responseIQ != null) { if (reasonOtherExtension != null) { ReasonPacketExtension reason = (ReasonPacketExtension) responseIQ.getExtension( ReasonPacketExtension.ELEMENT_NAME, ReasonPacketExtension.NAMESPACE); if (reason == null) { if (reasonOtherExtension instanceof ReasonPacketExtension) { responseIQ.setReason((ReasonPacketExtension) reasonOtherExtension); } } else reason.setOtherExtension(reasonOtherExtension); } getProtocolProvider().getConnection().sendPacket(responseIQ); } }
/** * Puts this peer into a {@link CallPeerState#DISCONNECTED}, indicating a reason to the user, if * there is one. * * @param sessionIQ the {@link SessionIQ} that's terminating our session. */ public void processSessionTerminate(SessionIQ sessionIQ) { String reasonStr = "Call ended by remote side."; ReasonPacketExtension reasonExt = sessionIQ.getReason(); if (reasonStr != null && reasonExt != null) { Reason reason = reasonExt.getReason(); if (reason != null) reasonStr += " Reason: " + reason.toString() + "."; String text = reasonExt.getText(); if (text != null) reasonStr += " " + text; } getMediaHandler().getTransportManager().close(); setState(CallPeerState.DISCONNECTED, reasonStr); }