public void cancel(String[] protocol, int[] reasonCode, String[] reasonText) {
		if(proxy.getAckReceived()) throw new IllegalStateException("There has been an ACK received on this branch. Can not cancel.");
		
		try {			
			cancelTimer();
			if(this.isStarted() && !canceled && !timedOut &&
					(outgoingRequest.getMethod().equalsIgnoreCase(Request.INVITE) ||
							// https://code.google.com/p/sipservlets/issues/detail?id=253
							outgoingRequest.getMethod().equalsIgnoreCase(Request.PRACK) ||
							// https://code.google.com/p/sipservlets/issues/detail?id=33
							outgoingRequest.getMethod().equalsIgnoreCase(Request.UPDATE))) {
				if(lastResponse != null) { /* According to SIP RFC we should send cancel only if we receive any response first*/
					if(logger.isDebugEnabled()) {
						logger.debug("Trying to cancel ProxyBranch for outgoing request " + outgoingRequest);
					}
					if(lastResponse.getStatus() > Response.OK && !recursedBranches.isEmpty()) {
						//  Javadoc says it should throw an java.lang.IllegalStateException if the transaction has already been completed and it has no child branches
						if(logger.isDebugEnabled()) {
							logger.debug("lastResponse status for this branch is " + lastResponse.getStatus() + " and it has " + recursedBranches.size() + " to cancel");
						}
						return;
					}
					SipServletRequest cancelRequest = null;
					if(outgoingRequest.getMethod().equalsIgnoreCase(Request.PRACK) || outgoingRequest.getMethod().equalsIgnoreCase(Request.UPDATE)) {
						// https://code.google.com/p/sipservlets/issues/detail?id=253 and https://code.google.com/p/sipservlets/issues/detail?id=33
						// in case of PRACK or UPDATE we need to take the original INVITE
						cancelRequest = originalRequest.getLinkedRequest().createCancel();
					} else {
						cancelRequest = outgoingRequest.createCancel();
					}
					
					//https://code.google.com/p/sipservlets/issues/detail?id=272 Adding reason headers if needed
					if(protocol != null && reasonCode != null && reasonText != null
							&& protocol.length == reasonCode.length && reasonCode.length == reasonText.length) {
						for (int i = 0; i < protocol.length; i++) {
							String reasonHeaderValue = protocol[i] + ";cause=" + reasonCode[i];
							if(reasonText[i] != null && reasonText[i].trim().length() > 0) {
								reasonHeaderValue = reasonHeaderValue.concat(";text=\"" + reasonText[i] + "\"");
							}
							((SipServletRequestImpl)cancelRequest).setHeaderInternal("Reason", reasonHeaderValue, false);
							
						}
					}
					cancelRequest.send();
				} else {
					// We dont send cancel, but we must stop the invite retrans
					SIPClientTransaction tx = (SIPClientTransaction) outgoingRequest.getTransaction();
					
					if(tx != null) {
						StaticServiceHolder.disableRetransmissionTimer.invoke(tx);
						//disableTimeoutTimer.invoke(tx);
					} else {
						logger.warn("Transaction is null. Can not stop retransmission, they are already dead in the branch.");
					}
					/*
					try {
						//tx.terminate();
						// Do not terminate the tx here, because com.bea.sipservlet.tck.agents.spec.ProxyTest.testProxyCancel test is failing. If the tx
						// is terminated 100 Trying is dropped at JSIP.
					} catch(Exception e2) {
						logger.error("Can not terminate transaction", e2);
					}*/

				}
				canceled = true;
			}
			if(!this.isStarted() &&
					(outgoingRequest.getMethod().equalsIgnoreCase(Request.INVITE) ||
							// https://code.google.com/p/sipservlets/issues/detail?id=253
							outgoingRequest.getMethod().equalsIgnoreCase(Request.PRACK))) {
				canceled = true;	
			}
		}
		catch(Exception e) {
			throw new IllegalStateException("Failed canceling proxy branch", e);
		} finally {
			onBranchTerminated();
		}
			
	}
public void cancel ( String [ ] protocol , int [ ] reasonCode , String [ ] reasonText ) { if ( proxy . getAckReceived ( ) ) throw new IllegalStateException ( "There has been an ACK received on this branch. Can not cancel." ) ; try { cancelTimer ( ) ; if ( this . isStarted ( ) && ! canceled && ! timedOut && ( outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . INVITE ) || outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . PRACK ) || outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . UPDATE ) ) ) { if ( lastResponse != null ) { if ( logger . isDebugEnabled ( ) ) { logger . debug ( "Trying to cancel ProxyBranch for outgoing request " + outgoingRequest ) ; } if ( lastResponse . getStatus ( ) > Response . OK && ! recursedBranches . isEmpty ( ) ) { if ( logger . isDebugEnabled ( ) ) { logger . debug ( "lastResponse status for this branch is " + lastResponse . getStatus ( ) + " and it has " + recursedBranches . size ( ) + " to cancel" ) ; } return ; } SipServletRequest cancelRequest = null ; if ( outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . PRACK ) || outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . UPDATE ) ) { cancelRequest = originalRequest . getLinkedRequest ( ) . createCancel ( ) ; } else { cancelRequest = outgoingRequest . createCancel ( ) ; } if ( protocol != null && reasonCode != null && reasonText != null && protocol . length == reasonCode . length && reasonCode . length == reasonText . length ) { for ( int i = 0 ; i < protocol . length ; i ++ ) { String reasonHeaderValue = protocol [ i ] + ";cause=" + reasonCode [ i ] ; if ( reasonText [ i ] != null && reasonText [ i ] . trim ( ) . length ( ) > 0 ) { reasonHeaderValue = reasonHeaderValue . concat ( ";text=\"" + reasonText [ i ] + "\"" ) ; } ( ( SipServletRequestImpl ) cancelRequest ) . setHeaderInternal ( "Reason" , reasonHeaderValue , false ) ; } } cancelRequest . send ( ) ; } else { SIPClientTransaction tx = ( SIPClientTransaction ) outgoingRequest . getTransaction ( ) ; if ( tx != null ) { StaticServiceHolder . disableRetransmissionTimer . invoke ( tx ) ; } else { logger . warn ( "Transaction is null. Can not stop retransmission, they are already dead in the branch." ) ; } } canceled = true ; } if ( ! this . isStarted ( ) && ( outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . INVITE ) || outgoingRequest . getMethod ( ) . equalsIgnoreCase ( Request . PRACK ) ) ) { canceled = true ; } } catch ( Exception e ) { throw new IllegalStateException ( "Failed canceling proxy branch" , e ) ; } finally { onBranchTerminated ( ) ; } }
/*
(non-Javadoc)
@see javax.servlet.sip.ProxyBranch#cancel(java.lang.String[], int[], java.lang.String[])