org.mobicents.ussdgateway.slee.sip.SipClientSbb Maven / Gradle / Ivy
/*
* TeleStax, Open Source Cloud Communications
* Copyright 2011-2017, Telestax Inc and individual contributors
* by the @authors tag.
*
* This program is free software: you can redistribute it and/or modify
* under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see
*/
package org.mobicents.ussdgateway.slee.sip;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import javax.sdp.SdpFactory;
import javax.sip.ClientTransaction;
import javax.sip.Dialog;
import javax.sip.DialogState;
import javax.sip.ListeningPoint;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.ServerTransaction;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.header.CSeqHeader;
import javax.sip.header.CallIdHeader;
import javax.sip.header.ContactHeader;
import javax.sip.header.ContentLengthHeader;
import javax.sip.header.ContentTypeHeader;
import javax.sip.header.FromHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.MaxForwardsHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import javax.slee.ActivityContextInterface;
import javax.slee.SbbContext;
import javax.slee.resource.ResourceAdaptorTypeID;
import javolution.util.FastList;
import net.java.slee.resource.sip.DialogActivity;
import net.java.slee.resource.sip.SipActivityContextInterfaceFactory;
import net.java.slee.resource.sip.SleeSipProvider;
import org.mobicents.protocols.ss7.map.api.MAPMessage;
import org.mobicents.protocols.ss7.map.api.MAPMessageType;
import org.mobicents.protocols.ss7.map.api.datacoding.CBSDataCodingScheme;
import org.mobicents.protocols.ss7.map.api.primitives.AddressString;
import org.mobicents.protocols.ss7.map.api.primitives.ISDNAddressString;
import org.mobicents.protocols.ss7.map.api.primitives.USSDString;
import org.mobicents.protocols.ss7.map.api.service.supplementary.MAPDialogSupplementary;
import org.mobicents.protocols.ss7.map.api.service.supplementary.ProcessUnstructuredSSRequest;
import org.mobicents.protocols.ss7.map.api.service.supplementary.UnstructuredSSResponse;
import org.mobicents.protocols.ss7.map.dialog.MAPUserAbortChoiceImpl;
import org.mobicents.protocols.ss7.map.primitives.USSDStringImpl;
import org.mobicents.protocols.ss7.tcap.api.MessageType;
import org.mobicents.ussdgateway.AnyExt;
import org.mobicents.ussdgateway.EventsSerializeFactory;
import org.mobicents.ussdgateway.SipUssdErrorCode;
import org.mobicents.ussdgateway.SipUssdMessage;
import org.mobicents.ussdgateway.XmlMAPDialog;
import org.mobicents.ussdgateway.rules.ScRoutingRule;
import org.mobicents.ussdgateway.slee.ChildSbb;
import org.mobicents.ussdgateway.slee.cdr.RecordStatus;
/**
*
* @author amit bhayani
* @author sergey vetyutnev
*
*/
public abstract class SipClientSbb extends ChildSbb {
// Get the transport
private final String TRANSPORT = "udp";
public static final String FROM_DISPLAY_NAME = "MobicentsUSSDGateway";
private static final String CONTENT_TYPE = "application";
private static final String CONTENT_SUB_TYPE = "vnd.3gpp.ussd+xml";
private static final String RECV_INFO_HEADER_NAME = "Recv-Info";
private static final String RECV_INFO_HEADER_VALUE = "g.3gpp.ussd";
private static final String ACCEPT_HEADER_VALUE = "application/sdp; application/3gpp-ims+xml; application/vnd.3gpp.ussd+xml";
protected String ipAddress;
protected int port;
// /////////////////
// SIP RA Stuff //
// /////////////////
private static final ResourceAdaptorTypeID sipRATypeID = new ResourceAdaptorTypeID("JAIN SIP", "javax.sip", "1.2");
private static final String sipRALink = "SipRA";
protected SleeSipProvider provider;
protected AddressFactory addressFactory;
protected HeaderFactory headerFactory;
protected SdpFactory sdpFactory;
protected MessageFactory messageFactory;
protected SipActivityContextInterfaceFactory sipActConIntFac;
/** Creates a new instance of CallSbb */
public SipClientSbb() {
super("SipClientSbb");
}
// //////////////////////
// SIP Event handlers //
// //////////////////////
public void onTryingRespEvent(ResponseEvent event, ActivityContextInterface aci) {
if (this.logger.isFineEnabled()) {
this.logger.fine("Received the TRYING Response " + event.getResponse().getStatusCode()
+ " For SIP Dialog Id " + this.getDialogActivityId());
}
}
public void onProvisionalRespEvent(ResponseEvent event, ActivityContextInterface aci) {
if (this.logger.isFineEnabled()) {
this.logger.fine("Received the PROVISIONAL Response " + event.getResponse().getStatusCode()
+ " For SIP Dialog Id " + this.getDialogActivityId());
}
}
public void onSuccessRespEvent(ResponseEvent event, ActivityContextInterface aci) {
if (this.logger.isFineEnabled()) {
this.logger.fine("Received the SUCCESS Response " + event.getResponse().getStatusCode()
+ " For SIP Dialog Id " + this.getDialogActivityId());
}
try {
Response response = event.getResponse();
Dialog dialog = event.getDialog();
int status = response.getStatusCode();
if (logger.isFineEnabled()) {
logger.fine("Received success response event " + status);
}
CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
if (cseq.getMethod().equals(Request.INVITE)) {
// Send ACK
Request ack = dialog.createAck(dialog.getLocalSeqNumber());
dialog.sendAck(ack);
}
} catch (Exception e) {
logger.severe("Error while processing 2xx \n" + event, e);
this.sendServerErrorMessage();
this.abortSipDialog();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_TRANSPORT_FAILURE);
return;
}
}
public void onGlobalFailureRespEvent(ResponseEvent event, ActivityContextInterface aci) {
if (this.logger.isSevereEnabled()) {
this.logger.severe("Received GLOBAL_FAILURE Response " + event.getResponse().getStatusCode()
+ " For SIP Dialog Id " + this.getDialogActivityId());
}
this.sendServerErrorMessage();
abortSipDialog();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_TRANSPORT_ERROR);
return;
}
public void onClientErrorRespEvent(ResponseEvent event, ActivityContextInterface ac) {
if (this.logger.isSevereEnabled()) {
this.logger.severe("Received CLIENT_ERROR Response " + event.getResponse().getStatusCode()
+ " For SIP Dialog Id " + this.getDialogActivityId());
}
this.sendServerErrorMessage();
abortSipDialog();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_TRANSPORT_ERROR);
}
public void onServerErrorRespEvent(ResponseEvent event, ActivityContextInterface ac) {
if (this.logger.isSevereEnabled()) {
this.logger.severe("Received SERVER_ERROR Response " + event.getResponse().getStatusCode()
+ " For SIP Dialog Id " + this.getDialogActivityId());
}
this.sendServerErrorMessage();
abortSipDialog();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_TRANSPORT_ERROR);
}
public void onRedirectRespEvent(ResponseEvent event, ActivityContextInterface aci) {
logger.severe("Received onRedirectRespEvent " + event);
// TODO what to do?
}
public void onInfoReqEvent(RequestEvent event, ActivityContextInterface aci) {
if (logger.isInfoEnabled()) {
logger.info("Received onInfoReqEvent " + event);
}
this.cancelTimer();
Request request = event.getRequest();
try {
// send back ACK
ServerTransaction serverTransactionId = event.getServerTransaction();
Response response = this.messageFactory.createResponse(Response.OK, request);
serverTransactionId.sendResponse(response);
// TODO test content-type header
byte[] rawContent = request.getRawContent();
if (logger.isInfoEnabled()) {
logger.info("Payload " + rawContent);
}
if (rawContent == null || rawContent.length <= 0) {
logger.severe("Received INFO but USSD Payload is null \n" + event);
this.sendServerErrorMessage();
SipUssdMessage sipMsg = new SipUssdMessage(SipUssdErrorCode.unexpectedDataValue);
abortSipDialog(sipMsg);
this.createCDRRecord(RecordStatus.FAILED_CORRUPTED_MESSAGE);
return;
}
EventsSerializeFactory factory = this.getEventsSerializeFactory();
SipUssdMessage sipUssdMessage = factory.deserializeSipUssdMessage(rawContent);
if (sipUssdMessage == null) {
logger.severe("Received INFO but couldn't deserialize to SipUssdMessage. SipUssdMessage is null \n"
+ event);
this.sendServerErrorMessage();
SipUssdMessage sipMsg = new SipUssdMessage(SipUssdErrorCode.unexpectedDataValue);
this.sendBye(sipMsg);
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_CORRUPTED_MESSAGE);
return;
}
MAPDialogSupplementary mapDialogSupplementary = this.getMAPDialog();
if (mapDialogSupplementary == null) {
logger.warning("Error while processing INFO event: no MAP dialog is found, terminating of SIP dialog");
abortSipDialog();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_DIALOG_TIMEOUT);
return;
}
if (sipUssdMessage.isSuccessMessage()) {
CBSDataCodingScheme cbsDataCodingScheme = sipUssdMessage.getCBSDataCodingScheme();
USSDStringImpl ussdStr = new USSDStringImpl(sipUssdMessage.getUssdString(), cbsDataCodingScheme, null);
mapDialogSupplementary.addUnstructuredSSRequest(cbsDataCodingScheme, ussdStr, null, null);
super.ussdStatAggregator.updateUssdRequestOperations();
super.ussdStatAggregator.updateMessagesSent();
super.ussdStatAggregator.updateMessagesAll();
mapDialogSupplementary.send();
} else {
this.sendServerErrorMessage();
SipUssdMessage sipMsg = new SipUssdMessage(SipUssdErrorCode.unexpectedDataValue);
this.sendBye(sipMsg);
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.ABORT_APP);
return;
}
} catch (Exception e) {
logger.severe("Error while processing INFO event", e);
this.sendServerErrorMessage();
abortSipDialog();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_CORRUPTED_MESSAGE);
}
}
public void onCallTerminated(RequestEvent evt, ActivityContextInterface aci) {
if (this.logger.isFineEnabled()) {
this.logger.fine("Received BYE Request For SIP Dialog Id " + this.getDialogActivityId());
}
this.cancelTimer();
ServerTransaction tx = evt.getServerTransaction();
Request request = evt.getRequest();
try {
Response response = messageFactory.createResponse(Response.OK, request);
tx.sendResponse(response);
} catch (Exception e) {
logger.severe("Error while sending OK to received BYE \n" + evt, e);
}
try {
// TODO test content-type header
byte[] rawContent = request.getRawContent();
if (logger.isInfoEnabled()) {
logger.info("Payload " + rawContent);
}
if (rawContent == null || rawContent.length <= 0) {
logger.severe("Received BYE but USSD Payload is null \n" + evt);
this.sendServerErrorMessage();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_CORRUPTED_MESSAGE);
return;
}
EventsSerializeFactory factory = this.getEventsSerializeFactory();
SipUssdMessage sipUssdMessage = factory.deserializeSipUssdMessage(rawContent);
if (sipUssdMessage == null) {
logger.severe("Received BYE but couldn't deserialize to SipUssdMessage. SipUssdMessage is null \n"
+ evt);
this.sendServerErrorMessage();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_CORRUPTED_MESSAGE);
return;
}
MAPDialogSupplementary mapDialogSupplementary = this.getMAPDialog();
if (sipUssdMessage.isSuccessMessage()) {
CBSDataCodingScheme cbsDataCodingScheme = sipUssdMessage.getCBSDataCodingScheme();
USSDStringImpl ussdStr = new USSDStringImpl(sipUssdMessage.getUssdString(), cbsDataCodingScheme, null);
mapDialogSupplementary.addProcessUnstructuredSSResponse(this.getProcessUnstructuredSSRequestInvokeId(),
cbsDataCodingScheme, ussdStr);
mapDialogSupplementary.close(false);
this.createCDRRecord(RecordStatus.SUCCESS);
} else {
MAPUserAbortChoiceImpl abort = new MAPUserAbortChoiceImpl();
abort.setUserSpecificReason();
mapDialogSupplementary.abort(abort);
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.ABORT_APP);
}
} catch (Exception e) {
logger.severe("Error while processing BYE event \n" + evt, e);
this.sendServerErrorMessage();
this.updateDialogFailureStat();
this.createCDRRecord(RecordStatus.FAILED_CORRUPTED_MESSAGE);
}
}
@Override
public void setSbbContext(SbbContext sbbContext) {
super.setSbbContext(sbbContext);
try {
// initialize SIP API
this.sipActConIntFac = (SipActivityContextInterfaceFactory) super.sbbContext
.getActivityContextInterfaceFactory(sipRATypeID);
this.provider = (SleeSipProvider) super.sbbContext.getResourceAdaptorInterface(sipRATypeID, sipRALink);
// this.mapServiceFactory = this.mapProvider.getMapServiceFactory();
this.ipAddress = this.provider.getListeningPoint(TRANSPORT).getIPAddress();
this.port = this.provider.getListeningPoint(TRANSPORT).getPort();
addressFactory = provider.getAddressFactory();
headerFactory = provider.getHeaderFactory();
sdpFactory = SdpFactory.getInstance();
messageFactory = provider.getMessageFactory();
} catch (Exception ne) {
logger.severe("Could not set SBB context:", ne);
}
}
// //////////////////////////////
// Child abstract implemented //
// //////////////////////////////
@Override
protected void updateDialogFailureStat() {
super.ussdStatAggregator.updateDialogsAllFailed();
super.ussdStatAggregator.updateDialogsPullFailed();
super.ussdStatAggregator.updateDialogsSipFailed();
}
@Override
protected void sendUssdData(XmlMAPDialog xmlMAPDialog) throws Exception {
MessageType messageType = xmlMAPDialog.getTCAPMessageType();
switch (messageType) {
case Begin:
// Initiate SIP Dialog
// Create INVITE Request
Request inviteReq = this.buildInvite(getCall(), xmlMAPDialog);
this.logger.info("Trying to send INVITE message:\n" + inviteReq);
// get new Client Tx
ClientTransaction inviteCt = this.provider.getNewClientTransaction(inviteReq);
// TODO : Should it attach to Client Tx?
// Attach this SBB to Client Tx Activity
ActivityContextInterface calleeAci = this.sipActConIntFac.getActivityContextInterface(inviteCt);
calleeAci.attach(this.sbbContext.getSbbLocalObject());
// Get Dialog
Dialog dialog = inviteCt.getDialog();
if (dialog != null) {
if (this.logger.isFineEnabled()) {
this.logger.fine("Obtained dialog from ClientTransaction : automatic dialog support on");
}
} else {
// Automatic dialog support turned off
dialog = this.provider.getNewDialog(inviteCt);
if (this.logger.isFineEnabled()) {
this.logger.fine("Obtained dialog for INVITE request to callee with getNewDialog");
}
}
// Attach this SBB to Dialog Activity
ActivityContextInterface calleeDialogAci = this.sipActConIntFac
.getActivityContextInterface((DialogActivity) dialog);
calleeDialogAci.attach(this.sbbContext.getSbbLocalObject());
dialog.terminateOnBye(true);
// Send Request
inviteCt.sendRequest();
break;
case Continue:
UnstructuredSSResponse unstructuredSSResponse = (UnstructuredSSResponse) xmlMAPDialog.getMAPMessages()
.getFirst();
SipUssdMessage simMsg = new SipUssdMessage(unstructuredSSResponse.getDataCodingScheme(),
unstructuredSSResponse.getUSSDString());
simMsg.setAnyExt(new AnyExt(MAPMessageType.unstructuredSSRequest_Response));
byte[] data = this.getEventsSerializeFactory().serializeSipUssdMessage(simMsg);
String content = new String(data);
DialogActivity sipDialogActivity = this.getDialog();
Request infoRequest = sipDialogActivity.createRequest(Request.INFO);
// Create the Via header and add to an array list
ListeningPoint listeningPoint = provider.getListeningPoints()[0];
ViaHeader viaHeader = headerFactory.createViaHeader(listeningPoint.getIPAddress(), listeningPoint.getPort(),
listeningPoint.getTransport(), null);
viaHeader.setRPort();
infoRequest.setHeader(viaHeader);
ContentTypeHeader contentTypeHeader = headerFactory.createContentTypeHeader(CONTENT_TYPE, CONTENT_SUB_TYPE);
infoRequest.setContent(content, contentTypeHeader);
ContentLengthHeader contentLengthHeader = headerFactory.createContentLengthHeader(content.length());
infoRequest.setContentLength(contentLengthHeader);
ClientTransaction infoCt = provider.getNewClientTransaction(infoRequest);
// TODO : Should it attach to Client Tx?
// Attach this SBB to Client Tx Activity
ActivityContextInterface infoRequestAci = this.sipActConIntFac.getActivityContextInterface(infoCt);
infoRequestAci.attach(this.sbbContext.getSbbLocalObject());
sipDialogActivity.sendRequest(infoCt);
break;
case Abort:
abortSipDialog();
break;
case End:
// End can never come from Mobile side
// TODO may be this is error?
logger.severe("Received unexpected MessageType.End " + xmlMAPDialog);
abortSipDialog();
break;
case Unknown:
// Unknown can never come from Mobile side
// TODO may be this is error?
logger.severe("Received unexpected MessageType.Unknown " + xmlMAPDialog);
break;
default:
logger.severe("Received unidentified MessageType " + xmlMAPDialog);
break;
}
}
@Override
protected boolean checkProtocolConnection() {
return getDialog() != null;
}
private String generateTag() {
String tag = new Integer((int) (Math.random() * 10000)).toString();
return tag;
}
private ContactHeader createLocalContactHeader(String fromMsisdnStr) throws ParseException {
SipURI contactURI = this.addressFactory.createSipURI(fromMsisdnStr, this.ipAddress);
contactURI.setPort(this.port);
Address contactAddress = this.addressFactory.createAddress(contactURI);
contactAddress.setDisplayName(FROM_DISPLAY_NAME);
ContactHeader contactHeader = this.headerFactory.createContactHeader(contactAddress);
return contactHeader;
}
protected Request buildInvite(ScRoutingRule call, XmlMAPDialog xmlMAPDialog) throws Exception {
FastList mList = xmlMAPDialog.getMAPMessages();
MAPMessage mes = mList.getFirst();
if (mes == null) {
throw new NullPointerException("No USSD message to send to SIP.");
}
if (mes.getMessageType() != MAPMessageType.processUnstructuredSSRequest_Request) {
throw new Exception("Bad USSD message type to send to SIP: " + mes.getMessageType());
}
ProcessUnstructuredSSRequest pmes = (ProcessUnstructuredSSRequest) mes;
ISDNAddressString fromMsisdn = pmes.getMSISDNAddressString();
String fromMsisdnStr = null;
if(fromMsisdn != null){
fromMsisdnStr = fromMsisdn.getAddress();
} else {
AddressString fromAddressString = xmlMAPDialog.getReceivedOrigReference();
fromMsisdnStr = fromAddressString.getAddress();
}
USSDString ussd = pmes.getUSSDString();
CBSDataCodingScheme dcs = pmes.getDataCodingScheme();
String reqMessage = ussd.getString(null);
int ind1 = reqMessage.indexOf("#");
String destString;
if (ind1 > 0) {
destString = reqMessage.substring(0, ind1 + 1);
} else {
destString = reqMessage;
}
destString = destString.replaceAll("#", "%23");
SipURI toSipUri = addressFactory.createSipURI(destString, call.getSipProxy()); // user,
// host
Address toAddress = this.addressFactory.createAddress(toSipUri);
// !!!!: TODO: changing of To and SIP-URI to special USSD form
// To header:
ToHeader toHeader = headerFactory.createToHeader(toAddress, null);
// Locale x;
// From Header:
ListeningPoint listeningPoint = provider.getListeningPoints()[0];
SipURI fromAddressUri = addressFactory.createSipURI(fromMsisdnStr, listeningPoint.getIPAddress() + ":"
+ listeningPoint.getPort());
javax.sip.address.Address fromAddress = addressFactory.createAddress(fromAddressUri);
FromHeader fromHeader = headerFactory.createFromHeader(fromAddress, generateTag());
// Set the sequence number for the invite
CSeqHeader cseqHeader = headerFactory.createCSeqHeader(1l, Request.INVITE);
// Create the Via header and add to an array list
List viaHeadersList = new ArrayList(1);
ViaHeader viaHeader = headerFactory.createViaHeader(listeningPoint.getIPAddress(), listeningPoint.getPort(),
listeningPoint.getTransport(), null);
viaHeader.setRPort();
viaHeadersList.add(viaHeader);
MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
CallIdHeader callIdHeader = this.provider.getNewCallId();
Request request = this.messageFactory.createRequest(toSipUri, Request.INVITE, callIdHeader, cseqHeader,
fromHeader, toHeader, viaHeadersList, maxForwardsHeader);
ContactHeader contactHeader = createLocalContactHeader(fromMsisdnStr);
request.setHeader(contactHeader);
// Set Content
SipUssdMessage simMsg = new SipUssdMessage(pmes.getDataCodingScheme(), pmes.getUSSDString());
simMsg.setAnyExt(new AnyExt(MAPMessageType.processUnstructuredSSRequest_Request));
byte[] data = this.getEventsSerializeFactory().serializeSipUssdMessage(simMsg);
String content = new String(data);
// Set Content
ContentTypeHeader contentTypeHeader = this.headerFactory
.createContentTypeHeader(CONTENT_TYPE, CONTENT_SUB_TYPE);
request.setContent(content, contentTypeHeader);
ContentLengthHeader contentLengthHeader = headerFactory.createContentLengthHeader(content.length());
request.setContentLength(contentLengthHeader);
return request;
}
private DialogActivity getDialog() {
ActivityContextInterface[] acis = this.sbbContext.getActivities();
for (ActivityContextInterface aci : acis) {
if (aci.getActivity() instanceof DialogActivity) {
return (DialogActivity) aci.getActivity();
}
}
return null;
}
private String getDialogActivityId() {
DialogActivity act = this.getDialog();
if (act != null)
return act.getDialogId();
else
return null;
}
private void sendBye(SipUssdMessage simMsg) {
Dialog sipDialog = this.getDialog();
if (sipDialog == null) {
// Most probably the Dialog between the GW and application died!
return;
}
if (sipDialog.getState() == DialogState.CONFIRMED) {
// TODO : Confirm BYE is to be sent only for Confirmed Dialog
try {
Request byeRequest = sipDialog.createRequest(Request.BYE);
byte[] data = this.getEventsSerializeFactory().serializeSipUssdMessage(simMsg);
String content = new String(data);
ContentTypeHeader contentTypeHeader = this.headerFactory.createContentTypeHeader(CONTENT_TYPE,
CONTENT_SUB_TYPE);
byeRequest.setContent(content, contentTypeHeader);
ContentLengthHeader contentLengthHeader = headerFactory.createContentLengthHeader(content.length());
byeRequest.setContentLength(contentLengthHeader);
ClientTransaction ct = this.provider.getNewClientTransaction(byeRequest);
ActivityContextInterface calleeAci = this.sipActConIntFac.getActivityContextInterface(ct);
calleeAci.attach(this.sbbContext.getSbbLocalObject());
sipDialog.sendRequest(ct);
} catch (Exception e) {
this.logger.severe("Error while sending BYE Request ", e);
}
} else {
logger.warning("Trying to send BYE for Dialog that is not CONFIRMED. Will delete SIP Dialog \n" + sipDialog);
this.terminateProtocolConnection();
}
}
private void abortSipDialog() {
SipUssdMessage sipMsg = new SipUssdMessage(SipUssdErrorCode.errorUnspecified);
abortSipDialog(sipMsg);
}
private void abortSipDialog(SipUssdMessage sipMsg) {
this.sendBye(sipMsg);
}
@Override
protected void terminateProtocolConnection() {
Dialog sipDialog = this.getDialog();
if (sipDialog == null) {
// Most probably the Dialog between the GW and application died!
return;
}
sipDialog.delete();
}
protected boolean isSip() {
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy