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

org.restcomm.protocols.ss7.sccp.impl.router.RouterImpl Maven / Gradle / Ivy

There is a newer version: 10.0.37-java11
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2011, Red Hat, Inc. and individual contributors
 * Copyright 2019, Mobius Software LTD 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.protocols.ss7.sccp.impl.router;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.restcomm.protocols.ss7.sccp.LoadSharingAlgorithm;
import org.restcomm.protocols.ss7.sccp.LongMessageRule;
import org.restcomm.protocols.ss7.sccp.LongMessageRuleType;
import org.restcomm.protocols.ss7.sccp.Mtp3ServiceAccessPoint;
import org.restcomm.protocols.ss7.sccp.OriginationType;
import org.restcomm.protocols.ss7.sccp.Router;
import org.restcomm.protocols.ss7.sccp.Rule;
import org.restcomm.protocols.ss7.sccp.RuleType;
import org.restcomm.protocols.ss7.sccp.SccpStack;
import org.restcomm.protocols.ss7.sccp.impl.SccpOAMMessage;
import org.restcomm.protocols.ss7.sccp.impl.parameter.SccpAddressImpl;
import org.restcomm.protocols.ss7.sccp.parameter.SccpAddress;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 

* The default implementation for the SCCP router. *

* *

* The SCCP router allows to add/remove/list routing rules and implements persistence for the routing rules. *

*

* RouterImpl when {@link #start() started} looks for file sccprouter.xml containing serialized information of * underlying {@link RuleImpl}. Set the directory path by calling {@link #setPersistDir(String)} to direct RouterImpl to look at * specified directory for underlying serialized file. *

*

* If directory path is not set, RouterImpl searches for system property sccprouter.persist.dir to get the path for * directory *

* *

* Even if sccprouter.persist.dir system property is not set, RouterImpl will look at property user.dir *

* *

* Implementation of SCCP routing mechanism makes routing decisions based on rules. Each rule consists of three elements: *

    *
  • *

    * The pattern determines pattern to which destination address is compared. It has complex structure which looks as * follows: *

      *
    • *

      * translation type (tt) integer numer which is used in a network to indicate the preferred method of global title * analysis *

      *
    • *
    • *

      * numbering plan (np) integer value which inidcates which numbering plan will be used for the global title. Its value * aids the routing system in determining the correct network system to route message to. *

      *
    • *
    • *

      * nature of address (noa) integer value which indicates address type., Specifically it indicates the scope of the * address value, such as whether it is an international number (i.e. including the country code), a "national" or domestic * number (i.e. without country code), and other formats such as "local" format. *

      *
    • *
    • *

      * digits (digits) actual address *

      *
    • *
    • *

      * sub-system number (ssn) identifies application in SCCP routing network. *

      *
    • *
    *

    *
  • *
  • *

    * The translation determines target for messages which destination address matches pattern. It has exactly the same * structure as pattern . *

    *
  • *
  • *

    * The mtpinfo determines mtp layer information. If translation does not indicate local address, this information is used * to send message through MTP layer. It has following structure: *

      *
    • *

      * name (name) identifying one of link sets used by SCCP *

      *
    • *
    • *

      * originating point code (opc) local point code used as originating MTP address *

      *
    • *
    • *

      * adjacent point code (apc) remote point code used as destination MTP address *

      *
    • *
    • *

      * signaling link selection (sls) indentifies link in set *

      *
    • *
    *

    *
  • *
*

*

* While the pattern is mandatory, translation and mtpinfo is optional. Following combinations are possible *

    *
  • *

    * pattern and translation : specifies local routing *

    *
  • *
  • *

    * pattern and mtpinfo : specifies remote routing using specified mtp routing info and no translation needed *

    *
  • *
  • *

    * pattern, translation and mtpinfo specifies remote routing using specified mtp routing info after * applying specified translation *

    *
  • *
*

* * @author amit bhayani * @author kulikov * @author yulianoifa */ public class RouterImpl implements Router { private static final Logger logger = LogManager.getLogger(RouterImpl.class); // rule list private RuleMap rulesMap = new RuleMap(); private SccpAddressMap routingAddresses = new SccpAddressMap(); private LongMessageRuleMap longMessageRules = new LongMessageRuleMap(); private Mtp3ServiceAccessPointMap saps = new Mtp3ServiceAccessPointMap(); private final String name; private final SccpStack sccpStack; public RouterImpl(String name, SccpStack sccpStack) { this.name = name; this.sccpStack = sccpStack; } public String getName() { return name; } public void start() { logger.info("Started SCCP Router"); } public void stop() { } /** * Looks up rule for translation. * * @param calledParty called party address * @return the rule with match to the called party address */ public Rule findRule(SccpAddress calledParty, SccpAddress callingParty, boolean isMtpOriginated, int msgNetworkId) { Iterator iterator=this.rulesMap.values().iterator(); while(iterator.hasNext()) { Rule rule = iterator.next(); if (rule.matches(calledParty, callingParty, isMtpOriginated, msgNetworkId)) { return rule; } } return null; } public LongMessageRule findLongMessageRule(int dpc) { Iterator iterator=this.longMessageRules.values().iterator(); while(iterator.hasNext()) { LongMessageRule rule = iterator.next(); if (rule.matches(dpc)) { return rule; } } return null; } public Mtp3ServiceAccessPoint findMtp3ServiceAccessPoint(int dpc, int sls) { Iterator iterator=this.saps.values().iterator(); while(iterator.hasNext()) { Mtp3ServiceAccessPoint sap = iterator.next(); if (sap.matches(dpc, sls)) { return sap; } } return null; } public Mtp3ServiceAccessPoint findMtp3ServiceAccessPoint(int dpc, int sls, int networkId) { Iterator iterator=this.saps.values().iterator(); while(iterator.hasNext()) { Mtp3ServiceAccessPoint sap = iterator.next(); if (sap.matches(dpc, sls)) { if (sap.getNetworkId() == networkId) { return sap; } } } return null; } public Mtp3ServiceAccessPoint findMtp3ServiceAccessPointForIncMes(int localPC, int remotePC, String localGtDigits) { Iterator iterator=this.saps.values().iterator(); while(iterator.hasNext()) { Mtp3ServiceAccessPoint sap = iterator.next(); if (sap.getLocalGtDigits() != null && sap.getLocalGtDigits().length() > 0) { if (sap.getOpc() == localPC && sap.matches(remotePC) && (localGtDigits != null && localGtDigits.equals(sap.getLocalGtDigits()))) { return sap; } } } // a second step - sap's without LocalGtDigits iterator=this.saps.values().iterator(); while(iterator.hasNext()) { Mtp3ServiceAccessPoint sap = iterator.next(); if (sap.getLocalGtDigits() == null || sap.getLocalGtDigits().length() == 0) { if (sap.getOpc() == localPC && sap.matches(remotePC)) { return sap; } } } return null; } public Rule getRule(int id) { return this.rulesMap.get(id); } public SccpAddress getRoutingAddress(int id) { return this.routingAddresses.get(id); } // public SccpAddress getBackupAddress(int id) { // return this.backupAddresses.get(id); // } public LongMessageRule getLongMessageRule(int id) { return this.longMessageRules.get(id); } public Mtp3ServiceAccessPoint getMtp3ServiceAccessPoint(int id) { return this.saps.get(id); } public boolean spcIsLocal(int spc) { Iterator iterator=this.saps.values().iterator(); while(iterator.hasNext()) { Mtp3ServiceAccessPoint sap = iterator.next(); if (sap.getOpc() == spc) { return true; } } return false; } public Map getRules() { Map rulesMapTmp = new HashMap(); rulesMapTmp.putAll(rulesMap); return rulesMapTmp; } public Map getRoutingAddresses() { Map routingAddressesTmp = new HashMap(); routingAddressesTmp.putAll(routingAddresses); return routingAddressesTmp; } // public Map getBackupAddresses() { // return backupAddresses.unmodifiable(); // } public Map getLongMessageRules() { Map longMessageRulesTmp = new HashMap(); longMessageRulesTmp.putAll(longMessageRules); return longMessageRulesTmp; } public Map getMtp3ServiceAccessPoints() { Map sapsTmp = new HashMap(); sapsTmp.putAll(saps); return sapsTmp; } public void addRule(int id, RuleType ruleType, LoadSharingAlgorithm algo, OriginationType originationType, SccpAddress pattern, String mask, int pAddressId, int sAddressId, Integer newCallingPartyAddressAddressId, int networkId, SccpAddress patternCallingAddress) throws Exception { Rule ruleTmp = this.getRule(id); if (ruleTmp != null) { throw new Exception(SccpOAMMessage.RULE_ALREADY_EXIST); } int maskumberOfSecs = (mask.split("/").length - 1); int patternNumberOfSecs = (pattern.getGlobalTitle().getDigits().split("/").length - 1); if (maskumberOfSecs != patternNumberOfSecs) { throw new Exception(SccpOAMMessage.SEC_MISMATCH_PATTERN); } SccpAddress pAddress = this.getRoutingAddress(pAddressId); if (pAddress == null) { throw new Exception(String.format(SccpOAMMessage.NO_PRIMARY_ADDRESS, pAddressId)); } int primAddNumberOfSecs = (pAddress.getGlobalTitle().getDigits().split("/").length - 1); if (maskumberOfSecs != primAddNumberOfSecs) { throw new Exception(SccpOAMMessage.SEC_MISMATCH_PRIMADDRESS); } if (sAddressId != -1) { SccpAddress sAddress = this.getRoutingAddress(sAddressId); if (sAddress == null) { throw new Exception(String.format(SccpOAMMessage.NO_BACKUP_ADDRESS, sAddressId)); } int secAddNumberOfSecs = (sAddress.getGlobalTitle().getDigits().split("/").length - 1); if (maskumberOfSecs != secAddNumberOfSecs) { throw new Exception(SccpOAMMessage.SEC_MISMATCH_SECADDRESS); } } if (sAddressId == -1 && ruleType != RuleType.SOLITARY) { throw new Exception(SccpOAMMessage.RULETYPE_NOT_SOLI_SEC_ADD_MANDATORY); } RuleImpl rule = new RuleImpl(ruleType, algo, originationType, pattern, mask, networkId, patternCallingAddress); rule.setPrimaryAddressId(pAddressId); rule.setSecondaryAddressId(sAddressId); rule.setNewCallingPartyAddressId(newCallingPartyAddressAddressId); rule.setRuleId(id); this.rulesMap.put(id, rule); } public void modifyRule(int id, RuleType ruleType, LoadSharingAlgorithm algo, OriginationType originationType, SccpAddress pattern, String mask, int pAddressId, int sAddressId, Integer newCallingPartyAddressAddressId, int networkId, SccpAddress patternCallingAddress) throws Exception { Rule ruleTmp = this.getRule(id); if (ruleTmp == null) { throw new Exception(String.format(SccpOAMMessage.RULE_DOESNT_EXIST, name)); } int maskumberOfSecs = (mask.split("/").length - 1); int patternNumberOfSecs = (pattern.getGlobalTitle().getDigits().split("/").length - 1); if (maskumberOfSecs != patternNumberOfSecs) { throw new Exception(SccpOAMMessage.SEC_MISMATCH_PATTERN); } SccpAddress pAddress = this.getRoutingAddress(pAddressId); if (pAddress == null) { throw new Exception(String.format(SccpOAMMessage.NO_PRIMARY_ADDRESS, pAddressId)); } int primAddNumberOfSecs = (pattern.getGlobalTitle().getDigits().split("/").length - 1); if (maskumberOfSecs != primAddNumberOfSecs) { throw new Exception(SccpOAMMessage.SEC_MISMATCH_PRIMADDRESS); } if (sAddressId != -1) { SccpAddress sAddress = this.getRoutingAddress(sAddressId); if (sAddress == null) { throw new Exception(String.format(SccpOAMMessage.NO_BACKUP_ADDRESS, sAddressId)); } int secAddNumberOfSecs = (pattern.getGlobalTitle().getDigits().split("/").length - 1); if (maskumberOfSecs != secAddNumberOfSecs) { throw new Exception(SccpOAMMessage.SEC_MISMATCH_SECADDRESS); } } if (sAddressId == -1 && ruleType != RuleType.SOLITARY) { throw new Exception(SccpOAMMessage.RULETYPE_NOT_SOLI_SEC_ADD_MANDATORY); } this.removeRule( id ); } public void removeRule(int id) throws Exception { if (this.getRule(id) == null) { throw new Exception(String.format(SccpOAMMessage.RULE_DOESNT_EXIST, name)); } this.rulesMap.remove(id); } public void addRoutingAddress(int primAddressId, SccpAddress primaryAddress) throws Exception { if (this.getRoutingAddress(primAddressId) != null) { throw new Exception(SccpOAMMessage.ADDRESS_ALREADY_EXIST); } this.routingAddresses.put(primAddressId, (SccpAddressImpl) primaryAddress); } public void modifyRoutingAddress(int primAddressId, SccpAddress primaryAddress) throws Exception { if (this.getRoutingAddress(primAddressId) == null) { throw new Exception(String.format(SccpOAMMessage.ADDRESS_DOESNT_EXIST, name)); } this.routingAddresses.put(primAddressId, (SccpAddressImpl) primaryAddress); } public void removeRoutingAddress(int id) throws Exception { if (this.getRoutingAddress(id) == null) { throw new Exception(String.format(SccpOAMMessage.ADDRESS_DOESNT_EXIST, name)); } this.routingAddresses.remove(id); } public void addLongMessageRule(int id, int firstSpc, int lastSpc, LongMessageRuleType ruleType) throws Exception { if (this.getLongMessageRule(id) != null) { throw new Exception(SccpOAMMessage.LMR_ALREADY_EXIST); } LongMessageRuleImpl longMessageRule = new LongMessageRuleImpl(firstSpc, lastSpc, ruleType); this.longMessageRules.put(id, longMessageRule); } public void modifyLongMessageRule(int id, int firstSpc, int lastSpc, LongMessageRuleType ruleType) throws Exception { if (this.getLongMessageRule(id) == null) { throw new Exception(String.format(SccpOAMMessage.LMR_DOESNT_EXIST, name)); } LongMessageRuleImpl longMessageRule = new LongMessageRuleImpl(firstSpc, lastSpc, ruleType); this.longMessageRules.put(id, longMessageRule); } public void modifyLongMessageRule(int id, Integer firstSpc, Integer lastSpc, LongMessageRuleType ruleType) throws Exception { LongMessageRule oldLmr = this.getLongMessageRule(id); if (oldLmr == null) { throw new Exception(String.format(SccpOAMMessage.LMR_DOESNT_EXIST, name)); } if(firstSpc == null) firstSpc = oldLmr.getFirstSpc(); if(lastSpc == null) lastSpc = oldLmr.getLastSpc(); if(ruleType == null) ruleType = oldLmr.getLongMessageRuleType(); LongMessageRuleImpl longMessageRule = new LongMessageRuleImpl(firstSpc, lastSpc, ruleType); this.longMessageRules.put(id, longMessageRule); } public void removeLongMessageRule(int id) throws Exception { if (this.getLongMessageRule(id) == null) { throw new Exception(String.format(SccpOAMMessage.LMR_DOESNT_EXIST, name)); } this.longMessageRules.remove(id); } public void addMtp3Destination(int sapId, int destId, int firstDpc, int lastDpc, int firstSls, int lastSls, int slsMask) throws Exception { Mtp3ServiceAccessPoint sap = this.getMtp3ServiceAccessPoint(sapId); if (sap == null) { throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); } // TODO Synchronize?? sap.addMtp3Destination(destId, firstDpc, lastDpc, firstSls, lastSls, slsMask); } public void modifyMtp3Destination(int sapId, int destId, int firstDpc, int lastDpc, int firstSls, int lastSls, int slsMask) throws Exception { Mtp3ServiceAccessPoint sap = this.getMtp3ServiceAccessPoint(sapId); if (sap == null) { throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); } // TODO Synchronize?? sap.modifyMtp3Destination(destId, firstDpc, lastDpc, firstSls, lastSls, slsMask); } public void modifyMtp3Destination(int sapId, int destId, Integer firstDpc, Integer lastDpc, Integer firstSls, Integer lastSls, Integer slsMask) throws Exception { Mtp3ServiceAccessPoint sap = this.getMtp3ServiceAccessPoint(sapId); if (sap == null) throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); Mtp3DestinationImpl dest = (Mtp3DestinationImpl) sap.getMtp3Destination(destId); if(dest == null) throw new Exception(String.format(SccpOAMMessage.DEST_DOESNT_EXIST, name)); if(firstDpc == null) firstDpc = dest.getFirstDpc(); if(lastDpc == null) lastDpc = dest.getLastDpc(); if(firstSls == null) firstSls = dest.getFirstSls(); if(lastSls == null) lastSls = dest.getLastSls(); if(slsMask == null) slsMask = dest.getSlsMask(); sap.modifyMtp3Destination(destId, firstDpc, lastDpc, firstSls, lastSls, slsMask); } public void removeMtp3Destination(int sapId, int destId) throws Exception { Mtp3ServiceAccessPoint sap = this.getMtp3ServiceAccessPoint(sapId); if (sap == null) { throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); } sap.removeMtp3Destination(destId); } public void addMtp3ServiceAccessPoint(int id, int mtp3Id, int opc, int ni, int networkId, String localGtDigits) throws Exception { if (this.getMtp3ServiceAccessPoint(id) != null) { throw new Exception(SccpOAMMessage.SAP_ALREADY_EXIST); } if (this.sccpStack.getMtp3UserPart(mtp3Id) == null) { throw new Exception(SccpOAMMessage.MUP_DOESNT_EXIST); } if (localGtDigits != null && (localGtDigits.equals("null") || localGtDigits.equals(""))) localGtDigits = null; Mtp3ServiceAccessPointImpl sap = new Mtp3ServiceAccessPointImpl(mtp3Id, opc, ni, this.name, networkId, localGtDigits); this.saps.put(id, sap); } public void modifyMtp3ServiceAccessPoint(int id, int mtp3Id, int opc, int ni, int networkId, String localGtDigits) throws Exception { if (this.getMtp3ServiceAccessPoint(id) == null) { throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); } if (this.sccpStack.getMtp3UserPart(mtp3Id) == null) { throw new Exception(SccpOAMMessage.MUP_DOESNT_EXIST); } if (localGtDigits != null && (localGtDigits.equals("null") || localGtDigits.equals(""))) localGtDigits = null; Mtp3ServiceAccessPointImpl sap = new Mtp3ServiceAccessPointImpl(mtp3Id, opc, ni, this.name, networkId, localGtDigits); this.saps.put(id, sap); } public void modifyMtp3ServiceAccessPoint(int id, Integer mtp3Id, Integer opc, Integer ni, Integer networkId, String localGtDigits) throws Exception { Mtp3ServiceAccessPointImpl sap = (Mtp3ServiceAccessPointImpl) this.getMtp3ServiceAccessPoint(id); if (sap == null) { throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); } if (mtp3Id != null && this.sccpStack.getMtp3UserPart(mtp3Id) == null) { throw new Exception(SccpOAMMessage.MUP_DOESNT_EXIST); } if (localGtDigits != null && (localGtDigits.equals("null") || localGtDigits.equals(""))) localGtDigits = null; if(mtp3Id == null) mtp3Id = sap.getMtp3Id(); if(opc == null) opc = sap.getOpc(); if(ni == null) ni = sap.getNi(); if(networkId == null) networkId = sap.getNetworkId(); if(localGtDigits == null) localGtDigits = sap.getLocalGtDigits(); Mtp3ServiceAccessPointImpl newSap = new Mtp3ServiceAccessPointImpl(mtp3Id, opc, ni, this.name, networkId, localGtDigits); this.saps.put(id, newSap); } public void removeMtp3ServiceAccessPoint(int id) throws Exception { if (this.getMtp3ServiceAccessPoint(id) == null) { throw new Exception(String.format(SccpOAMMessage.SAP_DOESNT_EXIST, name)); } this.saps.remove(id); } public void removeAllResourses() { // if (this.rulesMap.size() == 0 && this.routingAddresses.size() == 0 && this.backupAddresses.size() == 0 // && this.longMessageRules.size() == 0 && this.saps.size() == 0) if (this.rulesMap.size() == 0 && this.routingAddresses.size() == 0 && this.longMessageRules.size() == 0 && this.saps.size() == 0) // no resources allocated - nothing to do return; rulesMap = new RuleMap(); routingAddresses = new SccpAddressMap(); // backupAddresses = new SccpAddressMap(); longMessageRules = new LongMessageRuleMap(); saps = new Mtp3ServiceAccessPointMap(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy