All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.restcomm.camelgateway.slee.CamelBaseSbb Maven / Gradle / Ivy

/*
 * TeleStax, Open Source Cloud Communications  
 * Copyright 2012, Telestax Inc and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.restcomm.camelgateway.slee;

import java.io.IOException;

import javax.slee.ActivityContextInterface;
import javax.slee.CreateException;
import javax.slee.RolledBackContext;
import javax.slee.SbbContext;
import javax.slee.facilities.TimerFacility;
import javax.slee.facilities.Tracer;
import javax.slee.resource.ResourceAdaptorTypeID;

import javolution.util.FastList;
import javolution.util.FastMap;
import net.java.client.slee.resource.http.HttpClientActivityContextInterfaceFactory;
import net.java.client.slee.resource.http.HttpClientResourceAdaptorSbbInterface;

import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import org.restcomm.camelgateway.CamelStatAggregator;
import org.restcomm.camelgateway.EventsSerializeFactory;
import org.restcomm.camelgateway.XmlCAPDialog;
import org.mobicents.protocols.asn.AsnOutputStream;
import org.mobicents.protocols.ss7.cap.api.CAPDialog;
import org.mobicents.protocols.ss7.cap.api.CAPException;
import org.mobicents.protocols.ss7.cap.api.CAPMessage;
import org.mobicents.protocols.ss7.cap.api.CAPParameterFactory;
import org.mobicents.protocols.ss7.cap.api.CAPProvider;
import org.mobicents.protocols.ss7.cap.api.dialog.CAPUserAbortReason;
import org.mobicents.protocols.ss7.cap.api.errors.CAPErrorMessage;
import org.mobicents.protocols.ss7.cap.api.service.circuitSwitchedCall.CAPDialogCircuitSwitchedCall;
import org.mobicents.protocols.ss7.cap.api.service.circuitSwitchedCall.ConnectRequest;
import org.mobicents.protocols.ss7.cap.primitives.CAPAsnPrimitive;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.ApplyChargingReportRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.ApplyChargingRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.CancelRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.ConnectToResourceRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.ContinueRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.EventReportBCSMRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.FurnishChargingInformationRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.InitialDPRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.PromptAndCollectUserInformationRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.ReleaseCallRequestImpl;
import org.mobicents.protocols.ss7.cap.service.circuitSwitchedCall.RequestReportBCSMEventRequestImpl;
import org.mobicents.slee.SbbContextExt;
import org.mobicents.slee.resource.cap.CAPContextInterfaceFactory;

/**
 * @author Amit Bhayani
 * @author sergey vetyutnev
 * 
 */
public class CamelBaseSbb {

	/**
	 * 
	 */
	public CamelBaseSbb() {
		// TODO Auto-generated constructor stub
	}

	protected EventsSerializeFactory eventsSerializeFactory = null;

    // -------------------------------------------------------------
    // Statistics STUFF
    // -------------------------------------------------------------
    protected CamelStatAggregator camelStatAggregator;

	// -------------------------------------------------------------
	// SLEE STUFF
	// -------------------------------------------------------------
	protected SbbContextExt sbbContext;

	protected Tracer logger;
	
	protected TimerFacility timerFacility = null;

	// -------------------------------------------------------------
	// CAP RA STUFF
	// -------------------------------------------------------------
	protected static final ResourceAdaptorTypeID capRATypeID = new ResourceAdaptorTypeID("CAPResourceAdaptorType",
			"org.mobicents", "2.0");
	protected static final String capRaLink = "CAPRA";
	protected CAPContextInterfaceFactory capAcif;
	protected CAPProvider capProvider;
	protected CAPParameterFactory capParameterFactory;

	// -------------------------------------------------------------
	// HTTP Client RA STUFF
	// -------------------------------------------------------------
	protected static final ResourceAdaptorTypeID httpClientRATypeID = new ResourceAdaptorTypeID(
			"HttpClientResourceAdaptorType", "org.mobicents", "4.0");
	protected static final String httpClientRaLink = "HttpClientResourceAdaptor";

	protected HttpClientActivityContextInterfaceFactory httpClientActivityContextInterfaceFactory;
	protected HttpClientResourceAdaptorSbbInterface httpClientProvider;

	protected EventsSerializeFactory getEventsSerializeFactory() {
		if (this.eventsSerializeFactory == null) {
			this.eventsSerializeFactory = new EventsSerializeFactory();
		}
		return this.eventsSerializeFactory;
	}

	// -------------------------------------------------------------
	// SLEE minimal STUFF
	// -------------------------------------------------------------
	public void setSbbContext(SbbContext sbbContext) {
		this.sbbContext = (SbbContextExt) sbbContext;
		this.logger = sbbContext.getTracer("CAMEL-GW");

		this.eventsSerializeFactory = new EventsSerializeFactory();

		// CAP RA
		this.capAcif = (CAPContextInterfaceFactory) this.sbbContext.getActivityContextInterfaceFactory(capRATypeID);
		this.capProvider = (CAPProvider) this.sbbContext.getResourceAdaptorInterface(capRATypeID, capRaLink);
		this.capParameterFactory = this.capProvider.getCAPParameterFactory();

		// HTTP-Client RA
		this.httpClientActivityContextInterfaceFactory = (HttpClientActivityContextInterfaceFactory) this.sbbContext
				.getActivityContextInterfaceFactory(httpClientRATypeID);
		this.httpClientProvider = (HttpClientResourceAdaptorSbbInterface) this.sbbContext.getResourceAdaptorInterface(
				httpClientRATypeID, httpClientRaLink);

		camelStatAggregator = CamelStatAggregator.getInstance();

		this.timerFacility = this.sbbContext.getTimerFacility();
	}

	public void unsetSbbContext() {
		// clean RAs
		this.capAcif = null;
		this.capProvider = null;
		this.capParameterFactory = null;

		this.httpClientActivityContextInterfaceFactory = null;
		this.httpClientProvider = null;

		// clean SLEE
		this.sbbContext = null;
		this.logger = null;
	}

	public void sbbCreate() throws CreateException {
	}

	public void sbbPostCreate() throws CreateException {
	}

	public void sbbActivate() {
	}

	public void sbbPassivate() {
	}

	public void sbbLoad() {
	}

	public void sbbStore() {
	}

	public void sbbRemove() {
	}

	public void sbbExceptionThrown(Exception exception, Object object, ActivityContextInterface activityContextInterface) {
	}

	public void sbbRolledBack(RolledBackContext rolledBackContext) {
	}

	protected void processXmlCAPDialog(XmlCAPDialog xmlCAPDialog, CAPDialog capDialog, boolean isScf, FastList sentInvokeIds)
			throws CAPException {

	    // marking of incoming Invokes for which there will not be responses / errors
		FastList processInvokeWithoutAnswerIds = xmlCAPDialog.getProcessInvokeWithoutAnswerIds();
		for (FastList.Node n = processInvokeWithoutAnswerIds.head(), end = processInvokeWithoutAnswerIds.tail(); (n = n
				.getNext()) != end;) {
			capDialog.processInvokeWithoutAnswer(n.getValue());
		}

        int addedMsgs = 0;
		Boolean prearrangedEnd = xmlCAPDialog.getPrearrangedEnd();

        // sending of errors
		FastMap errorMessages = xmlCAPDialog.getErrorComponents().getErrorComponents();
        for (FastMap.Entry n = errorMessages.head(), end = errorMessages.tail(); (n = n.getNext()) != end;) {
            Long invokeId = n.getKey();
            CAPErrorMessage capError = n.getValue();
            capDialog.sendErrorComponent(invokeId, capError);
            addedMsgs++;
        }

        // sending of Invokes / RRL
        FastList capMessages = xmlCAPDialog.getCAPMessages();
        for (FastList.Node n = capMessages.head(), end = capMessages.tail(); (n = n.getNext()) != end;) {
            camelStatAggregator.updateMessagesSent();
            camelStatAggregator.updateMessagesAll();

            CAPMessage capMessage = n.getValue();
            if (addedMsgs > 0) {
                // we need to test if we have enough free space to send a component in the same massage
                int encodedSize;
                if (prearrangedEnd != null) {
                    encodedSize = capDialog.getMessageUserDataLengthOnClose(prearrangedEnd);
                } else {
                    encodedSize = capDialog.getMessageUserDataLengthOnSend();
                }

                CAPAsnPrimitive asnPrimitive = (CAPAsnPrimitive) capMessage;
                AsnOutputStream asnOs = new AsnOutputStream();
                int nextMessageSize = 10; // 10 = max component encoding header size
                try {
                    asnPrimitive.encodeAll(asnOs);
                    nextMessageSize += asnOs.size(); // 10 = max component encoding header size
                } catch (CAPException e) {
                    // ignore it: this means that a message does not have a parameter body
                }

                if (encodedSize + nextMessageSize + 5 > capDialog.getMaxUserDataLength()) {
                    capDialog.send();
                    addedMsgs = 0;
                }
            }

            ProcessComponentResult ps = this.processCAPMessageFromApplication(capMessage, capDialog, isScf);
            if (ps.componentAdded)
                addedMsgs++;
            if (ps.invokeId != null && sentInvokeIds != null) {
                sentInvokeIds.add(ps.invokeId);
            }
		}// for loop
	}

    protected ProcessComponentResult processCAPMessageFromApplication(CAPMessage capMessage, CAPDialog capDialog, boolean isScf)
            throws CAPException {
        ProcessComponentResult res = new ProcessComponentResult();

		switch (capMessage.getMessageType()) {
		case initialDP_Request:
			if (!isScf) {
				// If its acting as SSF we accept IDP
				InitialDPRequestImpl initialDPRequestImpl = (InitialDPRequestImpl) capMessage;

				res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addInitialDPRequest(
						initialDPRequestImpl.getServiceKey(), initialDPRequestImpl.getCalledPartyNumber(),
						initialDPRequestImpl.getCallingPartyNumber(), initialDPRequestImpl.getCallingPartysCategory(),
						initialDPRequestImpl.getCGEncountered(), initialDPRequestImpl.getIPSSPCapabilities(),
						initialDPRequestImpl.getLocationNumber(), initialDPRequestImpl.getOriginalCalledPartyID(),
						initialDPRequestImpl.getExtensions(), initialDPRequestImpl.getHighLayerCompatibility(),
						initialDPRequestImpl.getAdditionalCallingPartyNumber(),
						initialDPRequestImpl.getBearerCapability(), initialDPRequestImpl.getEventTypeBCSM(),
						initialDPRequestImpl.getRedirectingPartyID(), initialDPRequestImpl.getRedirectionInformation(),
						initialDPRequestImpl.getCause(), initialDPRequestImpl.getServiceInteractionIndicatorsTwo(),
						initialDPRequestImpl.getCarrier(), initialDPRequestImpl.getCugIndex(),
						initialDPRequestImpl.getCugInterlock(), initialDPRequestImpl.getCugOutgoingAccess(),
						initialDPRequestImpl.getIMSI(), initialDPRequestImpl.getSubscriberState(),
						initialDPRequestImpl.getLocationInformation(), initialDPRequestImpl.getExtBasicServiceCode(),
						initialDPRequestImpl.getCallReferenceNumber(), initialDPRequestImpl.getMscAddress(),
						initialDPRequestImpl.getCalledPartyBCDNumber(), initialDPRequestImpl.getTimeAndTimezone(),
						initialDPRequestImpl.getCallForwardingSSPending(),
						initialDPRequestImpl.getInitialDPArgExtension());
			} else {
				logger.warning("CAMEL Gw is acting as SCF and received InitialDPRequest from an application. Dropping request");
			}

			break;

		case applyCharging_Request:
			if (isScf) {
				ApplyChargingRequestImpl applyChargingRequest = (ApplyChargingRequestImpl) capMessage;
                res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addApplyChargingRequest(
						applyChargingRequest.getAChBillingChargingCharacteristics(),
						applyChargingRequest.getPartyToCharge(), applyChargingRequest.getExtensions(),
						applyChargingRequest.getAChChargingAddress());
			} else {
				logger.warning("CAMEL Gw is acting as SSF and received ApplyChargingRequest from an application. Dropping request");
			}

			break;
		case applyChargingReport_Request:
			if (!isScf) {
				ApplyChargingReportRequestImpl applyChargingReportRequestImpl = (ApplyChargingReportRequestImpl) capMessage;
                res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog)
						.addApplyChargingReportRequest(applyChargingReportRequestImpl.getTimeDurationChargingResult());

			} else {
				logger.warning("CAMEL Gw is acting as SCF and received ApplyChargingReportRequest from an application. Dropping request");
			}
			break;

		case cancel_Request:
			if (isScf) {
				CancelRequestImpl cancelRequest = (CancelRequestImpl) capMessage;
				if (cancelRequest.getAllRequests()) {
	                res.componentAdded = true;
				    res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addCancelRequest_AllRequests();
				} else if (cancelRequest.getCallSegmentToCancel() != null) {
	                res.componentAdded = true;
				    res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog)
							.addCancelRequest_CallSegmentToCancel(cancelRequest.getCallSegmentToCancel());
				} else if (cancelRequest.getInvokeID() != null) {
	                res.componentAdded = true;
				    res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addCancelRequest_InvokeId(cancelRequest
							.getInvokeID());
				}
			} else {
				logger.warning("CAMEL Gw is acting as SSF and received CancelRequest from an application. Dropping request");
			}

			break;

		case connect_Request:
			if (isScf) {
				ConnectRequest connectRequest = (ConnectRequest) capMessage;
                res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addConnectRequest(
						connectRequest.getDestinationRoutingAddress(), connectRequest.getAlertingPattern(),
						connectRequest.getOriginalCalledPartyID(), connectRequest.getExtensions(),
						connectRequest.getCarrier(), connectRequest.getCallingPartysCategory(),
						connectRequest.getRedirectingPartyID(), connectRequest.getRedirectionInformation(),
						connectRequest.getGenericNumbers(), connectRequest.getServiceInteractionIndicatorsTwo(),
						connectRequest.getChargeNumber(), connectRequest.getLegToBeConnected(),
						connectRequest.getCUGInterlock(), connectRequest.getCugOutgoingAccess(),
						connectRequest.getSuppressionOfAnnouncement(), connectRequest.getOCSIApplicable(),
						connectRequest.getNAOliInfo(), connectRequest.getBorInterrogationRequested());
			} else {
				logger.warning("CAMEL Gw is acting as SSF and received ConnectRequest from an application. Dropping request");
			}
			break;
		case continue_Request:
			if (isScf) {
				ContinueRequestImpl continueRequest = (ContinueRequestImpl) capMessage;
                res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addContinueRequest();
			} else {
				logger.warning("CAMEL Gw is acting as SSF and received ContinueRequest from an application. Dropping request");
			}
			break;
		case eventReportBCSM_Request:
			if (!isScf) {
				EventReportBCSMRequestImpl eventReportBCSMRequestImpl = (EventReportBCSMRequestImpl) capMessage;
                res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addEventReportBCSMRequest(
						eventReportBCSMRequestImpl.getEventTypeBCSM(),
						eventReportBCSMRequestImpl.getEventSpecificInformationBCSM(),
						eventReportBCSMRequestImpl.getLegID(), eventReportBCSMRequestImpl.getMiscCallInfo(),
						eventReportBCSMRequestImpl.getExtensions());

			} else {
				logger.warning("CAMEL Gw is acting as SCF and received EventReportBCSMRequest from an application. Dropping request");
			}
			break;
		case releaseCall_Request:
			if (isScf) {
				ReleaseCallRequestImpl releaseCallRequest = (ReleaseCallRequestImpl) capMessage;
                res.componentAdded = true;
				res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addReleaseCallRequest(releaseCallRequest.getCause());
			} else {
				logger.warning("CAMEL Gw is acting as SSF and received ReleaseCallRequest from an application. Dropping request");
			}
			break;
        case requestReportBCSMEvent_Request:
            if (isScf) {
                RequestReportBCSMEventRequestImpl requestReportBCSMEventRequest = (RequestReportBCSMEventRequestImpl) capMessage;
                res.componentAdded = true;
                res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog)
                        .addRequestReportBCSMEventRequest(requestReportBCSMEventRequest.getBCSMEventList(),
                                requestReportBCSMEventRequest.getExtensions());
            } else {
                logger.warning("CAMEL Gw is acting as SSF and received RequestReportBCSMEventRequest. Dropping request");
            }
            break;

        case connectToResource_Request:
                if (isScf) {
                    ConnectToResourceRequestImpl connectToResourceRequest = (ConnectToResourceRequestImpl) capMessage;
                    res.componentAdded = true;
                    res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addConnectToResourceRequest(
                            connectToResourceRequest.getResourceAddress_IPRoutingAddress(),
                            connectToResourceRequest.getResourceAddress_Null(), connectToResourceRequest.getExtensions(),
                            connectToResourceRequest.getServiceInteractionIndicatorsTwo(),
                            connectToResourceRequest.getCallSegmentID());
                } else {
                    logger.warning("CAMEL Gw is acting as SSF and received connectToResource_Request. Dropping request");
                }
            break;
        case furnishChargingInformation_Request:
            if (isScf) {
                    FurnishChargingInformationRequestImpl furnishChargingInformationRequestImplRequest = (FurnishChargingInformationRequestImpl) capMessage;
                    res.componentAdded = true;
                    res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog)
                            .addFurnishChargingInformationRequest(furnishChargingInformationRequestImplRequest
                                    .getFCIBCCCAMELsequence1());
            } else {
                logger.warning("CAMEL Gw is acting as SSF and received furnishChargingInformation_Request. Dropping request");
            }
        break;
        case promptAndCollectUserInformation_Request:
            if (isScf) {
                PromptAndCollectUserInformationRequestImpl promptAndCollectUserInformationRequest = (PromptAndCollectUserInformationRequestImpl) capMessage;
                    res.componentAdded = true;
                    res.invokeId = ((CAPDialogCircuitSwitchedCall) capDialog).addPromptAndCollectUserInformationRequest(
                            promptAndCollectUserInformationRequest.getCollectedInfo(),
                            promptAndCollectUserInformationRequest.getDisconnectFromIPForbidden(),
                            promptAndCollectUserInformationRequest.getInformationToSend(),
                            promptAndCollectUserInformationRequest.getExtensions(),
                            promptAndCollectUserInformationRequest.getCallSegmentID(),
                            promptAndCollectUserInformationRequest.getRequestAnnouncementStartedNotification());
            } else {
                logger.warning("CAMEL Gw is acting as SSF and received furnishChargingInformation_Request. Dropping request");
            }
        break;
		}// switch

		return res;
	}

	protected CAPDialog getCAPDialog() {
		ActivityContextInterface[] acis = this.sbbContext.getActivities();
		for (ActivityContextInterface aci : acis) {
			Object activity = aci.getActivity();
			if (activity instanceof CAPDialog) {
				return (CAPDialog) activity;
			}
		}

		return null;
	}

	protected void abort(CAPDialog capDialog) {
		if (capDialog != null) {
			try {
				capDialog.abort(CAPUserAbortReason.no_reason_given);
			} catch (CAPException e) {
				logger.severe("Exception while trying to abort CAP Dialog", e);
			}
		}
	}

	protected byte[] getResultData(HttpEntity entity) throws IOException {
		return EntityUtils.toByteArray(entity);
	}

    private class ProcessComponentResult {
        public boolean componentAdded;
        public Long invokeId;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy