/* * TeleStax, Open Source Cloud Communications Copyright 2012. * 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.mobicents.protocols.ss7.map.service.oam; import org.apache.log4j.Logger; import org.mobicents.protocols.asn.AsnInputStream; import org.mobicents.protocols.asn.Tag; import org.mobicents.protocols.ss7.map.MAPDialogImpl; import org.mobicents.protocols.ss7.map.MAPProviderImpl; import org.mobicents.protocols.ss7.map.MAPServiceBaseImpl; import org.mobicents.protocols.ss7.map.api.MAPApplicationContext; import org.mobicents.protocols.ss7.map.api.MAPApplicationContextName; import org.mobicents.protocols.ss7.map.api.MAPApplicationContextVersion; import org.mobicents.protocols.ss7.map.api.MAPDialog; import org.mobicents.protocols.ss7.map.api.MAPException; import org.mobicents.protocols.ss7.map.api.MAPOperationCode; import org.mobicents.protocols.ss7.map.api.MAPParsingComponentException; import org.mobicents.protocols.ss7.map.api.MAPParsingComponentExceptionReason; import org.mobicents.protocols.ss7.map.api.MAPServiceListener; import org.mobicents.protocols.ss7.map.api.dialog.ServingCheckData; import org.mobicents.protocols.ss7.map.api.dialog.ServingCheckResult; import org.mobicents.protocols.ss7.map.api.primitives.AddressString; import org.mobicents.protocols.ss7.map.api.service.oam.MAPDialogOam; import org.mobicents.protocols.ss7.map.api.service.oam.MAPServiceOam; import org.mobicents.protocols.ss7.map.api.service.oam.MAPServiceOamListener; import org.mobicents.protocols.ss7.map.dialog.ServingCheckDataImpl; import org.mobicents.protocols.ss7.sccp.parameter.SccpAddress; import org.mobicents.protocols.ss7.tcap.api.tc.dialog.Dialog; import org.mobicents.protocols.ss7.tcap.asn.ApplicationContextName; import org.mobicents.protocols.ss7.tcap.asn.TcapFactory; import org.mobicents.protocols.ss7.tcap.asn.comp.ComponentType; import org.mobicents.protocols.ss7.tcap.asn.comp.Invoke; import org.mobicents.protocols.ss7.tcap.asn.comp.OperationCode; import org.mobicents.protocols.ss7.tcap.asn.comp.Parameter; /** * * @author sergey vetyutnev * */ public class MAPServiceOamImpl extends MAPServiceBaseImpl implements MAPServiceOam { protected Logger loger = Logger.getLogger(MAPServiceOamImpl.class); public MAPServiceOamImpl(MAPProviderImpl mapProviderImpl) { super(mapProviderImpl); } /* * Creating a new outgoing MAP OAM dialog and adding it to the MAPProvider.dialog collection */ public MAPDialogOam createNewDialog(MAPApplicationContext appCntx, SccpAddress origAddress, AddressString origReference, SccpAddress destAddress, AddressString destReference) throws MAPException { return this.createNewDialog(appCntx, origAddress, origReference, destAddress, destReference, null); } public MAPDialogOam createNewDialog(MAPApplicationContext appCntx, SccpAddress origAddress, AddressString origReference, SccpAddress destAddress, AddressString destReference, Long localTrId) throws MAPException { // We cannot create a dialog if the service is not activated if (!this.isActivated()) throw new MAPException("Cannot create MAPDialogOam because MAPServiceOam is not activated"); Dialog tcapDialog = this.createNewTCAPDialog(origAddress, destAddress, localTrId); MAPDialogOamImpl dialog = new MAPDialogOamImpl(appCntx, tcapDialog, this.mapProviderImpl, this, origReference, destReference); this.putMAPDialogIntoCollection(dialog); return dialog; } protected MAPDialogImpl createNewDialogIncoming(MAPApplicationContext appCntx, Dialog tcapDialog) { return new MAPDialogOamImpl(appCntx, tcapDialog, this.mapProviderImpl, this, null, null); } public void addMAPServiceListener(MAPServiceOamListener mapServiceListener) { super.addMAPServiceListener(mapServiceListener); } public void removeMAPServiceListener(MAPServiceOamListener mapServiceListener) { super.removeMAPServiceListener(mapServiceListener); } public ServingCheckData isServingService(MAPApplicationContext dialogApplicationContext) { MAPApplicationContextName ctx = dialogApplicationContext.getApplicationContextName(); int vers = dialogApplicationContext.getApplicationContextVersion().getVersion(); switch (ctx) { case imsiRetrievalContext: if (vers >= 2 && vers <= 2) { return new ServingCheckDataImpl(ServingCheckResult.AC_Serving); } else if (vers > 2) { long[] altOid = dialogApplicationContext.getOID(); altOid[7] = 3; ApplicationContextName alt = TcapFactory.createApplicationContextName(altOid); return new ServingCheckDataImpl(ServingCheckResult.AC_VersionIncorrect, alt); } else { return new ServingCheckDataImpl(ServingCheckResult.AC_VersionIncorrect); } case tracingContext: if (vers >= 1 && vers <= 3) { return new ServingCheckDataImpl(ServingCheckResult.AC_Serving); } else if (vers > 3) { long[] altOid = dialogApplicationContext.getOID(); altOid[7] = 3; ApplicationContextName alt = TcapFactory.createApplicationContextName(altOid); return new ServingCheckDataImpl(ServingCheckResult.AC_VersionIncorrect, alt); } else { return new ServingCheckDataImpl(ServingCheckResult.AC_VersionIncorrect); } } return new ServingCheckDataImpl(ServingCheckResult.AC_NotServing); } @Override public MAPApplicationContext getMAPv1ApplicationContext(int operationCode, Invoke invoke) { switch (operationCode) { case MAPOperationCode.activateTraceMode: return MAPApplicationContext.getInstance(MAPApplicationContextName.tracingContext, MAPApplicationContextVersion.version1); } return null; } public void processComponent(ComponentType compType, OperationCode oc, Parameter parameter, MAPDialog mapDialog, Long invokeId, Long linkedId, Invoke linkedInvoke) throws MAPParsingComponentException { // if an application-context-name different from version 1 is // received in a syntactically correct TC- // BEGIN indication primitive but is not acceptable from a load // control point of view, the MAP PM // shall ignore this dialogue request. The MAP-user is not informed. // if (compType == ComponentType.Invoke && this.mapProviderImpl.isCongested()) { // // TODO: we need to care of it // } MAPDialogOamImpl mapDialogOamImpl = (MAPDialogOamImpl) mapDialog; Long ocValue = oc.getLocalOperationCode(); if (ocValue == null) new MAPParsingComponentException("", MAPParsingComponentExceptionReason.UnrecognizedOperation); MAPApplicationContextName acn = mapDialog.getApplicationContext().getApplicationContextName(); int vers = mapDialog.getApplicationContext().getApplicationContextVersion().getVersion(); int ocValueInt = (int) (long) ocValue; switch (ocValueInt) { case MAPOperationCode.activateTraceMode: if (acn == MAPApplicationContextName.tracingContext) { if (compType == ComponentType.Invoke) this.processActivateTraceModeRequest(parameter, mapDialogOamImpl, invokeId); else this.processActivateTraceModeResponse(parameter, mapDialogOamImpl, invokeId, compType == ComponentType.ReturnResult); } break; case MAPOperationCode.sendIMSI: if (acn == MAPApplicationContextName.imsiRetrievalContext) { if (compType == ComponentType.Invoke) this.processSendImsiRequest(parameter, mapDialogOamImpl, invokeId); else this.processSendImsiResponse(parameter, mapDialogOamImpl, invokeId, compType == ComponentType.ReturnResult); } break; default: throw new MAPParsingComponentException("MAPServiceOam: unknown incoming operation code: " + ocValueInt, MAPParsingComponentExceptionReason.UnrecognizedOperation); } } private void processActivateTraceModeRequest(Parameter parameter, MAPDialogOamImpl mapDialogImpl, Long invokeId) throws MAPParsingComponentException { if (parameter == null) throw new MAPParsingComponentException( "Error while decoding processActivateTraceModeRequest: Parameter is mandatory but not found", MAPParsingComponentExceptionReason.MistypedParameter); if (parameter.getTag() != Tag.SEQUENCE || parameter.getTagClass() != Tag.CLASS_UNIVERSAL || parameter.isPrimitive()) throw new MAPParsingComponentException( "Error while decoding processActivateTraceModeRequest: Bad tag or tagClass or parameter is primitive, received tag=" + parameter.getTag(), MAPParsingComponentExceptionReason.MistypedParameter); byte[] buf = parameter.getData(); AsnInputStream ais = new AsnInputStream(buf); ActivateTraceModeRequestImpl_Oam ind = new ActivateTraceModeRequestImpl_Oam(); ind.decodeData(ais, buf.length); ind.setInvokeId(invokeId); ind.setMAPDialog(mapDialogImpl); for (MAPServiceListener serLis : this.serviceListeners) { try { serLis.onMAPMessage(ind); ((MAPServiceOamListener) serLis).onActivateTraceModeRequest_Oam(ind); } catch (Exception e) { loger.error("Error processing processActivateTraceModeRequest: " + e.getMessage(), e); } } } private void processActivateTraceModeResponse(Parameter parameter, MAPDialogOamImpl mapDialogImpl, Long invokeId, boolean returnResultNotLast) throws MAPParsingComponentException { ActivateTraceModeResponseImpl_Oam ind = new ActivateTraceModeResponseImpl_Oam(); if (parameter != null) { if (parameter.getTag() != Tag.SEQUENCE || parameter.getTagClass() != Tag.CLASS_UNIVERSAL || parameter.isPrimitive()) throw new MAPParsingComponentException( "Error while decoding processActivateTraceModeResponse: Bad tag or tagClass or parameter is primitive, received tag=" + parameter.getTag(), MAPParsingComponentExceptionReason.MistypedParameter); byte[] buf = parameter.getData(); AsnInputStream ais = new AsnInputStream(buf); ind.decodeData(ais, buf.length); } ind.setInvokeId(invokeId); ind.setMAPDialog(mapDialogImpl); ind.setReturnResultNotLast(returnResultNotLast); for (MAPServiceListener serLis : this.serviceListeners) { try { ((MAPServiceOamListener) serLis).onActivateTraceModeResponse_Oam(ind); } catch (Exception e) { loger.error("Error processing processActivateTraceModeResponse: " + e.getMessage(), e); } } } private void processSendImsiRequest(Parameter parameter, MAPDialogOamImpl mapDialogImpl, Long invokeId) throws MAPParsingComponentException { if (parameter == null) throw new MAPParsingComponentException( "Error while decoding processSendImsiRequest: Parameter is mandatory but not found", MAPParsingComponentExceptionReason.MistypedParameter); if (parameter.getTag() != Tag.STRING_OCTET || parameter.getTagClass() != Tag.CLASS_UNIVERSAL || !parameter.isPrimitive()) throw new MAPParsingComponentException( "Error while decoding processSendImsiRequest: Bad tag or tagClass or parameter is not primitive, received tag=" + parameter.getTag(), MAPParsingComponentExceptionReason.MistypedParameter); byte[] buf = parameter.getData(); AsnInputStream ais = new AsnInputStream(buf); SendImsiRequestImpl ind = new SendImsiRequestImpl(); ind.decodeData(ais, buf.length); ind.setInvokeId(invokeId); ind.setMAPDialog(mapDialogImpl); for (MAPServiceListener serLis : this.serviceListeners) { try { serLis.onMAPMessage(ind); ((MAPServiceOamListener) serLis).onSendImsiRequest(ind); } catch (Exception e) { loger.error("Error processing processSendImsiRequest: " + e.getMessage(), e); } } } private void processSendImsiResponse(Parameter parameter, MAPDialogOamImpl mapDialogImpl, Long invokeId, boolean returnResultNotLast) throws MAPParsingComponentException { if (parameter == null) throw new MAPParsingComponentException("Error while decoding processSendImsiResponse: Parameter is mandatory but not found", MAPParsingComponentExceptionReason.MistypedParameter); if (parameter.getTag() != Tag.STRING_OCTET || parameter.getTagClass() != Tag.CLASS_UNIVERSAL || !parameter.isPrimitive()) throw new MAPParsingComponentException( "Error while decoding processSendImsiResponse: Bad tag or tagClass or parameter is not primitive, received tag=" + parameter.getTag(), MAPParsingComponentExceptionReason.MistypedParameter); byte[] buf = parameter.getData(); AsnInputStream ais = new AsnInputStream(buf); SendImsiResponseImpl ind = new SendImsiResponseImpl(); ind.decodeData(ais, buf.length); ind.setInvokeId(invokeId); ind.setMAPDialog(mapDialogImpl); ind.setReturnResultNotLast(returnResultNotLast); for (MAPServiceListener serLis : this.serviceListeners) { try { serLis.onMAPMessage(ind); ((MAPServiceOamListener) serLis).onSendImsiResponse(ind); } catch (Exception e) { loger.error("Error processing processSendImsiResponse: " + e.getMessage(), e); } } } }